Создать случайный вектор с учетом косинуса сходства - PullRequest
0 голосов
/ 21 октября 2018

В основном, учитывая некоторый вектор v, я хочу получить другой случайный вектор w с некоторым косинусным сходством между v и w.Есть ли способ, которым мы можем получить это в python?

Пример: для простоты у меня будет 2D вектор v [3, -4].Я хочу получить случайный вектор w с косинусным сходством 60% или плюс 0,6.Это должно генерировать вектор w со значениями [0,875, 3] или любой другой вектор с таким же косинусным сходством.Поэтому я надеюсь, что это достаточно ясно.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Учитывая вектор 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-м:

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
0 голосов
/ 21 октября 2018

Расстояние косинуса 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)

с точки зрения работы в обратном направлении, вы можете сделать это самостоятельно, используя точечные продукты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...