Question

Je travaille sur l'implémentation de l'algorithme de descente de gradient stochastique pour les systèmes de recommandation utilisant des matrices clairsemées avec Scipy.

Voici à quoi ressemble une première implémentation de base :

    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

Malheureusement, mon code est encore assez lent, même pour une petite matrice de notation 4x5.Je pensais que cela était probablement dû à la matrice clairsemée pour la boucle.J'ai essayé d'exprimer les changements q et p en utilisant une indexation sophistiquée, mais comme je suis encore assez nouveau chez scipy et numpy, je ne pouvais pas trouver une meilleure façon de le faire.

Avez-vous des indications sur la façon dont je pourrais éviter de parcourir explicitement les lignes et les colonnes de la matrice clairsemée ?

Était-ce utile?

La solution

J'ai presque tout oublié sur les systèmes de recommandation, donc j'ai peut-être traduit votre code par erreur, mais vous réévaluez self.model-np.dot(self.p,self.q.T) à l'intérieur de chaque boucle, alors que je suis presque convaincu qu'elle devrait être évaluée une fois par étape.

Ensuite, il semble que vous effectuiez une multiplication matricielle à la main, qui peut probablement être accélérée avec une mulitplication matricielle directe (numpy ou scipy le fera plus rapidement que vous à la main), quelque chose comme ça :

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

Autres conseils

Êtes-vous sûr de mettre en œuvre SGD?Parce que dans chaque étape, vous devez calculer l'erreur d'une seule note utilisateur, pas l'erreur de toutes les matrices d'évaluation ou peut-être que je ne peux pas comprendre cette ligne de votre code:

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

Et pour la bibliothèque Scipy, je suis sûr que vous aurez un goulot d'étranglement lent si vous souhaitez accéder directement aux éléments de la matrice clairsemé.Au lieu d'accéder aux éléments de la matrice de notation de SciPy-Sparse-Matrix, vous pouvez apporter la ligne et la colonne spécifiques dans la RAM dans chaque étape, puis effectuez votre calcul.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top