【问题标题】:An algorithm for computing the edit-distance between two words一种计算两个词之间编辑距离的算法
【发布时间】:2020-08-05 11:09:40
【问题描述】:

我正在尝试编写 Python 代码,将单词作为输入(例如 book),并输出具有相似度分数的最相似单词。

我尝试过不同的现成编辑距离算法,如余弦、Levenshtein 等,但这些无法说明差异程度。例如,(book, bouk) 和 (book,bo0k)。我正在寻找一种可以为这两个示例给出不同分数的算法。我正在考虑使用 fastText 或 BPE,但是它们使用余弦距离。

有什么算法可以解决这个问题吗?

【问题讨论】:

    标签: python-3.x nlp text-classification fasttext edit-distance


    【解决方案1】:

    问题是“bo0k”和“bouk”都是与“book”不同的一个字符,没有其他指标可以让您区分它们。

    您需要做的是更改评分:如果它是不同的字符类别(即数字而不是字母),您可以给它更高的分数,而不是将不同的字符计算为编辑距离 1。这样你的例子就会得到不同的分数。

    不过,您可能还需要调整其他分数,以便替换/插入/删除仍然一致。

    【讨论】:

      【解决方案2】:

      这是一个非常有趣的问题——可能有很多可能的答案。您可以添加二元组(n-gram)分析,以对典型单词中字母相互关联的可能性进行排名。

      假设您的系统不“知道”目标词,但有人键入“bouk”。然后它分析所有的二元组:

      博,欧,英国

      或三元组

      呜呜呜

      我猜这里“bo”、“ou”、“bou”会得分很高,因为它们很常见,但“uk”和“ouk”不太可能在英语中出现。所以这可能只是一个 3/5 的分数,但实际上每个三元组都有自己的频率分数(概率),所以建议单词的总数可以非常精确。

      然后将其与“bo0k”进行比较,您会看到所有的二元组:

      bo, o0, 0k

      或三元组

      bo0, o0k

      现在您可以看到,只有“bo”才能在此处得分。所有其他人都不会在一个常见的 n-gram 语料库中找到。所以这个词的可能性会比“bouk”低得多,例如1/5 与“bouk”的 3/5 相比。

      解决方案大致分为三个部分:

      您将需要该语言的已建立 n-gram 频率的语料库。例如,我发现的这个随机博客讨论了:https://blogs.sas.com/content/iml/2014/09/26/bigrams.html

      然后您需要将输入的单词处理(标记和扫描)为 n-gram,然后在语料库中查找它们的频率。你可以使用类似 SK Learn 的东西,

      然后,您可以以任何您喜欢的方式对各个部分求和,从而确定该单词的总分。

      请注意,您可能会发现大多数用于自然语言的标记器和 n-gram 处理都围绕单词关系而不是单词中的字母。很容易忘记这一点,因为图书馆专注于 word-gram 的事实通常没有被明确提及,因为它是最常见的。我以前注意到过,但是 n-grams 也用于各种其他数据集(时间序列、音乐、任何序列) 这个问题确实讨论了如何将 SK Learn 的矢量化器转换为字母-grams,但我我自己没有试过这个:N-grams for letter in sklearn

      【讨论】:

      • 感谢@scipilot 的建议和慷慨的解释。我喜欢这两个想法,但第一个更适合我的任务。
      • 不客气。顺便说一句,感谢堆栈溢出的人们的最佳方式是,如果他们的答案相关且写得很好,即使没有被接受,也要对他们的答案进行投票。有些问题会有多个有效答案,重要的是要对它们都投赞成票。
      【解决方案3】:

      我有第二个想法,在这种情况下使用“领域知识”,即有人在键盘上打字。它没有直接回答您的问题,但说明了可能有完全不同的方法来实现最终目标(您没有直接描述 - 即显示拼写检查选项的用户界面?)。

      我曾经在 uni 写过一个算法,它使用键盘布局图(作为拼写检查器中的一种策略),它迭代所有周围的键,当在字典中找不到单词时提出“胖指法”更正.

      例如,O 被 I90PLK 包围,I 被 U89OK 或 U89OKJ 包围。

      因此,您可以通过将每个字母替换为周围邻居的所有组合来改变每个输入单词。你最终会得到很多组合,但其中大部分都是完全虚假的词。其中之一可能与字典中的单词完美匹配。

      因此,您需要做的就是生成所有可能的拼写错误邻居,并简单地查找突变体中的所有字典单词,这应该是一个有效的查询。

      例如为了书

      bo0k
      vo0k
      go0k
      ho0k
      no0k
      _o0k
      
      bi0k
      b90k
      b00k
      bp0k
      bl0k
      bk0k
      
      bo9k
      bo0k
      bo-k
      bopk
      book       - bingo!
      boik
      
      bo0j
      bo0u
      bo0i
      bo0o
      bo0l
      bo0,
      bo0m
      

      您可以在这里看到,在整个基本错字突变体中只有一个字典单词。

      所以这不使用任何相似性算法,但在键盘拼写错误的情况下,它可以找到更正。您甚至可以记录用户对这些建议的“接受”并形成您自己的修正概率语料库。我猜很多拼写错误都很常见且一致。

      显然这不包括拼写错误,尽管可以根据自然语言采用类似的领域知识方法,但有其特定的怪癖和困难。

      【讨论】:

        猜你喜欢
        • 2016-05-25
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-30
        • 2010-09-28
        • 2010-10-30
        相关资源
        最近更新 更多