2017-01-24 2 views
3

Скажем, у меня есть список векторов, и я хочу создать от него матрицу расстояний. Что такое аккуратный способ сделать это? Например, у меня есть список из 3 векторов:вычислить матрицу расстояния из списка векторов

k = [[2, 4, 7], [3, 4, 7], [5,1,3]] 
distance = pairwise_distances(v1, v2, metric='cosine', n_jobs=-1) 

Желаемый выход: A Numpy массив косинус-расстояний данного вектора списка.

array([[ 1.  , 0.00638545, 0.28778769], 
     [ 0.00638545, 1.  , 0.21402251], 
     [ 0.28778769, 0.21402251, 1.  ]]) 

Это то, что я сделал: Получил все комбинации, используя itertools.combinations. Вычисляли расстояния для каждой пары. Затем становится немного беспорядочно размещать дистанционные меры в «правой» ячейке (нужны индексы исходных векторов в списке).

combs = list(itertools.combinations(k, 2)) 
print combs 

Есть ли «аккуратный» или «питонический» способ получить на последней матрице расстояния?

+2

Поскольку вы отметили 'Scipy' - вы посмотрели [' cdist, pdist, squareform в Scipy'] (https://docs.scipy.org/doc/scipy/reference/spatial.distance.html)? – Divakar

+0

Хммм, квадрат выглядит многообещающе. Я знаю о pdist, cdist. Спасибо, что указали это. Позвольте мне попробовать. – user1717931

+1

Также обратите внимание, что матрица расстояний симметрична, а диагональ равна 1. Вам нужно только вычислить одну треугольную часть. –

ответ

2

Основываясь на предположении @ Дивакара, я смог получить то, что хотел. вот фрагмент кода для тех, кто ищет ответ:

distance_vectors = [cosine_distance([pair[0]], [pair[1]]) for pair in combs] 
print distance_vectors 

distance_vectors = [x[0][0] for x in distance_vectors] 
print distance_vectors 
X = squareform(np.array(distance_vectors)) 
print X 

И, да (благодаря @Warren), диагональ матрицы расстояний равна нулю.

+1

'pdist' имеет косинус-метрику. Таким образом, вы можете напрямую использовать это и, таким образом, избегать цикла на первом шаге. – Divakar

0

Опять же, благодаря @Divakar, более компактный способ сделать это:

k = [[2, 4, 7], [3, 4, 7], [5,1,3]] 
dm = pdist(np.array(k), 'cosine') 
dm = squareform(dm) 
print dm 

Не может быть лучше !!

Спасибо!

Смежные вопросы