63

我正在学习fuzzywuzzyPython。

我理解fuzz.ratio,fuzz.partial_ratiofuzz.token_sort_ratio的概念fuzz.token_set_ratio。我的问题是什么时候使用哪个功能?

  • 我是否先检查 2 个字符串的长度,如果不相似,然后排除fuzz.partial_ratio
  • 如果 2 个字符串的长度相似,我将使用 fuzz.token_sort_ratio?
  • 我应该一直使用fuzz.token_set_ratio吗?

有人知道 SeatGeek 使用什么标准吗?

我正在尝试建立一个房地产网站,想用它fuzzywuzzy来比较地址。

4

2 回答 2

129

好问题。

我是 SeatGeek 的工程师,所以我想我可以在这里提供帮助。我们有一篇很棒的博客文章很好地解释了这些差异,但我可以总结并提供一些关于我们如何使用不同类型的见解。

概述

在后台,这四种方法中的每一种都会计算两个输入字符串中某些标记排序之间的编辑距离。这是使用以下difflib.ratio功能完成

返回序列相似性的度量(在 [0,1] 中浮动)。

其中 T 是两个序列中元素的总数,M 是匹配数,这是 2.0*M / T。请注意,如果序列相同,则为 1,如果它们没有共同点,则为 0。

四个fuzzywuzzy 方法调用difflib.ratio输入字符串的不同组合。

模糊比

简单的。只需调用difflib.ratio两个输入字符串(代码)。

fuzz.ratio("NEW YORK METS", "NEW YORK MEATS")
> 96

fuzz.partial_ratio

尝试更好地解释部分字符串匹配。ratio使用最短字符串(长度 n)对较大字符串的所有 n 长度子字符串进行调用,并返回最高分数(代码)。

请注意,“YANKEES”是最短的字符串(长度为 7),我们使用“YANKEES”对“NEW YORK YANKEES”的所有长度为 7 的子字符串运行比率(这将包括检查“YANKEES”,100% 匹配):

fuzz.ratio("YANKEES", "NEW YORK YANKEES")
> 60
fuzz.partial_ratio("YANKEES", "NEW YORK YANKEES")
> 100

fuzz.token_sort_ratio

尝试无序地解释类似的字符串。ratio在对每个字符串(代码)中的标记进行排序后调用两个字符串。注意这里fuzz.ratiofuzz.partial_ratio两者都失败了,但是一旦你对令牌进行排序,它就是 100% 匹配:

fuzz.ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 45
fuzz.partial_ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 45
fuzz.token_sort_ratio("New York Mets vs Atlanta Braves", "Atlanta Braves vs New York Mets")
> 100

fuzz.token_set_ratio

尝试排除字符串中的差异。调用三个特定子字符串集的 ratio 并返回最大值(代码):

  1. 仅交集和与字符串一的其余部分的交集
  2. 仅交集和与字符串 2 的其余部分的交集
  3. 与余数相交和与余数相交

请注意,通过拆分两个字符串的交集和余数,我们计算了两个字符串的相似和不同之处:

fuzz.ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 36
fuzz.partial_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 61
fuzz.token_sort_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 51
fuzz.token_set_ratio("mariners vs angels", "los angeles angels of anaheim at seattle mariners")
> 91

应用

这就是魔法发生的地方。在 SeatGeek,本质上我们为每个数据点(地点、事件名称等)创建了每个比率的向量分数,并使用它来通知特定于我们问题域的相似性的程序决策。

话虽如此,事实告诉它听起来并不像 FuzzyWuzzy 对您的用例有用。确定两个地址是否相似将非常糟糕。考虑 SeatGeek HQ 的两个可能地址:“235 Park Ave Floor 12”和“235 Park Ave S. Floor 12”:

fuzz.ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 93
fuzz.partial_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 85
fuzz.token_sort_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 95
fuzz.token_set_ratio("235 Park Ave Floor 12", "235 Park Ave S. Floor 12")
> 100

FuzzyWuzzy 为这些字符串提供了很高的匹配分数,但一个地址是我们在联合广场附近的实际办公室,另一个地址在 Grand Central 的另一侧。

对于您的问题,您最好使用Google Geocoding API

于 2015-08-05T05:08:53.463 回答
28

截至 2017 年 6 月,fuzzywuzzy还包括其他一些比较功能。以下是接受的答案中缺少的概述(取自源代码):

fuzz.partial_token_sort_ratio

与 中的算法相同token_sort_ratio,但不是ratio在对标记进行排序后应用,而是使用partial_ratio

fuzz.token_sort_ratio("New York Mets vs Braves", "Atlanta Braves vs New York Mets")
> 85
fuzz.partial_token_sort_ratio("New York Mets vs Braves", "Atlanta Braves vs New York Mets")
> 100    
fuzz.token_sort_ratio("React.js framework", "React.js")
> 62
fuzz.partial_token_sort_ratio("React.js framework", "React.js")
> 100

fuzz.partial_token_set_ratio

与 中的算法相同token_set_ratio,但不是应用于ratio标记集,而是使用partial_ratio

fuzz.token_set_ratio("New York Mets vs Braves", "Atlanta vs New York Mets")
> 82
fuzz.partial_token_set_ratio("New York Mets vs Braves", "Atlanta vs New York Mets")
> 100    
fuzz.token_set_ratio("React.js framework", "Reactjs")
> 40
fuzz.partial_token_set_ratio("React.js framework", "Reactjs")
> 71   

fuzz.QRatio, fuzz.UQRatio

只是fuzz.ratio用一些验证和短路来包装,为了完整起见包括在这里。 UQRatioQRatio.

fuzz.WRatio

尝试加权(名称代表“加权比率”)来自不同的算法以计算“最佳”分数。来自源代码的描述:

1. Take the ratio of the two processed strings (fuzz.ratio)
2. Run checks to compare the length of the strings
    * If one of the strings is more than 1.5 times as long as the other
      use partial_ratio comparisons - scale partial results by 0.9
      (this makes sure only full results can return 100)
    * If one of the strings is over 8 times as long as the other
      instead scale by 0.6
3. Run the other ratio functions
    * if using partial ratio functions call partial_ratio,
      partial_token_sort_ratio and partial_token_set_ratio
      scale all of these by the ratio based on length
    * otherwise call token_sort_ratio and token_set_ratio
    * all token based comparisons are scaled by 0.95
      (on top of any partial scalars)
4. Take the highest value from these results
   round it and return it as an integer.

fuzz.UWRatio

Unicode 版本的WRatio.

于 2017-06-13T19:43:26.060 回答