在给定余弦相似性的情况下创建随机向量



基本上给定一些向量v,我想得到另一个随机向量w,在v和w之间有一些余弦相似性。有什么方法可以在python中得到这个吗?

示例:为简单起见,我将有 v [3,-4] 的 2D 向量。我想得到余弦相似度为 60% 或正 0.6 的随机向量 w。这应该生成值为 [0.875, 3] 的向量 w 或任何其他具有相同余弦相似性的向量。所以我希望这足够清楚。

给定向量v和余弦相似性costheta(介于 -1 和 1 之间的标量(,计算w,如函数rand_cos_sim(v, costheta)

import numpy as np

def rand_cos_sim(v, costheta):
# Form the unit vector parallel to v:
u = v / np.linalg.norm(v)
# Pick a random vector:
r = np.random.multivariate_normal(np.zeros_like(v), np.eye(len(v)))
# Form a vector perpendicular to v:
uperp = r - r.dot(u)*u
# Make it a unit vector:
uperp = uperp / np.linalg.norm(uperp)
# w is the linear combination of u and uperp with coefficients costheta
# and sin(theta) = sqrt(1 - costheta**2), respectively:
w = costheta*u + np.sqrt(1 - costheta**2)*uperp
return w

例如

In [17]: v = np.array([3, -4])
In [18]: w = rand_cos_sim(v, 0.6)
In [19]: w
Out[19]: array([-0.28, -0.96])

验证余弦相似性:

In [20]: v.dot(w)/(np.linalg.norm(v)*np.linalg.norm(w))
Out[20]: 0.6000000000000015
In [21]: w = rand_cos_sim(v, 0.6)
In [22]: w
Out[22]: array([1., 0.])
In [23]: v.dot(w)/(np.linalg.norm(v)*np.linalg.norm(w))
Out[23]: 0.6

返回值的量级始终为 1,因此在上面的例子中,只有两个可能的随机向量 [1, 0] 和 [-0.28, -0.96]。

另一个例子,这个3-D:

In [24]: v = np.array([3, -4, 6])
In [25]: w = rand_cos_sim(v, -0.75)
In [26]: w
Out[26]: array([ 0.3194265 ,  0.46814873, -0.82389531])
In [27]: v.dot(w)/(np.linalg.norm(v)*np.linalg.norm(w))
Out[27]: -0.75
In [28]: w = rand_cos_sim(v, -0.75)
In [29]: w
Out[29]: array([-0.48830063,  0.85783797, -0.16023891])
In [30]: v.dot(w)/(np.linalg.norm(v)*np.linalg.norm(w))
Out[30]: -0.75

SciPy 余弦距离:https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.spatial.distance.cosine.html

from scipy.spatial.distance import cosine
v = [3, -4]
w = [0.875, 3]
cosine(v, w)

在逆向工作方面,您可以使用点积自己完成。

相关内容

最新更新