Spark ALS: рекомендация для новых пользователей

10

Вопрос

Как я могу предсказать рейтинг нового пользователя в модели 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, но я думаю, что это потребовало бы от меня переобучения модели, чтобы это тоже не было идеальным решением. Конечно, должен быть более элегантный способ?

Где я сейчас нахожусь:

Я думаю, что мне нужно найти скрытое представление нового вектора. Согласно оригинальной статье мы можем вычислить это так:

Xu=(YTCuY+λI)1YTCup(u)

Но когда я вычисляю, используя значения в статье, это не соответствует значениям из модели. Я исправляю альфа и параметр регуляризации, но я думаю, что внедрение MLLIB имеет другую реализацию . Это определено здесь (см. Строку 1304), но не будучи адептом в Scala, это очень трудно для меня реконструировать ...Cu

Моя текущая попытка:

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

Но это не совпадает.

Цири
источник

Ответы:

9

Здесь много вопросов. Во-первых, для действительно нового пользователя без данных невозможно использовать рекомендательную модель. Если у вас буквально нет информации о пользователе, единственное, что вы можете сделать, это предоставить некоторые рекомендации по умолчанию.

Конечно, когда у вас есть какие-либо данные, и вы можете перестроить модель для включения пользователя, вы можете дать рекомендации. Вы можете сделать это в Spark, но вы уже знаете это. Это займет слишком много времени, если вам нужно добавить информацию о новых пользователях во время выполнения. Техника, которую вы хотите, называется «складной», используемой для определения того, что представляет собой новый пользовательский вектор (приблизительно) с учетом элементов, с которыми взаимодействует пользователь. Это просто линейная алгебра, которая вытекает из уравнения, которое вы даете.

Я вытащил старый слайд, который может помочь:

ALS Fold-In

«Cu» на самом деле не отличается. Я добавил «расширение» для обработки случая отрицательного ввода, но то же самое для положительного ввода.

Вот реализация сложения, хотя я думаю, что она будет слишком плотной, чтобы иметь большую ценность:

https://github.com/OryxProject/oryx/blob/2c01d496f93f2825a076eb7fe492aa39a5290aa6/app/oryx-app-common/src/main/java/com/cloudera/oryx/app/als/ALSUtils.java#L74

Вычисление нового вектора пользователя, подразумеваемого взаимодействием пользователя с элементом, является довольно простой линейной алгеброй. Сложная часть, которую я нашел, - это решить, сколько ее весить.

Надеюсь, что это толчок в правильном направлении.

Шон Оуэн
источник