我想在某個範圍內表示實數,以便向量空間中的距離較近的數字在向量空間中也較近,可以使用餘弦距離來測量近距離。餘弦相似度空間中的數字
例如,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
中螺旋完整扭曲的參數化。
這是一件很奇怪的事情。餘弦相似性的目的是比較向量,比如我們比較實數 - 你想以另一種方式。比較真實數字很容易 - 爲什麼你想讓它更復雜?這裏的背景是什麼?除此之外,一個向量空間(通常)具有比其他集合更多的成員,對多維度做更多的操作。 –