web-dev-qa-db-fra.com

Trouver la métrique de similarité entre deux chaînes

Comment obtenir la probabilité qu'une chaîne soit similaire à une autre chaîne en Python?

Je souhaite obtenir une valeur décimale telle que 0,9 (soit 90%), etc. De préférence avec la norme Python et la bibliothèque.

par exemple.

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

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

Il y a un construit dans.

from difflib import SequenceMatcher

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

En l'utilisant:

>>> similar("Apple","Appel")
0.8
>>> similar("Apple","Mango")
0.0
468
Inbar Rose

Je pense que vous cherchez peut-être un algorithme décrivant la distance entre les chaînes. En voici quelques exemples:

  1. distance de Hamming
  2. distance de Levenshtein
  3. distance Damerau – Levenshtein
  4. distance Jaro – Winkler
62
hbprotoss

Fuzzy Wuzzy est un package qui implémente la distance Levenshtein en python, avec des fonctions d'assistance pour vous aider dans certaines situations où vous souhaiterez peut-être que deux chaînes distinctes soient considérées comme identiques. Par exemple:

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    91
>>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    100
24
BLT

Vous pouvez créer une fonction comme:

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))
9

Le forfait distance comprend la distance de Levenshtein:

import distance
distance.levenshtein("lenvestein", "levenshtein")
# 3
8

La fonction intégrée SequenceMatcher est très lente pour les entrées volumineuses. Voici comment procéder avec 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
5
damio