基于倒排索引和向量空间模型的信息检索系统
- 通过网络爬虫爬取100+篇中文文档,进行本地存储;
- 文章通过开源jieba库进行分词,以词作为基本单元;
- 系统提供了倒排索引、向量空间索引、隐性语义分析3种方法进行检索;
- 用户查询输入可以是自然语言字串,查询结果按相关度从大到小排序,并列出相关内容;
- 使用了基于Vue+Django的前后端B/S结构。
布尔检索的核心在于布尔表达式,即由关键词和布尔运算符按照语法规则构成的一句表达式。 关键词就是需要被查询的词,运算符包括“与”逻辑“and”;“或”逻辑 “or”;“非”逻辑“not”。对于以上给定的运算符,运算优先级顺序为:“not”> “and” > “not”。除此之外,还可以使用成对括号“(”,“)”来改变局部的优先级。
- 倒排索引(Inversed index)的特点是不通过文档来寻找关键词,而是通过关键词来定位文档及它在文档中出现的具体位置, 它的工作原理就是通过建立索引和位置表的映射来达到高速查询的效果。
- 倒排索引的数据结构逻辑上可以分为两部分:索引项和位置表。索引项应当是有具体含义(名词)并且在文档中频繁出现、占有较大比重的词,在我们的系统设计中,因为文档的数目只有100篇左右,所以我们将所有名词之外的词视作停用词,将所有的名词都作为索引项。最终我们索引的规模在4000个左右。
- 对于每一个索引,都有一个位置表项与之对应,这个位置表项列举了它在文本库中出现的所有位置。在我们系统中,位置表项是一个列表,每个列表元素是一个字典,字典的键值对包括文章的ID、词频数、以及索引项的位置信息。这个位置信息不仅包括改索引项的序号,还包括一定的上下文信息。所有的索引项和与之对应的位置表项组成了倒排索引的索引表,它的结构示意图如下所示:
- 向量空间模型中,所有的查询和文档都被表示成n维空间中的向量,检索系统计算查询向量和所有文档向量之间的相关性,按照相关性大小对文档排序返回给用户。相关性的计算既可以采用夹角余弦的方法,也可以使用求向量内积的方法,二者都是取最大值。
- n维空间的维数就是索引项的数目,每篇文档都对应一个向量,所有向量组成的矩阵叫做索引项-文档矩阵。一个向量中各个位置的定义可以有很多方式,比如某个词在文档或查询中出现,就在相应位置上置1,否则置0;或者在相应位置上填写某个词的出现次数。
- TF-IDF算法
- TF-IDF算法实际上是一个非常简单的算法,词频(Term Frequency,缩写TF)的局限性(不重要的词可能广泛出现在许多文章中)决定了它需要一个重要性调整系数也就是权重。这个权重叫做逆文档频率(Inverse Document Frequency,缩写为IDF),它的大小与一个词的常见程度成反比。对每个词计算它的IDF值,之后和每篇文章的词频向量相乘,就可得出基于TF-IDF算法的向量。
- TF(词频) 的计算:
为了不同长短的文章之间进行比较,需要对词频进行标准化,可以采用如下方法: TF = 某个词在文章的出现次数/文章的总词数;或者 TF = 某个词在文章的出现次数/该文章出现次数最多的词的出现次数。 这两种计算方法本质上是一致的,在我们的系统中,我们选择第一种。 - IDF(逆文档频率) 的计算:
IDF = log(语料库的文档总数/(包含该词的文档数+1)) 如果一个词越常见,分母越大,逆文档频率越小。分母之所以要加1,是为了避免分母取0(有可能所有文档都没有该词)。 - TF-IDF 的计算:
TF-IDF = TF(词频)× IDF(逆文档频率) 可以看到,TF-IDF值与一个词在文档中的出现次数成正比,与该词在整个语言环境中的出现次数成反比。
- 不同语义段的权重赋予 单纯以“词频”衡量一个词的重要性是有局限的,TF-IDF算法无法体现一个词的位置信息。根据我们观察,每篇文档都可以分为标题和正文两部分。针对标题语义段,我们赋予更大的权重。具体的实现方法是,在计算词频的时候,将标题的词频乘以一定的权重,之后计算TF和IDF等内容,最后完成索引项-文档矩阵的构造。
- 隐性语义索引(Latent Semantic Idexing, LSI),也叫Latent Semantic Analysis(LSA),是信息检索领域一类非常重要的技术思想。它通过对词项-文档矩阵的奇异值分解,在理论上成功地解决了潜在语义(或者叫隐性语义)的检索问题。
- 前面两种算法都是基于关键词的匹配,实际上大部分情况是很有效的。但是随着信息结构的复杂和长度增加,完全依靠匹配判断就显得有所不足。比如“北邮”和“北京邮电大学”这两个词,在语义上是完全一样的,但是通过关键词查找很可能找不到另外一个词;再比如“苹果”与“ios”放在一起的语义和“苹果”与“香蕉”放在一起的语义几乎是无关的,但是关键词检索完全可能同时检索出这两个词。
- 因此,识别数词的“隐性语义”是一个重要问题。关于隐性语义,有一个最基本的原则:在大型的文档集中,两个词的语义越相近,它们共现的概率也就越大。这样,我们可以利用对于词项和文档之间关系的分析,得到概念与词项之间的关系。
- 和PCA(主成分分析)的基本思想基本一致,不同词项之间也可能存在着相关关系,比如,如果词a出现,则词b也以极大的概率出现,相应的,我们自然想到可以用类似于PCA的降维方式对词项-文档矩阵降维,使得每个文档对应的词向量的维度降低。而维度降低之后的元素则不是词项了,我们把它叫做“概念”(或者叫“主题”)。降维是LSI的核心思想,只不过他的出发点不是要加速计算,而是解决如何将一个个的词,映射为统一的语义(概念、主题)。实际上,LSI的处理方法与PCA在最后一步是有所不同的,对于搜索算法的复杂度来说,LSI并未真正降维,而是将每个维度的词变换为一个词义。
- LSI的主要工作结果是:词义-文档矩阵,也就是上式中近似分解计算出来的A′。其中每个列向量代表了一个文档,这个文档的每个元素由“词义”决定,而并非最初用的TF-IDF。至于查询向量和文档向量的相似度计算,采用和传统向量空间模型的计算方法即可。
本项目除了信息检索以外,还包括信息抽取系统,包括文本信息抽取和图片信息抽取两部分,这两部分由我的两位伙伴QLX和XR完成,本人主要负责信息检索部分。