La domanda
Come posso prevedere la valutazione per un nuovo utente in un modello ALS addestrato in Spark? (Nuovo = non visto durante il tempo di allenamento)
Il problema
Sto seguendo il tutorial ufficiale di Spark ALS qui:
http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html
Sono in grado di creare un buon consulente con un MSE decente ma sto lottando su come inserire nuovi dati nel modello. Il tutorial modifica le valutazioni del primo utente prima dell'allenamento, ma questo è davvero un trucco. Danno il seguente suggerimento:
9.2. Fattori di matrice in aumento:
In questo tutorial, aggiungiamo le tue valutazioni al set di formazione. Un modo migliore per ottenere i consigli per te consiste nell'addestrare prima un modello di fattorizzazione a matrice e poi aumentare il modello usando le tue valutazioni. Se questo ti sembra interessante, puoi dare un'occhiata all'implementazione di MatrixFactorizationModel e vedere come aggiornare il modello per i nuovi utenti e i nuovi film.
L'implementazione non mi aiuta affatto. Idealmente, sto cercando qualcosa come:
predictions = model.predictAllNew(newinput)
Ma non esiste tale metodo. Potrei andare a modificare il RDD originale, ma penso che mi richiederebbe di riqualificare il modello, quindi non sarebbe nemmeno una soluzione ideale. Sicuramente ci deve essere un modo più elegante?
Dove sono adesso:
Penso di aver bisogno di trovare la rappresentazione latente del nuovo vettore. Secondo il documento originale possiamo calcolarlo in questo modo:
Ma quando calcolo usando i valori nel documento, non corrisponde ai valori del modello. Correggo l'alfa e il parametro di regolarizzazione, ma penso che l'implementazione MLLIB abbia un'implementazione diversa . Qui è definito (vedi riga 1304), ma non essendo esperto in Scala, è molto difficile decodificare per me ...
Il mio tentativo attuale:
V = model.productFeatures().map(lambda x: (x[1])).collect() #product latent matrix Y
Cui = alpha * np.abs(newinput)
Cui = (1. + Cui) / (Cui)
Cui[np.where(newinput == 0)] = 0
Cui = np.diag(Cui)
lambdaI = len(np.where(newinput!=0)) * regularization_parameter * np.eye(np.shape(V)[1]) #
term = np.dot(np.dot(Vt,Cui),V)+lambdaI
term = np.dot(np.linalg.inv(term),Vt)
term = np.dot(term,Cui)
term = np.dot(term,newinput)
latentinput = term
Ma questo non corrisponde.