2013-06-30 5 views
133

Come ottengo la probabilità che una stringa sia simile a un'altra stringa in Python?Trova la percentuale di somiglianza tra due stringhe

voglio ottenere un valore decimale come:

0.9 #means 90% 

ecc

Preferibilmente con standard di Python e biblioteca.

ad es.

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

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

non credo "probabilità" è proprio il termine giusto qui. In ogni caso, consulta http://stackoverflow.com/questions/682367/good-python-modules-for-fuzzy-string-comparison – NPE

+1

La parola che stai cercando è rapporto, non probabilità. –

+1

Dai un'occhiata a [distanza di Hamming] (http://en.wikipedia.org/wiki/Hamming_distance). – Diana

risposta

313

v'è una costruito nel

from difflib import SequenceMatcher 

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

Usandolo:

>>> similar("Apple","Appel") 
0.8 
>>> similar("Apple","Mango") 
0.0 
+15

Guarda questa ottima risposta confrontando il modulo 'SequenceMatcher' vs' python-Levenshtein'. http://stackoverflow.com/questions/6690739/fuzzy-string-comparison-in-python-confused-with-which-library-to-use – ssoler

+1

Interessante articolo e strumento: http://chairnerd.seatgeek.com/fuzzywuzzy -fuzzy-string-matching-in-python/ –

+2

Consiglio vivamente di controllare l'intero documento difflib https://docs.python.org/2/library/difflib.html c'è un 'get_close_matches' integrato, sebbene io trovato 'ordinato (... key = lambda x: difflib.SequenceMatcher (None, x, search) .ratio(), ...)' più affidabile, con 'ordinamento personalizzato (... .get_matching_blocks()) [- 1]> min_match' checks – ThorSummoner

8

È possibile creare una funzione come:.

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)) 
+0

ma simile ('appel', 'apple') è superiore a simile ('appel', 'ape') – tenstar

+1

La funzione confronterà una data stringa con altre punture. Voglio un modo per restituire la stringa con il più alto rapporto di similarità – answerSeeker

+1

@SaulloCastro, 'se self.similar (search_string, item.text())> 0.80:' funziona per ora. Grazie, – answerSeeker

14

Fuzzy Wuzzy è un package che implementa Levenshtein distanza in pitone, con alcune funzioni di supporto per aiutare in determinate situazioni in cui è possibile che due stringhe distinte siano considerate identiche. Per esempio:

>>> 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 
6

pacchetto distance include Levenshtein distanza:

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

Soluzione # 1: Python builtin

uso SequenceMatcher da difflib

pro: libreria Python nativo, non è necessario alcun pacchetto aggiuntivo.
cons: troppo limitato, ci sono tanti altri buoni algoritmi per la similarità delle stringhe là fuori.

esempio:
>>> from difflib import SequenceMatcher 
>>> s = SequenceMatcher(None, "abcd", "bcde") 
>>> s.ratio() 
0.75 

Soluzione # 2: jellyfish biblioteca

sua una buona biblioteca con una buona copertura e alcuni problemi. supporta:
- Levenshtein Distanza
- Damerau-Levenshtein Distanza
- Jaro Distanza
- Jaro-Winkler Distanza
- Partita Voto metodo di confronto di
- distanza di Hamming

pro: facile da usare, gamma di algoritmi supportati, testati.
cons: non la libreria nativa.

esempio:

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