一般一个文件都是以字节的方式存储的,如果想要让其可读,就必须要通过正确的编码方式转换成字符;就像Java IO一样,如果没有通过正确的编码方式打开一个文件,会出现乱码。因此在一系列处理步骤之前,知道文档的编码是重要的。一般在文档的meta data部分都会保存编码方式。
索引粒度的选取也是很重要的。因为如果把索引粒度选的太大,比如你想找Information Retrieval,如果索引粒度为整本书,则只要出现Information和Retrieval的书都会被选中,这非常不精确。
词条化:这个方法就像Java中StringTokenizer的用法,将一个文档(长的字符串)切分成一个个小单词。
Token:词条化后的一个个单词;
Type:将词条化的单词放入集合后的结果。
Term:将Type进行归一化后的结果,即dictionary中能找到的词。
比如 a apple and a banana ;有5个token,4个type(a合并),2个Term(去除停用词);
停用词就是一些很常用的词,比如the, a 等;这些词因为出现的次数很多,每篇文档都会出现,所以如果要让他也在倒排索引中,则会引起posting过大的情况。
注意:
(1)有时去除停用词的方法也会有问题,比如:to be or not to be,to be 都是停用词,那么查询变成了 or not,则意义完全不一致。
(2)去除停用词是应用于文档和查询的,在文档中,不对停用词构建倒排索引,而在查询中,也去除停用词,只将其他词做索引。
去除停用词缺点:会使表达的语义不一致,比如from Shanghai to BeiJing;变成Shanghai Beijing 则语义会不一致;
如果有一个等价类:{A,B,C,D};如果需要查询A,则等同于查询A,B,C,D;
而Normalization就是利用等价类,常用的方法是:大小写转换(case folding);
注意:
(1)大小写转换也会有缺点:比如C.A.T,会转换成cat ,偏离了原本意义。
(2)等价类也是同时应用于查询和文档的。
Stemming:简单的通过截取的方式去除前缀和后缀。比如solution,变成 solu;
词干还原能够提高查全率,降低查准率;因为比如respective和respectability都转换成respect,但是意义却不一样,因此在查询respectability时,会通过stemming转换成respect,并且查询到respective。
stemming能够降低dictionary的大小;
Porter算法:一种针对英文,有效的词干分析的算法。
Porter预先会给出一些mapping:
tion--->空
IES---->I
等等;
规则1:去除后缀后长度大于1;
规则2:当多条匹配时,则取最长的。
Lemmatization:通过词典的分析来进行合理地去除词缀,比如men,变成man;
lemma:词形分析后得到的单词;
注意:词干还原和词形分析是对文档和查询词使用的,因此在建立索引是就会把respective和respectability解析成一个respect,即dictionary中是respect,posting是这两个词的docID的并集。而在查询时如果查询的词是respective,则会进行词干还原,并变成respect后在倒排索引中寻找。
原本的倒排记录表合并算法需要O(m+n),但是如果使用了跳表,则可以达到次线性时间。
在posting中包含skip pointer,可以跳过那些肯定不在结果中的docID,并且只适用于AND操作。
通常:每(根号p)处放一个倒排指针,p为倒排记录表的长度;
比如:有16个docID,如下:
则每四个放置一个跳表,即1-->5,5-->9,9-->13,13-->17;
注意:这种方法适用于倒排索引稳定的前提;
在posting的每个docID后面跟上单词出现的位置,比如:apple -----> 1(2,3,4);2(4,5,6);
注意:positional index可以进行邻近搜索,而二元词不能。
缺点:倒排记录表的posting太大。
应用:处理邻近查询。
采用positional index进行合并需要的复杂度是O(T); T是文档集中词条数目;
将两个词看成一个item,即在dictionary中都是两个词为一组。
比如invert and revert,则会变成invert and和and revert;但是这种做法使得倒排记录表迅速变大。
这种方法的缺点很多:
(1)不适用于单词查询。
(2)倒排记录表太大。
(3)查询有时还不正确。需要进行后过滤(即在查询词组中过滤一遍)
(1)对于单个单词出现次数非常多,而组成一个词组后出现次数大大减少的词组,用biword index;
(2)对于那些经常被用户查询的词组,使用biword index;
(3)其余使用positional index;