何时使用哪个模糊函数来比较2个字符串

Pot*_*Pot 28 python string-comparison fuzzywuzzy

我在python中学习fuzzywuzzy,理解fuzz.ratio,fuzz.partial_ratio,fuzz.token_sort_ratio和fuzz.token_set_ratio的概念.我的问题是何时使用哪个功能?我先检查2个字符串的长度,如果不相似,那么排除fuzz.partial_ratio吗?或者,如果2个字符串的长度相似,我将使用fuzz.token_sort_ratio?或者我应该总是使用fuzz.token_set_ratio?

谁知道SeatGeek使用什么标准?

我正在尝试建立一个房地产网站,思考使用fuzzywuzzy来比较地址.

任何见解都非常感激.

R.

Ric*_* II 57

好问题.

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

概观

在引擎盖下,四种方法中的每一种都计算两个输入字符串中令牌的某些排序之间的编辑距离.这是使用进行difflib.ratio功能这将:

返回序列相似性的度量(浮点数为[0,1]).

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

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

fuzz.ratio

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

fuzz.ratio("NEW YORK METS", "NEW YORK MEATS")
> 96
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

fuzz.token_set_ratio

尝试排除字符串中的差异.调用三个特定子字符串集的比率并返回max(代码):

  1. 仅交叉和与字符串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
Run Code Online (Sandbox Code Playgroud)

应用

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

话虽如此,真相告诉它听起来不像FuzzyWuzzy对你的用例有用.确定两个地址是否相似会非常糟糕.考虑SeatGeek总部的两个可能的地址:"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
Run Code Online (Sandbox Code Playgroud)

FuzzyWuzzy给这些字符串一个高匹配分数,但一个地址是我们在联合广场附近的实际办公室,另一个是在大中央的另一边.

对于您的问题,最好使用Google地理编码API.


Den*_*zov 11

截至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
Run Code Online (Sandbox Code Playgroud)

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   
Run Code Online (Sandbox Code Playgroud)

fuzz.QRatio,fuzz.UQRatio

只需包装fuzz.ratio一些验证和短路,这里包含完整性. UQRatio是一个unicode版本QRatio.

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.
Run Code Online (Sandbox Code Playgroud)

fuzz.UWRatio

Unicode版本WRatio.