Imagine que para cada usuário registrado em seu site você pudesse recomendar produtos diferentes, personalizados para os gostos do cliente. Isso é possível usando sistemas de recomendação automática baseados em machine learning.

Esta é uma das aplicações mais famosas de machine learning em comércio eletrônico. Quem nunca visitou o site de uma loja e dentro da página havia “outros produtos que podem te interessar”? Várias empresas já adotam este tipo de sistema, inclusive gigantes como a Amazon e Netflix.

Os métodos descritos neste artigo podem ser aplicados a qualquer produto. Aqui vou demonstrar o uso com um banco de dados de usuários de uma comunidade de leitores. O desafio é, baseado em notas de 0 a 10 dadas a livros, recomendar novos livros que o usuário possa gostar.

Índice

Formato dos Dados e Tarefa

Para criar o sistema de recomendação, basta termos os dados no seguinte formato:

Usuário - Produto - Nota

Ou seja, para cada produto que o usuário deu uma nota, teremos uma linha em nosso arquivo. Se o seu site não possui um sistema de avaliação de produtos, também é possível substituir a nota pelo número um, caso o cliente tenha comprado o produto, e zero, em caso negativo.

Nós tentaremos prever a nota que um usuário dará a um livro que ele ainda não avaliou (e provavelmente não leu). Na prática, baseado nas notas dadas aos novos livros, podemos recomendar a ele os livros com maior nota, pois estes são os livros que nosso modelo sugere que despertam o interesse deste leitor.

Fiz uma breve limpeza nos dados, e tanto eles quanto o código se encontram neste link: Github Materiais Recomendação
Os dados originais foram retirados deste site: Book-Crossing Dataset

Ferramentas

Eu utilizarei a biblioteca Surprise, em Python, que possui algoritmos de recomendação que podemos treinar usando nossos dados. Ela não é uma biblioteca muito extensa, mas possui tudo o que precisamos para fazer nosso sistema.

Para avaliar o modelo usarei a função nativa da biblioteca para dividir os exemplos em 3 partes e fazer validação cruzada.

import numpy as np
from surprise import Reader, Dataset, BaselineOnly, SVD, accuracy

reader = Reader(line_format='user item rating', sep=',', skip_lines=1, rating_scale=(0,10))
data = Dataset.load_from_file('BX-Book-Ratings_clean.csv', reader=reader)
data.split(n_folds=3)

O Primeiro Modelo

O primeiro modelo que faremos é muito simples, baseado na nota geral dos produtos, diferença da nota média do produto para a nota geral e diferença da nota média do usuário para a nota geral.

Então, por exemplo, imagine que a média de todas as notas, de todos os produtos de seu site seja 3. Esta é o que chamamos de média geral.

Agora imagine que a nota do livro que queremos recomendar ao usuário seja 4. Para obtermos a diferença da média geral, subtraímos 3 de 4 (4 - 3), e temos que o valor da diferença da nota média do produto para a nota geral é 1. Ou seja, este livro é avaliado como melhor do que a média dos livros do site.

O último componente de nossa fórmula envolve a média de notas que o usuário dá aos livros. Isso leva em consideração a personalidade mais seletiva ou não de alguns usuários. Em nosso exemplo, a média da nota do usuário é 3, significando que o usuário é mais exigente que a média. Subtraímos a média geral deste valor (3-3), e obtemos a diferença da nota média do usuário para a nota geral, que é 0.

A fórmula que usamos para prever a nota que este usuário dará a este produto é a seguinte:

Avaliação = média geral + diferença da nota média do produto para a nota geral + diferença da nota média do usuário para a nota geral

Ou seja, neste caso 3 + 1 + 0 = 4.

No código abaixo usei o modelo BaselineOnly, que calcula os coeficientes de cada usuário e produto, além da média geral, de acordo com nossos dados de treino, e armazena para podermos usar em novos produtos.

Para medir o erro, usei a Raiz Quadrada do Erro Médio Quadrado, que basicamente mostra em média quanto a nota prevista desvia da nota real.

model = BaselineOnly()

results = []
for train, val in data.folds():

    model.train(train)
    predictions = model.test(val)

    rmse = accuracy.rmse(predictions, verbose=True)
    results.append(rmse)
print('Mean RMSE %.5f' % (np.mean(results)) )

O erro para este modelo foi de: 1,65347. Este é um erro baixo, se pensarmos que as notas vão de 1 a 10.

Testando um Modelo mais Complexo

Agora vou testar um modelo mais avançado. Em vez dos três números usados pelo modelo acima, este vai tentar encontrar representações mais complexas para cada usuário e produto. Isso dá maior capacidade do modelo capturar detalhes, e a ideia é que capturando estes detalhes o modelo possa estimar com menor erro a nota dada a um novo produto.

model = SVD()

results = []
for train, val in data.folds():

    model.train(train)
    predictions = model.test(val)

    rmse = accuracy.rmse(predictions, verbose=True)
    results.append(rmse)
print('Mean RMSE %.5f' % (np.mean(results)) )

O erro para este modelo foi de 1,74865. Apesar de ser um erro baixo, não é melhor que nosso modelo mais simples.

Nem sempre um modelo ou algoritmo mais avançado, complexo, significa uma melhora. E em alguns casos, a melhora é tão pequena que não vale a pena.

Por isso é importante que o cientista de dados saiba o que está fazendo, e conheça o funcionamento dos modelos, para saber qual é a melhor alternativa para o banco de dados e a tarefa em questão, em vez de apenas aplicar o que é mais popular ou mais avançado.

Eu ainda tentei encontrar parâmetros para otimizar este modelo, pensando que isso pudesse ajudá-lo a superar o modelo mais simples, mas não obtive êxito. Isso fortalece a hipótese que o modelo mais simples é melhor neste caso.

Conclusão

Esta foi uma demonstração bem simples e rápida de como criar um modelo de recomendação que poderia ser usado em um site de comércio eletrônico.

Existem vários outros passos, como a verificação mais cautelosa dos dados, definições da melhor maneira de fazer o processo de modelagem e a otimização e testes dos modelos, que devem ser feitas para garantir que o modelo tenha uma boa performance e seja robusto, mas elas fogem ao escopo deste artigo.

Seja o primeiro a saber das novidades em Machine Learning. Me siga no LinkedIn.