Language agnostic 人名比较:完成此任务的方法

Language agnostic 人名比较:完成此任务的方法,language-agnostic,nlp,Language Agnostic,Nlp,我不是自然语言编程专业的学生,但我知道这不是一个微不足道的strcmp(n1,n2) 以下是我到目前为止学到的: 比较人名无法100%解决 有一些方法可以达到一定程度的准确性 答案将是特定于地区的,没关系 我不是在找拼写的替代品!假设输入的拼写是正确的 例如,以下所有姓名都可以指同一个人: 贝里查卡拉 伯纳德·查卡拉 贝里·查卡拉 查卡拉,贝瑞 我正试图: 构建(或复制)一个算法,该算法对两个输入名称之间的关系进行分级 查找索引方法(用于数据库中的名称、哈希表等) 注: 我的任务不是在文

我不是自然语言编程专业的学生,但我知道这不是一个微不足道的strcmp(n1,n2)

以下是我到目前为止学到的:

  • 比较人名无法100%解决
  • 有一些方法可以达到一定程度的准确性
  • 答案将是特定于地区的,没关系
我不是在找拼写的替代品!假设输入的拼写是正确的

例如,以下所有姓名都可以指同一个人:

  • 贝里查卡拉
  • 伯纳德·查卡拉
  • 贝里·查卡拉
  • 查卡拉,贝瑞
我正试图:

  • 构建(或复制)一个算法,该算法对两个输入名称之间的关系进行分级
  • 查找索引方法(用于数据库中的名称、哈希表等)
  • 注: 我的任务不是在文本中查找名称,而是比较两个名称。e、 g

    name_compare( "James Brown", "Brown, James", "en-US" ) ---> 99.0%
    

    有时用于比较相似的名称。它不处理名字/姓氏排序,但您可以让代码查找逗号来解决这个问题。

    我使用Tanimoto系数作为一个快速(但不是超级)解决方案,在Python中:

    """
    Formula:
      Na = number of set A elements
      Nb = number of set B elements
      Nc = number of common items
    
      T = Nc / (Na + Nb - Nc)
    """
    def tanimoto(a, b):
        c = [v for v in a if v in b]
        return float(len(c)) / (len(a)+len(b)-len(c))
    
    def name_compare(name1, name2):
        return tanimoto(name1, name2)
    
    
    >>> name_compare("James Brown", "Brown, James")
    0.91666666666666663
    >>> name_compare("Berry Tsakala", "Bernard Tsakala")
    0.75
    >>> 
    

    编辑:

    当然,分析姓名顺序和中间姓名/首字母的存在并不重要,因此看起来真正的挑战是了解常用名称的替代方案。我怀疑不使用某种昵称查找表就可以做到这一点。这是一个很好的起点。它没有把伯纳德和贝瑞联系起来,但它可能会抓住最常见的病例。也许可以在其他地方找到更详尽的列表,但我肯定认为特定于区域设置的查找表是一种可行的方法。

    我们最近一直在不间断地进行这类工作,我们采取的方法是建立一个查找表或别名列表。如果你能对拼写错误/听错/非英语的名字打折扣,那么困难的部分就被去掉了。在你的例子中,我们假设第一个单词和最后一个单词是名字和姓氏。介于两者之间的任何内容都将被丢弃(中间名、首字母)。贝瑞和伯纳德将在别名列表中,当Tsakala与贝瑞不匹配时,我们将颠倒词序,然后获得匹配

    您需要了解的一件事是您正在处理的数据库/人员列表。在英语国家,中间名的记录不一致。因此,您不能基于中间名或中间首字母进行匹配或拒绝匹配。Soundex不会帮助您使用常见的别名,如“迪克”和“理查德”、“贝瑞”和“伯纳德”,可能还有“史蒂夫”和“斯蒂芬”。在一些社区,人们住在同一个地址,并且有2到3代人用同一个名字住在同一地址是很常见的。你能把他们分开的唯一方法是按出生日期。出生日期可以记录,也可以不记录。如果你有影响力,那么你可能应该强制记录出生日期。很多“人脉数据库”要么不记录出生日期,要么出于隐私原因不愿透露

    实际上,人名匹配并没有那么复杂。这完全取决于所提供数据的质量。实际情况是,许多记录仍然不匹配——甚至一个人看着它们也无法解决不匹配的问题。人们可能会注意到别名列表中没有记录姓名别名,或者可以在互联网上查找此人的详细信息,但你不能指望你的程序能做到这一点


    银行、信用评级机构和政府都有很多关于我们的详细信息。以前的地址,出生日期等,这有助于他们把名字联系起来。但对于我们普通的程序员来说,并没有什么灵丹妙药。

    我对Tanimoto使用utf-8有过真正的问题


    对使用变音符号的语言有效的是
    difflib.SequenceMatcher()

    是的@Jacob soundex是正确的,但是@berry必须在他使用的语言中找到一些好的实现。这很好,谷歌找到了许多soundex库和在线转换器。然而,伯纳德=Barry在Soundex里回答错了。Soundex克服了拼写错误,而不是顺序不同。我写得很明确——拼写总是正确的。对不起,我想我没有抓住你文章的重点。我现在明白了,你不是在试图纠正别人对一个名字的错误表述,而是在纠正一个名字的表述。塔尼莫托非常乐意接受字符串,不需要列出它们。非常有趣!谢谢它实际上给了我一个有意义的数值结果。(我正在为我们所有的平台编译一个……找不到二进制实现)Berry,我很高兴我能帮助你:)不错,尽管中间名在区分常用名方面起着非常重要的作用。以西班牙语名字为例:添加一个字母或中间名会大大缩小与备选名字列表的匹配范围。我确实说过,如果你不考虑非英语名字的话。如果你在一个中间名很重要的文化环境中工作,那么你显然会改变逻辑。第二个名字实际上将成为第一个名字的一部分。在这种情况下,我会尝试在名字、第二个名字和姓氏上进行匹配,然后在没有第二个名字的情况下再试一次,也许会按照英语对结果进行排序。建议忽略中间名/中间首字母。中间名的记录不一致,中间首字母在记录时容易听错。我采用这种方法匹配来自不同数据库的名称。我们最终得到了大约2万人的记录。