快速计算Levenshtein距离


24

给定一个庞大的允许单词(按字母顺序排序)和单词的数据库,请从数据库中找到就Levenshtein距离而言最接近给定单词的单词。

当然,幼稚的方法是简单地计算给定单词与字典中所有单词之间的levenshtein距离(我们可以在实际计算距离之前在数据库中进行二进制搜索)。

我想知道是否有一个更有效的解决方案。也许可以通过某种启发式方法来减少搜索的单词数,或者对levenshtein距离算法进行优化。

欢迎访问有关该主题论文的链接。

Answers:


16

您要问的是在编辑距离下的近邻搜索问题。您没有提到您对理论结果还是启发式技术感兴趣,因此我将回答前者。

对于构建近邻搜索结构,编辑距离有些麻烦。主要问题是,作为度量标准,出于维和逼近的目的,它的行为类似于等其他众所周知的不良度量标准。关于此主题,有大量的工作需要阅读,并且最好的资料来源是Alex Andoni的论文集:通过追随往后的指针(例如,从他的FOCS 2010论文中得出),您将获得大量的资料来源。1


1
我对度量空间的所有了解都来自语义,所以提出一个问题:是否有将Levenshtein度量嵌入到超度量中的任何体面(对于体面的值)?副手,这可能会引起二叉树式算法。
Neel Krishnaswami

我不太确定。我怀疑答案通常不是,但是我没有什么可指的。
Suresh Venkat

关于boytsov.info/pubs的第二篇论文很好地调查了Levenshtein和Damereau-Levenshtein编辑距离下的近邻搜索可能的解决方案。
2012年

@NeelKrishnaswami嵌入到超度量标准中将至少具有失真,其中是字符串长度。这是由于Krauthgamer和Rabani导致的嵌入的变形下界,因为超度量等距地等距地嵌入了欧几里德空间,而欧氏空间也等距地嵌入了。d L 1 L 1Ω(logd)dL1L1
Sasho Nikolov


5

如果您会容忍少量的误编辑,则可以尝试使用点缀后缀树。免责声明:我写了这篇论文,但是它可以解决您想要的东西:它具有很高的磁盘空间成本,但是查询确实非常快。

通常,最好以另一种方式查看它:您拥有字典中所有单词的索引。现在,对于输入单词w,如果它在词典中,请停止。否则,生成距离1处的所有变化并寻找这些变化。如果不存在,请寻找距离2的变化,依此类推...

此基本思想有一些改进。


1
您应该已经包括了指向该论文可复制研究档案的链接。
Dan D.


4

我在cs.stackexchange.com(/cs//a/2096/1490)上写了一个非常类似的问题的答案,然后我发现了这个问题。答案是在编辑距离内进行近似的近邻搜索(即算法输出的字符串与查询字符串的最近邻居近似接近查询字符串)。我在这里发布,是因为我在这里给出的答案中找不到我在此给出的任何参考。



2

您可以使用您的意思吗?

然后使用“动态编程”找到“您的意思是”返回的答案与输入字符串之间的Levenshtein距离。


我不明白这个答案。该问题询问如何在大型字典中有效地找到距给定输入的莱文施泰因距离很近的单词,而不是如何计算莱文施泰因距离或与黑盒拼写检查器的输出进行比较...
Huck Bennett

@Huck Bennett:我以为@Grigory Javadyan正在构建Did you mean?功能。除了Did you mean?返回与给定输入非常接近的单词,还可以非常有效地完成该操作。:)
Pratik Deoghare 2011年

我认为您的想法很好,但是Grigory似乎要求的是更深入,更具体的内容。
哈克·贝内特

@Huck Bennett:是的,你是对的!:)
Pratik Deoghare 2011年

-1

一种方法是训练机器学习模型,以将单词映射到向量,并将levenshtein距离映射到欧氏距离。然后,您可以从向量中为您要使用的字典构建一个KDTree。我创建了一个在这里执行此操作的jupyter笔记本:https ://gist.github.com/MichaelSnowden/9b8b1e662c98c514d571f4d5c20c3a03

根据DW的评论:

  1. 训练程序=具有自适应梯度的随机梯度下降
  2. 损失函数=真实编辑距离和欧氏距离之间的均方误差
  3. 训练数据=长度在1到32个字符之间的随机字符串(可以通过匹配实际常见错别字的数据进行改进)
  4. 定量结果:在训练了大约150个历元且批量大小为2048(墙时间=大约一分钟)之后,使用512维尺寸的单词嵌入和一个隐藏层,真实编辑距离和预测编辑距离之间的平均绝对误差位于0.75左右,这意味着预测的编辑距离大约减少了一个字符

模型结构摘要:

  1. 为每个字符(包括空字符)创建学习的嵌入(稍后用于字符限制下的右击文本)
  2. 用空字符填充文本的右侧,直到达到字符数限制(32)
  3. 连接这些嵌入
  4. 通过前馈神经网络运行嵌入以生成低维单词嵌入(512维)
  5. 对两个词都这样做
  6. 找出向量之间的欧式距离
  7. 将损失设置为真实Levenshtein距离与欧氏距离之间的均方误差

我的训练数据只是随机字符串,但是我认为,如果训练数据是(错别字/正确的单词)对,结果确实可以改善。我最终只使用了/usr/share/dict/words它,因为它是普遍可用的。


2
您如何训练ML模型,以使Levenshtein距离附近的单词映射到相似的向量?您为此使用什么训练程序和损失函数?您能否在答案中总结该方法,以使即使链接停止工作,答案仍然有用,并且我们不必深入研究笔记本即可了解所使用的方法?另外,您能以某种定量的方式评估其效果如何吗?这比其他选择好吗?
DW

就目前而言,这(我认为)不适合CSTheory。也就是说,不知道具体建议什么,也没有理论上的依据。
克莱门特·C·

@DW抱歉,我进行了相当大的编辑,以防万一链接断开(或者如果您不想在笔记本上戳戳)应该是全面的。尽管由于这不是研究,所以它并不是真正的CS理论,但我确实认为这是一种实用的方法,因为它既快速又容易进行训练和推理。
michaelsnowden

1
您正在训练随机字符串。两根这样的琴弦之间的预期Levenshtein距离将近似于较长琴弦的长度。因此,很容易估计随机字符串上的距离,但这对处理现实世界的数据没有用。我怀疑您的嵌入内容可能只是对字符串的长度进行了编码,因此您可能已经构建了一种奇妙的方式来执行琐碎且无用的操作。这是使用ML的问题;它对您使用的损失函数非常敏感。
DW

@DW如果您在笔记本中查看结果,则检索最终返回的结果不错-不仅是相同长度的字符串。我真的鼓励您略过。我不会称其为琐碎和无用的。
michaelsnowden '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.