Criando recomendações com Machine Learning

Quando assistimos nosso filme ou série preferidos no Netflix, ouvimos música no Spotify ou compramos produtos na Amazon, sempre recebemos indicações de novos filmes, músicas ou produtos. Essa talvez seja uma das formas mais básicas da aplicação do aprendizado de máquina: utilizar as preferências de um grupo de pessoas para fazer recomendações de novos produtos ou items para outras pessoas.

Coletando Preferências

Essas empresas armazenam os hábitos de seus usuários e, quando você faz login, usa essas informações para sugerir novos produtos que você pode estar interessado. As preferências podem ser coletadas de diferentes formas: empresas de comércio online armazenam os produtos que as pessoas compraram e as suas opiniões sobre esses produtos (que podem estar na forma de quantas estrelas um usuário avalia um produto ou apenas votos do tipo “esse produto é bom” ou “esse produto é ruim”), o Netflix armazena os filmes que você assistiu e a sua avaliação sobre aquele filme, e assim por diante.

Criar uma boa representação das preferências dos usuários é uma etapa essencial em um sistema de recomendação. É a partir desses dados que o nosso sistema vai “aprender” as preferências dos usuários e recomendar novos items que sejam interessantes.

Independente de como as preferências são expressadas, o importante é mapeá-las em valores númericos. Por exemplo, a Amazon pode usar os valores de 1 a 5 representando quantas estrelas eu usei para expressar a minha avaliação sobre um determinado livro. O Youtube pode utilizar o valor 1 (um) para representar quando eu marco um vídeo como “Gostei” e o valor -1 para “Não Gostei”.

A tabela abaixo mostra como alguns usuários avaliaram um conjunto de filmes. No nosso exemplo, vamos utilizar a representação baseada em estrelas com valores de 1 a 5. Por exemplo, Juliana avaliou o filme “Deadpool” com 3 estrelas. Entretando, independente da sua representação, a ideia geral continua a mesma. Os itens sem avaliação representam que o usuário não avaliou aquele filme. Nas próximas seções vamos utilizar essas informação para sugerir novos filmes baseado nas preferências dos usuários.

Encontrando Pessoas com Preferências Similares

Nesse momento já coletamos as avaliações dos nossos usuários e, assim, já conseguimos representar suas preferências. Agora, precisamos de um modo de determinar quão similar são as pessoas em relação às suas preferências. Por exemplo, será que os gostos de Juliana, em relação aos filmes, são parecidos com o de Cláudio? Fabrício gosta dos mesmos tipos de filmes que Joaquim? Pedro seria uma boa pessoa para indicar novos filmes para Marcelo? Uma das formas de responder essas perguntas é comparar cada pessoa com todas as outras pessoas da nossa lista e calcular uma medida de similaridade entre eles.

Existem diversas formas de calcular essa medida. Nesse artigo vamos utilizar uma das formas mais simples: a Distância Euclidiana. Em matemática, distância euclidiana é a distância entre dois pontos no espaço. Então, para calcular a similaridade entre as pessoas, plotamos as avaliações em um gráfico onde os eixos são os filmes que essas pessoas avaliaram em comum. Por exemplo, a imagem abaixo mostra um gráfico com a avaliação das pessoas em relação aos filmes “Zootopia” e “Moonlight”:

Por questão de visualização (é difícil representar gráficos com diversas dimensões), mostramos o gráfico com apenas dois eixos (“Zootopia” e “Moonlight”). Entretando, o princípio continua o mesmo independente da quantidade de filmes avaliados.

A ideia agora é bem simples: quanto mais próximo as pessoas estão no espaço do gráfico, mais similares são as suas preferências. Ou seja, levando em consideração apenas os dois filmes plotados no gráfico acima, podemos ver que Cláudio gosta de filmes mais parecidos com os filmes que Pedro gosta e talvez não tenha gostos similares ao de Joaquim.

Para calcular a distância entre as pessoas vamos utilizar a distância euclidiana. A fórmula é bem simples e pode ser vista neste artigo na Wikipédia. Entretanto, não queremos somente a distância entre as pessoas e sim uma medida de similaridade, ou seja, quanto maior a distância, menor a similaridade entre as pessoas.

Assim, precisamos de uma função que dê valores mais altos para pessoas com menores distâncias. Isto pode ser feito dividindo a distância encontrada por 1. Para evitar divisões por zero, adicionamos 1 para a distância calculada. Dessa forma, a nossa medida de similaridade pode ser dada por:

A tabela abaixo mostra as medidas de similaridade entre todas as pessoas na nossa aplicação. Juliana possui um grau de similaridade com Marcelo de 0,44 e com Pedro de 0,15. Isso mostra que os gostos de Juliana são mais parecidos com as preferências de Marcelo. Ou seja, existe uma tendência de que Juliana goste dos filmes que Marcelo avaliou bem.

A medida de similaridade acima foi calculada utilizando a distância euclidiana. Como eu disse anteriormente, essa forma de cálculo é uma das mais simples e pode não apresentar bons resultados dependendo do seus dados de entrada e da sua aplicação. Existem diversas outras formas de calcular a medida de similaridade. Você pode ler mais sobre outras métricas para comparar itens neste link.

Recomendando novos filmes

Encontrar pessoas com gostos parecidos com os meus é uma etapa importante da nossa aplicação, mas o que realmente queremos é recomendar novos filmes para as pessoas. Eu poderia simplesmente pegar a pessoa que possui gostos mais similares com os meus e indicar os filmes que ela avaliou bem.

Entretando, esta abordagem pode trazer alguns problemas. Por exemplo, você pode receber indicações de um filme que uma única pessoa em todo o conjunto avaliou bem enquanto todas as outras pessoas deram notas ruins. Pode ser que esse filme seja bom para você, mas existe uma probabiblidade pequena. Existe também a chance de que aquela avaliação foi feita de forma acidental ou errada pela aquela pessoa. Um outro problema é desconsiderar um filme que você gostaria pelo fato da pessoa com gostos mais parecidos com o seu não ter assistido (e avaliado) aquele filme ainda.

Para resolver esses problemas, podemos criar uma média ponderada das avaliações dos críticos que possuem gostos mais parecidos com os meus. Assim, teremos não só uma lista de filmes para indicar, mas também uma estimativa de avaliação que eu daria para aquele filme.

A tabela abaixo mostra recomendações para o usuário Joaquim. Neste caso consideramos apenas as 5 pessoas com gostos mais parecidos com o de Joaquim. Limitar o número de pessoas é uma boa prática para um conjunto de dados grandes.

Ao lado da coluna de cada filme, criamos uma coluna com a avaliação multiplicada pela similaridade (por exemplo “S * Start Trek”). Desse modo, levamos em consideração o grau de similaridade nos nossos cálculos. A linha “Soma(S)” é a soma de todas as similaridades dos usuários que avaliaram aquele filme. Por exemplo, no filme “Start Trek”, não somamos a similaridade do usuário “Fabrício” porque ele não avaliou o filme. A linha “Total / Soma(S)” faz a média ponderada das avaliações. O valor encontrado nessa linha nos dá uma estimativa de avaliação do filme pelo usuário Joaquim. Assim, podemos prever que, caso Joaquim assista e avalie o filme “Logan”, ele o avaliará com 3,5 estrelas.

Acabamos de criar um sistema de recomendação de filmes. No caso de Joaquim, indicaríamos o filme “Logan”. Apesar de simples, esse sistema irá funcionar com qualquer tipo de item: músicas, produtos ou serviços. Existem diversas melhorias que podem ser feitas nesse sistema, como testar novas formas de calcular a similaridade ou evitar a comparação de um usuário com todos os outros usuários do meu sistema. A abordagem apresentada neste artigo funcionaria bem para um sistema com poucos milhares de usuários e items, mas para um sistema como o da Amazon, com um banco de dados extremamente grande, seria impraticável. Nos próximos artigos eu apresentarei uma melhoria para evitar esse problema.

Esse artigo mostrou um sistema de recomendação sem entrar em detalhes de linguagem ou programação. Mas para quem se interessar, existe uma implementação em Python no meu Github: https://github.com/ricardoej/programming_collective_intelligence

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.