Python��用于字符串相似度比较的方法

4
我希望能够测量两个单词之间的相似度。我的想法是使用OCR读取文本并检查其中关键词的结果。 我需要的函数应该比较两个单词,并以%的形式返回它们之间的相似度。因此,将一个单词与自身进行比较应该是100%的相似度。 我已经编写了自己的函数,并逐个字符进行比较,然后根据长度返回匹配数量的比率。但问题在于:
wordComp('h0t',hot')
0.66
wordComp('tackoverflow','stackoverflow')
0

但是直观上看,这两个例子应该具有非常高的相似度>90%。添加Levenstein距离。

import nltk
nltk.edit_distance('word1','word2')

在我的函数中,第二个结果将增加到92%,但第一个结果仍不好。我已经找到了这个“R”的 解决方案,可以使用rpy2或使用agrepy作为另一种方法。但是,我想通过更改接受标准的基准来使程序更加敏感和不敏感(只接受相似度> x%的匹配)。是否有其他好的度量标准可以使用,或者您有任何改进函数的想法?
2个回答

9

你可以使用difflib库。以下函数是我从之前一个回答中获得的,一直为我服务得很好:

from difflib import SequenceMatcher

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

print (similar('tackoverflow','stackoverflow'))
print (similar('h0t','hot'))

0.96
0.666666666667

您可以轻松地添加该函数或将其包装在另一个函数中,以考虑不同程度的相似性,例如通过传递第三个参数:
from difflib import SequenceMatcher

def similar(a, b, c):
    sim = SequenceMatcher(None, a, b).ratio()
    if sim > c: 
        return sim

print (similar('tackoverflow','stackoverflow', 0.9))
print (similar('h0t','hot', 0.9))

0.96
None

谢谢你的建议。这对我解决第一个问题有所帮助,但是短单词的问题仍然没有答案。你还有其他的想法吗? - tifi90
我不太确定为什么您想要一个三个字母单词的更高价值。您说直觉上您期望更高的相似度。严格来说,两个字符串之间有一个字符不同,这使它们的相似度为66%。您能详细说明您期望的结果以及原因吗? - ragamuffin
我不知道确切的结果应该是什么。让我觉得分数更高的一点是,如果你比较h0t和hxt,直观上h0t比hxt更接近hot,因为0和o几乎相同。想象一下,如果这是手写的,你不会真的把h0t标记为错误,但hxt显然是错的。 - tifi90
嗯,是的,它们在美学上很相似,我不知道有什么方法可以测试这一点。这也很主观,不是吗?就所有意图和目的而言,X、O和0彼此同样不相似。 - ragamuffin
我刚刚想到了以下“快速而简单”的解决方案:只需使用固定映射将数字映射到字符(0->o,5->s,3->E,9->g,...)。由于我正在搜索真实单词,因此零或五或任何数字都不应该成为关键字的一部分。 - tifi90
显示剩余2条评论

0

我写了以下代码。试一下吧。我定义了一个 str3,用于处理两个比较字符串(str1 和 str2)长度不相等的情况。代码使用 while 循环,并且可以通过输入 k 来退出。

k=1
cnt=0
str3=''
while not k==-1:
    str1=input()
    str2=input()
    k=int(input())

    if len(str1)>len(str2):
        str3=str1[0:len(str2)]
        for j in range(0,len(str3)):
            if str3[j]==str2[j]:
                cnt+=1
        print((cnt/len(str1)*100))

    elif len(str1)<len(str2):
        str3=str2[0:len(str1)]
        for j in range(0,len(str2)):
            if str3[j]==str1[j]:
                cnt+=1
        print((cnt/len(str2)*100))

    else:
        for j in range(0,len(str2)):
            if str2[j]==str1[j]:
                cnt+=1
        print((cnt/len(str1)*100))

感谢分享你的代码。这看起来就像我一开始尝试的那样。使用这个函数可以得到类似的结果,就像我做的一样。我看到的主要问题是当你截取字符串 str3=str2[0:len(str1)] 时会丢失很多信息。 - tifi90

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接