我有一个非常大的(1.5M x 16M)稀疏csr scipy矩阵A.我需要计算的是每对行的相似性。我已将相似性定义为:
Assume a and b are two rows of matrix A
a = (0, 1, 0, 4)
b = (1, 0, 2, 3)
Similarity (a, b) = 0*1 + 1*0 + 0*2 + 4*3 = 12
要计算所有成对行的相似度,我使用它(或余弦相似度):
AT = np.transpose(A)
pairs = A.dot(AT)
现在,对[i,j]是所有这样的i和j的行i和行j的相似度。 这与行的成对余弦相似性非常相似。因此,如果有一个有效的并行算法来计算成对余弦相似度,它对我也有用。
问题:这个点产品非常慢,因为它只使用一个cpu(我可以在我的服务器上访问64个cpu)。
我还可以将A和AT导出到一个文件并运行任何其他并行执行乘法的外部程序,并将结果返回给Python程序。
有没有更有效的方法来做这个点产品?或计算并行中的成对相似性?
答案 0 :(得分:4)
我最终使用了scikit-learn的'余弦'距离度量及其支持稀疏矩阵并且高度并行化的pairwise_distances函数。
sklearn.metrics.pairwise.pairwise_distances(X, Y=None, metric='euclidean', n_jobs=1, **kwds)
我还可以将A划分为n个水平部分,并使用并行python包运行多次乘法,然后水平堆叠结果。
答案 1 :(得分:1)
我使用sklearn
编写了自己的实现。它不是平行的,但对于大型矩阵来说速度相当快。
from scipy.sparse import spdiags
from sklearn.preprocessing import normalize
def get_similarity_by_x_dot_x_greedy_for_memory(sp_matrix):
sp_matrix = sp_matrix.tocsr()
matrix = sp_matrix.dot(sp_matrix.T)
# zero diagonal
diag = spdiags(-matrix.diagonal(), [0], *matrix.shape, format='csr')
matrix = matrix + diag
return matrix
def get_similarity_by_cosine(sp_matrix):
sp_matrix = normalize(sp_matrix.tocsr())
return get_similarity_by_x_dot_x_greedy_for_memory(sp_matrix)