找出两个字符串的相似程度

Posted

技术标签:

【中文标题】找出两个字符串的相似程度【英文标题】:Finding how similar two strings are 【发布时间】:2010-10-09 07:31:09 【问题描述】:

我正在寻找一种算法,它采用 2 个字符串并会返回一个“相似性因素”。

基本上,我的输入可能拼写错误、字母转置等,我必须在我拥有的可能值列表中找到最接近的匹配项。

这不适用于在数据库中搜索。我将有一个包含 500 个左右的字符串的内存列表进行匹配,全部都在 30 个字符以下,所以它可能相对较慢。

我知道它存在,我以前见过它,但我不记得它的名字了。


编辑:感谢您指出 Levenshtein 和 Hamming。 现在,我应该实施哪一个?它们基本上测量不同的东西,两者都可以用于我想要的,但我不确定哪个更合适。

我已经阅读了算法,Hamming 似乎明显更快。由于两者都不会检测到两个字符被转置(即 Jordan 和 Jodran),我认为这将是一个常见错误,这对于我想要的更准确? 有人能告诉我一些权衡吗?

【问题讨论】:

实际上,Hamming 距离和 Levenshtein 距离都检测转置,每个都指定成本 2。这是 Hamming 距离明智地发现的少数典型错误之一——任何单个字符的插入或删除会立即给您带来巨大的差异分数。使用 Levenshtein。 【参考方案1】:

好的,所以标准算法是:

1) Hamming distance 仅适用于相同长度的字符串,但非常有效。基本上它只是计算不同字符的数量。不适用于自然语言文本的模糊搜索。

2)Levenstein distance。 Levenstein 距离根据将一个字符串转换为另一个字符串所需的“操作”数量来衡量距离。这些操作包括插入、删除和替换。计算 Levenstein 距离的标准方法是使用动态规划。

3) Generalized Levenstein/(Damerau–Levenshtein distance) 该距离还考虑了单词中字符的换位,可能是最适合手动输入文本的模糊匹配的编辑距离。计算距离的算法比 Levenstein 距离更复杂(检测转置并不容易)。最常见的实现是对bitap 算法的修改(如grep)。

一般来说,您可能希望考虑在基于 k-d 树的某种最近邻搜索中实现第三个选项的实现

【讨论】:

【参考方案2】: 列文斯坦距离 汉明距离 soundex 变音位

【讨论】:

嗯...好的...我应该使用哪一个?如果我没记错的话,Soundex 没用,因为它取决于第一个字母是否相同,再加上我使用它的时间(不同的项目),我对此并不满意。例如,Levenshtein 和 Hamming 之间的权衡是什么? 汉明距离只能用在相同长度的字符串上...Levenshtein距离就像汉明距离的推广 嗯,汉明距离更多是出于理论目的。如果您想纠正或忽略拼写错误——Levenstein。如果你想纠正或忽略错误的拼写——变音位。但是请注意,Levenstein 可以使用任何语言,变音位——仅限英语。 就 Soundex 而言,我认为这并不取决于第一个字母是否相同,您可以找到该算法的本地化版本(至少对于法语而言)。我个人在法文版上取得了不错的成绩。 并不是说 Soundex 可以非常方便地处理大型数据集,因为您将获得永远不变的单词的 Soundex 表示。我在数据库中有超过 80000 个条目,并存储了它们的 Soundex 表示,以便与针进行快速匹配。不过,我从来没有做过任何真正的基准测试。【参考方案3】:

Damerau-Levenshtein distance 类似于 Levenshtein 距离,但也包括两个字符的换位。***页面(链接)包含应该相当容易实现的伪代码。

【讨论】:

【参考方案4】:

您正在寻找Levenshtein distance

【讨论】:

以上是关于找出两个字符串的相似程度的主要内容,如果未能解决你的问题,请参考以下文章

使用 TF-IDF 加权的空间向量模型实现句子相似度计算

如何在 Python 中比较两个字符串(英语除外)之间的相似性

如何使用 WordNet 路径算法计算两个字符串中单词的语义相似度

华为机试-计算字符串的相似度

[华为]计算字符串的相似度

Python:字符串的语义相似度得分