La pregunta
¿Cómo pronostico la calificación de un nuevo usuario en un modelo ALS capacitado en Spark? (Nuevo = no visto durante el tiempo de entrenamiento)
El problema
Estoy siguiendo el tutorial oficial de Spark ALS aquí:
http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html
Puedo construir un buen recomendador con un MSE decente, pero estoy luchando con la forma de ingresar nuevos datos al modelo. El tutorial cambia las calificaciones del primer usuario antes del entrenamiento, pero esto es realmente un truco. Dan la siguiente pista:
9.2. Factores de matriz de aumento:
En este tutorial, agregamos sus calificaciones al conjunto de entrenamiento. Una mejor manera de obtener las recomendaciones para usted es entrenar primero un modelo de factorización matricial y luego aumentar el modelo utilizando sus calificaciones. Si esto le parece interesante, puede echar un vistazo a la implementación de MatrixFactorizationModel y ver cómo actualizar el modelo para nuevos usuarios y nuevas películas.
Sin embargo, la implementación no me ayuda en absoluto. Idealmente, estoy buscando algo como:
predictions = model.predictAllNew(newinput)
Pero no existe tal método. Podría ir y modificar el RDD original, pero creo que eso requeriría que vuelva a entrenar el modelo, por lo que tampoco sería una solución ideal. ¿Seguramente debe haber una manera más elegante?
Donde estoy ahora:
Creo que necesito encontrar la representación latente del nuevo vector. De acuerdo con el documento original , podemos calcular esto así:
Pero cuando calculo usando los valores en el documento, no coincide con los valores del modelo. Arreglo alfa y el parámetro de regularización, pero creo que la implementación MLLIB tiene una implementación diferente . Se define aquí (ver línea 1304), pero no siendo experto en Scala, esto es muy difícil de realizar ingeniería inversa para mí ...
Mi intento actual:
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
Pero esto no coincide.