我是编程新手,以前从未使用过numpy

因此,我有一个尺寸为19001 x 19001的矩阵。它包含很多零,因此相对稀疏。如果行中的项目不为零,我编写了一些代码来计算列的成对余弦相似度。我将一行的所有成对相似度值相加,并对它们进行一些数学运算,最后得到矩阵每一行的一个值(请参见下面的代码)。它可以实现预期的功能,但是处理大量尺寸时,它确实很慢。有什么方法可以修改我的代码以使其更高效?

import numpy as np
from scipy.spatial.distance import cosine

row_number = 0
out_file = open('outfile.txt', 'w')

for row in my_matrix:
    non_zeros = np.nonzero(my_matrix[row_number])[0]
    non_zeros = list(non_zeros)
    cosine_sim = []
    for item in non_zeros:
        if len(non_zeros) <= 1:
            break
        x = non_zeros[0]
        y = non_zeros[1]
        similarity = 1 - cosine(my_matrix[:, x], my_matrix[:, y])
        cosine_sim.append(similarity)
        non_zeros.pop(0)
    summing = np.sum(cosine_sim)
    mean = summing / len(cosine_sim)
    log = np.log(mean)
    out_file_value = log * -1
    out_file.write(str(row_number) + " " + str(out_file_value) + "\n")
    if row_number <= 19000:
        row_number += 1
    else:
        break


我知道即使在列(from sklearn.metrics.pairwise import cosine_similarity)之间也有一些函数可以实际计算余弦相似度,所以我尝试了一下。但是,即使我阅读了文档和本页上有关该问题的文章,输出还是一样,但同时却让我感到困惑。

例如:

my_matrix =[[0.    0.    7.    0.    5.]
            [0.    0.   11.    0.    0.]
            [0.    2.    0.    0.    0.]
            [0.    0.    2.   11.    5.]
            [0.    0.    5.    0.    0.]]

transposed = np.transpose(my_matrix)
sim_matrix = cosine_similarity(transposed)

# resulting similarity matrix
sim_matrix =[[0.        0.        0.            0.            0.]
             [0.        1.        0.            0.            0.]
             [0.        0.        1.            0.14177624    0.45112924]
             [0.        0.        0.14177624    1.            0.70710678]
             [0.        0.        0.45112924    0.70710678    1.]]


如果我用上面的代码计算余弦相似度,则它对第一行([0])返回0.45112924,对第四行([3])返回0.14177624和0.70710678。

out_file.txt

0 0.796001425306
1 nan
2 nan
3 0.856981065776
4 nan


我非常感谢任何对我的问题的帮助或建议!

最佳答案

您可以考虑使用scipy代替。但是,它不需要稀疏矩阵输入。您必须提供numpy数组。

import scipy.sparse as sp
from scipy.spatial.distance import cdist

X = np.random.randn(10000, 10000)
D = cdist(X, X.T, metric='cosine') # cosine distance matrix between 2 columns


这是我获得10000 x 10000个随机数组的速度。

%timeit cdist(X, X.T, metric='cosine')
16.4 s ± 325 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


尝试小阵列

X = np.array([[1,0,1], [0, 3, 2], [1,0,1]])
D = cdist(X, X.T, metric='cosine')


这将给

[[  1.11022302e-16   1.00000000e+00   4.22649731e-01]
 [  6.07767730e-01   1.67949706e-01   9.41783727e-02]
 [  1.11022302e-16   1.00000000e+00   4.22649731e-01]]


例如,D[0, 2]是列0和2之间的余弦距离

from numpy.linalg import norm
1 - np.dot(X[:, 0], X[:,2])/(norm(X[:, 0]) * norm(X[:,2])) # give 0.422649

关于python - python numpy-提高按列余弦相似度的效率,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44281758/

10-12 16:34