为什么要压缩?
词典压缩:
词典压缩的主要动机: 使之能够尽量放入内存中
倒排记录表压缩:
倒排记录表压缩的主要动机: 减少磁盘存储空间,减少从磁盘读入内存的时间
注意: 大型搜索引擎将相当比例的倒排记录表都放入内存
有损(Lossy) vs 无损(Lossless)压缩
有损压缩: 丢弃一些信息。前面讲到的很多常用的预处理步骤可以看成是有损压缩:统一小写,去除停用词, Porter词干还原, 去掉数字
无损压缩: 所有信息都保留。索引压缩中通常都使用无损压缩
信息检索中词项的统计特性
词项数目(即词汇表(词典) 大小)的估计:Heaps定律 M = kTb
M 是词汇表大小, T 是文档集的大小(文档集合中所有词条的个数,即所有文档大小之和)
参数k 和b 的一个经典取值是: 30 ≤ k ≤ 100 及 b ≈ 0.5.
Heaps定律通过文档集合中的词条数来估计词汇表大小,词汇表大小会随着文档集的大小增长而增长!
Heaps定律结论:
词项分布的估计:Zipf定律 cfi ∝ (1/i)
如果出现最多的词项的出现次数是 cf1的话,出现第二多的词项的出现次数就是 cf1的一半,出现第三多的词项出现次数会是 cf1的 1/3,其余均可依此类推。
注:cfi 是文档频率(collection frequency): 词项ti在所有文档中出现的次数(不是出现该词项的文档数目df)
词典压缩
根据Heaps定律,词典会随着文档集的增加而持续增长,因此为了能够把词典全部都放在内存中,我们必须要对其进行压缩。
回顾: 定长数组方式下的词典存储
需要空间:词项+文档频率+倒排记录表指针(20+4+4)*M
大量存储空间被浪费(英语中每个词项的平均长度为8个字符),即使是长度为1的词项,我们也分配20个字节。
不能处理长度大于20字节的词项。
定长数组方式进行优化:将所有的词项存成一个长字符串并给每个词项增加一个定位指针,它在指向下一词项的指针同时也标识着当前词项的结束。
需要空间:词项+文档频率+倒排记录表指针+指向字符串的指针(8+4+4+3)*M
进一步压缩:将长字符串中的词项进行分组变成大小为k 的块(即 k 个词项一组) ,然后对每个块只保留第一个词项的指针。同时,我们用一个额外字节将每个词项的长度存储在每个词项的首部。
再进一步压缩:回顾词典是按字母排序的,词项之间的冗余性信息还没有利用,实际上,按照词典顺序排序的连续词项之间往往具有公共前缀。
前端编码(Front coding):当某个词和前一个词有共同的前缀的时候,后面的词仅仅保存前缀在词中的偏移(offset),以及除前缀以外的字符串(称为后缀)。
8automata8automate9automatic10automation可以采用前端编码方式继续压缩为8automat*a1◇e2◇ic3◇ion
多个连续词项具有公共前缀 automat,那么在前缀的末尾用“ *” 号标识,在后续的词项中用“◇” 表示该前缀。和前面一样,每个词项的前面第一个字节存储了该词项的长度
倒排记录表压缩
对间隔编码: 存储docID间隔而不是docID本身
可变字节(VB)码
一元编码
如果为数n,则n个1后面添一个0。例如3→ 1110
Elias gamma编码
Wiki地址:http://en.wikipedia.org/wiki/Elias_gamma_coding
Elias delta编码
Wki地址:http://en.wikipedia.org/wiki/Elias_delta_coding
对于大数字来说,γ 编码的效率相对较低,这是因为在对偏移部分长度进行编码的时候采用了效率并不高的一元编码,在这点上,δ 编码和 γ编码不一样,即偏移长度部分进行编码并不采用一元编码,而是采用 γ 编码。
例如13的长度部分采用γ 编码为101,13→101,101
注:δ 编码和 γ编码有等价编码方法,估最后编码结果可能会有所不同