【问题标题】:Python fuzzy matching of names with only first initialsPython模糊匹配只有名字首字母的名字
【发布时间】:2017-09-12 22:11:29
【问题描述】:

我有一种情况,我需要将给定字符串中的名称与名称数据库进行匹配。下面我给出了一个非常简单的例子来说明我遇到的问题,我不清楚为什么一个案例比另一个案例有效?如果我没记错的话,extractOne() 的 Python 默认算法是 Levenshtein 距离算法。是因为 Clemens 的名字提供了前两个首字母,而 Gonzalez 的案例中只有一个?

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

s = ['Gonzalez, E. walked down the street.', 'Gonzalez, R. went to the market.', 'Clemens, Ko. reach the intersection; Clemens, Ka. did not.']

names = []

for i in s:

    name = [] #clear name
    for k in i.split():
        if k[0].isupper(): name.append(k)
        else: break
    names.append(' '.join(name))

    if ';' in i:
        for each in i.split(';')[1:]:
            name = [] #clear name
            for k in each.split():
                if k[0].isupper(): name.append(k)
                else: break
            names.append(' '.join(name))

print(names)

choices = ['Kody Clemens','Kacy Clemens','Gonzalez Ryan', 'Gonzalez Eddy']

for i in names:
    s = process.extractOne(i, choices)
    print(s, i)

输出:

['Gonzalez, E.', 'Gonzalez, R.', 'Clemens, Ko.', 'Clemens, Ka.']
('Gonzalez Ryan', 85) Gonzalez, E.
('Gonzalez Ryan', 85) Gonzalez, R.
('Kody Clemens', 86) Clemens, Ko.
('Kacy Clemens', 86) Clemens, Ka.

【问题讨论】:

  • 您可以发布您在运行案例时得到的结果吗?我不确定你的问题是什么
  • 编辑以包含输出
  • 我不知道匹配到底是如何发生的,但s = process.extractOne(i, choices, scorer=fuzz.token_sort_ratio) 有效
  • 哇,效果很好。可能是因为我的匹配更多地依赖于排序而不是实际相似的单词/名称。包括您的回复作为答案,我会接受。谢谢!

标签: python fuzzywuzzy


【解决方案1】:

虽然@Igle 的评论确实解决了这个特定问题,但我想强调这是一个狭隘的解决方案,不一定适用于所有事情。 Fuzzywuzzy 有多个计分器,它们使用 Levenshtein 距离算法结合不同的逻辑来比较字符串。默认记分器 fuzz.WRatio 将直接 Levenshtein 距离算法 (fuzz.ratio) 的匹配分数与其他变体进行比较,并返回所有记分器的最佳匹配。不仅如此,还包括关于加权不同方法的分数的附加逻辑,如果您有兴趣,我建议您查看the source code for fuzz.WRatio

要查看您的情况发生了什么,您可以通过稍微修改代码的最后几行来比较评分者中所有选择的分数:

对于 token_set_ratio:

for i in names:
   s = process.extract(i, choices,scorer=fuzz.token_set_ratio)
   print(s, i)

[('Gonzalez Ryan', 89), ('Gonzalez Eddy', 89), ('Kody Clemens', 27), ('Kacy Clemens', 27)] Gonzalez, E.
[('Gonzalez Ryan', 89), ('Gonzalez Eddy', 89), ('Kody Clemens', 27), ('Kacy Clemens', 27)] Gonzalez, R.
[('Kody Clemens', 91), ('Kacy Clemens', 82), ('Gonzalez Ryan', 26), ('Gonzalez Eddy', 26)] Clemens, Ko.
[('Kacy Clemens', 91), ('Kody Clemens', 82), ('Gonzalez Ryan', 35), ('Gonzalez Eddy', 26)] Clemens, Ka.

对于 token_sort_ratio:

for i in names:
   s = process.extract(i, choices,scorer=fuzz.token_sort_ratio)
   print(s, i)

[('Gonzalez Eddy', 87), ('Gonzalez Ryan', 70), ('Kody Clemens', 27), ('Kacy Clemens', 27)] Gonzalez, E.
[('Gonzalez Ryan', 87), ('Gonzalez Eddy', 70), ('Kody Clemens', 27), ('Kacy Clemens', 27)] Gonzalez, R.
[('Kody Clemens', 91), ('Kacy Clemens', 82), ('Gonzalez Ryan', 26), ('Gonzalez Eddy', 26)] Clemens, Ko.
[('Kacy Clemens', 91), ('Kody Clemens', 82), ('Gonzalez Ryan', 35), ('Gonzalez Eddy', 26)] Clemens, Ka.

虽然 token_sort_ratio 显示出明显的获胜匹配,但 token_set_ratio 返回更高的分数,这就是 fuzz.WRatio 选择它返回的结果的方式。另一个主要问题是,当您有类似的查询和选择时,它们的比较顺序开始变得重要。例如,当我运行与上面完全相同的代码,但颠倒选择列表的顺序时,我们得到的都是“Gonzalez Eddy”:

for i in names:
   s = process.extract(i, choices[::-1],scorer=fuzz.token_set_ratio)
   print(s, i)
[('Gonzalez Eddy', 89), ('Gonzalez Ryan', 89), ('Kacy Clemens', 27), ('Kody Clemens', 27)] Gonzalez, E.
[('Gonzalez Eddy', 89), ('Gonzalez Ryan', 89), ('Kacy Clemens', 27), ('Kody Clemens', 27)] Gonzalez, R.
[('Kody Clemens', 91), ('Kacy Clemens', 82), ('Gonzalez Eddy', 26), ('Gonzalez Ryan', 26)] Clemens, Ko.
[('Kacy Clemens', 91), ('Kody Clemens', 82), ('Gonzalez Ryan', 35), ('Gonzalez Eddy', 26)] Clemens, Ka.

我猜正确的比赛实际上得分更高,但“Eddy”和“Ryan”足够接近以使最终得分相同。

我过去处理类似问题的方式:

  1. 使用 extract 而不是 extractOne(就像我在上面的示例中所做的那样)
  2. 使用多个评分器(ratio、token_set_ratio、token_sort_ratio)处理相同的查询/选择,并使用这些分数的加权平均值来选择最佳匹配。
  3. 调整fuzzywuzzy 源代码以合并自定义权重或删除舍入。

【讨论】:

  • 感谢您的详细解答。我一直在推进以前的 cmets 中的解决方案,它对我的​​应用程序非常可靠,但是这提供了很好的清晰度。谢谢!
  • 很高兴为您提供帮助,很高兴它对您有用。这实际上帮助我更好地了解了我自己项目的模块的内部工作原理,所以每个人都赢了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多