Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS

Camila Waltrick
Camila Waltrick
Published in
5 min readDec 6, 2020
Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS
Photo by Compare Fibre on Unsplash

Plataformas como Netflix, Spotify, Amazon e Facebook, por exemplo, têm a capacidade de recomendar entretenimento, produtos e pessoas de modo assertivo para seus usuários. Você já se perguntou como elas sabem no que você pode ou não se interessar? 🤔 Pois bem, nesse post eu conto como funciona um sistema de recomendação — mais precisamente sobre filtro colaborativo e, por fim, demonstro como eu fiz um modelo de filtragem colaborativa de filmes com Spark e o algoritmo ALS da biblioteca MLlib com PySpark. 🎬👌

Se quiser pular direto pra parte prática, meu script completo está aqui.

O que é sistemas de recomendação 🎯

A grande quantidade e diversidade de produtos no mercado online foi um dos gatilhos para o surgimento dos Sistemas de Recomendação, os quais geram, automaticamente, indicações baseadas na análise dos dados comportamentais dos usuários.

Trata-se de algoritmos de Machine Learning que se baseiam em alguma técnica, entre as mais utilizadas: a filtragem colaborativa (considera a experiência de todos os usuários), filtragem baseada em conteúdo (considera a experiência do usuário alvo) e híbrida (as duas técnicas anteriores são consideradas).

Por que usar?

  • Recomendar itens relevantes para os usuário;
  • Aumentar a taxa de conversão;
  • Diminuir o churn;
  • Aprimorar a experiência do usuário;

Filtragem colaborativa 👩🔛👨

É o método que recomenda itens para o usuário A, baseado nas preferências de outro(s) usuário(s) com gostos similares aos do A. Ou seja, esse tipo de sistema se alimenta das informações de consumo do usuário A (processo de aprender) para identificar outros usuários que tiveram um comportamento de consumo semelhante e, então, realiza a troca de indicações de itens entre eles (processo de prever).

Spark, PySpark e ALS… Que? 😵❓ ❔

Spark: é uma estrutura de processamento paralelo, é 100% open source, que dá suporte ao processamento na memória para melhorar o desempenho de aplicativos de análise de Big Data. Além disso, pode ser utilizado com o Hadoop, como substituto do Map Reduce . O Spark possui bibliotecas próprias que dão suporte para consultas SQL, streaming de dados, aprendizado de máquina e processamento gráfico.

PySpark: é a API para programar em Python no Spark.

ALS (Mínimos Quadrados Alternados): é um algoritmo usado no método de filtragem colaborativa, o qual faz parte da MLlib — biblioteca de Machine Learning do Spark. Basicamente, esse filtro colaborativo visa preencher as entradas que faltam em uma matriz de associação de usuário-item. Usuários e produtos são descritos por um pequeno conjunto de fatores latentes que podem ser usados ​​para prever entradas ausentes. Assim, o algoritmo de ALS é usado para aprender esses fatores latentes. A ideia é pegar uma matriz grande e fatorá-la em alguma representação menor da matriz original por meio de mínimos quadrados alternados. Acabamos com duas ou mais matrizes dimensionais inferiores cujo produto é igual ao original.

Criação do sistema de recomendação 🚀

Dica: Para simplificar a vida e não precisar de nenhuma instalação adicional na sua máquina, utilize o Google Colab. Como eu fiz isso e, também, todo o código completo, você encontra aqui.

Iniciar a sessão spark: Após a preparação do ambiente e do Spark ter sido encontrado no sistema, cria-se sessão Spark:

spark = SparkSession.builder.master('local[*]').getOrCreate()

Carregar os dados: O conjunto de dados escolhido pertence ao Movielens, estou usando ele em formato txt e os dados, em cada linha, correspondem ao id do usuário, id do filme, nota e timestamp, conforme a amostra na imagem:

Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS
Amostra do conjunto de dados original.

No código, abaixo, instancio os dados na variável lines com o RDD (Resilient Distributed Dataset), a principal estrutura de dados do Spark. Essa estrutura permite trabalhar com computação distribuída, ou seja, os dados serão distribuídos entre os nós do cluster e controlados pelo nó master. Assim, é possível processá-los em paralelo, aumentando a velocidade de processamento.

lines = spark.read.text("sample_movielens_ratings.txt").rdd

Dividir a linha em partes: Como as entradas vieram juntas na mesma linha, é necessário separar os valores a cada “::”, a fim de obter um array com 4 itens. Deste modo, usa-se o método split, responsável por isso. Também usa-se a função map, que mapeia a operação, que está entre parênteses, para todas as linhas do rdd.

parts = lines.map(lambda row: row.value.split("::"))

Transformar em Row: Com o módulo Row, o rdd faz a transformação para linhas do tipo Row. Essa transformação é necessária pois, também, serão mapeados nomes e posições das colunas, instanciando tudo na variável ratingsRDD.

ratingsRDD = parts.map(lambda p: Row(userId=int(p[0]), movieId=int(p[1]), rating=float(p[2]), timestamp=long(p[3])))

Apresentar dados em tabela: O próximo passo é dispor as informações em formato de tabela.

ratings = spark.createDataFrame(ratingsRDD)
ratings.show()

Assim, obtendo a seguinte visualização:

Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS
Data frame exibido com ratings.show()

O modelo: Nesta etapa, divide-se o conjunto de dados em porções para training e test. Após, instancia-se o modelo ALS, indicando os parâmetros de quantidade máxima de iterações, coeficiente de aprendizado, as colunas utilizadas e desconsidera o usuário que tiver coldstart, caso ocorra.

(training, test) = ratings.randomSplit([0.8, 0.2])
als = ALS(maxIter=5, regParam=0.01, userCol="userId", itemCol="movieId", ratingCol="rating", coldStartStrategy="drop")

Treinamento e teste: A seguir, treinamos o modelo com o dataset de treinamento usando o als.fit(), aplicamos o modelo no conjunto de teste para fazer as predições com model.transform() e avalição o modelo.

predictions = model.transform(test) 
evaluator = RegressionEvaluator(metricName="rmse", labelCol="rating",
predictionCol="prediction")
rmse = evaluator.evaluate(predictions)
print("Erro médio quadrático = " + str(rmse))

Recomendações: Considerando todos os usuários do conjunto de dados, geramos 10 recomendações.

userRec = model.recommendForAllUsers(10)
userRec.show()
Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS
Data frame exibido com userRec.show()

Opcionalmente, foi feita a transposta da matriz de ratings, a fim de recomendar usuários em potencial para itens específicos:

movieRecs = model.recommendForAllItems(10)
movieRecs.show()
Sistema de recomendação de filmes com filtragem colaborativa usando Spark e ALS
Data frame exibido com movieRecs.show()

Podemos, também, visualizar os filmes recomendados por usuários:

UserRecsOnlyItemId = userRec.select(userRec['userId'], userRec['recommendations']['movieid'])UserRecsOnlyItemId.show(10, False)
Data frame exibido com UserRecsOnlyItemId.show(10, False)

Além dessa demonstração, são inúmeras as análises que podem ser realizadas com o dataset em questão, conforme o objetivo de exploração e utilidade a que se destina.

--

--