考虑这个例子:
>> from fuzzywuzzy import process
>> choices = ['account', 'update', 'query']
>> process.extract('u', choices)
[('account', 90), ('update', 90), ('query', 90)]
在上述情况下,对于我的最终用户而言,帐户的排名高于给定字符串的 update ,这让我感到困惑。在这种情况下,由于列表顺序,帐户碰巧被任意放在前面,因为所有匹配都共享相同的分数。但是,我会想象 update 会有更高的分数,因为字符 u 会在字符串的前面显示。
这是一个概念错误,还是我没有在这里使用正确的得分手?
答案 0 :(得分:3)
首先,你使用的是一名“糟糕”的得分手。根据您的分数,您可能正在使用difflib。您应该切换到基于python-Levenshtein
的实现。这可以使用scorer
参数完成。
from fuzzywuzzy import process
from fuzzywuzzy import fuzz
def MyScorer(s1, s2):
fratio = fuzz.ratio(s1, s2)
fratio -= (s2.find(s1)*5)
return fratio
choices = ['account', 'update', 'query']
dex = process.extract('u', choices, scorer=fuzz.token_sort_ratio)
mex = process.extract('u', choices, scorer=MyScorer)
print("Default Scorer:", dex)
print("MyScorer:", mex)
现在输出
[('query', 33), ('update', 29), ('account', 25)]
哪个更好,但Levenshtein
并不真正关心这个位置,
Levenshtein距离(LD)是两个字符串之间相似性的度量,我们将其称为源字符串和目标字符串(t)。距离是将s转换为t所需的删除,插入或替换的数量。
这就是为什么我添加了MyScorer()
的定义,您可以在其中实现自己的算法,该算法将位置考虑在内。我还添加了一个实现的例子,它考虑了这个位置(但我在设计这样的算法方面并不是很有经验,所以不要指望这个算法是完美的甚至可用的)。无论如何,MyScorer的输出是:
[('update', 29), ('query', 28), ('account', 5)]
答案 1 :(得分:1)
在您的代码中:
process.extract('u', choices)
您没有将记分器功能传递给提取方法。该方法将选择4足球的最大比例。
- base_ratio:两个字符串的Levenshtein距离。
- partial_ratio:大多数相似子字符串的比率。
- token_sort_ratio:衡量在比较之前对令牌进行排序的相似性。
- token_set_ratio:查找每个字符串中的所有字母数字标记。
在您的情况下,原始字符串为u
,目标字符串为account
,update
,query
。
基本比率为account : 25
,update : 29
,query : 33
部分比例均为90
令牌排序比率和令牌集合率均为85.5
所以每根弦的最大比例是90
所以你得到输出[('account', 90), ('update', 90), ('query', 90)]
。
答案 2 :(得分:0)
" process.extract"在列表或选项词典中找到最佳匹配,返回包含匹配及其得分的元组列表。它不依赖于"位置"列表或字典中的选择。