【发布时间】:2013-09-13 17:34:06
【问题描述】:
将协同过滤代码转换为使用稀疏矩阵我对以下问题感到困惑:给定两个完整矩阵 X(m x l)和 Theta(n x l),以及一个稀疏矩阵 R(m x n),有没有一种快速计算稀疏内积的方法。大尺寸是 m 和 n(100000 阶),而 l 很小(10 阶)。对于大数据来说,这可能是一个相当常见的操作,因为它出现在大多数线性回归问题的成本函数中,所以我希望 scipy.sparse 中有一个内置的解决方案,但我还没有发现任何明显的东西。
在 python 中执行此操作的简单方法是 R.multiply(XTheta.T),但这将导致计算完整矩阵 XTheta.T(m x n,阶数 100000 **2) 占用太多内存,然后因为 R 是稀疏的,所以转储大部分条目。
有一个pseudo solution already here on stackoverflow,但是一步不稀疏:
def sparse_mult_notreally(a, b, coords):
rows, cols = coords
rows, r_idx = np.unique(rows, return_inverse=True)
cols, c_idx = np.unique(cols, return_inverse=True)
C = np.array(np.dot(a[rows, :], b[:, cols])) # this operation is dense
return sp.coo_matrix( (C[r_idx,c_idx],coords), (a.shape[0],b.shape[1]) )
这对我来说在足够小的数组上运行良好且快速,但在我的大数据集上却出现以下错误:
... in sparse_mult(a, b, coords)
132 rows, r_idx = np.unique(rows, return_inverse=True)
133 cols, c_idx = np.unique(cols, return_inverse=True)
--> 134 C = np.array(np.dot(a[rows, :], b[:, cols])) # this operation is not sparse
135 return sp.coo_matrix( (C[r_idx,c_idx],coords), (a.shape[0],b.shape[1]) )
ValueError: array is too big.
一个实际上稀疏但非常慢的解决方案是:
def sparse_mult(a, b, coords):
rows, cols = coords
n = len(rows)
C = np.array([ float(a[rows[i],:]*b[:,cols[i]]) for i in range(n) ]) # this is sparse, but VERY slow
return sp.coo_matrix( (C,coords), (a.shape[0],b.shape[1]) )
有人知道一种快速、完全稀疏的方法吗?
【问题讨论】:
-
该操作与矢量化方法一样稀疏。将违规行分成三部分以查看内存错误何时发生会很有趣,即
aa = a[rows, :]; bb = b[:, cols]; C = np.dot(aa, bb)。您不需要np.array调用,它实际上会复制数组,因此它甚至可能是您的内存错误的罪魁祸首。可以在生成R的过程中销毁X和Theta吗? -
我的输入 a,b 是 np.matrix,因此没有 np.array 的结果 C[r_idx,c_idx] 是 2D (n x 1) 矩阵而不是 1D 数组。这导致 sp.coo_matrix 调用出错,所以我把 np.array 放在那里。不过,提前转换为数组可能会节省一些时间。
-
X 和 Theta 都是完整矩阵,但我不明白您为什么要销毁它们?我会注意到,虽然我的矩阵 R 是稀疏的,但稀疏模式是这样的:每一行至少有一个条目,每一列至少有一个条目,这样唯一调用的结果是整个范围 m 和n.这导致 np.dot 结果成为我们尝试稀疏相乘的两个数组的全密集乘积。我尝试按照您的建议定义 aa 和 bb,但它在 'C = ...' 处再次出现相同的错误。也许 cython 是解决方案?
标签: python numpy scipy sparse-matrix