字符串相似度应用场景:拼写纠错、文本去重、上下文相似性、不同来源数据对比等。
评价字符串相似度最常见的办法就是:把一个字符串通过插入、删除或替换这样的编辑操作,变成另外一个字符串,所需要的最少编辑次数,这种就是编辑距离(edit distance)度量方法,也称为Levenshtein距离。
方法1、difflib模块
1 # 优点:python自带模块,效率比较高 2 def similar_diff_ratio(str1, str2): 3 return difflib.SequenceMatcher(None, str1, str2).ratio() 4 5 # quick_ratio()比ratio()计算效率更高,计算结果一致 6 def similar_diff_qk_ratio(str1, str2): 7 return difflib.SequenceMatcher(None, str1, str2).quick_ratio() 8 9 # None参数是一个函数,用来去掉不需要比较的字符。比如,列表lst_str表示计算相似度时不需要比较的字符 10 def similar_diff_ratio_filter(lst_str, str1, str2): 11 return difflib.SequenceMatcher(lambda x: x in lst_str, str1, str2).ratio() 12 13 print(similar_diff_ratio("临安区中小企业创业基地", "临安区电子商务科技园")) 14 print(similar_diff_qk_ratio("临安区中小企业创业基地", "临安区电子商务科技园")) 15 # 有一点疑问,将不需要比较的字符加入后,相似度计算结果没变化,欢迎大佬留言解惑,谢谢! 16 lst_str = ['临安区', '创业', '为什么', '忽略', '某些字符之后', '相似度还是一致'] 17 print(similar_diff_ratio_filter(lst_str, "临安区中小企业创业基地", "临安区电子商务科技园"))
0.2857142857142857
0.2857142857142857
0.2857142857142857
方法2、通过在长度较短的字符串末尾补充空格,将2个字符串处理成等长,然后从左至右比较同位置字符串
1 def similar_left(str1, str2): 2 str1 = str1 + ' ' * (len(str2) - len(str1)) 3 str2 = str2 + ' ' * (len(str1) - len(str2)) 4 return sum(1 if i == j else 0 for i, j in zip(str1, str2)) / float(len(str1)) 5 6 print(similar_left("临安区中小企业创业基地", "临安区电子商务科技园")) 7 print(similar_left("临安区电子商务科技园", "园技科务商子电区安临"))
0.2727272727272727
0.0
方法3、Levenshtein模块
3.1、相似度
1 # 莱文斯坦比 2 def similar_lvst_ratio(str1, str2): 3 return Levenshtein.ratio(str1, str2) 4 5 # jaro距离 6 def similar_lvst_jaro(str1, str2): 7 return Levenshtein.jaro(str1, str2) 8 9 # Jaro–Winkler距离 10 def similar_lvst_winkler(str1, str2): 11 return Levenshtein.jaro_winkler(str1, str2) 12 13 print(similar_lvst_ratio("临安区中小企业创业基地", "临安区电子商务科技园")) 14 print(similar_lvst_jaro("临安区中小企业创业基地", "临安区电子商务科技园")) 15 print(similar_lvst_winkler("临安区中小企业创业基地", "临安区电子商务科技园"))
0.2857142857142857
0.5242424242424243
0.666969696969697
3.2、相似性度量
1 # distance编辑距离(也称为Levenshtein距离 )。是描述由一个字串转化成另一个字串最少的操作次数,在其中的操作包括插入、删除、替换。 2 def similar_lvst_distance(str1, str2): 3 return Levenshtein.distance(str1, str2) 4 5 # hamming汉明距离是编辑距离的一种特殊情况。 要求str1和str2必须长度一致,描述两个等长字串之间对应位置上不同字符的个数。 6 def similar_lvst_hamming(str1, str2): 7 return Levenshtein.hamming(str1, str2) 8 9 print(similar_lvst_distance("临安区中小企业创业基地", "临安区电子商务科技园")) 10 print(similar_lvst_hamming("临安区中小企业创业基地", "临安区电子商务科技园区"))
8
8
其他常用相似性度量方法还有 Jaccard distance、J-W距离(Jaro–Winkler distance)、余弦相似性(cosine similarity)、欧氏距离(Euclidean distance)等。
若想对以上方法有更深入研究,可参考大佬博客:https://www.cnblogs.com/wt869054461/p/5777782.html