Вопрос
Как я могу предсказать рейтинг нового пользователя в модели ALS, обученной в Spark? (Новое = не видно во время тренировки)
Проблема
Я следую официальному учебнику Spark ALS здесь:
http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html
Я могу построить хороший рекомендатель с приличным MSE, но я борюсь с тем, как вводить новые данные в модель. Учебник изменяет рейтинг первого пользователя до начала обучения, но это действительно взлом. Они дают следующую подсказку:
9.2. Увеличивающие матричные факторы:
В этом уроке мы добавляем ваши рейтинги в тренировочный набор. Лучший способ получить рекомендации для вас - сначала обучить матричную модель факторизации, а затем дополнить ее, используя ваши рейтинги. Если вам это интересно, вы можете взглянуть на реализацию MatrixFactorizationModel и посмотреть, как обновить модель для новых пользователей и новых фильмов.
Реализация мне совсем не помогает. В идеале я ищу что-то вроде:
predictions = model.predictAllNew(newinput)
Но не такой метод существует. Я мог бы пойти и изменить оригинальный RDD, но я думаю, что это потребовало бы от меня переобучения модели, чтобы это тоже не было идеальным решением. Конечно, должен быть более элегантный способ?
Где я сейчас нахожусь:
Я думаю, что мне нужно найти скрытое представление нового вектора. Согласно оригинальной статье мы можем вычислить это так:
Но когда я вычисляю, используя значения в статье, это не соответствует значениям из модели. Я исправляю альфа и параметр регуляризации, но я думаю, что внедрение MLLIB имеет другую реализацию . Это определено здесь (см. Строку 1304), но не будучи адептом в Scala, это очень трудно для меня реконструировать ...
Моя текущая попытка:
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
Но это не совпадает.