首页 > 解决方案 > 从数据库中查找相似的人名

问题描述

我在 MySql 中有一个表,其中包含名称。我正在尝试,给定一个输入名称,在表中找到所有相似的名称。我听说过很多关于 Levenshtien/Damerau-Levenshtein 距离的信息,但它似乎不适用于此,稍后我将解释我的推理。

详细说明:

我质疑在这种情况下使用 Levenshtien/Damerau–Levenshtein 距离的原因是它无法很好地检测到额外的名称或缺失的名称。我对 Levenshtien 距离的理解是,它找到了将一个单词更改为另一个单词所需的最小单字符编辑(插入、删除或替换)次数。因此,以下将被认为与原始字符串的距离相同。

Original string: "Juan Beldad"
Want to find: "Juan Manuel Beldad"
(7 character insertion)
Would also find: "Mike Bell"
(5 character substitution (M-i-k-e-l), 2 character deletion(a-d))

由于两者的距离均为 7 次编辑,因此“Mike Bell”与“Juan Beldad”的距离与“Juan Manuel Beldad”的距离相同。

我正在考虑查询数据库,删除输入端和表端的中间名,然后进行 Levenshtien/Damerau–Levenshtein 距离?我是不是想多了,有没有更好的方法来做到这一点?

标签: c#mysqlsql

解决方案


匹配名称时需要考虑许多可能的问题。其中一些是:

  • 昵称(鲍勃 - 罗伯特)
  • 错别字
  • 名称交换(姓与名交换)
  • 娘家姓
  • 缩写
  • 被截断的名字
  • 发音相似的名字(詹妮弗 - 珍妮)

Damerau–Levenshtein 距离是您可以使用的编辑距离算法之一。每种算法都考虑了不同的操作(字符插入、替换、删除、交换等),两者都不是完美的,但每种算法都提供了两个字符串之间的距离。

您需要决定您可以接受多少错误(即正匹配的截止值)。您给出的示例包括至少 7 个操作。在许多操作中,许多名称将返回相同的距离。

比较名称时,您应该尝试通过规范化它们来使双方具有可比性:例如,如果一侧只有名字的第一个字母,您应该在另一侧也这样做,以便编辑距离算法为您提供更好的结果.

同样,如果对方没有中间名,您可以去掉中间名(并且您可以忽略输入中间名作为名字的情况)。但更好的选择是使用名称中所有可用的单词生成所有可能的名字对,看看是否有任何对会产生更好的编辑距离。您还可以单独比较每个单词并找到得分最高的最佳单词组合(权衡是忽略单词边界处的拼写错误)。

除了 Damerau-Levenshtein 之外,您还应该考虑使用语音相似性算法(如 Double Metaphone)并生成组合分数。语音算法是为特定语系设计的,并试图确定两个名称在该语系中是否听起来相似。结果本身并不可靠(至少我的经验是这样),但结合编辑距离算法将改善您的匹配。

为了降低错误率,应考虑额外的数据元素,如 ZIP、DOB 等。

最后,这一切都与权衡有关:您的预期用例、您可接受的正匹配阈值、数据质量、时间/成本限制等。例如:您可以简单地要求第一个字母的第一个字母除了 Damerau-Levenshtein 距离之外,姓名和姓氏的第一个字母要相同。这将通过忽略首字母拼写错误的权衡来减少误报池。

就像现在的许多事情一样,我认为这方面的最佳结果可以通过训练有素的机器学习模型来实现。我已经有一段时间没有在这个领域工作了,所以我不确定那里有什么,但你可能会找到一个很好的基于云的解决方案来获得最优质的匹配,当然,如果这对你很重要,需要付费。

您可以在此处查看名称匹配技术的概述作为进一步阅读。


推荐阅读