Cosine similarity là widely used cho số lượng gram hoặc véc tơ 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
Tính tương tự của Cosine có thể được sử dụng để tính toán số liệu khoảng cách chính thức according to wikipedia. Nó tuân theo tất cả các thuộc tính của một khoảng cách mà bạn mong đợi (đối xứng, không âm, vv):
def distance_metric(x, y):
return 1 - 2 * acos(similarity(x, y))/pi
Cả hai số liệu dao động giữa 0 và 1.
Nếu bạn có một tokenizer sản xuất N gram từ một chuỗi bạn có thể sử dụng các số liệu như thế này:
>>> 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
tôi tìm thấy sản phẩm thanh lịch bên trong của Counter
trong this SO answer
Tôi tò mò muốn biết nếu vấn đề của bạn đòi hỏi khoảng cách phải tuân theo [bất đẳng thức tam giác] (http://en.wikipedia.org/wiki/Triangle_inequality) và nếu như vậy bạn đã tìm thấy giải pháp nào thỏa đáng nhất. –