我正在努力使用带有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,我无法弄清楚更好的方法。

您是否有任何指针如何避免明确地迭代稀疏矩阵的行和列?

有帮助吗?

解决方案

我几乎忘记了关于推荐系统的一切,所以我可能会错误地翻译代码,但是您可以在每个循环中重新评估生成的生成aceTagcode,而我几乎相信它应该每步评估一次。

然后似乎你用手做矩阵乘法,可能可以用直接矩阵Mulitplication(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=self.model-np.dot(self.p,self.q.T) #calculate error for gradient
.

和fipy库,如果要直接访问稀疏矩阵的元素,我相信您将有一个慢的瓶颈。而不是从scipy-sparse-matrix访问评级矩阵的元素,而是可以将特定行和列带到每个步骤中的RAM中,然后执行计算。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top