倒排索引作用
试想一下这个情景,你也记不清什么时候读过这个一段话:“老刘,老刘,食量大似牛,吃一个老母猪不抬头.”,只记得是红楼梦里面的台词,上学的时候语文老师还解读过,现在觉得特别有意思,想看看完整的这个故事。
于是你买了一本《红楼梦》,打开目录,定位不同章节的位置,然后按照顺序一章一章的遍历,找找哪一章里面有这么一句话。终于经过你不懈的努力终于找到这句话来自于“刘姥姥进大观园”哪一章。
这个检索的过程,映射关系是从文档到关键词,因为我们是翻阅不同的章节文档来检索哪里出现了这么一句话。
这都能忍?也是服了。如何解决这个问题呢?为了查找某一个或多个关键词,不得不查询遍历所有文档,得出这些关键词出现在哪些文档中。这种方式未免也太耗时耗力了,有没有一种方法能够快速检索到呢?
思考一下,我们要避免根据章节一章章的取遍历查询,能不能够根据词来定位到章节呢?像新华字典那样,查找某个词,然后定位到某个词的页数,如果也对《红楼梦》这本书也建立那样的索引,起步不是非常的方便?
这个建索引的过程,就是所谓的倒排索引,是从关键词到文档,这是一个反过程。英文叫 invert index ,你也可以理解为反索引,或者逆索引,只不过这种索引方式,大部分译为倒排索引。
创建倒排索引
针对《红楼梦》这本书,我们搭建一个搜索引擎,因此人为的查找实在是太变态了。
首先以章节为 ID 建立一个《红楼梦》数据库。
ID | Text |
---|---|
0 | 老刘,老刘,食量大似牛,吃一个老母猪不抬头 |
1 | 女儿是水作的骨肉,男人是泥作的骨肉。 |
2 | 必得两个女儿伴着我读书,我方能认得字 |
常规的检索方法,遍历 ID ,通过 ID 查找对应的 Text 是否包含”老刘,老刘,食量大似牛,吃一个老母猪不抬头“这句话。如果使用倒排索引该怎么做呢?
- 首先对文档分词,并统计词在哪个章节 ID 里面
- 生成一张"词-章节"映射表
- 对查找句子进行分词,拿着这些词到映射表中查找,在哪个章节里面
- 计算并排序相似度,相似度的 topN 推荐给用户
建设倒排索引映射表(为了减少冗余,这里分词结果没有被全部列出):
Word | ID |
---|---|
老刘 | 0 |
食量 | 0 |
老母猪 | 0 |
女儿 | 1,2 |
男人 | 1 |
骨肉 | 1 |
读书 | 2 |
方能 | 2 |
两个 | 2 |
基于倒排索引查询
假设映射表如上,我们再对”老刘,老刘,食量大似牛,吃一个老母猪不抬头“这句话进行检索,首先这句话会被分词处理成”老刘,食量,老母猪“。
得到了这三个词,到索引表中检索,得到的结果是(0,3,100%),0代表章节的ID,4代表词在对应章节中命中的次数,100%代表通过某种相似度计算方法得出的相似度(这里相似度的计算方法,假设为”相似度=检索语句命中的词个数/检索语句总的词个数“),因此就能轻易的得出,这句话很有可能出现在《红楼梦》的第一章中。
再对一句话进行检索”女儿一定要学会读书写字“,这句话将会被分词处理成”女儿,读书,写字“。
再到索引表中去检索,得到
- (1,1,33%),第一个1代表章节ID,第二个1代表三个词在这个章节中只命中了一个,33%代表我使用相似度方法计算的相似度。
- (2,2,66%),第一个2代表章节ID,第二个2代表三个词在第2章节中命中了2个,66%是计算的相似度。
对相似度进行排序,自然搜索引擎将会把文档2推荐出来。这里可能会有个疑问,为什么把2推荐出来呢?这句话在红楼梦中并不存在啊?从这里就可以看出,搜索引擎只是根据相似度进行推荐,而并不能保证推荐的一定是对的。搜索引擎只是将数据库中相似的案例推荐给你。
小结
通过本小节我们明白了,什么是倒排索引,以及如何建立倒排索引。对搜索引擎原理有个大致的了解,明白了搜索引擎原理,原来搜索引擎是通过相似度的指标将文档推荐出来,怪不得使用百度搜索关键词是总是出来很多链接,并且越往后的链接越是跟想要搜索的内容不相关。