Frage

Ich arbeite an der Implementierung des stochastischen Gradientenabstiegsalgorithmus für Empfehlungssysteme unter Verwendung spärlicher Matrizen mit Scipy.

So sieht eine erste Grundimplementierung aus:

    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

Leider ist mein Code selbst für eine kleine 4x5-Bewertungsmatrix immer noch ziemlich langsam.Ich dachte, dass das wahrscheinlich an der spärlichen Matrix-for-Schleife liegt.Ich habe versucht, die q- und p-Änderungen mithilfe einer ausgefallenen Indizierung auszudrücken, aber da ich bei Scipy und Numpy noch ziemlich neu bin, konnte ich mir keinen besseren Weg vorstellen, dies zu tun.

Haben Sie Hinweise, wie ich das explizite Durchlaufen der Zeilen und Spalten der Sparse-Matrix vermeiden könnte?

War es hilfreich?

Lösung

Ich habe fast alles über Empfehlungssysteme vergessen, daher habe ich Ihren Code möglicherweise falsch übersetzt, aber Sie bewerten ihn noch einmal self.model-np.dot(self.p,self.q.T) innerhalb jeder Schleife, obwohl ich fast davon überzeugt bin, dass es einmal pro Schritt ausgewertet werden sollte.

Dann scheint es, dass Sie die Matrixmultiplikation von Hand durchführen, was wahrscheinlich mit der direkten Matrixmultiplikation beschleunigt werden kann (Numpy oder Scipy erledigen das schneller als Sie von Hand), etwa so:

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

Andere Tipps

Sind Sie sicher, dass Sie SGD implementieren?Denn in jedem Schritt müssen Sie den Fehler eines einzelnen Benutzerwerts berechnen, nicht den Fehler der All Rating-Matrix oder vielleicht kann ich diese Zeile Ihres Codes nicht verstehen:

generasacodicetagpre.

und für die Scipy-Bibliothek, bin ich sicher, dass Sie einen langsamen Engpass haben, wenn Sie direkt auf die Elemente der sparsamen Matrix zugreifen möchten.Anstatt auf Elemente von Rating Matrix von Scipy-SPARSE-Matrix zuzugreifen, können Sie die bestimmte Zeile und die Spalte in jedem Schritt in RAM bringen und dann Ihre Berechnung durchführen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top