搜索引擎的拼写纠错功能实现

转自:http://blog.sina.com.cn/s/blog_567842410100obxd.html

现在各大流行的搜索引擎几乎都具备一个功能,那就是提供拼写纠错功能。用户将查询的关键词提交给搜索引擎之后,搜索引擎便开始分析用户的输入,检查用户的拼写是否有错误,如果有的话,给出正确的拼写建议。也就是说,搜索引擎的拼写纠错功能,要完成两部分的工作,首先,对用户输入的查询进行处理,判断是否有拼写错误,接着,对于有拼写错误的查询输入,给出正确词汇的提示。因为中文的拼写纠错涉及到中文分词等复杂逻辑,所以本文只对英文的拼写纠错进行讨论。

 

1     英文单词纠错法

常见的英文单词纠错法,主要有以下几种:误拼词典法、最小编辑距离法、词干法,N-gram法和基于规则的技术等,下面我们对这些英文单词纠错法逐个进行介绍。

 

(1)误拼字典法。这种方法可以理解成穷举法,通过收集大规模真实文本中拼写出错的英文单词并给出相应的正确拼写,建造一个无歧义的误拼字典。在进行英文单词拼写检查时,查找误拼字典,如命中,则说明该单词拼写有误,该词的正确拼写字段为纠错建议。比如在搜索引擎的实现中,通过记录日志的形式,把所有用户的输入都记录下来,提取有拼写错误的输入,形成误拼词典。该方法的特点是算法简单,效率高。但英文拼写错误具有随机性,很难保证误拼字典的无歧义性和全面性,因此查准率低、校对效果差;而且,对于搜索引擎用户海量的误拼输入,空间复杂度也是需要考虑的问题。

 

(2)最小编辑距离法。通过计算误拼字符串与词典中某个词间的最小编辑距离来确定纠错候选词。所谓最小编辑距离是指将一个词串转换为另一个词串所需的最少的编辑操作次数。在编辑操作中,可以将单次的编辑动作归纳为三种:插入字符、删除字符和替换字符;考虑到在实际计算机输入过程中,字符的颠倒异位也是常见的错误,我们将颠倒异位也算作一种编辑动作。还有人提出了反向最小编辑距离法,这种方法首先对每个可能的单个错误按照编辑距离进行搜索,生成一个候选集,然后,通过查词典看哪些是有效的单词,并将这些有效的单词作为误拼字符串的纠错建议。

 

(3)词干法。通过构建词干词典,在英文单词出现错误时,先抽取出该错误单词的词干,然后再去查词干词典,将词典中与该单词具有相同词干的正确单词作为该单词的纠错建议。这种方法主要的难度在于构建词干词典上,需要对几乎所有的英文单词都进行分析,提取出每个单词的词干,或者称为骨架词;这种实现的工作量是巨大的,而且词干的选择非常重要,每个词干要有很好的区分度,才能给用户给出良好的纠错建议。

 

(4)N-gram法。基于n元文法,通过对大规模英文文本的统计得到单词与单词问的转移概率矩阵。当检测到某英文单词不在词典中时。查转移概率矩阵,取转移概率大于某给定阈值的单词为纠错建议。

 

(5)基于规则的技术。利用规则的形式将通常的拼写错误模式进行表示,这些规则可用来将拼写错误的单词转换为正确有效的单词。对于一个误拼字符串,应用所有合适的规则从词典中找到一些与之对应的单词作为候选结果;然后,对每个结果根据事先赋予生成它的规则的概率估计计算一个数值,依据这个数值对所有候选结果进行排序,把将排序靠前的结果当成纠错结果返回给用户。

 

通过对这些现有的英文单词纠错法的分析,我们选定反向最小编辑距离法作为拼写纠错功能的实现方式,进行分析然后给出C++的实现。

 

2     拼写纠错功能的实现

搜索引擎如何判断用户的输入是否有拼写错误呢?通过分析现有的著名搜索引擎的行为,我想应该是查词典的方式。每个搜索引擎维护一个关键词的词典,对于用户的输入,检查它是否在词典中。如果词典中有这个词条,则直接返回搜索结果;如果发现这个用户输入的词并不包含在词典里边,那么它很有可能是一个错误的输入,于是马上触发拼写纠错功能,对用户提供拼写建议。我们很容易就能在Google或者百度这样的搜索引擎中验证这个猜想,在搜索框里输入一个正常的词,比如“Microsoft”,搜索引擎不会有错误提示;而你故意输入一个词典不包括的词,比如“Micorsoft”,搜索引擎会提示你正确的搜索词汇。

 

2.1    字典的数据结构

字典的数据结构,大多数情况下,比照C++ STL中的map,我们会想到两种实现途径,首先是二叉树,其次是哈希表。对于哈希表,在选取恰当的哈希函数的情况下,它的理论查找效率是O(1),这看起来是个不错的选择,事实上哈希表已经用作在一些搜索引擎中[1]。于是我们可以在训练搜索引擎的过程中,把所有的常用词都输入到这个词典中,然后就能够用很高的效率进行搜索。但是这种方法带来一个问题,词典里的单词量通常是非常巨大的,每一个单词都需要完整的存储,随着时间的推移,这种实现需要的内存空间也会变得越来越大。

 

在二叉树的实现中,我们可以把所有的单词都保存在二叉树的节点中,但这样需要的空间几乎可以肯定不会比哈希表的方式少,除了存储单词的空间,还需要额外的实现二叉树的空间,况且搜索的时间复杂度是O(logn),所以我们需要对这种方式进行优化。所有的单词还是存储在二叉树结构中,但是每个节点仅保存一个字符,每个节点可以有两个子节点,其中左子节点表示当前字符的兄弟(Sibling), 说明有多个单词存在相同的前缀,右子节点表示当前字符的后续字符(Next),图1说明了我们如何将“ape”、“apple”和“applet”这三个词存储起来。利用这种存储方法,我们可以高效率地将有相同前缀的词存储在同一棵子树中。

 

搜索引擎的拼写纠错功能实现

1 字典的存储结构

2.2    二叉树的创建与查找

创建或者将新词插入这棵二叉树的算法,可以由递归来实现:

        1.从根节点开始。

2.如果当前节点保存的字符和当前插入字符相同,则递归进入下一层,把后续节点作为当前节点,再处理下一个字符。

3.如果当前节点保存的字符和当前插入字符不相同,检查Sibling节点是否存在,如果存在则进入Sibling节点。否则,创建Sibling节点,把当前插入字符保存在Sibling中,同时进入下一层,把Sibling作为当前节点,再处理下一个字符。

4.如果当前节点没有Next节点,则创建一个节点作为Next节点,把当前插入字符保存在Next节点中,同时进入下一层,把Next作为当前节点,再处理下一个字符。

5.递归的结束条件是遇到了字符串结束符(\0),在插入\0之后返回。

 

查找一个词是否在字典中的算法则很简单:

1. 比较当前节点和当前检查的字符,如果相同则进入Next节点子树,当前检查字符的指针加一,否则,判断是否有Sibling,如果有则进入Sibling子树,否则说明不存在这个单词,直接返回。

2. 结束的条件是遇到了字符串结束符,且当前检查字符为\0

3. 为了实现模式匹配,我们还支持?号作为通配符的查找,用以返回所有符合模式的单词。

 

2.3    给出拼写建议

前面我们提到最小编辑距离法中,需要对用户输入的误拼字符串按照编辑距离进行搜索并形成候选集,然后在字典中查找后选的单词。如果存在,则说明是个有效的单词,可以作为拼写建议提供给用户。我们只考虑编辑距离为1的情况,如果编辑距离更大的话,返回的结果太多,反而影响拼写建议的准确度。

 

我们按照编辑操作来枚举生成候选集模式。比如对于误拼字符串abc,删除字符可以产生abacbc;插入字符可以产生?abca?bcab?cabc?;替换字符可以产生?bca?cab?;将字符颠倒可以产生bacacb。然后,我们将这些候选模式放到二叉树中去搜索,就可以返回匹配的候选单词集合。

 

候选单词集中包含有我们需要提供给用户的拼写建议,但是我们不能这样直接给用户。首先,候选单词集中可能存在重复的单词,其次存在多个单词的情况下,如何才能把最准确的拼写建议返回给用户。第一个问题,我们可以通过过滤逻辑去除重复;而第二个问题,我想不同的搜索引擎都有自己不同的实现,比如可以按照单词的优先级返回,分析用户查询日志,查询次数越多的单词优先级越高。

 

3     结论

本文对搜索引擎的拼写纠错功能进行了讨论,然后选择最小编辑距离法来进行用户误拼输入的纠错,提供了一个可行的方法和具体的实现逻辑。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值