Spark ALS: recomendando para novos usuários

10

A questão

Como posso prever a classificação de um novo usuário em um modelo de ALS treinado no Spark? (Novo = não visto durante o tempo de treinamento)

O problema

Estou seguindo o tutorial oficial do Spark ALS aqui:

http://ampcamp.berkeley.edu/big-data-mini-course/movie-recommendation-with-mllib.html

Eu sou capaz de construir um bom recomendador com um MSE decente, mas estou tendo dificuldades para inserir novos dados no modelo. O tutorial altera as classificações do primeiro usuário antes do treinamento, mas isso é realmente um hack. Eles dão a seguinte dica:

9.2 Fatores da matriz crescente:

Neste tutorial, adicionamos suas classificações ao conjunto de treinamento. Uma maneira melhor de obter as recomendações para você é treinar primeiro um modelo de fatoração de matriz e depois aumentar o modelo usando suas classificações. Se isso lhe parecer interessante, você pode dar uma olhada na implementação do MatrixFactorizationModel e ver como atualizar o modelo para novos usuários e novos filmes.

A implementação não me ajuda em nada. Idealmente, estou procurando algo como:

predictions = model.predictAllNew(newinput)

Mas esse método não existe. Eu poderia modificar o RDD original, mas acho que isso exigiria que eu treinasse novamente o modelo, para que também não fosse a solução ideal. Certamente deve haver uma maneira mais elegante?

Onde estou agora:

Eu acho que preciso encontrar a representação latente do novo vetor. De acordo com o artigo original , podemos calcular isso assim:

Xvocê=(YTCvocêY+λEu)-1 1YTCvocêp(você)

Cvocê

Minha tentativa atual:

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

Mas isso não corresponde.

ciri
fonte

Respostas:

9

Muitas perguntas aqui. Primeiro, para um usuário verdadeiramente novo sem dados, não há como usar um modelo de recomendação. Se você literalmente não tem informações sobre o usuário, a única coisa que você pode fazer é fornecer algumas recomendações padrão.

Obviamente, depois de ter quaisquer dados e reconstruir o modelo para incorporar o usuário, você pode fazer recomendações. Você pode fazer isso no Spark, mas você já sabe disso. Isso levará muito tempo se você precisar adicionar informações sobre novos usuários em tempo de execução. A técnica que você deseja é chamada de "dobrável", usada para descobrir qual é o novo vetor de usuário (aproximadamente), considerando os itens com os quais o usuário interage. É apenas uma álgebra linear e segue a equação que você fornece.

Eu cavei um slide antigo que pode ajudar:

Desdobramento do ALS

O "Cu" não é realmente diferente. Eu adicionei uma 'extensão' para lidar com o caso de entrada negativa, mas é o mesmo para entrada positiva.

Aqui está uma implementação do fold-in, embora eu ache que será muito denso para ter muito valor:

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

Computar o novo vetor de usuário implícito em uma interação usuário-item é uma álgebra linear bastante fácil. A parte complicada que encontrei é decidir quanto pesar.

Espero que seja um empurrão na direção certa.

Sean Owen
fonte