【问题标题】:Efficient Parallel Sparse Matrix dot product in Scipy PythonScipy Python中的高效并行稀疏矩阵点积
【发布时间】:2015-03-26 21:03:02
【问题描述】:

我有一个非常大的 (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)

现在pairs[i, j] 是所有这样的i 和j 的第i 行和第j 行的相似度。 这与行的成对余弦相似度非常相似。因此,如果有一种有效的并行算法可以计算成对余弦相似度,那么它也适用于我。

问题:这个点积非常慢,因为它只使用一个 cpu(我可以访问我服务器上的 64 个 cpu)。

我还可以将 A 和 AT 导出到一个文件中,然后运行任何其他并行执行乘法运算的外部程序,并将结果返回给 Python 程序。

有没有更有效的方法来做这个点积?或并行计算成对相似度?

【问题讨论】:

    标签: performance numpy scipy sparse-matrix dot-product


    【解决方案1】:

    我终于使用了 scikit-learn 的“余弦”距离度量及其 pairwise_distances 函数,它们支持稀疏矩阵并且高度并行化。

    sklearn.metrics.pairwise.pairwise_distances(X, Y=None, metric='euclidean', n_jobs=1, **kwds)
    

    我也可以将A分成n个水平部分,并使用parallel python包运行多个乘法,然后将结果水平堆叠。

    【讨论】:

    • 相似度 = 1 - '余弦'的距离
    【解决方案2】:

    我使用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)
    

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 2016-08-31
      • 2016-08-15
      • 2012-06-30
      • 2023-04-10
      • 2012-08-20
      • 1970-01-01
      • 2021-12-24
      • 2015-05-08
      相关资源
      最近更新 更多