Python 中字符串的相似性度量
Similarity measure for Strings in Python
我想衡量两个词之间的相似度。这个想法是用 OCR 阅读文本并检查关键词的结果。
我正在寻找的函数应该比较两个词和 return 相似度(%)。所以将一个词与其自身进行比较应该是 100% 相似的。
我自己写了一个函数,一个字符一个字符地比较,然后 return 匹配的数量与长度的比例。但问题是
wordComp('h0t',hot')
0.66
wordComp('tackoverflow','Whosebug')
0
但直观上这两个例子应该有非常高的相似度>90%。添加 Levenstein 距离
import nltk
nltk.edit_distance('word1','word2')
在我的函数中会将第二个结果提高到 92%,但第一个结果仍然不好。
我已经为 "R" 找到了这个 solution 并且可以将此函数与 rpy2
一起使用或使用 agrepy
作为另一种方法。但是我想通过更改接受基准(只接受相似度 > x% 的匹配项)来使程序变得越来越敏感。
我可以使用其他好的措施吗?或者您有什么想法可以改进我的功能?
我写了下面的代码。尝试一下。我为那些两个比较字符串(str1 和 str2)的长度不相等的情况定义了一个 str3。代码在 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))
您可以只使用 difflib。我前段时间从一个答案中得到的这个功能对我很有用:
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
print (similar('tackoverflow','Whosebug'))
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','Whosebug', 0.9))
print (similar('h0t','hot', 0.9))
0.96
None
我想衡量两个词之间的相似度。这个想法是用 OCR 阅读文本并检查关键词的结果。 我正在寻找的函数应该比较两个词和 return 相似度(%)。所以将一个词与其自身进行比较应该是 100% 相似的。 我自己写了一个函数,一个字符一个字符地比较,然后 return 匹配的数量与长度的比例。但问题是
wordComp('h0t',hot')
0.66
wordComp('tackoverflow','Whosebug')
0
但直观上这两个例子应该有非常高的相似度>90%。添加 Levenstein 距离
import nltk
nltk.edit_distance('word1','word2')
在我的函数中会将第二个结果提高到 92%,但第一个结果仍然不好。
我已经为 "R" 找到了这个 solution 并且可以将此函数与 rpy2
一起使用或使用 agrepy
作为另一种方法。但是我想通过更改接受基准(只接受相似度 > x% 的匹配项)来使程序变得越来越敏感。
我可以使用其他好的措施吗?或者您有什么想法可以改进我的功能?
我写了下面的代码。尝试一下。我为那些两个比较字符串(str1 和 str2)的长度不相等的情况定义了一个 str3。代码在 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))
您可以只使用 difflib。我前段时间从一个答案中得到的这个功能对我很有用:
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
print (similar('tackoverflow','Whosebug'))
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','Whosebug', 0.9))
print (similar('h0t','hot', 0.9))
0.96
None