Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python numpy-提高列式余弦相似性的效率_Python_Numpy - Fatal编程技术网

python numpy-提高列式余弦相似性的效率

python numpy-提高列式余弦相似性的效率,python,numpy,Python,Numpy,我对编程相当陌生,以前从未使用过numpy 我有一个19001x19001维的矩阵。它包含很多零,因此相对稀疏。我编写了一些代码来计算列的成对余弦相似性,如果行中的项不为零。我将一行的所有成对相似性值相加,并对它们进行一些数学运算,最终为矩阵的每一行获得一个值(参见下面的代码)。它做了它应该做的,但是当处理大量的维度时,它真的很慢。有没有办法修改我的代码以提高效率 import numpy as np from scipy.spatial.distance import cosine row_

我对编程相当陌生,以前从未使用过
numpy

我有一个19001x19001维的矩阵。它包含很多零,因此相对稀疏。我编写了一些代码来计算列的成对余弦相似性,如果行中的项不为零。我将一行的所有成对相似性值相加,并对它们进行一些数学运算,最终为矩阵的每一行获得一个值(参见下面的代码)。它做了它应该做的,但是当处理大量的维度时,它真的很慢。有没有办法修改我的代码以提高效率

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
如果我用上面的代码计算余弦相似性,则第1行([0])返回0.45112924,第4行([3])返回0.14177624和0.70710678

out_file.txt

0 0.796001425306
1 nan
2 nan
3 0.856981065776
4 nan

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

> P>你可以考虑使用<代码> SimPy <代码>。但是,它不需要稀疏矩阵输入。您必须提供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

对于枚举(矩阵)中的行编号,这不应该是
吗?
要在每次循环迭代中更改
行编号
。如果在发布之前检查代码是否存在不一致,那会更好。@Divakar我缩进了块,这只是一个格式问题,粘贴在这里时发生的,所以没什么太严重的;)我认为您的代码已损坏,您应该使用已找到的库代码。否则,不要在NumPy数组上编写Python循环。很慢。写向量运算,如果你不能,就用Numba。@John Zwinck-ja,你完全正确,但我的问题是我不理解库的功能,因为它们的结果不同。如果我为一个小测试矩阵手动计算它,我得到的是代码的输出,而不是库的输出,这就是导致我出现问题的原因。
from numpy.linalg import norm
1 - np.dot(X[:, 0], X[:,2])/(norm(X[:, 0]) * norm(X[:,2])) # give 0.422649