0

在比较 2 个字符串的相似性时,我想排除一个字符串列表,例如,忽略 'Texas' 和 'US'。

我尝试在 Difflib 的 SequenceMatcher 中使用参数“isjunk”:

exclusion = ['Texas', 'US']
sr = SequenceMatcher(lambda x: x in exclusion, 'Apple, Texas, US', 'Orange, Texas, US', autojunk=True).ratio()

print (sr)

相似度高达 0.72,因此显然它没有排除不需要的字符串。

这样做的正确方法是什么?

4

1 回答 1

1

我对这个包不熟悉,但作为一个好奇的人,我用谷歌搜索了一下,并通过一些自我示例对其进行了一些探索。我发现了一些有趣的东西,这不是解决您问题的方法,它更像是您收到结果的借口。

正如我在这里发现的:

ratio( ) 返回输入字符串之间的相似度分数( float in [0,1] )。它将函数 get_matching_blocks 返回的所有匹配序列的大小相加,并计算比率为: ratio = 2.0*M / T ,其中 M = matches , T = 两个序列中的元素总数

所以让我们看一个例子:

from difflib import SequenceMatcher
exclusion = ['Texas', 'US']
a = 'Apple, Texas, US'
b = 'Orange, Texas, US'
sr = SequenceMatcher(lambda x: x in exclusion, a, b, autojunk=True)
matches = sr.get_matching_blocks()
M = sum([match[2] for match in matches])
print(matches)
ratio = 2*M/(len(a) + len(b))
print(f'ratio calculated: {ratio}')
print(sr.ratio())

我懂了:

[Match(a=4, b=5, size=12), Match(a=16, b=17, size=0)]
ratio calculated: 0.7272727272727273
0.7272727272727273

那么对于这个例子,我希望得到相同的结果:

a = 'Apple, Texas, USTexasUS'
b = 'Orange, Texas, US'

我预计额外的TexasUS将被忽略,因为它在exclusion列表中,然后ratio将保持不变,让我们看看我们得到了什么:

[Match(a=4, b=5, size=12), Match(a=23, b=17, size=0)]
ratio calculated: 0.6
0.6

口粮比第一个例子少,没有任何意义。但是如果我们深入研究一下输出,我们会发现匹配是完全一样的!那么有什么区别呢?字符串的长度(它与排除的字符串一起计算)!如果我们坚持链接中的命名约定,T现在更大:

T2>T1 ----> ratio2<ratio1

我可以建议您在匹配之前自行过滤单词,如下所示:

exclusion = ['Texas', 'US']
a = 'Apple, Texas, USTexasUS'
b = 'Orange, Texas, US'
for word2exclude in exclusion:
    a = a.replace(word2exclude,'')
    b = b.replace(word2exclude,'')
sr = SequenceMatcher(None, a, b)

希望你会发现它很有用,也许不是为了解决你的问题,而是为了理解它(理解一个问题是解决问题的第一步!)

于 2020-10-07T06:42:34.597 回答