我想在某个范围内表示实数,以便向量空间中的距离较近的数字在向量空间中也较近,可以使用余弦距离来测量近距离。余弦相似度空间中的数字
例如,0-100,9和10之间的余弦相似度应接近1,而9和100的余弦相似度应接近-1。
如何才能实现这样的映射?我正在考虑尝试使用神经网络编码器,但有没有其他方法可以实现这一点。
我想在某个范围内表示实数,以便向量空间中的距离较近的数字在向量空间中也较近,可以使用余弦距离来测量近距离。余弦相似度空间中的数字
例如,0-100,9和10之间的余弦相似度应接近1,而9和100的余弦相似度应接近-1。
如何才能实现这样的映射?我正在考虑尝试使用神经网络编码器,但有没有其他方法可以实现这一点。
在2维向量空间的特殊情况下很容易做到。我将说明[0,100]
的范围,尽管将其推广到其他区间会很容易。
将单位圆认为是以原点为中心的模拟时钟。将x
中的一个点[0,100]
映射到第二只手0.3x
秒的位置。对于x = 0
,秒针指向12,相应的矢量将是<0,1>
。对于x = 50
,秒针将指向3,而x
将映射到<1,0>
。对于x = 100
,秒针将指向6并且x
将映射到<0,-1>
。
用于映射的公式为:
f(x) = <sin(1.8*x),cos(1.8*x)> #measured in degrees
这里是一个Python实现,广义来处理任意间隔:
from math import sin, cos, radians, sqrt
def to_vector(x,a,b):
m = 180/(b-a)
theta = radians(m*(x-a))
return (sin(theta),cos(theta))
def similarity(v1,v2):
dot = sum(x*y for x,y in zip(v1,v2))
norm1 = sqrt(sum(x**2 for x in v1))
norm2 = sqrt(sum(x**2 for x in v2))
return dot/(norm1*norm2)
例如,
>>> u = to_vector(9,0,100)
>>> u
(0.2789911060392293, 0.9602936856769431)
>>> v = to_vector(10,0,100)
>>> v
(0.3090169943749474, 0.9510565162951535)
>>> w = to_vector(100,0,100)
>>> w
(1.2246467991473532e-16, -1.0)
>>> similarity(v,u)
0.9995065603657316
>>> similarity(v,w)
-0.9510565162951536
上编辑:这是一个更抽象的方法,可以用于构建任何维度的示例。
以任何连续的一对一映射开始g: [a,b] \rightarrow R^n
(其中R^n
是n维欧几里德空间)。由于它是一对一的,g(a) != g(b)
。假设m
是连接g(a)
和g(b)
的线段的中点。因此m = (g(a) + g(b))/2
。定义另一个功能如下:
f(x) = g(x) - m
不难看出:
如果x
和y
紧靠在一起,然后f(x)
和f(y)
之间的余弦相似度接近1
如果x
接近a
并且y
接近b
t如果f(x)
和f(y)
之间的余弦相似性接近-1
。
通过适当选择g
,你可以构造一些有趣的例子,例如,g
可能是R^3
中螺旋完整扭曲的参数化。
这是一件很奇怪的事情。余弦相似性的目的是比较向量,比如我们比较实数 - 你想以另一种方式。比较真实数字很容易 - 为什么你想让它更复杂?这里的背景是什么?除此之外,一个向量空间(通常)具有比其他集合更多的成员,对多维度做更多的操作。 –