python - 提高 Scipy 稀疏矩阵乘法的性能

标签 python performance scipy sparse-matrix matrix-multiplication

给定一个尺寸为 (170k x 170k) 且具有 4.4 亿个非空点的 Scipy CSC 稀疏矩阵“sm”和一个具有几个非空点的稀疏 CSC 向量“v”(170k x 1),是否存在任何问题可以这样做来提高操作的性能:

resul = sm.dot(v)

?

目前大约需要 1 秒。将矩阵初始化为 CSR 将时间增加到 3 秒,因此 CSC 表现更好。

SM 是产品之间的相似性矩阵,V 是表示用户购买或点击了哪些产品的向量。所以对于每个用户 sm 都是一样的。

我使用的是 Ubuntu 13.04、Intel i3 @3.4GHz、4 核。

研究 SO 我读到了 Ablas 包。我在终端输入:

~$ ldd /usr/lib/python2.7/dist-packages/numpy/core/_dotblas.so

结果是:

    linux-vdso.so.1 =>  (0x00007fff56a88000)
    libblas.so.3 => /usr/lib/libblas.so.3 (0x00007f888137f000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8880fb7000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8880cb1000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f888183c000)

据我所知,这意味着我已经在使用 Ablas 的高性能软件包。我仍然不确定这个包是否已经实现了并行计算,但看起来它没有。

多核处理是否有助于提高性能?如果是这样,是否有任何库对 python 有帮助?

我也在考虑在 Cython 中实现这个想法,但我不知道这是否会带来好的结果。

提前致谢。

最佳答案

稀疏矩阵乘法例程直接用 C++ 编码,只要快速查看源代码就会发现,似乎没有任何优化库的 Hook 。此外,它似乎没有利用第二个矩阵是向量来最小化计算的事实。因此,您可以通过访问稀疏矩阵的内部并自定义乘法算法来大大加快速度。以下代码在纯 Python/Numpy 中执行此操作,并且如果向量确实具有“一些非空点”,则它与 scipy 的 C++ 代码的速度相匹配:如果您在 Cython 中实现它,速度提升应该是显而易见的:

def sparse_col_vec_dot(csc_mat, csc_vec):
    # row numbers of vector non-zero entries
    v_rows = csc_vec.indices
    v_data = csc_vec.data
    # matrix description arrays
    m_dat = csc_mat.data
    m_ind = csc_mat.indices
    m_ptr = csc_mat.indptr
    # output arrays
    sizes = m_ptr.take(v_rows+1) - m_ptr.take(v_rows)
    sizes = np.concatenate(([0], np.cumsum(sizes)))
    data = np.empty((sizes[-1],), dtype=csc_mat.dtype)
    indices = np.empty((sizes[-1],), dtype=np.intp)
    indptr = np.zeros((2,), dtype=np.intp)

    for j in range(len(sizes)-1):
        slice_ = slice(*m_ptr[[v_rows[j] ,v_rows[j]+1]])
        np.multiply(m_dat[slice_], v_data[j], out=data[sizes[j]:sizes[j+1]])
        indices[sizes[j]:sizes[j+1]] = m_ind[slice_]
    indptr[-1] = len(data)
    ret = sps.csc_matrix((data, indices, indptr),
                         shape=csc_vec.shape)
    ret.sum_duplicates()

    return ret

快速解释正在发生的事情:CSC 矩阵定义在三个线性数组中:

  • data 包含非零条目,按列主要顺序存储。
  • indices 包含非零条目的行。
  • indptr 比矩阵的列数多一个条目,j 列的项目在 data[indptr[j]:indptr [j+1]] 并且在行 indices[indptr[j]:indptr[j+1]] 中。

因此,要乘以稀疏列向量,您可以迭代列向量的 dataindices,并且对于每个 (d, r) 对,提取矩阵的相应列并乘以 d,即 data[indptr[r]:indptr[r+1]] * d指数[indptr[r]:indptr[r+1]]

关于python - 提高 Scipy 稀疏矩阵乘法的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18595981/

相关文章:

python - 在 Jupyter Notebook 中使用 Flask-SQLAlchemy 模型

java - 高性能应用程序中的 C/C++ 与 Java/C#

iphone - UIScrollView 或自定义绘图

performance - 如何在使用 Spring EntityManager Hibernate 持久化大型集合时提高性能

python - 从小对数概率向量中以numpy/scipy采样多项式

python - 具有大结构元素的图像特征检测

python - 使用随机模块python进行不同程度的改组

python - Bokeh 中轴类型日期时间的矩形散点图

python - 将 SQLAlchemy 继承关系重新映射到不同的 postgres 模式

python - 如何从python中的wav文件绘制波形?