Python模糊匹配库Fuzzywuzzy的process.extract()函数:它是如何工作的?

15
我想要了解 Python 模块 fuzzywuzzy 的 process.extract() 函数是如何工作的?
我主要在这里阅读关于 fuzzywuzzy 包的内容:http://chairnerd.seatgeek.com/fuzzywuzzy-fuzzy-string-matching-in-python/,这篇文章说明了在尝试进行模糊匹配时不同情况下的处理方式。他们讨论了部分字符串相似性的几种情况:
1)无序
2)令牌排序
3)令牌集
然后,从这篇文章中:https://pathindependence.wordpress.com/2015/10/31/tutorial-fuzzywuzzy-string-matching-in-python-improving-merge-accuracy-across-data-products-and-naming-conventions/ 我学习了如何使用 fuzzywuzzy 的 process.extract() 函数来选择前 k 个匹配项。
我找不到太多关于 process.extract() 函数如何工作的信息。这是它们 GitHub 页面上提供的定义/信息(https://github.com/seatgeek/fuzzywuzzy/blob/master/fuzzywuzzy/process.py),该函数:
在选择的列表或字典中查找最佳匹配项,返回包含匹配和其得分的元组列表。如果使用字典,还会返回每个匹配项的键。
但是,它没有提供有关如何找到最佳匹配项的详细信息。它使用了我上面提到的 3 种情况来寻找吗?
我之所以问这个问题,是因为当我使用此函数时,有时会有两个非常相似但未被匹配的字符串。例如,在我的当前样本数据集中,对于待匹配字符串 "Total replenishment lead time (in workdays)",它被匹配到了 "PLANNING_TIME_FENCE_CODE" 和 "BUILD_IN_WIP_FLAG",但没有匹配到正确答案 "FULL_LEAD_TIME"。尽管正确答案也包含 "lead time",但它根本没有与待匹配字符串进行匹配。为什么?而且,那些看起来不像待匹配字符串的其它字段却可以被匹配。为什么?我现在很茫然。
3个回答

20
另一个答案在一个关键方面是错误的 - 推断process.extract的结果在某种情况下与fuzz.partial_ratio相同,因此它们默认执行相同的操作。实际上,process.extract默认使用WRatio(),这是四个fuzz比率的加权组合。这实际上是一种很酷的功能,在模糊匹配场景中经验性地表现得非常好。不过,你可以通过extractscorer参数手动指定字符串比较函数。 process.extract的源代码:https://github.com/seatgeek/fuzzywuzzy/blob/master/fuzzywuzzy/process.py

1
这是一个重要的澄清!感谢您提出这个问题。 - dTanMan

9

在fuzzywuzzy比较中有四种比率。

  • base_ratio: 两个字符串的Levenshtein距离。
  • partial_ratio: 最相似子字符串的比率。
  • token_sort_ratio: 在比较之前对令牌进行排序,以测量序列的相似度。
  • token_set_ratio: 查找每个字符串中的所有字母数字标记。

可以在此处找到更多关于比率的详细信息:http://chairnerd.seatgeek.com/fuzzywuzzy-fuzzy-string-matching-in-python/

默认情况下,process.extract()使用Partial_ratio进行比较,但是您也可以使用第三个参数覆盖它来调用process.extract()

例如:

print(fuzz.partial_ratio('Total replenishment lead time (in workdays)', 'Lead_time_planning'))
query = 'Total replenishment lead time (in workdays)'
choices = ['PLANNING_TIME_FENCE_CODE', 'BUILD_IN_WIP_FLAG','Lead_time_planning']
print(process.extract(query, choices))

结果将是:

50
[('Lead_time_planning', 50), ('PLANNING_TIME_FENCE_CODE', 38), ('BUILD_IN_WIP_FLAG', 26)]

这表明它默认使用partial_ratio算法,而您可以随时覆盖它。


4
覆写示例:process.extract(query, choices, scorer=fuzzywuzzy.token_set_ratio)。注:这是 Python 中使用 fuzzywuzzy 库进行字符串匹配时的一个示例。该函数将查询字符串 query 与备选字符串列表 choices 进行相似度匹配,并返回最佳匹配结果。参数 scorer 指定了匹配算法,此处为 token_set_ratio 算法。 - VISQL
1
今天你需要执行 from fuzzywuzzy import fuzz,然后将评分器传递为 fuzz.token_set_ratio - igorkf

1

关于process.extract的默认评分器WRatio,我一直在思考同样的问题。由于查询字符串中有一个孤立的A字符,所有其他评分器都能够识别正确的匹配项,即Alphabet,但是使用默认解析器时,可能会出现A/S子字符串的更高匹配度,如果有人能解释为什么会这样,那就太棒了。

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_set_ratio, limit=3)
[('Alphabet Inc', 89, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_sort_ratio, limit=3)
[('Alphabet Inc', 73, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.partial_ratio, limit=3)
[('Alphabet Inc', 82, 4955), ('EQT AB', 73, 5838), ('BEL SA', 67, 2430)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.ratio, limit=3)
[('Alphabet Inc', 78, 4955), ('Alpha Bank SA', 67, 4720), ('Pharnext SA', 64, 9228)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], limit=3)
[('Iss A/S', 86, 4), ('Vestas Wind Systems A/S', 86, 87), ('AP Moeller - Maersk A/S', 86, 126)]

编辑:从github代码中可以看出,似乎还有另一个得分器叫做partial_token_set_ratio,它可能是罪魁祸首。但我仍然希望了解Wration使用哪些得分器以及它们的权重是多少。如果能够创建自定义的WRatio并选择使用哪些得分器,那将是非常棒的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接