Cosine similarity è widely used per conteggio n-grammi o vettori TFIDF.
from math import pi, acos
def similarity(x, y):
return sum(x[k] * y[k] for k in x if k in y)/sum(v**2 for v in x.values())**.5/sum(v**2 for v in y.values())**.5
coseno di similitudine può essere utilizzato per calcolare una distanza metrica formale according to wikipedia. Esso obbedisce tutte le proprietà di una distanza che ci si aspetterebbe (simmetria, non negatività, ecc):
def distance_metric(x, y):
return 1 - 2 * acos(similarity(x, y))/pi
Entrambe queste metriche variare tra 0 e 1.
Se si dispone di un tokenizer che produce N- grammi da una stringa si potrebbe utilizzare questi parametri in questo modo:
>>> import Tokenizer
>>> tokenizer = Tokenizer(ngrams=2, lower=True, nonwords_set=set(['hello', 'and']))
>>> from Collections import Counter
>>> list(tokenizer('Hello World again and again?'))
['world', 'again', 'again', 'world again', 'again again']
>>> Counter(tokenizer('Hello World again and again?'))
Counter({'again': 2, 'world': 1, 'again again': 1, 'world again': 1})
>>> x = _
>>> Counter(tokenizer('Hi world once again.'))
Counter({'again': 1, 'world once': 1, 'hi': 1, 'once again': 1, 'world': 1, 'hi world': 1, 'once': 1})
>>> y = _
>>> sum(x[k]*y[k] for k in x if k in y)/sum(v**2 for v in x.values())**.5/sum(v**2 for v in y.values())**.5
0.42857142857142855
>>> distance_metric(x, y)
0.28196592805724774
ho trovato l'elegante prodotto interno di Counter
in this SO answer
Sono curioso di sapere se il tuo problema richiede che la distanza obbedisca [disuguaglianza triangolare] (http://en.wikipedia.org/wiki/Triangle_inequality) e, in caso affermativo, quale di queste soluzioni tu abbia trovato più soddisfacente. –