如何在Python中获得一个字符串与另一个字符串相似的概率?

我想要得到一个十进制值,比如0.9(意思是90%)等等。最好是标准的Python和库。

e.g.

similar("Apple","Appel") #would have a high prob.

similar("Apple","Mango") #would have a lower prob.

当前回答

你可以在这个链接下找到大多数文本相似度方法及其计算方法:https://github.com/luozhouyang/python-string-similarity#python-string-similarity 这里有一些例子;

归一化,度量,相似度和距离 (归一化)相似度和距离 距离度量 基于相似度和距离的带状(n-gram) Levenshtein 规范化Levenshtein 加权Levenshtein Damerau-Levenshtein 最佳字符串对齐 Jaro-Winkler 最长公共子序列 度量最长公共子序列 语法 基于瓦(n-gram)的算法 Q-Gram 余弦相似度 Jaccard指数 Sorensen-Dice系数 重叠系数(即Szymkiewicz-Simpson)

其他回答

这是我想到的:

import string

def match(a,b):
    a,b = a.lower(), b.lower()
    error = 0
    for i in string.ascii_lowercase:
            error += abs(a.count(i) - b.count(i))
    total = len(a) + len(b)
    return (total-error)/total

if __name__ == "__main__":
    print(match("pple inc", "Apple Inc."))

内置的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

还添加了Spacy NLP库;

@profile
def main():
    str1= "Mar 31 09:08:41  The world is beautiful"
    str2= "Mar 31 19:08:42  Beautiful is the world"
    print("NLP Similarity=",nlp(str1).similarity(nlp(str2)))
    print("Diff lib similarity",SequenceMatcher(None, str1, str2).ratio()) 
    print("Jellyfish lib similarity",jellyfish.jaro_distance(str1, str2))

if __name__ == '__main__':

    #python3 -m spacy download en_core_web_sm
    #nlp = spacy.load("en_core_web_sm")
    nlp = spacy.load("en_core_web_md")
    main()

使用Robert Kern的line_profiler运行

kernprof -l -v ./python/loganalysis/testspacy.py

NLP Similarity= 0.9999999821467294
Diff lib similarity 0.5897435897435898
Jellyfish lib similarity 0.8561253561253562

然而,时间的启示

Function: main at line 32

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    32                                           @profile
    33                                           def main():
    34         1          1.0      1.0      0.0      str1= "Mar 31 09:08:41  The world is beautiful"
    35         1          0.0      0.0      0.0      str2= "Mar 31 19:08:42  Beautiful is the world"
    36         1      43248.0  43248.0     99.1      print("NLP Similarity=",nlp(str1).similarity(nlp(str2)))
    37         1        375.0    375.0      0.9      print("Diff lib similarity",SequenceMatcher(None, str1, str2).ratio()) 
    38         1         30.0     30.0      0.1      print("Jellyfish lib similarity",jellyfish.jaro_distance(str1, str2))

出于我的目的,我有自己的quick_ratio(),它比difflib SequenceMatcher的quick_ratio()快2倍,同时提供类似的结果。A和b是字符串:

    score = 0
    for letters in enumerate(a):
        score = score + b.count(letters[1])

Textdistance:

TextDistance - python库,用于通过多种算法比较两个或多个序列之间的距离。它有Textdistance

30 +算法 纯python实现 简单的使用 两个以上的序列比较 有些算法在一个类中有多个实现。 可选的numpy使用最高速度。

例二:

import textdistance
textdistance.hamming('test', 'text')

输出:

1

Example2:

import textdistance

textdistance.hamming.normalized_similarity('test', 'text')

输出:

0.75

谢谢,干杯!