Um modelo de previsão de churn com AUC de 0,98 na validação deveria provocar desconfiança, não comemoração. Na maioria dos problemas de negócio, um resultado desses indica que o modelo teve acesso, durante o treino ou a validação, a informação que não estará disponível no momento real da previsão. Isso é vazamento de dados, e é uma das causas mais frequentes de modelos que funcionam no notebook e falham em produção.
Os três tipos mais comuns
Vazamento do alvo
Uma variável de entrada carrega, direta ou indiretamente, a resposta. O exemplo clássico: prever cancelamento de clientes usando o campo "motivo do cancelamento", que só é preenchido depois que o cliente cancela. Exemplos menos óbvios são mais perigosos:
- "Número de chamados de suporte nos últimos 30 dias", quando a janela inclui os dias após o cancelamento.
- "Data da última fatura", quando faturas param de ser emitidas justamente para quem cancelou.
A pergunta que separa uma feature válida de uma vazada é sempre a mesma: no instante em que o modelo vai fazer a previsão, esse valor já existe?
Contaminação entre treino e teste
Transformações ajustadas sobre o conjunto inteiro antes da divisão vazam estatísticas do teste para o treino. Normalização, imputação de valores ausentes, seleção de features e codificação de categorias raras são os casos típicos. O efeito costuma ser pequeno, mas cresce com conjuntos pequenos e features de alta cardinalidade.
A solução é estrutural: toda transformação aprendida deve fazer parte do pipeline e ser ajustada apenas nos dados de treino de cada divisão.
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# O imputador e o scaler são ajustados dentro de cada divisão, nunca no conjunto inteiro.
model = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(), LogisticRegression(max_iter=1000))Vazamento temporal e de grupo
Divisões aleatórias assumem que as linhas são independentes. Em dados de negócio, quase nunca são.
- Tempo: se você embaralha transações de 2024 e 2025 e valida aleatoriamente, o modelo aprende padrões do futuro para prever o passado. Em produção, ele só terá o passado.
- Grupos: se o mesmo cliente aparece no treino e no teste, o modelo pode memorizar o cliente em vez de aprender o padrão. A métrica sobe, a generalização não.
Valide como o modelo será usado
A regra mais útil é simples: a validação deve imitar a forma como o modelo será usado em produção. Se o modelo será treinado com dados até hoje para prever o próximo mês, a validação deve treinar até uma data e avaliar no período seguinte, repetidamente.
from sklearn.model_selection import TimeSeriesSplit, GroupKFold, cross_val_score
# Dados ordenados por data: cada divisão treina no passado e valida no período seguinte.
temporal = TimeSeriesSplit(n_splits=5, gap=30) # gap evita sobreposição de janelas de features
scores = cross_val_score(model, X_sorted, y_sorted, cv=temporal, scoring="roc_auc")
# Quando o mesmo cliente gera várias linhas, ele deve ficar inteiro em um só lado.
grouped = GroupKFold(n_splits=5)
scores_by_customer = cross_val_score(model, X, y, cv=grouped, groups=customer_id, scoring="roc_auc")O parâmetro gap merece atenção: se uma feature usa uma janela de 30 dias, as últimas linhas do treino e as primeiras da validação compartilham informação. Um intervalo entre os dois conjuntos elimina essa sobreposição.
Como detectar vazamento
Alguns sinais aparecem com frequência:
- Métricas boas demais para a dificuldade conhecida do problema.
- Uma feature domina a importância com folga. Investigue como e quando ela é calculada.
- Queda grande entre validação aleatória e validação temporal. A diferença é uma medida aproximada do quanto o modelo dependia do futuro.
- Desempenho em produção muito abaixo da validação nas primeiras semanas, sem mudança aparente nos dados.
Uma prática eficaz é documentar, para cada feature, o horário em que ela fica disponível em relação ao evento previsto. Essa tabela costuma revelar o problema antes de qualquer experimento.
Construa features "no ponto no tempo"
A forma mais robusta de evitar vazamento temporal é calcular features com consultas que recebem explicitamente a data de referência e só enxergam dados anteriores a ela. Em vez de uma tabela de clientes com o "estado atual", você gera, para cada exemplo de treino, o estado do cliente naquela data.
Isso exige dados históricos com carimbo de tempo, e às vezes significa descobrir que o sistema de origem sobrescreve valores sem guardar histórico. Descobrir isso cedo é parte do trabalho: um modelo honesto com menos features vale mais que um modelo brilhante que não se sustenta.
Resumo
Vazamento de dados não é um erro raro de iniciante. Ele surge naturalmente quando dados de negócio são tratados como amostras independentes. Validar como o modelo será usado, manter transformações dentro do pipeline e calcular features no ponto no tempo resolve a maior parte dos casos, e uma métrica um pouco menor e verdadeira é o que permite tomar decisões confiáveis com o modelo.
Leituras relacionadas
- Machine Learning · 4 min de leitura
- IA aplicada · 3 min de leitura
- IA aplicada · 4 min de leitura