>
Ashay Pathak, Chatana Mandava, Ritesh Patel
Collaborative Filtering é uma técnica amplamente utilizada em sistemas de recomendação e está avançando rapidamente na área de pesquisa. Os dois métodos mais utilizados são baseados em memória e baseados em modelos.
Neste post, vamos focar apenas em (User-Based Collaborative Filtering) UB-CF que é um método baseado em memória. A idéia principal por trás do UB-CF é que pessoas com características semelhantes compartilham gostos semelhantes. Por exemplo, se você estiver interessado em recomendar um filme ao nosso amigo Bob, suponha que eu e o Bob tenhamos visto muitos filmes juntos e os classificamos de forma quase idêntica. Faz sentido pensar que no futuro também gostaríamos de continuar a gostar de filmes semelhantes e usar essa métrica de similaridade para recomendar filmes.
Vamos tentar implementar o UB-CF e gerar uma lista de filmes que nosso amigo Bob, também conhecido como um usuário ativo, possa estar interessado em assistir. A motivação por trás de escrever este post é mergulhar profundamente no algoritmo e entender como o UB-CF realmente funciona. A maior parte do conteúdo deste post é inspirado por um Curso em Coursera.
Filtragem Colaborativa Usuário-Usuário
O método identifica usuários que são similares ao usuário consultado e estima que a classificação desejada seja a média ponderada das classificações desses usuários similares.
Estaríamos fazendo as recomendações no MovieLens Dataset. A linguagem de programação usada é python e o trabalho de análise de dados é feito principalmente usando a biblioteca de pandas. A IDE utilizada é jupyter notebook.
Então antes de começar eu gostaria de dar a lista de bibliotecas utilizadas :
- Pandas
- Numpy
- sklearn
Então vamos avançar e entender os conceitos por trás das recomendações. Eu anexei alguns trechos de código e saídas no blog para melhor compreensão. Todo o arquivo ipynb está anexado no final do blog.
Score function
É fácil criar uma função para filtragem colaborativa não personalizada (ou seja, não consideramos os gostos, aversões e classificações de usuários ativos do passado) que retorna uma pontuação tomando o usuário u e o item i como parâmetros de entrada. A função produz uma pontuação que quantifica o quanto um usuário u gosta/prefere o item i.
Então isso geralmente é feito usando as classificações de outras pessoas similares ao usuário. Tudo isso seria discutido em detalhes mais tarde. Por enquanto a fórmula que usei é,
No nosso exemplo, eu usei a função de similaridade cosine_similaridade do sklearn para calcular a similaridade. Mas antes disso temos que fazer algum pré-processamento e limpar os dados.
from sklearn.metrics.pairwise import cosine_similarityfinal=pd.pivot_table(Rating_avg,values='adg_rating',index='userId',columns='movieId')
>
Contém muito valor de NaN já que todos os usuários não viram todos os filmes e esta é a razão pela qual este tipo de matriz é chamada de matriz esparsa. Métodos como a factorização matricial são usados para lidar com esta sparsity, mas não nos focaríamos nela neste blog. O próximo passo e um dos passos importantes é substituir estes valores NaN.
Existem dois métodos comumente usados para isto :
- Utilizar a média do usuário sobre a linha.
- Utilizar a média do filme sobre a coluna.
Utilizei ambos os métodos e você pode obtê-la no código abaixo. Mas para explicar eu usaria o método da média do filme.
# Replacing NaN by Movie Average
final_movie = final.fillna(final.mean(axis=0))
Agora, o próximo passo é calcular a similaridade entre os usuários.
# user similarity on replacing NAN by item(movie) avg
cosine = cosine_similarity(final_movie)
np.fill_diagonal(cosine, 0 )
similarity_with_movie =pd.DataFrame(cosine,index=final_movie.index)
similarity_with_movie.columns=final_user.index
similarity_with_movie.head()
Vejamos se o que calculamos faz realmente sentido !!
a = get_user_similar_movies(370,86309)
a = a.loc]
a.head()
Da imagem acima podemos ver que a similaridade que geramos é verdadeira já que ambos os usuários (370.86309) têm quase as mesmas classificações e gostos.
Então terminamos de calcular as semelhanças entre os usuários, mas ainda não estou satisfeito. Eu discutiria a razão no próximo passo.
Neighborhood for User (K)
Então de cima podemos ver que calculamos as semelhanças para todos os usuários. Mas como sou um estudante de Grandes Dados, a complexidade do problema sempre me impulsiona. Com isto quero dizer que o sistema de recomendação funciona com os dados enormes e por isso torna-se muito importante manter e capturar apenas os destaques importantes e necessários dos dados.
Para explicar isto usando nosso exemplo de sistema de recomendação de filmes, a matriz que obtivemos acima é (862*862), já que existem 862 usuários únicos nos dados. Este número ainda é pequeno quando comparado com o sistema original de dados em que o sistema estaria trabalhando. Vamos pensar na Amazon. Teria mais de milhões de usuários em sua base de dados e assim, ao calcular a pontuação para qualquer item, não seria uma boa solução ou método para olhar para todos os outros usuários o tempo todo. Portanto, para superar isso, geramos uma noção de vizinhança. Isto inclui apenas o conjunto de (K) usuários similares para um determinado usuário.
Agora vamos dar mais passos para implementar a idéia. No nosso exemplo eu tomei o valor de k como 30. Então teríamos 30 vizinhos mais próximos para todos os usuários.
Utilizei minha função find_n_neighbours personalizada que toma a matriz de similaridade e o valor de n como input e retorna os n vizinhos mais próximos para todos os usuários. Você pode encontrar o código no notebook dado no final do blog.
# top 30 neighbours for each user
sim_user_30_m = find_n_neighbours(similarity_with_movie,30)
sim_user_30_m.head()
Então agora se você pensa então nós reduzimos seriamente o número de cálculos desnecessários. Agora, estamos prontos para calcular a pontuação de um item agora.
Gerar a pontuação final S(u,i)
Wow! terminamos com o processo. Eu sei que passamos por algumas coisas técnicas reais, mas o tempo que gastamos vale a pena pois chegamos ao último passo.
Aqui vamos tentar prever a pontuação para o filme que o usuário não viu.
score = User_item_score(320,7371)
print(score)
Então o nosso sistema previu que a pontuação fosse de 4,25 o que é realmente bom. Eu acho que o usuário (370) poderia gostar do filme com id (7371).
Agora vamos dar um toque final ao nosso sistema. Eu acho que a maioria de nós teria usado Netflix ou Hotstar. Então quando abrimos o aplicativo ele mostra o item que você faz como.
Fico sempre fascinado com a recomendação, pois eles acabam sendo os filmes que eu gosto. Tudo isso acontece através do próprio sistema de recomendação. Agora vamos fazer o mesmo e tentar prever os 5 melhores filmes que o usuário pode gostar.
A lógica não é tão difícil assim. Nós já geramos a pontuação para um item. Da mesma forma podemos gerar a pontuação para os outros itens com o mesmo usuário.
Mas, agora novamente mantendo os Grandes Dados em consideração faz sentido gerar a pontuação para todos os outros itens ??
Eu penso NOOOOOOO!!!!
Vamos considerar usuário (U) e usuário (K). Agora suponha que K não esteja na vizinhança de U ,é possível para o usuário U gostar de um filme que K tenha visto e classificado. Na maioria das vezes No.
Pensei que você conseguiu o truque. Sim, estamos apenas interessados em calcular a pontuação dos itens que seus usuários vizinhos viram.
Somos realmente bem sucedidos. Reduzimos o cálculo de 2500 para N ( onde N é o conjunto de filmes que minha vizinhança gostava ) e que é muito inferior a 2500.
Então finalmente vamos recomendar os filmes.
User_item_score1 é a minha função personalizada que usa a nossa discussão acima para calcular previsões
user = int(input("Enter the user id to whom you want to recommend : "))
predicted_movies = User_item_score1(user)
print(" ")
print("The Recommendations for User Id : ",user)
print(" ")
for i in predicted_movies:
print(i)
>
>>>Finalmente em !!!! Conseguimos. Nós temos nosso próprio sistema de recomendação.
A representação do código abaixo pode não ser muito fácil de ler, então por favor vá até meu repositório GitHub para acessar o código.
Os conjuntos de dados necessários podem ser obtidos aqui.
Eu espero que você tenha gostado do blog. Para qualquer consulta, você pode me enviar um e-mail. Fique ligado para mais blogs, já que esta é uma das minhas áreas de interesse e eu definitivamente postaria algumas coisas novas.
Obrigado…!!