我有一个SequenceMatcher
函数来查找给定的最接近的匹配项:
代码:
def seq_match(text, values, min_match=10):
highest = (None, 0)
for v in values:
sm = SequenceMatcher(a=text, b=v, autojunk=False)
ratio = int(sm.quick_ratio() * 100)
print(f'{text} : {v} : {ratio}')
if ratio > min_match and ratio > highest[1]:
highest = v, ratio
return highest
我还有一个数据集:
# (text, value1, value2, value3...): expected_output
test_map = {
# 1
('super delicious cat food', 'decent', 'delicious', 'super delicious'): 'super delicious',
# 2
('salmon: does not contain real salmon', 'chicken', 'salmon', 'arctic salmon'): 'arctic salmon',
}
在#1
数据正确匹配的情况下,#2
匹配假定更长的字符串artic salmon
比salmon
更好。
换句话说,我希望salmon
可以更好地匹配等于或更大的数学公式artic salmon
。
以下是所有匹配结果:
# correct
super delicious cat food : decent : 33
super delicious cat food : delicious : 54
super delicious cat food : super delicious : 76
salmon: does not contain real salmon : chicken : 18
salmon: does not contain real salmon : salmon : 28
# incorrect
salmon: does not contain real salmon : arctic salmon : 48
# expected
salmon: does not contain real salmon : arctic salmon : 28 or less
我可以强制SequenceMatcher
在这里更理性吗?如何获得想要的结果?为什么arctic
甚至会产生分数?
我尝试关闭自动垃圾邮件,但似乎没有影响。
答案 0 :(得分:1)
如果您查看SequenceMatcher
here
您将看到其算法的以下说明:
The idea is to find the longest contiguous matching subsequence that contains
no “junk” elements
根据此定义,arctic salmon
的相似性得分要比salmon
高。
为了更好地理解为什么查看以下代码:
a = 'salmon: does not contain real salmon'
b = 'arctic salmon'
sm = SequenceMatcher(a, b, autojunk=False)
sm.get_matching_blocks()
输出:
[Match(a=1, b=0, size=1),
Match(a=15, b=3, size=1),
Match(a=17, b=5, size=1),
Match(a=29, b=6, size=7),
Match(a=36, b=13, size=0)]
如您所见,arctic salmon
有10个匹配项,而salmon
中只有6个匹配项,因此您的比率为2 * 10 / 49 = 0.40816326530612246
。
有关以上链接中ratio()
计算赃物的完整说明。