Domanda

Sto lavorando per implementare l'algoritmo di discesa sfumata stocastica per i sistemi di raccomandare utilizzando matrici sparse con scottili.

Ecco come appare una prima implementazione di 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
.

Sfortunatamente, il mio codice è ancora abbastanza lento, anche per una piccola matrice di 4x5 rating.Stavo pensando che questo sia probabilmente dovuto alla matrice sparsa per il ciclo.Ho provato a esprimere i cambiamenti Q e P utilizzando l'indicizzazione di fantasia, ma da quando sono ancora abbastanza nuovo a Scipiy e Numpy, non riuscivo a capire un modo migliore per farlo.

Avete dei puntatori su come potrei evitare di interadiare le righe e le colonne della matrice sparsa esplicitamente?

È stato utile?

Soluzione

Ho quasi dimenticato tutto sui sistemi di raccomandare, quindi posso essere erroneamente tradotto il tuo codice, ma rivalutato self.model-np.dot(self.p,self.q.T) all'interno di ciascun loop, mentre sono quasi convinto che dovrebbe essere valutato una volta al passo.

Allora sembra che tu faccia la moltiplicazione della matrice a mano, che probabilmente può essere accelerata con la mulituplicazione diretta della matrice (polpera o scipy lo farà più velocemente di te a mano), qualcosa del genere:

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
.

Altri suggerimenti

Sei sicuro di implementare SGD?Poiché in ogni fase, è necessario calcolare l'errore di un singolo utente-rating, non l'errore della matrice di valutazione Tutto o forse non riesco a capire questa riga del tuo codice:

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

E per la biblioteca sciposa, sono sicuro che avrai un collo di bottiglia lento se vuoi accedere direttamente agli elementi della matrice sparsa.Invece di accedere agli elementi della matrice di rating da Scipy-Sparse-Matrix, è possibile portare la riga e la colonna specifica nella RAM in ogni passaggio e quindi eseguire il calcolo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top