【问题标题】:create cosine similarity matrix numpy创建余弦相似度矩阵numpy
【发布时间】:2017-06-13 18:54:16
【问题描述】:

假设我有一个如下所示的 numpy 矩阵:

array([array([ 0.0072427 ,  0.00669255,  0.00785213,  0.00845336,  0.01042869]),
   array([ 0.00710799,  0.00668831,  0.00772334,  0.00777796,  0.01049965]),
   array([ 0.00741872,  0.00650899,  0.00772273,  0.00729002,  0.00919407]),
   array([ 0.00717589,  0.00627021,  0.0069514 ,  0.0079332 ,  0.01069545]),
   array([ 0.00617369,  0.00590539,  0.00738468,  0.00761699,  0.00886915])], dtype=object)

如何生成一个 5 x 5 矩阵,其中矩阵的每个索引都是原始矩阵中两个对应行的余弦相似度?

例如第 0 行第 2 列的值将是原始矩阵中第 1 行和第 3 行之间的余弦相似度。

这是我尝试过的:

from sklearn.metrics import pairwise_distances
from scipy.spatial.distance import cosine
import numpy as np

#features is a column in my artist_meta data frame
#where each value is a numpy array of 5 floating point values, similar to the
#form of the matrix referenced above but larger in volume

items_mat = np.array(artist_meta['features'].values)

dist_out = 1-pairwise_distances(items_mat, metric="cosine")

上面的代码给了我以下错误:

ValueError: 使用序列设置数组元素。

不知道为什么我会得到这个,因为每个数组的长度相同 (5),我已经验证了这一点。

【问题讨论】:

  • 你尝试了什么?向我们展示您的代码。
  • 1-pairwise_distances(f,metric="cosine") 正在做您需要的事情,假设 f 是您帖子顶部的原始数组。 items_mat 的内容可能有问题。你能展示它的第一个,比如说,5x5 的元素吗?
  • 当然 - 原始帖子中的矩阵已更新,以反映我正在计算的前五行。即使在计算前五行的余弦相似度时,我也遇到了错误。
  • 所以,正如我之前所说,假设f 是您的矩阵,1-pairwise_distances(f,metric="cosine") 不会出现任何错误。
  • 确保数组 dtype 是 float 而不是 object

标签: python numpy matrix cosine-similarity


【解决方案1】:

x 成为你的数组

from scipy.spatial.distance import cosine

m, n = x.shape
distances = np.zeros((m,n))
for i in range(m):
    for j in range(n):
        distances[i,j] = cosine(x[i,:],x[:,j])

【讨论】:

    【解决方案2】:

    m 成为数组

    m = np.array([
            [ 0.0072427 ,  0.00669255,  0.00785213,  0.00845336,  0.01042869],
            [ 0.00710799,  0.00668831,  0.00772334,  0.00777796,  0.01049965],
            [ 0.00741872,  0.00650899,  0.00772273,  0.00729002,  0.00919407],
            [ 0.00717589,  0.00627021,  0.0069514 ,  0.0079332 ,  0.01069545],
            [ 0.00617369,  0.00590539,  0.00738468,  0.00761699,  0.00886915]
        ])
    

    per wikipedia: Cosine_Similarity

    我们可以计算我们的分子

    d = m.T @ m
    

    我们的‖A‖

    norm = (m * m).sum(0, keepdims=True) ** .5
    

    那么相似之处是

    d / norm / norm.T
    
    [[ 1.      0.9994  0.9979  0.9973  0.9977]
     [ 0.9994  1.      0.9993  0.9985  0.9981]
     [ 0.9979  0.9993  1.      0.998   0.9958]
     [ 0.9973  0.9985  0.998   1.      0.9985]
     [ 0.9977  0.9981  0.9958  0.9985  1.    ]]
    

    距离是

    1 - d / norm / norm.T
    
    [[ 0.      0.0006  0.0021  0.0027  0.0023]
     [ 0.0006  0.      0.0007  0.0015  0.0019]
     [ 0.0021  0.0007  0.      0.002   0.0042]
     [ 0.0027  0.0015  0.002   0.      0.0015]
     [ 0.0023  0.0019  0.0042  0.0015  0.    ]]
    

    【讨论】:

    • 为了优化您的代码,您可以在执行 m.T @ m 之前将 m 除以范数一次。它保存了按 norm.T. 的除法。
    • 我同意@IsmaelELATIFI。优化后的代码为:norm = (m * m).sum(0, keepdims=True) ** .5m_norm = m/norm; similarity_matrix = m_norm.T @ m_norm
    猜你喜欢
    • 2015-07-17
    • 2019-12-23
    • 1970-01-01
    • 2021-08-20
    • 2012-07-09
    • 2017-04-15
    • 2016-09-08
    • 2020-10-28
    • 2014-03-25
    相关资源
    最近更新 更多