【问题标题】:How do I approximate "Did you mean?" without using Google?我如何近似“您的意思是?”不使用谷歌?
【发布时间】:2011-07-13 00:47:09
【问题描述】:

我知道这个问题的重复:

这些问题对算法的实际工作方式很感兴趣。我的问题更像是:让我们假设 Google 不存在,或者这个功能不存在并且我们没有用户输入。如何实现该算法的近似版本?

为什么这很有趣?

好的。尝试在 Google 中输入“qualfy”,它会告诉您:

您的意思是: 合格

很公平。它对从数十亿用户收集的数据使用统计机器学习来做到这一点。但现在尝试在 Google 中输入:“Trytoreconnectyou”,它会告诉你:

你的意思是: 尝试重新连接你

现在这是更有趣的部分。谷歌如何确定这一点?有一本方便的字典并使用用户输入再次猜测最有可能的单词吗?它如何区分拼写错误的单词和句子?

现在考虑到大多数程序员无法访问数十亿用户的输入,我正在寻找实现该算法的最佳近似方法以及可用的资源(数据集、库等)。有什么建议吗?

【问题讨论】:

  • @Benjamin:我也可以列出可以利用的数据集吗?我不是来自这个领域,所以任何额外的帮助都会是一个福音。
  • 您是否阅读了您发布的链接的答案?第一个链接的第二个答案指向norvig.com/spell-correct.html,这几乎正是您要查找的内容。
  • Norvig 链接也在您的第二个链接的第三高答案中。
  • 您注意到google.com/… 不起作用了吗?

标签: algorithm language-agnostic nlp machine-learning


【解决方案1】:

假设您有一个单词字典(最坏情况下出现在字典中的所有单词,最好情况下出现在系统数据中的所有短语)并且您知道各种单词的相对频率单词,您应该能够通过similarity of the word 和类似单词的点击次数的某种组合合理地猜测用户的意思。权重显然需要一些试验和错误,但通常用户会更感兴趣的是一个流行的结果,它在语言上离他们输入的字符串有点远,而不是一个在语言上更接近但只有一两个的有效单词在您的系统中点击。

第二种情况应该更简单一些。你找到所有以字符串开头的有效词(“T”无效,“Tr”无效,“Try”是一个词,“Tryt”不是一个词,等等)并且对于每个有效词,你重复剩余字符串的算法。假设您的字典已编入索引,这应该很快。如果您发现可以将长字符串分解为一组没有剩余字符的有效单词的结果,那么这就是您的建议。当然,如果您是 Google,您可能会修改算法以查找与实际单词相当接近的拼写错误的子字符串,并且您有一些逻辑来处理可以通过足够松散的拼写检查以多种方式读取字符串的情况(可能使用打破平局的结果数)。

【讨论】:

  • 我一直在寻找 yonks 的单词距离算法。谢谢。
【解决方案2】:

来自马口:How to Write a Spelling Corrector

这里的有趣之处在于您如何需要一堆查询日志来近似算法。您可以使用大部分正确文本的语料库(例如古腾堡计划中的一堆书籍)。

【讨论】:

    【解决方案3】:

    我认为这可以使用spellcheckerN-grams 来完成。

    对于Trytoreconnectyou,我们首先检查所有 1-grams(所有字典单词)并找到一个非常糟糕的最接近的匹配。所以我们尝试 2-grams(可以通过从长度为 2 的短语中删除空格来构建),然后是 3-grams,依此类推。当我们尝试 4-gram 时,我们发现有一个短语与我们的搜索词的距离为 0。由于我们无法做得比这更好,因此我们将该答案作为建议返回。

    我知道这是非常低效的,但 Peter Norvig 的帖子 here 清楚地表明 Google 使用拼写纠正器来生成它的建议。由于谷歌拥有海量的并行化能力,他们可以很快完成这项任务。

    【讨论】:

    • Google 做得很快,不是因为它暴力破解所有组合,而是因为它的启发式搜索将复杂性引入亚线性。
    【解决方案4】:

    令人印象深刻的教程之一,您可以在这里找到它的工作原理http://alias-i.com/lingpipe-3.9.3/demos/tutorial/querySpellChecker/read-me.html

    简而言之,它是查询修改(在字符或单词级别)与增加搜索文档覆盖率的权衡。例如“aple”导致200万个文档,但“apple”导致6000万个文件,修改只有一个字符,所以很明显你的意思是苹果。

    【讨论】:

      【解决方案5】:

      可能有用的数据集/工具:

      您可以将 WordNet 用作简单的术语词典,并且可以使用从语料库中提取的常用术语来提升它。

      您可以使用前面提到的 Peter Norvig 链接作为第一次尝试,但对于大型字典,这不是一个好的解决方案。

      相反,我建议您使用局部敏感哈希 (LSH) 之类的东西。这通常用于检测重复文档,但也可以用于拼写更正。您将需要从您认为人们可能会搜索的数据中提取的术语列表和术语字符串 - 您必须为字符串选择截止长度。或者,如果你有一些人们实际搜索的数据,你可以使用它。对于每个术语字符串,您生成一个向量(可能是字符二元组或三元组就可以了)并将其存储在 LSH 中。

      对于任何查询,您都可以在 Charikar 描述的 LSH 上使用近似最近邻搜索来从您的可能匹配集中找到最近邻。

      注意:链接已删除,因为我是新用户 - 抱歉。

      【讨论】:

        【解决方案6】:

        @Legend - 考虑使用Soundex algorithm 的变体之一。它有一些已知的缺陷,但在大多数需要近似拼错单词的应用程序中运行良好。


        编辑(2011-03-16):

        我突然想起了几年前我遇到的另一个类似 Soundex 的算法。在 this Dr. Dobb's article 中,Lawrence Philips 讨论了对他的 Metaphone 算法的改进,称为 Double Metaphone。

        您可以在here 上找到该算法的 Python 实现,以及在同一站点 here 上的更多实现。

        同样,这些算法与 Google 使用的算法不同,但对于英语单词,它们应该会让您非常接近。您还可以查看Phonetic Algorithms 的维基百科页面,了解其他类似算法的列表。

        【讨论】:

          【解决方案7】:

          【讨论】:

          • 谢谢。我在我的问题中确实链接到了这个。我更感兴趣的是我可以利用哪些资源(Google 除外)来完成这项任务。
          • 糟糕——我现在明白了。道歉。
          猜你喜欢
          • 1970-01-01
          • 2010-11-20
          • 1970-01-01
          • 2011-05-08
          • 2011-05-27
          • 1970-01-01
          • 2016-05-18
          • 2017-03-08
          • 1970-01-01
          相关资源
          最近更新 更多