1

Consider this example:

>> from fuzzywuzzy import process
>> choices = ['account', 'update', 'query']
>> process.extract('u', choices)
[('account', 90), ('update', 90), ('query', 90)]

In the above case, it's confusing for my end-users that account is ranked above update for the given string. In this case account happens to be arbitrarily placed in front due to list order, since all matches share the same score. However, I would have imagined that update would have a higher score simply because the character u shows up earlier in the string.

Is this a conceptual error or am I not using the correct scorer here?

4

3 回答 3

4

首先,您使用的是“糟糕”的得分手。根据您的分数,您可能正在使用 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) 是衡量两个字符串之间相似性的指标,我们将其称为源字符串 (s) 和目标字符串 (t)。距离是将 s 转换为 t 所需的删除、插入或替换的数量。

这就是为什么我添加了MyScorer()你可以在哪里实现自己的算法的定义,该算法考虑了这个位置。我还添加了一个将位置考虑在内的实现示例(但我在设计此类算法方面并没有真正的经验,所以不要指望这个算法是完美的,甚至是可用的)。无论如何,MyScorer 的输出是:

[('update', 29), ('query', 28), ('account', 5)]

于 2017-06-01T06:21:36.277 回答
1

在您的代码中:

process.extract('u', choices)  

您没有通过 scorer 函数来提取方法。该方法将为您选择 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)]

于 2017-06-01T06:48:08.630 回答
0

“process.extract”在选择列表或字典中找到最佳匹配,返回包含匹配的元组列表及其分数。它不依赖于列表或字典中选择的“位置”。

于 2017-06-01T06:14:44.323 回答