2017-08-12 78 views
0

我想在某个范围内表示实数,以便向量空间中的距离较近的数字在向量空间中也较近,可以使用余弦距离来测量近距离。余弦相似度空间中的数字

例如,0-100,9和10之间的余弦相似度应接近1,而9和100的余弦相似度应接近-1。

如何才能实现这样的映射?我正在考虑尝试使用神经网络编码器,但有没有其他方法可以实现这一点。

+0

这是一件很奇怪的事情。余弦相似性的目的是比较向量,比如我们比较实数 - 你想以另一种方式。比较真实数字很容易 - 为什么你想让它更复杂?这里的背景是什么?除此之外,一个向量空间(通常)具有比其他集合更多的成员,对多维度做更多的操作。 –

回答

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 

不难看出:

  1. 如果xy紧靠在一起,然后f(x)f(y)之间的余弦相似度接近1

  2. 如果x接近a并且y接近bt如果f(x)f(y)之间的余弦相似性接近-1

通过适当选择g,你可以构造一些有趣的例子,例如,g可能是R^3中螺旋完整扭曲的参数化。