首页 文章

Scipy - 如何进一步优化随机梯度下降的稀疏矩阵码

提问于
浏览
4

我正在使用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的新手,我无法想出更好的方法来做到这一点 .

你有没有关于如何避免明确地迭代稀疏矩阵的行和列的指针?

2 回答

  • 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
    
  • 0

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

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

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

相关问题