如何获得一个字符串与Python中另一个字符串相似的概率?
我想得到一个十进制值,例如0.9(表示90%)等。最好使用标准Python和库。
例如
similar("Apple","Appel") #would have a high prob.
similar("Apple","Mango") #would have a lower prob.
如何获得一个字符串与Python中另一个字符串相似的概率?
我想得到一个十进制值,例如0.9(表示90%)等。最好使用标准Python和库。
例如
similar("Apple","Appel") #would have a high prob.
similar("Apple","Mango") #would have a lower prob.
Answers:
有一个内置的。
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
使用它:
>>> similar("Apple","Appel")
0.8
>>> similar("Apple","Mango")
0.0
get_close_matches
,尽管我发现sorted(... key=lambda x: difflib.SequenceMatcher(None, x, search).ratio(), ...)
更可靠,但还是内置了自定义sorted(... .get_matching_blocks())[-1] > min_match
检查功能
get_closest_matches
)。这是一个便捷功能,可能就是您想要的,请阅读文档!在我的特定应用程序中,我正在对提供错误输入的用户进行一些基本的错误检查/报告,并且此答案使我可以向他们报告潜在的匹配以及 “相似性”是什么。但是,如果您不需要显示相似性,请一定要查看一下get_closest_matches
我认为您可能正在寻找一种描述字符串之间距离的算法。您可能会参考以下内容:
优点:本地python库,不需要额外的软件包。
缺点:太有限了,还有很多其他的用于字符串相似性的好的算法。
>>> from difflib import SequenceMatcher
>>> s = SequenceMatcher(None, "abcd", "bcde")
>>> s.ratio()
0.75
它是一个很好的图书馆,覆盖面广,几乎没有问题。它支持:
-莱文斯坦距离
- Damerau-Levenshtein距离
-哈罗距离
-哈罗-温克勒距离
-比赛评分方法比较
-海明距离
优点:易于使用,所支持算法的色域经过测试。
缺点:不是本机库。
例如:
>>> import jellyfish
>>> jellyfish.levenshtein_distance(u'jellyfish', u'smellyfish')
2
>>> jellyfish.jaro_distance(u'jellyfish', u'smellyfish')
0.89629629629629637
>>> jellyfish.damerau_levenshtein_distance(u'jellyfish', u'jellyfihs')
1
您可以创建如下函数:
def similar(w1, w2):
w1 = w1 + ' ' * (len(w2) - len(w1))
w2 = w2 + ' ' * (len(w1) - len(w2))
return sum(1 if i == j else 0 for i, j in zip(w1, w2)) / float(len(w1))
if self.similar(search_string, item.text()) > 0.80:
现在工作。谢谢,
包装距离包括莱文施泰因距离:
import distance
distance.levenshtein("lenvestein", "levenshtein")
# 3
对于SequenceMatcher
大输入量,内置函数非常慢,这是使用diff-match-patch可以完成的方法:
from diff_match_patch import diff_match_patch
def compute_similarity_and_diff(text1, text2):
dmp = diff_match_patch()
dmp.Diff_Timeout = 0.0
diff = dmp.diff_main(text1, text2, False)
# similarity
common_text = sum([len(txt) for op, txt in diff if op == 0])
text_length = max(len(text1), len(text2))
sim = common_text / text_length
return sim, diff
注意,difflib.SequenceMatcher
仅找到最长的连续匹配子序列,这通常不是所希望的,例如:
>>> a1 = "Apple"
>>> a2 = "Appel"
>>> a1 *= 50
>>> a2 *= 50
>>> SequenceMatcher(None, a1, a2).ratio()
0.012 # very low
>>> SequenceMatcher(None, a1, a2).get_matching_blocks()
[Match(a=0, b=0, size=3), Match(a=250, b=250, size=0)] # only the first block is recorded
寻找两个字符串之间的相似性与生物信息学中成对序列比对的概念密切相关。有很多专用的库,包括biopython。这个例子实现了Needleman Wunsch算法:
>>> from Bio.Align import PairwiseAligner
>>> aligner = PairwiseAligner()
>>> aligner.score(a1, a2)
200.0
>>> aligner.algorithm
'Needleman-Wunsch'
使用biopython或其他生物信息学软件包比python标准库的任何部分都更加灵活,因为可以使用许多不同的评分方案和算法。另外,您实际上可以获取匹配序列以可视化正在发生的事情:
>>> alignment = next(aligner.align(a1, a2))
>>> alignment.score
200.0
>>> print(alignment)
Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-Apple-
|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-|||-|-
App-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-elApp-el
你可以发现,大部分的文本类似方法,以及它们是如何此链接下式计算:https://github.com/luozhouyang/python-string-similarity#python-string-similarity 下面一些例子;
归一化,度量,相似度和距离
(归一化)相似度和距离
公制距离