简体   繁体   English

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

[英]Scipy - how to further optimize sparse matrix code for stochastic gradient descent

I'm working on implementing the stochastic gradient descent algorithm for recommender systems using sparse matrices with Scipy. 我正在使用Scipy的稀疏矩阵实现推荐系统的随机梯度下降算法。

This is how a first basic implementation looks like: 这是第一个基本实现的样子:

    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

Unfortunately, my code is still pretty slow, even for a small 4x5 ratings matrix. 不幸的是,我的代码仍然很慢,即使是一个小的4x5评级矩阵。 I was thinking that this is probably due to the sparse matrix for loop. 我在想这可能是由于循环的稀疏矩阵。 I've tried expressing the q and p changes using fancy indexing but since I'm still pretty new at scipy and numpy, I couldn't figure a better way to do it. 我尝试使用花哨的索引来表达q和p的变化但是因为我仍然是scipy和numpy的新手,我无法想出更好的方法来做到这一点。

Do you have any pointers on how i could avoid iterating over the rows and columns of the sparse matrix explicitly? 你有没有关于如何避免明确地迭代稀疏矩阵的行和列的指针?

I almost forgot everything about recommender systems, so I may be erroneously translated your code, but you reevaluate self.model-np.dot(self.p,self.qT) inside each loop, while I am almost convinced it should be evaluated once per step. 我差点忘了关于推荐系统的一切,所以我可能会错误地翻译你的代码,但你在每个循环中重新评估self.model-np.dot(self.p,self.qT) ,而我几乎确信它应该被评估一次每一步。

Then it seems that you do matrix multiplication by hand, that probably can be speeded up with direct matrix mulitplication (numpy or scipy will do it faster than you by hand), something like that: 然后看起来你手工进行矩阵乘法,可能会加速直接矩阵多重复制(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

Are you sure you are implementing SGD? 你确定你正在实施SGD吗? because in each step, you have to calculate the error of one single user-rating, not the error of the all rating matrix or maybe I can not understand this line of your code: 因为在每个步骤中,您必须计算单个用户评级的错误,而不是所有评级矩阵的错误,或者我可能无法理解您的代码行:

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

And for the Scipy library, I am sure you will have a slow bottleneck if you want to access the elements of the sparse matrix directly. 对于Scipy库,如果你想直接访问稀疏矩阵的元素,我相信你会有一个缓慢的瓶颈。 Instead of accessing elements of rating matrix from Scipy-sparse-matrix, you can bring the specific row and column into RAM in each step and then do your calculation. 您可以在每个步骤中将特定的行和列放入RAM中,然后进行计算,而不是从Scipy-sparse-matrix访问评级矩阵的元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM