什么算法在拼写检查器中提供建议?

时间:2010-02-19 08:31:49

标签: algorithm language-agnostic spell-checking levenshtein-distance

在实施伴有单词建议的拼写检查程序时,通常使用什么算法?

起初我认为从字典中的每个其他单词检查每个键入的新单词(如果没有在字典中找到)可能是有意义的,并且返回顶部结果。Levenshtein distance然而,这似乎非常低效,不得不反复评估整个字典。

这通常是如何完成的?

5 个答案:

答案 0 :(得分:193)

good essay by Peter Norvig如何实施拼写纠正器。它基本上是一种蛮力方法,尝试使用给定编辑距离的候选字符串。 (Here是如何使用Bloom Filterfaster candidate hashing提高拼写纠正器效果的一些提示。)

拼写检查程序的要求较弱。你只需要发现一个单词不在字典中。您可以使用Bloom Filter构建一个消耗较少内存的拼写检查程序。 Jon Bentley使用64kb作为英语词典,在Programming Pearls中描述了古代版本。

BK-Tree是一种替代方法。一篇不错的文章是here

Levenshstein距离不是拼写检查器的正确编辑距离。它只知道插入,删除和替换。缺少转置,并为1个字符的转置产生2(它是1个删除和1个插入)。 Damerau–Levenshtein distance是正确的编辑距离。

答案 1 :(得分:17)

用于生成我已经成功使用但从未在任何地方看到的建议的方法是使用“坏”散列函数预先计算建议(在构建字典时)。

我们的想法是查看人们所犯的拼写错误类型,并设计散列函数,将错误拼写分配给与正确拼写相同的存储桶。

例如,常见的错误是使用错误的元音,例如 definate 而不是明确的。因此,您设计了一个哈希函数,将所有元音视为相同的字母。一种简单的方法是首先“标准化”输入字,然后通过常规散列函数将标准化结果放入。在此示例中,规范化功能可能会删除所有元音,因此definite变为dfnt。然后使用典型的散列函数对“规范化”字进行散列。

使用此特殊哈希函数将所有词典单词插入辅助索引(哈希表)。此表中的存储桶将具有较长的冲突列表,因为哈希函数是“坏”的,但这些冲突列表基本上是预先计算的建议。

现在,当您找到拼写错误的单词时,您将查找拼写错误映射到辅助索引中的存储桶的冲突列表。塔达:你有一个建议清单!您所要做的就是对其中的单词进行排名。

在实践中,你需要一些带有其他哈希函数的辅助索引来处理其他类型的错误,比如转置字母,单/双字母,甚至是一个简单的类似Soundex的错误来捕捉拼音错误拼写。在实践中,我发现简单的发音有很长的路要走,并且基本上废除了一些旨在找到琐碎错别字的发音。

所以现在你在每个辅助索引中查找拼写错误并在排名之前连接碰撞列表。

请记住,碰撞列表仅包含字典中的单词。通过尝试生成替代拼写的方法(如Peter Norvig文章中所述),您可以获得(数十)数千个候选人,首先必须对字典进行过滤。使用预先计算的方法,你可能会得到几百名候选人,并且你知道他们都拼写正确,所以你可以直接跳到排名。

更新:我发现了一个与此类似的算法描述FAROO Distributed Search。这仍然是一个编辑距离限制搜索,但它非常快,因为预计算步骤就像我的“坏哈希函数”的想法。 FAROO只使用了有限的哈希函数概念。

答案 2 :(得分:6)

算法

  1. 将错误拼写的单词作为输入。
  2. 将英文单词列表及其频率存储在文本文件中。
  3. 在三元搜索树中插入所有可用的英语单词(存储在文本文件中)及其频率(衡量单词在英语中的使用频率)。
  4. 现在遍历三元搜索树 -
    • 对于三元搜索树中遇到的每个单词,从错误拼写的单词计算其Levensthein距离。
    • 如果Levensthein Distance< = 3,请将该字词存储在优先级队列中。
    • 如果两个单词具有相同的编辑距离,则频率较高的单词更重要。 打印优先级队列中的前10项。
  5. 优化

    1. 如果当前字的输入字的子字符串的编辑距离大于3,则可以在当前节点的子树中删除字。 您可以在github project上找到更详细的说明和源代码。

答案 3 :(得分:3)

您无需知道字典中每个单词的确切编辑距离。您可以在达到限制值后停止算法并排除该单词。这将为您节省大量的计算时间。

答案 4 :(得分:1)

拼写检查程序非常容易实现,就像Unix拼写程序一样。源代码公开发布。可以涉及校正,一种技术是进行编辑并再次检查这个新单词是否在字典中。这些新编辑可以分组并显示给用户。

Unix系统使用Mc IllRoy编写的程序。另一种方法是使用Trie,这对于大文件来说非常有用。

unix方法对于庞大的字典需要的空间非常少,因为它使用了散列散列算法。