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

2024-04-28 20:44:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习Python中的fuzzywuzzy

我理解fuzz.ratiofuzz.partial_ratiofuzz.token_sort_ratiofuzz.token_set_ratio的概念。我的问题是什么时候使用哪个函数?

  • 我要先检查这两个字符串的长度吗?如果不相似,就按规则 出去fuzz.partial_ratio
  • 如果两个字符串的长度相似,我将使用 fuzz.token_sort_ratio
  • 我应该一直使用fuzz.token_set_ratio

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

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


Tags: 函数字符串token概念标准网站规则地址
2条回答

好问题。

我是SeatGeek的工程师,所以我想我能帮上忙。我们有一个很好的blog post可以很好地解释这些差异,但是我可以总结并提供一些关于如何使用不同类型的见解。

概述

在引擎盖下,四个方法中的每一个都计算两个输入字符串中标记的某些顺序之间的编辑距离。这是使用difflib.ratio函数which will完成的:

Return a measure of the sequences' similarity (float in [0,1]).

Where T is the total number of elements in both sequences, and M is the number of matches, this is 2.0*M / T. Note that this is 1 if the sequences are identical, and 0 if they have nothing in common.

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

模糊比率

很简单。只需对两个输入字符串(code)调用difflib.ratio

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

模糊部分比

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

注意这里“洋基”是最短的字符串(长度7),我们用“洋基”与“纽约洋基”长度7的所有子字符串(包括检查“洋基”,100%比赛)的比率:

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

fuzz.token_sort_比率

试图解释类似字符串的顺序错误。在对每个字符串(code)中的标记进行排序后,对两个字符串调用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_比率

试图排除字符串中的差异。调用三个特定子字符串集的比率并返回最大值(code):

  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

应用程序

这就是魔法发生的地方。在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

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

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

截至2017年6月,fuzzywuzzy还包括一些其他比较函数。以下是已接受答案中缺少的部分的概述(摘自source code):

fuzz.partial_token_sort_比率

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_比率

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   

模糊.QRatio,模糊.UQRatio

只需在fuzz.ratio周围包装一些验证和短路,这里包括完整性。 UQRatioQRatio的unicode版本。

绒毛包装

尝试加权(名称代表“加权比率”)的结果来自不同的算法 计算“最佳”分数。 源代码中的说明:

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.

模糊率

WRatio的Unicode版本。

相关问题 更多 >