是否有通用方法在相似度量和距离度量之间进行转换?
考虑相似性度量,例如两个字符串共有的2克数。
2-grams('beta', 'delta') = 1
2-grams('apple', 'dappled') = 4
如果我需要将其提供给需要测量差异的优化算法,例如Levenshtein距离,该怎么办?
这只是一个例子......我正在寻找一个通用的解决方案,如果存在的话。比如如何从Levenshtein距离到相似度量?
我感谢您提供的任何指导。
答案 0 :(得分:10)
设 d 表示距离, s 表示相似度。要将距离度量转换为相似性度量,我们需要首先使用 d_norm = d / max(<强> d 强>)。然后,相似性度量由下式给出:
s = 1 - d_norm 。
其中 s 在[0 1]范围内,1表示最高相似度(比较项目相同),0表示最低相似度(最大距离)。
答案 1 :(得分:4)
如果您的相似性度量介于0和1之间,则可以使用以下其中一种:
1-s
sqrt(1-s)
-log(s)
(1/s)-1
答案 2 :(得分:4)
执行1 /相似性不会保留分布的属性。
最好的方法是 距离(a-> b)=最高相似度 - 相似度(a-> b)。 具有最高相似度的是具有最大值的相似距离。你因此翻转你的发行版。 最高相似度变为0等
答案 3 :(得分:1)
similarity = 1/difference
并提防difference = 0
答案 4 :(得分:0)
在Levenshtein距离的情况下,每次序列匹配时,您可以将sim分数增加1;也就是说,每次你不需要删除,插入或替换时为1。这样,度量标准将是两个字符串共有多少个字符的线性度量。
答案 5 :(得分:0)
在我的一个项目中(基于协同过滤)我必须在-1到1之间的相关性(矢量之间的余弦)之间进行转换(更接近1更接近-1,更接近-1更加多样化)到归一化距离(接近0,距离越小,如果接近1则距离越大)
在这种情况下:距离〜多样性
我的公式是:dist = 1 - (cor + 1)/2
如果你与多样性有相似性,并且在两种情况下域都是[0,1],那么最简单的方法是:
dist = 1 - sim
sim = 1 - dist
答案 6 :(得分:0)
Cosine similarity为widely used。
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-gram,你可以使用这些指标:
>>> 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
的优雅内在产品
答案 7 :(得分:0)
是的,在相似度和距离之间有一种最通用的方式:严格单调递减函数f(x)
。
也就是说,使用f(x)
可以创建similarity = f(distance)
或distance = f(similarity)
。它可以双向工作。之所以可以使用这种功能,是因为相似度和距离之间的关系是,一个相似度随着距离的增加而另一个减小。
示例:
以下是一些众所周知的严格单调递减的候选对象,它们可用于非负相似性或距离:
f(x) = 1 / (a + x)
f(x) = exp(- x^a
)f(x) = arccot(ax)
您可以选择参数a>0
(例如a=1
)
答案 8 :(得分:0)
根据scikit learn:
内核是相似性的度量,即如果对象 a 和 b 被认为比对象 a 和 c “更相似”,则 s(a, b) > s(a, c)。核也必须是半正定的。
有多种方法可以在距离度量和相似性度量之间进行转换,例如内核。设 D 为距离,S 为核: