Python 3.x 一种计算两词编辑距离的算法

Python 3.x 一种计算两词编辑距离的算法,python-3.x,nlp,text-classification,fasttext,edit-distance,Python 3.x,Nlp,Text Classification,Fasttext,Edit Distance,我正在尝试编写Python代码,将一个单词作为输入(例如book),并以相似性分数输出最相似的单词 我尝试过不同的现成的编辑距离算法,如余弦、Levenshtein和其他算法,但这些算法无法判断差异的程度。例如,(book,bouk)和(book,bo0k)。我正在寻找一个算法,可以给这两个例子不同的分数。我正在考虑使用fastText或BPE,但它们使用余弦距离 有什么算法可以解决这个问题吗?问题是“bo0k”和“bouk”都是与“book”不同的一个字符,没有其他指标可以让你区分它们 您需要

我正在尝试编写Python代码,将一个单词作为输入(例如book),并以相似性分数输出最相似的单词

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

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

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

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


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

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

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

波,欧,英国

或三角形

呜呜

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

然后将其与“bo0k”进行比较,你会看到所有的Bigram:

bo,o0,0k

或三角形

bo0,o0k

现在你可以看到,只有“波”在这里得分很好。所有其他的都不能在一个普通的n-gram语料库中找到。因此,这个词在可能性方面的得分要比“bouk”低很多,例如1/5比“bouk”低3/5

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

您将需要一个已建立的语言n-gram频率的语料库。例如,我发现的这个随机博客讨论了:

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

然后,你可以用任何你喜欢的方式对各个部分进行求和,以确定单词的总分


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

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

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

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

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

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

e、 g.对于bo0k

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
您可以在这里看到,在整个基本拼写变体集中只有一个字典单词

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


显然,这不包括拼写错误,尽管也可以采用类似的领域知识方法,针对自然语言及其特殊的怪癖和困难。

感谢@sciplot的建议和慷慨的解释。两个主意我都喜欢,但第一个更适合我的任务。不客气。顺便说一句,对堆栈溢出的人表示感谢的最好方法是,如果他们的答案相关且写得很好,即使不被接受,也要对他们的答案进行投票。有些问题会有多个有效答案,重要的是要把所有问题都归功于投票。