【问题标题】:Calculating cosine distance between the rows of matrix计算矩阵行之间的余弦距离
【发布时间】:2016-11-29 02:49:54
【问题描述】:

我正在尝试在 python 中计算矩阵中的行之间的余弦距离并有几个问题。所以我正在创建矩阵 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])

【问题讨论】:

  • 那个包不是有一个或两个pairwise 函数吗?
  • 恐怕不是 - 它使用余弦,它使用 2 个一维数组作为输入,如下所示:余弦 (u,v),其中 u,v-1-D 数组。
  • 你在使用 numpy 吗?
  • numpy 表示数组,scipy 表示余弦
  • 我在想其中一个答案中提到的pdist

标签: python numpy matrix scipy trigonometry


【解决方案1】:

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

import scipy.spatial.distance

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

【讨论】:

    【解决方案2】:

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

    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.  ]]
    

    这个矩阵是例如解释为“第 3 行与第 2 行(或同样,第 2 行与第 3 行)之间的余弦距离为 0.15”。

    【讨论】:

      【解决方案3】:

      您说“计算 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])
      

      请注意,pdist 返回的前五个值与上面使用 cdist 返回的值相同。

      关于pdist的返回值的进一步解释,见How does condensed distance matrix work? (pdist)

      【讨论】:

      • 这个答案似乎是错误的,不是吗?我希望所有“自我”比较的距离都是“0”。
      • @TasosPapastylianou pdist 计算的结果不包括任何“自我”比较。请参阅我在答案末尾提供的链接中的说明。
      猜你喜欢
      • 2017-01-13
      • 1970-01-01
      • 2017-08-03
      • 2015-12-17
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 2015-07-21
      • 2013-12-16
      相关资源
      最近更新 更多