【问题标题】:Scipy - how to further optimize sparse matrix code for stochastic gradient descentScipy - 如何进一步优化随机梯度下降的稀疏矩阵代码
【发布时间】:2013-11-30 16:36:48
【问题描述】:

我正在为使用 Scipy 的稀疏矩阵的推荐系统实现随机梯度下降算法。

这是第一个基本实现的样子:

    N = self.model.shape[0] #no of users
    M = self.model.shape[1] #no of items
    self.p = np.random.rand(N, K)
    self.q = np.random.rand(M, K)
    rows,cols = self.model.nonzero()        
    for step in xrange(steps):
        for u, i in zip(rows,cols):
            e=self.model-np.dot(self.p,self.q.T) #calculate error for gradient
            p_temp = learning_rate * ( e[u,i] * self.q[i,:] - regularization * self.p[u,:])
            self.q[i,:]+= learning_rate * ( e[u,i] * self.p[u,:] - regularization * self.q[i,:])
            self.p[u,:] += p_temp

不幸的是,我的代码仍然很慢,即使是一个小的 4x5 评级矩阵。我在想这可能是由于循环的稀疏矩阵。我尝试过使用花哨的索引来表达 q 和 p 的变化,但是由于我对 scipy 和 numpy 还是很陌生,所以我想不出更好的方法来做到这一点。

您对我如何避免显式迭代稀疏矩阵的行和列有任何指示吗?

【问题讨论】:

标签: python numpy scipy sparse-matrix matrix-factorization


【解决方案1】:

我几乎忘记了有关推荐系统的所有内容,因此我可能错误地翻译了您的代码,但您在每个循环内重新评估 self.model-np.dot(self.p,self.q.T),而我几乎确信应该每步评估一次。

然后似乎您手动进行矩阵乘法,这可能可以通过直接矩阵乘法加速(numpy 或 scipy 会比您手动更快),类似这样:

for step in xrange(steps):
    e = self.model - np.dot(self.p, self.q.T)
    p_temp = learning_rate * np.dot(e, self.q)
    self.q *= (1-regularization)
    self.q += learning_rate*(np.dot(e.T, self.p))
    self.p *= (1-regularization)
    self.p += p_temp

【讨论】:

  • 啊,这正是我想要的。我将按照您的建议,看看我是否得到相同的结果,计算时间更快。
  • 不,您的建议无效。首先,SGD 说 e 不应该每一步重新计算一次,也不是每个评级一次,而是实际上每个因子一次。所以我实际上应该自己迭代所有因素,我的代码也有点不正确。 (我只迭代每个评级)。我可以用 : 表示法在每个步骤上以某种方式指定此更新吗?
  • @AnaTodor 你能提供一个代数方程吗?
  • 我没有整个步骤的代数方程。但基本上每一步你都必须经过每个评分,重新计算每个评分的误差,然后根据误差重新调整 p 和 q。
  • @AnaTodor 任何形式化的算法描述都可以。我很确定研究生下降可能用矩阵方程来表达,几年前我已经做过几次了
【解决方案2】:

您确定要实施 SGD 吗?因为在每一步中,您都必须计算单个用户评分的误差,而不是所有评分矩阵的误差,或者我可能无法理解您的这行代码:

e=self.model-np.dot(self.p,self.q.T) #calculate error for gradient

对于 Scipy 库,如果您想直接访问稀疏矩阵的元素,我相信您会遇到缓慢的瓶颈。无需从 Scipy-sparse-matrix 访问评级矩阵的元素,您可以在每个步骤中将特定的行和列放入 RAM,然后进行计算。

【讨论】:

    猜你喜欢
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    相关资源
    最近更新 更多