Косинусное расстояние вектора к матрице

В python существует векторизованный эффективный способ вычисления косинусного расстояния разреженного массива u до разреженной матрицы v, в результате чего получается массив элементов [1, 2, ..., n], соответствующих cosine(u,v[0]), cosine(u,v[1]), ..., cosine(u, v[n])?


person David    schedule 28.04.2016    source источник
comment
Может решить ваш случай: Find minimum cosine distance between two matrices.   -  person Divakar    schedule 29.04.2016
comment
@David Дэвид: ты решил это без использования цикла?   -  person v09    schedule 25.04.2018
comment
Я не сделал, к сожалению.   -  person David    schedule 27.04.2018


Ответы (5)


Не родно. Однако вы можете использовать библиотеку scipy, которая вычисляет для вас косинусное расстояние между двумя векторами: http://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.spatial.Distance.cosine.html. Вы можете создать версию, которая использует матрицу, используя ее в качестве трамплина.

person the blizz    schedule 28.04.2016
comment
Да, но это потребует перебора строк. Хотел избежать этого, если бы мог, так как у меня много строк. Хотя попробую. - person David; 28.04.2016
comment
@David: Вы нашли способ избежать повторения строк? Я сталкиваюсь с той же проблемой - person Luk; 20.03.2020
comment
@Luk: к сожалению, так и не решил, в итоге перебрал все строки - заняло вечность. - person David; 22.03.2020

Добавьте вектор в конец матрицы, рассчитайте матрицу попарных расстояний, используя sklearn.metrics.pairwise_distances(), а затем извлеките соответствующий столбец/строку.

Итак, для вектора v (с формой (D,)) и матрицы m (с формой (N,D)) выполните:

import sklearn
from sklearn.metrics import pairwise_distances

new_m = np.concatenate([m,v[None,:]], axis=0)
distance_matrix = sklearn.metrics.pairwise_distances(new_m, axis=0), metric="cosine")
distances = distance_matrix[-1,:-1]

Не идеально, но лучше, чем повторение!

Этот метод можно расширить, если вы запрашиваете более одного вектора. Для этого вместо этого можно объединить список векторов.

person hank    schedule 15.01.2021

Я думаю, что есть способ использовать определение и библиотеку numpy:

Определение: Определение:

import numpy as np

#just creating random data
u = np.random.random(100)
v = np.random.random((100,100))

#dot product: for every row in v, multiply u and sum the elements
u_dot_v = np.sum(u*v,axis = 1)

#find the norm of u and each row of v
mod_u = np.sqrt(np.sum(u*u))
mod_v = np.sqrt(np.sum(v*v,axis = 1))

#just apply the definition
final = 1 - u_dot_v/(mod_u*mod_v)

#verify with the cosine function from scipy
from scipy.spatial.distance import cosine
final2 = np.array([cosine(u,i) for i in v])

Определение косинусного расстояния я нашел здесь: https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cosine.html#scipy.spatial.distance.cosine

person Filipe    schedule 31.01.2021

В scipy.spatial.distance.cosine()

http://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.spatial.distance.cosine.html

person kingledion    schedule 28.04.2016

Ниже сработало для меня, нужно предоставить правильную подпись

from scipy.spatial.distance import cosine

def cosine_distances(embedding_matrix, extracted_embedding):
  return cosine(embedding_matrix, extracted_embedding)
cosine_distances = np.vectorize(cosine_distances, signature='(m),(d)->()')

cosine_distances(corpus_embeddings, extracted_embedding)

В моем случае
corpus_embeddings — это (10000,128) матрица
Extracted_embedding — это 128-мерный вектор

person achint chaudhary    schedule 31.01.2021