Um serviço de backend com defeito costuma avisar: erros 500, filas crescendo, alertas. Um modelo de machine learning degradado não avisa nada. Ele continua respondendo em milissegundos, com o mesmo formato, só que com previsões cada vez piores. A causa mais comum é a deriva: os dados de produção deixam de se parecer com os dados em que o modelo foi treinado.
Três tipos de mudança
- Deriva de entrada (covariate drift): a distribuição das variáveis muda. Um modelo de crédito treinado antes de uma mudança de política de juros passa a ver clientes com perfis diferentes.
- Deriva do alvo (label drift): a proporção dos resultados muda. A taxa de inadimplência sobe, mesmo que os clientes pareçam iguais.
- Deriva de conceito (concept drift): a relação entre entrada e resultado muda. As mesmas características passam a indicar comportamentos diferentes, como hábitos de compra depois de uma mudança de canal.
A deriva de conceito é a mais perigosa e a mais difícil de detectar, porque só aparece quando o resultado real é conhecido, muitas vezes semanas depois.
O problema do rótulo atrasado
Em muitos casos de negócio, o resultado chega tarde. Você só sabe se um cliente ficou inadimplente meses depois da previsão. Esperar pelo rótulo para medir desempenho significa descobrir o problema tarde demais.
Por isso, o monitoramento combina duas camadas:
- Sinais imediatos: distribuição das entradas e das previsões, comparadas com uma referência. Não dizem que o modelo está errado, mas dizem que ele está operando fora do território conhecido.
- Sinais atrasados: métricas de desempenho calculadas quando os rótulos chegam, por coorte de data de previsão.
Medindo deriva com PSI
O Population Stability Index compara a distribuição de uma variável entre uma referência (por exemplo, o período de validação) e uma janela de produção. A variável é dividida em faixas, e o índice soma, para cada faixa, a diferença de proporções ponderada pelo logaritmo da razão entre elas.
import numpy as np
def psi(reference: np.ndarray, current: np.ndarray, bins: int = 10, eps: float = 1e-6) -> float:
"""Population Stability Index. Bin edges come from reference quantiles."""
edges = np.unique(np.quantile(reference, np.linspace(0, 1, bins + 1)))
edges[0], edges[-1] = -np.inf, np.inf
ref_share = np.histogram(reference, edges)[0] / len(reference)
cur_share = np.histogram(current, edges)[0] / len(current)
ref_share = np.clip(ref_share, eps, None)
cur_share = np.clip(cur_share, eps, None)
return float(np.sum((cur_share - ref_share) * np.log(cur_share / ref_share)))Uma convenção amplamente usada no setor de crédito trata PSI abaixo de 0,1 como estável, entre 0,1 e 0,25 como mudança moderada, e acima de 0,25 como mudança significativa. São regras práticas, não verdades estatísticas: calibre os limites com o histórico do seu próprio modelo antes de transformá-los em alertas.
Para variáveis contínuas, o teste de Kolmogorov-Smirnov é uma alternativa. Com muito volume, porém, ele aponta diferenças estatisticamente significativas que não têm importância prática, então use o tamanho do efeito, não apenas o p-valor.
O que monitorar
Monitorar todas as variáveis com o mesmo peso gera ruído. Priorize:
- As previsões. Uma mudança na distribuição das saídas é o sinal mais próximo do impacto no negócio.
- As variáveis mais importantes para o modelo, segundo a análise de importância feita no treino.
- Qualidade dos dados: proporção de valores ausentes, categorias novas nunca vistas no treino, valores fora da faixa. Muitas "derivas" são, na verdade, um sistema de origem que mudou o formato de um campo.
Diferença entre treino e produção
Antes de suspeitar do mundo, suspeite do pipeline. A diferença entre treino e produção (training-serving skew) acontece quando uma variável é calculada de um jeito no treino e de outro na produção: um fuso horário diferente, uma janela de agregação diferente, um valor padrão diferente para ausentes.
A melhor defesa é calcular as variáveis com o mesmo código nos dois contextos e registrar, em produção, as entradas exatamente como o modelo as recebeu. Assim, é possível compará-las diretamente com os dados de treino.
Do alerta à decisão
Um alerta de deriva não significa "retreine agora". Significa "investigue". O roteiro que costumamos seguir:
- Verificar se a mudança vem de um problema de dados (formato, ausentes, integração quebrada).
- Se a mudança é real, estimar o impacto: o desempenho caiu nas coortes que já têm rótulo?
- Decidir entre retreinar com dados recentes, ajustar o limiar de decisão ou, em mudanças estruturais, revisar as variáveis.
Retreinar automaticamente a cada alerta parece prático, mas pode incorporar ao modelo um problema de dados que deveria ter sido corrigido na origem. Prefira retreino agendado, com a mesma avaliação usada no desenvolvimento, e retreino extraordinário como decisão consciente.
Resumo
Modelos envelhecem em silêncio. Monitorar a distribuição de entradas e previsões contra uma referência, com métricas como PSI, detecta a mudança antes que os rótulos confirmem o prejuízo. Verificar primeiro a qualidade dos dados e a consistência entre treino e produção evita alarmes falsos, e tratar o alerta como início de uma investigação mantém o retreino uma decisão, não um reflexo.
Leituras relacionadas
- Machine Learning · 3 min de leitura
- IA aplicada · 3 min de leitura
- IA aplicada · 4 min de leitura