文本索引与检索

来源:互联网 发布:易企秀 java 面试 编辑:程序博客网 时间:2024/05/29 07:45


本质上,很多实际需要解决的问题归根到底都是搜索问题 - 在某个空间中寻找特定的目标。而, 文本检索又是其中最典型最基础的一种。文本检索之所以重要,也是因为很多更复杂对象或者结构的检索可以转化为文本检索,或者参考利用文本检索的思想。谈及文本检索, 各种各样的算法不一而足。大体可以分成两类:

        1. 模式固定,文本不定

                这类算法的一个典型场景: 事先定义一些模式(比如说黄色关键词), 对每一个给定的文本,确定是否含有这些关键词

        2. 文本固定,模式不定

                这类算法的一个典型场景:已知网络上的网页库,给定一个字符串,寻找含有这些字符串的网页


不考虑进行文本检索, 对问题,使用直接的文本查找算法当然也可以完成任务。但,这些直接暴力的方法,绝大多数情况都无法满足实际应用的需求。试想,如果搜索引擎在接收到每一个用户的查询关键词之后,开始一个网页一个网页地查找,恐怕需要长年累月才能返回结果了。 提高文本检索的效率, 重点在于构造文本索引。一个好的文本索引能极大地提升检索效率。


关于第一类场景“模式固定, 文本不定”, 文本索引主要是针对模式。 事先对模式实现构建文本索引之后, 新来的查询文本可以进行快速扫描。 本质上,模式索引帮助我们规避无关模式的干扰,避免不必要的计算。 常用的算法有:

        1. 单模式 (只有单一模式文本)

                KMP算法: http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm

        2. 多模式

                AC(Aho-Corasick)算法 (其实是KMP的升级版本): http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm


关于第二类场景“文本固定,模式不定”,文本索引主要针对文本。小到查找一个文档中包含的关键词,大到搜索引擎中的文本索引。常用的算法有:

        1. 文本索引数据结构

                1.a TRIE树

                        http://en.wikipedia.org/wiki/Trie

                1.b Suffix Tree/Suffix Array

                        http://en.wikipedia.org/wiki/Suffix_tree

                        http://en.wikipedia.org/wiki/Suffix_array

        2. 倒排表索引, 目前已经被广泛应用于绝大多数搜索引擎

                http://en.wikipedia.org/wiki/Inverted_index


大体上,似乎这些不同的文本索引都找到它们的“定位”。 Three Body 我也觉得倒排表这样的结构简直就是为大规模文本索引而生, 原本优美的Suffix Array只能望“文本海洋”兴叹。 倒排表,对检索性能的提升让人赞叹, 不过也有一些不及Suffix Array的地方。 比如:

        1. 像中文类似的文本,如果要构建文本索引。首当其冲的问题是需要对中文文本进行分词,然后才能基于词语进行倒排索引

        2. 像生物基因系列的检索,文本的字符集很小,普通的倒排表会出现倒排表的每一条倒排索引链很长,检索效果退化。另外,基因系列也无法进行“分词”


怎么办?Compressed Suffix Array给我们带来了希望。Compressed Suffix Array在解决Suffix Array存储和搜索方面都有了长足的进展,已经在一些领域的全文检索系统中使用。相比Suffix Array, CSA使用了以下一些富有启发性的改进:

        1. 相比传统后缀数组中的SA[], 压缩后缀数组引入Successor数组 Psi[]。 Psi[i] = rSA[T[SA[i] + 1]] (其中 rSA[SA[i]] = i) Psi[] 数组的引入, 带来了数据压缩和索引检索上潜能;

        2. 有序系列的压缩算法 a. Delta-encoding; b. Quotienting with Elias-Fano

        3. 基于Psi数组和少量额外存储, 文本的检索可以脱离原始文本

        4. 压缩后缀数组可以进一步压缩,如果原始文本可以压缩


更多内容,推荐大家阅读:

        1. Compressed Suffix Array wiki: http://en.wikipedia.org/wiki/Compressed_suffix_array

        2. 浅显易懂的文章 A simple introduction to Compressed Suffix Array: http://www.cs.cmu.edu/~dga/csa.pdf


从后缀数组如何进一步得到扩展和改进以适应更大规模数据的需求,除了得到更多索引算法设计方面的启发,还有两点深刻的感受:

        1. New wine in old bottles

            这已经一遍又一遍地在计算机发展中被验证。一个“古老”的想法,在新的环境下,焕发了新的生命。短时间内受挫的方法,在新的背景下,由于一些突破,重新得到发展。 近来火爆的深度神经网络,不也是度过一段寒冬之后的再次重生嘛。

        2. 数组索引 (index of array)的潜力

            数组索引,在这里指指向数组元素的索引,如array[i]中的i。 一般数组的索引i只是为了编号计数,或者是定义一种关系array[i] v.s array[j],  i vs j。CSA中的Psi[i]数组定义通过i跟SA数组建立起一种巧妙关系。 数组索引本身不构成内存消耗,如果能巧妙设计充分利用, 会在算法设计上有意外收获。关于这点,是否存在理论上的指导呢?



0 0
原创粉丝点击