Die Frage
Wie kann ich die Bewertung für einen neuen Benutzer in einem in Spark geschulten ALS-Modell vorhersagen? (Neu = während der Trainingszeit nicht gesehen)
Das Problem
Ich folge hier dem offiziellen Spark ALS-Tutorial:
http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html
Ich bin in der Lage, eine gute Empfehlung mit einer anständigen MSE zu erstellen, aber ich habe Probleme damit, neue Daten in das Modell einzugeben. Das Tutorial ändert die Bewertungen des ersten Benutzers vor dem Training, aber das ist wirklich ein Hack. Sie geben folgenden Hinweis:
9.2. Matrixfaktoren erweitern:
In diesem Tutorial fügen wir Ihre Bewertungen dem Trainingssatz hinzu. Eine bessere Möglichkeit, die Empfehlungen für Sie zu erhalten, besteht darin, zuerst ein Matrixfaktorisierungsmodell zu trainieren und das Modell dann anhand Ihrer Bewertungen zu erweitern. Wenn dies für Sie interessant klingt, können Sie sich die Implementierung von MatrixFactorizationModel ansehen und sehen, wie Sie das Modell für neue Benutzer und neue Filme aktualisieren.
Die Implementierung hilft mir allerdings überhaupt nicht. Idealerweise suche ich etwas wie:
predictions = model.predictAllNew(newinput)
Eine solche Methode gibt es jedoch nicht. Ich könnte das ursprüngliche RDD modifizieren, aber ich denke, dafür müsste ich das Modell neu trainieren, sodass dies auch keine ideale Lösung wäre. Sicherlich muss es einen eleganteren Weg geben?
Wo ich gerade bin:
Ich denke, ich muss die latente Darstellung des neuen Vektors finden. Nach dem Originalpapier können wir dies folgendermaßen berechnen:
Mein aktueller Versuch:
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
Das passt aber nicht zusammen.