计算矩阵行之间的余弦距离

Calculating cosine distance between the rows of matrix

我正在尝试计算矩阵中各行之间 python 中的余弦距离并耦合 questions.So 我正在创建矩阵 matr 并从列表中填充它,然后将其重塑分析目的:

s = []

for i in range(len(a)):
    for j in range(len(b_list)):
        s.append(a[i].count(b_list[j]))

matr = np.array(s) 
d = matr.reshape((22, 254)) 

d 的输出给我这样的东西:

array([[0, 0, 0, ..., 0, 0, 0],
       [2, 0, 0, ..., 1, 0, 0],
       [2, 0, 0, ..., 0, 0, 0],
       ..., 
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [1, 0, 0, ..., 0, 0, 0]])

然后我想使用 scipy.spatial.distance.cosine 包来计算 d 矩阵中从第一行到其他每一行的余弦。 我该如何执行?它应该是一些for循环吗?没有太多矩阵和数组操作经验。

那么我怎样才能在该构造中为第二个参数(d[1]、d[2] 等)使用 for 循环而不是每次都启动它:

from scipy.spatial.distance import cosine
x=cosine (d[0], d[6])

你说“计算 d 矩阵中第一行到其他每一行的余弦”[原文如此]。如果我理解正确,您可以使用 scipy.spatial.distance.cdist 来做到这一点,将第一行作为第一个参数传递,其余行作为第二个参数传递:

In [31]: from scipy.spatial.distance import cdist

In [32]: matr = np.random.randint(0, 3, size=(6, 8))

In [33]: matr
Out[33]: 
array([[1, 2, 0, 1, 0, 0, 0, 1],
       [0, 0, 2, 2, 1, 0, 1, 1],
       [2, 0, 2, 1, 1, 2, 0, 2],
       [2, 2, 2, 2, 0, 0, 1, 2],
       [0, 2, 0, 2, 1, 0, 0, 0],
       [0, 0, 0, 1, 2, 2, 2, 2]])

In [34]: cdist(matr[0:1], matr[1:], metric='cosine')
Out[34]: array([[ 0.65811827,  0.5545646 ,  0.1752139 ,  0.24407105,  0.72499045]])

如果你想计算所有 matr中的成对距离,你可以使用scipy.spatial.distance.pdist.

例如,

In [35]: from scipy.spatial.distance import pdist

In [36]: pdist(matr, metric='cosine')
Out[36]: 
array([ 0.65811827,  0.5545646 ,  0.1752139 ,  0.24407105,  0.72499045,
        0.36039785,  0.27625314,  0.49748109,  0.41498206,  0.2799177 ,
        0.76429774,  0.37117185,  0.41808563,  0.5765951 ,  0.67661917])

请注意,return 由 pdist 编辑的前五个值与上面使用 cdist 编辑的 return 相同。

有关 pdist 的 return 值的进一步说明,请参阅 How does condensed distance matrix work? (pdist)

您可以使用简单的 for 循环 scipy.spatial.distance.cosine:

import scipy.spatial.distance

dists = []
for row in matr:
    dists.append(scipy.spatial.distance.cosine(matr[0,:], row))

以下是您可以轻松地手工计算的方法:

from numpy import array as a
from numpy.random import random_integers as randi
from numpy.linalg.linalg import norm
from numpy import set_printoptions

M = randi(10, size=a([5,5]));   # create demo matrix

# dot products of rows against themselves
DotProducts = M.dot(M.T);       

# kronecker product of row norms
NormKronecker = a([norm(M, axis=1)]) * a([norm(M, axis=1)]).T; 

CosineSimilarity = DotProducts / NormKronecker
CosineDistance = 1 - CosineSimilarity

set_printoptions(precision=2, suppress=True)
print CosineDistance 

输出:

[[-0.    0.15  0.1   0.11  0.22]
 [ 0.15  0.    0.15  0.13  0.06]
 [ 0.1   0.15  0.    0.15  0.14]
 [ 0.11  0.13  0.15  0.    0.18]
 [ 0.22  0.06  0.14  0.18 -0.  ]]

这个矩阵例如解释为 "the cosine distance between row 3 against row 2 (or, equally, row 2 against row 3) is 0.15".