Como construir sistemas de recomendação simples com ML
1. Fundamentos de Sistemas de Recomendação
1.1 Conceitos básicos: o que é um sistema de recomendação e por que usá-lo
Sistemas de recomendação são algoritmos que preveem a preferência de um usuário por um item específico, ajudando a filtrar grandes volumes de dados para sugerir conteúdo relevante. Eles são amplamente utilizados em plataformas como Netflix, Amazon e Spotify para personalizar a experiência do usuário, aumentar o engajamento e impulsionar vendas.
1.2 Tipos de abordagens: filtragem colaborativa, baseada em conteúdo e híbrida
Existem três abordagens principais:
- Filtragem Colaborativa (FC): baseia-se em interações passadas de usuários similares para fazer recomendações.
- Filtragem Baseada em Conteúdo (FBC): utiliza atributos dos itens (gênero, descrição) e o histórico do usuário.
- Híbrida: combina ambas para mitigar limitações como cold start.
1.3 Métricas de avaliação: precisão, revocação, RMSE e MAP@K
- RMSE (Root Mean Square Error): mede o erro médio entre avaliações previstas e reais.
- Precisão@K: proporção de itens relevantes entre os K recomendados.
- Revocação@K: proporção de itens relevantes recuperados entre todos os relevantes.
- MAP@K: média da precisão média em diferentes níveis de K.
2. Preparação e Exploração dos Dados
2.1 Coleta e limpeza de dados de interação usuário-item
Vamos usar um dataset fictício de avaliações de filmes (usuário, filme, nota).
# Exemplo de dados brutos
usuario_id,filme_id,nota,timestamp
1,101,4.0,2023-01-01
1,102,3.5,2023-01-05
2,101,5.0,2023-02-10
2,103,2.0,2023-02-15
3,102,4.5,2023-03-01
Limpeza: remover duplicatas, tratar valores nulos e normalizar timestamps.
2.2 Análise exploratória: distribuição de usuários, itens e esparsidade
A esparsidade da matriz usuário-item é calculada como:
esparsidade = 1 - (num_interacoes / (num_usuarios * num_itens))
Se tivermos 1000 usuários, 500 filmes e 10.000 avaliações, a esparsidade é 98%.
2.3 Criação de matriz usuário-item e tratamento de dados faltantes
# Criando matriz esparsa
import pandas as pd
from scipy.sparse import csr_matrix
df = pd.read_csv('avaliacoes.csv')
matriz = df.pivot(index='usuario_id', columns='filme_id', values='nota').fillna(0)
matriz_esparsa = csr_matrix(matriz.values)
3. Filtragem Colaborativa com Memória
3.1 Similaridade entre usuários (cosseno, Pearson) e predição baseada em vizinhos
A similaridade de cosseno entre dois usuários u e v é:
similaridade(u,v) = (u · v) / (||u|| * ||v||)
3.2 Similaridade entre itens e recomendação item-item
Para recomendar itens similares a um item i:
# Calcular similaridade entre itens
from sklearn.metrics.pairwise import cosine_similarity
sim_itens = cosine_similarity(matriz_esparsa.T)
3.3 Implementação prática: cálculo de vizinhos mais próximos
from sklearn.neighbors import NearestNeighbors
# Encontrar 5 vizinhos mais próximos para cada usuário
modelo_knn = NearestNeighbors(metric='cosine', n_neighbors=5)
modelo_knn.fit(matriz_esparsa)
# Recomendar para um novo usuário
distancias, indices = modelo_knn.kneighbors(matriz_esparsa[0:1])
4. Filtragem Baseada em Conteúdo
4.1 Representação de itens por atributos
Cada filme pode ser representado por um vetor de gêneros:
# Exemplo: one-hot encoding de gêneros
filmes = {
101: {'acao': 1, 'aventura': 1, 'comedia': 0},
102: {'comedia': 1, 'romance': 1, 'drama': 0},
103: {'acao': 0, 'drama': 1, 'terror': 1}
}
4.2 Criação de perfis de usuário a partir de itens consumidos
O perfil do usuário é a média dos vetores dos itens que ele avaliou positivamente:
# Perfil do usuário 1 (avaliou bem filmes 101 e 102)
perfil_usuario1 = {
'acao': (1 + 0)/2,
'aventura': (1 + 0)/2,
'comedia': (0 + 1)/2,
'romance': (0 + 1)/2,
'drama': (0 + 0)/2,
'terror': (0 + 0)/2
}
4.3 Combinação de similaridade de conteúdo com preferências do usuário
# Calcular similaridade entre perfil do usuário e itens não avaliados
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
perfil = np.array([1, 1, 0.5, 0.5, 0, 0]).reshape(1, -1)
itens = np.array([[1,1,0,0,0,0], [0,0,1,1,0,0], [0,0,0,0,1,1]])
similaridades = cosine_similarity(perfil, itens)
5. Modelos de Fatoração de Matrizes
5.1 Introdução à decomposição SVD e redução de dimensionalidade
SVD decompõe a matriz R (usuário x item) em três matrizes: U, Σ, V^T. Reduzimos para k fatores latentes.
5.2 Implementação de SVD para predição de avaliações faltantes
from sklearn.decomposition import TruncatedSVD
svd = TruncatedSVD(n_components=10)
matriz_reduzida = svd.fit_transform(matriz_esparsa)
# Predizer avaliação do usuário 0 para o filme 101
predicao = np.dot(matriz_reduzida[0], svd.components_[:, 0])
5.3 Vantagens sobre métodos de memória: escalabilidade e generalização
SVD reduz a dimensionalidade, captura padrões latentes e funciona bem com dados esparsos, ao contrário da FC baseada em memória que exige armazenar toda a matriz.
6. Recomendação com Aprendizado de Máquina Clássico
6.1 Transformação do problema em classificação/regressão
Criamos features combinando atributos do usuário e do item:
# Features: idade do usuário, gênero do filme, nota média do usuário
X = [[25, 1, 3.8], [30, 0, 4.2], [22, 1, 3.5]]
y = [4.0, 5.0, 2.0] # notas reais
6.2 Uso de regressão logística, Random Forest ou Gradient Boosting
from sklearn.ensemble import RandomForestRegressor
modelo_rf = RandomForestRegressor(n_estimators=100)
modelo_rf.fit(X, y)
predicao = modelo_rf.predict([[28, 1, 4.0]])
6.3 Engenharia de features: one-hot encoding, normalização
from sklearn.preprocessing import StandardScaler, OneHotEncoder
scaler = StandardScaler()
X_normalizado = scaler.fit_transform(X)
7. Avaliação, Otimização e Deploy Simples
7.1 Divisão temporal dos dados: treino, validação e teste
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
7.2 Ajuste de hiperparâmetros
from sklearn.model_selection import GridSearchCV
param_grid = {'n_estimators': [50, 100], 'max_depth': [5, 10]}
grid = GridSearchCV(RandomForestRegressor(), param_grid, cv=5)
grid.fit(X_train, y_train)
7.3 Estratégias de deploy: API simples com Flask/FastAPI
from flask import Flask, request, jsonify
import joblib
app = Flask(__name__)
modelo = joblib.load('modelo_recomendacao.pkl')
@app.route('/recomendar', methods=['POST'])
def recomendar():
dados = request.json
predicao = modelo.predict([dados['features']])
return jsonify({'nota_prevista': predicao[0]})
if __name__ == '__main__':
app.run(debug=True)
8. Boas Práticas e Próximos Passos
8.1 Lidando com cold start: novos usuários e novos itens
Para novos usuários, use recomendações populares ou baseadas em conteúdo. Para novos itens, colete metadados e use FBC.
8.2 Considerações sobre escalabilidade e atualização do modelo
Modelos baseados em memória não escalam bem. Prefira fatoração de matrizes ou modelos de ML com atualização incremental.
8.3 Ferramentas e bibliotecas recomendadas
- Surprise: especializada em sistemas de recomendação com SVD, KNN e métricas.
- scikit-learn: para modelos de ML clássicos e pré-processamento.
- implicit: para recomendação com dados implícitos (cliques, visualizações).
Referências
- Documentação oficial do Surprise — Biblioteca Python especializada em sistemas de recomendação, com implementações de SVD, KNN e métricas de avaliação.
- scikit-learn: Nearest Neighbors — Tutorial completo sobre algoritmos de vizinhos mais próximos para recomendação.
- Curso de Sistemas de Recomendação (Coursera - University of Minnesota) — Curso abrangente cobrindo filtragem colaborativa, baseada em conteúdo e híbrida.
- Artigo: Matrix Factorization Techniques for Recommender Systems — Paper clássico de Yehuda Koren sobre fatoração de matrizes aplicada ao Netflix Prize.
- Documentação do Flask para APIs — Guia oficial para criar APIs REST que podem servir modelos de recomendação em produção.
- Tutorial de Sistemas de Recomendação com Python (Real Python) — Tutorial prático com implementação passo a passo de recomendação usando pandas e scikit-learn.