SequenceMatcher-更喜欢有序匹配

时间:2018-11-14 08:00:46

标签: python

我有一个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 salmonsalmon更好。 换句话说,我希望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甚至会产生分数?

我尝试关闭自动垃圾邮件,但似乎没有影响。

1 个答案:

答案 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()计算赃物的完整说明。