倒排文件索引(Inverted File Index)的建立

建立索引

目前主流的索引技术有三种:倒排文件、后缀数组和签名。后缀数组的方法虽然快,但是其维护困难,代价相当高,不适合做引擎的索引。签名是一种很好的索引方式,但倒排文件的速度和性能已经超过了签名。倒排文件是一种在各大搜索引擎中被主要使用的索引的方式,并且它也是搜索引擎中一个核心的技术。

5.2.1  倒排文件索引(Inverted File Index)的建立

倒排索引文件是一种面向单词的索引机制,每个文件都可以用一系列关键字来表示。一个典型的倒排索引主要由词汇表(也叫索引项)和事件表(也叫文件链表)两部分组成。词汇表是用来存放分词词典的,通常称存放词汇表的文件为索引文件;事件表是用来存放这个文件中对应词汇表中词汇出现的位置和次数的,通常称存放出现位置的文件为位置文件。

1.倒排文件的建立

(1)顺排文件的建立

假设有网页P1,P2,……,Pn,给每个网页文件赋予一个编号Pid,给每个关键字赋予一个编号keyi,假设key是网页文件中的一个关键字,ni表示该关键字在网页文件中出现的次数,<hit1,hit2,…,hitn>表示该关键字在网页文件中的位置信息。首先将网页内容切分成一系列关键字:Pi={Key1,key2,…,keyn}。建立以下顺排文件:

P1={[n1,Key1(hit1,hit2,…,hitn)],…,[nx,keyi(hit1,hit2,…,hitx)] }

P2={[n1,Key1(hit1,hit2,…,hitn)],…,[nn,keyk(hit1,hit2,…,hitn)] }

…………

Pn={[n1,Key1(hit1,hit2,…,hitn)],…,[ny,keyj(hit1,hit2,…,hity)] }

例如,对以下两段文字进行顺排文件操作。

“随着经济的发展,人们对生活的品质要求越来越高。特别是在视觉欣赏方面,更是追求精益求精。如何把模糊的图像变得清晰,把暗淡的色彩变得色彩鲜艳是一个非常值得研究的课题。并且在数字电视、扫描仪、医疗图像、计算机视觉、卫星监测、航空摄像等方面对图像的清晰度有着广泛的需求。目前基于网格和密度的聚类方法已经渗透到各个领域,且得到了令人意想不到的效果。本文是将基于网格和密度的聚类方法运用到模糊图像中,从而对图像进行增色处理。”

“数字图像处理又称为计算机图像处理,它是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。数字图像处理最早出现于20世纪50年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为一门学科大约形成于20世纪60年代初期。早期的图像处理的目的是改善图像的质量,它以人为对象,以改善人的视觉效果为目的。”

假设第一段文字是一个网页P1的全部内容,段首的起始位置为1。第二段文字是第二个网页P2的全部内容,段首的起始位置为1。

对网页进行自动分词,得到关键字以及关键字在网页文件中出现的位置信息。顺排文件的结果为:

P1={[1,经济(3)],[1,发展(6)],……,[2,视觉(26,93)],……,[5,图像(46,88,107,177,182)],……,[1,处理(189)]}

P2={[4,数字(1,29,48,101)],[8,图像(3,13,21,49,96,103,130,140)],……,[1,视觉(156)],……,[2,目的(135,161)]}

(2)实现倒排文件的原理

顺排文件是以网页来索引关键字的,即形式为(网页→关键字),不符合搜索引擎的需要。因此,需进行倒排处理,以关键字来索引网页,即形式为(关键字→网页):
Keyi→{[Pid1,ni1(hit1,hit2,…,hitni1)],…,[Pidn,nin(hit1,hit2,…,hitnin)]}

对以上顺排文件中建立的两个实例网页P1和P2的顺排文件进行倒排,倒排文件的结果为:

经济→{[P1,1(3)]}

发展→{[P1,1(6)],[P2,1(74)]}

……

视觉→{[P1,2(26,93)],[P2,1(156)]}

……

图像→{[P1,5(46,88,107,177,182)],[P2,8(3,13,21,49,96,103,130,140)]}

……

综上所述,倒排文件的实现过程是:先得到顺排文件,然后根据顺排文件得到倒排文件,从而实现由关键字来索引网页。

(3)倒排文件的优化之一—位图文件

在实际中,一般索引项并不存储实际的关键字,而存储它的一个编号值(kid),这样可以有效节约存储空间。对于文件链表(Posting),只存储网页文件编号(Pid)和网页文件编号加上该关键字在文件中出现的位置信息。

其中Pid1,…,Pidn表示包含关键字ki的所有网页文件集合,考虑到文件链表进行布尔运算时,速度不是很快,以及使用文件链表要消耗大量内存等问题,一般采用位图(Bitmap)文件来实现倒排索引。Bitmap的优点是布尔运算非常快,直接用对应的bit位作运算就可以了。想要得到同时包含某几个关键字的网页,那么直接把它们对应的网页文件位图向量进行与运算,就可以知道在哪些文件中同时包含了这几个关键字。在文件数目不是很多的情况下,只存储命中信息,实现了命中信息和非命中信息(比如关键字在文件中的位置,关键字在文件中出现的频率等)的分离,可以大大提高索引的效率。

把由网页文件向量Pi=<key1,key2,…,keyn>构成的“网页→关键字”,转化成“关键字→网页”。转换方法是根据网页文件向量构成“网页-关键字”阵列,如图5-2所示,并用Bitmap作为存储结构,形成倒排矩阵A,如图5-3所示。

倒排矩阵中的Aij元素取值为0,表示网页Pj中没有关键字ki;倒排矩阵中的Aij元素取值为1,表示网页Pj中有关键字ki。以此可以得到包含某关键字的网页的文件集合,然后根据文件链表得到此关键字在网页中的出现位置信息。

倒排文件索引(Inverted File Index)的建立_第1张图片 

Bitmap文件实现的倒排矩阵在海量数据环境下是比较稀疏的,必须对它进行压缩,并且保证在解压的过程中,速度也比较快,这样可以大大提高索引的性能,也节省了大量的存储空间。目前比较成熟的位图压缩算法主要有Delta encoding、Variable-length encoding、Gamma codes等。

虽然它们都是比较成熟的算法,但是要么实现起来比较复杂;要么压缩效率很高,但是解压的过程要消耗较长的时间,这对于搜索引擎的实时响应要求很高的系统是不适合的。

2.改善倒排文件性能的方法

倒排文件的时间代价主要取决于词汇表的组织方式,词汇表文件通常较小且比较固定,对于未登录词和数词可以按字建索引;倒排文件的空间代价主要取决于对事件表的压缩能力,事件表的压缩能减少I/O操作,也能提高部分时间性能。词汇表文件的组织方式通常采用Hash散列表,按字母表顺序有序排列,采用Trie树、B树等查找树。事件表的压缩通常采用Bitmap文件压缩或差值压缩(Delta Compression)词汇表的哈希存储,根据给定的关键字,散列成一个整数,用该整数作为词汇的访问地址。

倒排文件的优点是:实现简单,响应时间快,支持复杂查询,适合商用搜索引擎。缺点是:建立索引要消耗很大的磁盘、内存空间;当网页更新后,索引的维护代价也比较大

.建立倒排文件索引的举例——Lucene索引

下面讲解一个倒排文件索引的例子—Lucene倒排索引。Lucene是一个高性能的Java全文检索工具包,它使用的是倒排文件索引结构。该结构及相应的生成算法如下。

假设有3篇文章:

文章1的内容为:I was a student, i came from chengdu.

文章2的内容为:My father is a teacher, and i am a student.

文章3的内容为:Chengdu is my hometown. my father’s hometown is wuhan.

Lucene是基于关键字索引和查询的。首先取得这3篇文章的关键字,通常需要如下处理措施(在Lucene中以下措施由Analyzer类完成):

1)需要把3篇文章的内容切分成一个个单词,作为索引关键字的候选集。英文中单词与单词之间有空格,分词比较好处理,但中文字与字之间没有空隔,是连在一起的,所以中文分词处理要麻烦。

2)需要将文章中分离出来的没有实际意义的单词过滤掉。比如a、from、and,中文中的“的”、“也”、“啊”等通常无具体含义的词可以去掉。还要过滤掉标点符号。

3)单词需要统一大小写。

4)查找与当前关键字相关联的其他关键字,即统一单词不同的时态。如“came”、“coming”统一成“come”,再进行查找。

经过上面处理后,3篇文章的所有关键字为:

文章1:[i] [am] [student] [i] [come] [chengdu]

文章2:[my] [father] [is] [teacher] [i] [am] [student]

文章3:[chengdu] [is] [my] [hometown] [my] [father] [hometown] [is] [wuhan]

有了关键字后,就可以建立倒排索引了。上面的对应关系是顺排的,即“文章号→关键字”,倒排处理为“关键字→文章号”。文章1、2、3经过倒排后变成如表5-1所示。

表5-1  倒排文件

    

    

i

12

am

12

student

12

come

1

chengdu

1,3

my

2,3

father

2,3

is

2,3

teacher

2

hometown

3

wuhan

3

加上“出现频率”和“出现位置”信息后,索引结构变为如表5-2所示。

表5-2  索引结构

    

文章号[出现频率]

出 现 位 置

i

1[2],2[1]

[14,5]

am

1[1],2[1]

[2,6]

student

1[1],2[1]

[3,7]

come

1[1]

[5]

chengdu

1[1],3[1]

[6,1]

my

2[1],3[2]

[1,35]

father

2[1],3[1]

[2, 6]

is

2[1],3[2]

[3,28]

teacher

2[1]

[4]

hometown

3[2]

[47]

wuhan

3[1]

[9]

以my这行为例来说明一下该结构。my在文章2中出现了1次,文章3中出现了2次,它的出现位置为“1,3,5”,结合文章号和出现频率来分析,文章2中出现了1次,那么“1”就表示my在文章2中出现的一个位置,文章3中出现了2次,剩下的“3,5”就表示my是文章3中第3个和第5个关键字。

以上便是Lucene索引结构中最核心的部分。关键字是按字符顺序排列的(Lucene没有使用B树结构),因此Lucene可以用二元搜索算法快速定位关键字。

实现时Lucene将上面三列分别作为词典文件(Term Dictionary)、频率文件(Frequencies Dictionary)、位置文件(Positions Dictionary)保存(将事件表分为两个文件)。其中词典文件不仅保存有每个关键字,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。

Lucene中使用了field的概念,用于表达信息所在位置(如标题中、文章中、url中),在建索引中,该field信息也记录在词典文件中,每个关键字都有一个field信息(因为每个关键字一定属于一个或多个field)。

为了减小索引文件的大小,Lucene对索引还使用了压缩技术。首先,对词典文件中的关键字进行了压缩,关键字压缩为<前缀长度,后缀>。例如:当前词为“马来西亚语”,上一个词为“马来西亚”,那么“马来西亚语”压缩为<4,语>。其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如,当前文章号是14569(不压缩要用3个字节保存),上一文章号是145704,压缩后保存5(只用一个字节)。

你可能感兴趣的:(索引,搜索引擎)