2010-10-31 74 views
7

在相似性度量和距離度量之間轉換是否有一種通用方法?如何在相似性度量和差異度量之間進行轉換?

考慮一個相似性度量,比如兩個字符串共有的2克數。

2-grams('beta', 'delta') = 1 
2-grams('apple', 'dappled') = 4 

如果我需要這個喂到預期差異的措施,如Levenshtein距離的優化算法?

這只是一個例子......我在尋找一個通用的解決方案,如果存在的話。就像如何從Levenshtein距離到相似性的度量?

我很感謝您可能提供的任何指導。

+3

我很想知道你的問題是否要求距離服從[三角不等式](http://en.wikipedia.org/wiki/Triangle_inequality),如果是的話,你認爲哪些解決方案最令人滿意。 – 2012-11-29 17:20:20

回答

1
similarity = 1/difference 

並觀看了difference = 0

+7

所以你可以嘗試'相似度= 1 /(差異+ 1)' – 2010-10-31 19:45:37

+0

這是有道理的...謝謝。 – 135498 2010-11-01 23:15:46

0

在Levenshtein距離的情況下,可以以1爲每次序列比賽增加了SIM卡的分數;也就是說,每次您不需要刪除,插入或替換時,都是1。這樣,度量將是兩個字符串共有多少個字符的線性度量。

2

如果你的相似度(S)爲0和1之間,你可以使用其中的一個:

1-s 
sqrt(1-s) 
-log(s) 
(1/s)-1 
0

在我的項目之一(基於協同過濾),我不得不相關之間的轉換(餘弦在向量之間),從-1到1(更接近1更接近-1,更接近-1更加多樣化)到歸一化距離(接近0,距離更小並且接近1,距離更大)

在這種情況下:距離〜多樣性

我爲穆拉是:dist = 1 - (cor + 1)/2

如果你有相似的多樣性和域爲[0,1]在這兩種情況下的simlest方法是:

dist = 1 - sim

sim = 1 - dist

4

做1 /相似度不會保留分配的屬性。

最好的方法是 距離(a-> b)=最高相似度 - 相似度(a-> b)。具有最高相似度的 是具有最大值的相似度距離。您因此翻轉您的分配。 最高相似度變爲0等

9

d表示距離,小號表示相似性。到距離測量轉換成相似性度量,我們首先需要正常化d爲[0 1],通過使用d_norm = d /最高(d)。然後,相似性度量由下式給出:

s = 1-d_norm

其中s在[0 1]的範圍內,其中1表示最高相似度(比較項目相同),0表示最低相似度(最大距離)。

0

Cosine similaritywidely used用於n克計數或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 

餘弦相似性可以被用於計算一個正式的距離度量according to wikipedia。它遵循,你會期望的距離(對稱,非負性,等等)的所有屬性:

def distance_metric(x, y): 
    return 1 - 2 * acos(similarity(x, y))/pi 

這些度量的兩個範圍0和1之間

如果你有tokenizer產生N-從字符串克,你可以使用這些指標是這樣的:

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

我發現Counter優雅的內積this SO answer

相關問題