Desbalanceamento de classes
Visão geral
Desbalanceamento de classes (class imbalance) ocorre quando algumas classes aparecem com muito mais frequência do que outras no seu conjunto de dados (por exemplo, 99% “não é fraude”, 1% “fraude”). O desbalanceamento é comum em aprendizado de máquina (machine learning, ML) do mundo real — detecção de fraude, triagem médica, detecção de falhas, moderação de conteúdo e previsão de eventos raros.
O desbalanceamento importa por dois motivos interligados:
- Treinamento do modelo: Muitos algoritmos de aprendizado otimizam implicitamente a acurácia (accuracy) geral (ou a perda (loss) média), então podem preferir prever a classe majoritária (majority class).
- Avaliação: Métricas padrão podem se tornar enganosas quando a taxa-base (base rate) (prevalência da classe) é extrema. Você pode obter pontuações que parecem impressionantes enquanto falha na classe rara (classe minoritária (minority class)) que de fato importa.
Este artigo foca em lidar com dados desbalanceados e escolher métricas de forma apropriada, com orientações práticas e exemplos.
Conceitos-chave e por que o desbalanceamento é complicado
Prevalência e o “paradoxo da acurácia”
Considere a classe positiva como rara: (P(y=1)=1%). Um classificador (classifier) trivial que sempre prevê 0 alcança 99% de acurácia — porém tem 0% de revocação (recall) para positivos.
Este é o clássico paradoxo da acurácia: a acurácia reflete tão fortemente a classe majoritária que pode esconder uma falha completa na classe minoritária.
Matriz de confusão (confusion matrix): a base para a maioria das métricas
Para classificação binária:
- TP: verdadeiros positivos (prevê 1, é de fato 1)
- FP: falsos positivos (prevê 1, é de fato 0)
- TN: verdadeiros negativos (prevê 0, é de fato 0)
- FN: falsos negativos (prevê 0, é de fato 1)
Muitas métricas “amigáveis ao desbalanceamento” são diferentes formas de resumir essa matriz.
Mudança na probabilidade a priori (prior probability shift) afeta a avaliação
Mesmo que o comportamento condicional do seu modelo permaneça o mesmo, a precisão (precision) muda com a prevalência:
[ \text{Precision} = \frac{TP}{TP+FP} ]
Se os positivos se tornam mais raros em produção, a precisão geralmente cai (mais positivos previstos são alarmes falsos). Por isso é importante avaliar sob a prevalência esperada em produção (expected deployment prevalence), ou ajustar limiares/custos de decisão de acordo.
Para mais sobre confiabilidade de probabilidades, veja Calibração.
Escolhendo métricas para classificação desbalanceada
A escolha de métricas deve seguir o objetivo da decisão: você se importa em capturar o máximo de positivos possível, minimizar alarmes falsos, ranquear casos, ou minimizar custo esperado?
Métricas a evitar (ou usar com cautela)
Acurácia
Frequentemente enganosa para positivos raros, porque TN domina.
AUC ROC (às vezes)
AUC ROC (ROC AUC) mede a qualidade de ranqueamento independentemente de um limiar específico. Ela ainda pode parecer alta mesmo quando o desempenho na classe minoritária é praticamente ruim, porque a curva ROC pode permanecer otimista sob forte desbalanceamento.
A AUC ROC pode ser útil, mas para positivos raros você geralmente também deve reportar AUC PR (PR AUC) e métricas no ponto de operação (operating-point) (precisão/revocação em um limiar escolhido). Veja Métricas.
Métricas que tipicamente são mais informativas
Precisão, revocação e F1
- Revocação (TPR, sensibilidade): (TP/(TP+FN)) — “Quantos verdadeiros positivos capturamos?”
- Precisão (PPV): (TP/(TP+FP)) — “Quantos positivos previstos estavam corretos?”
- F1: média harmônica de precisão e revocação — útil quando você quer um único número e se importa com ambos.
Quando positivos são raros, a precisão se torna especialmente importante porque mesmo uma pequena taxa de FP pode superar TP.
Escolha com base em custos:
- Alto custo de FN (fraude não detectada, câncer não detectado) → priorize revocação (e monitore precisão).
- Alto custo de FP (revisão manual cara) → priorize precisão (e monitore revocação).
AUC de Precisão–Revocação (PR AUC) (Precisão Média (Average Precision))
AUC PR resume o trade-off de precisão–revocação ao longo de limiares e frequentemente é mais sensível do que a AUC ROC a melhorias na classe minoritária.
Um ponto-chave: a linha de base da AUC PR é igual à prevalência de positivos. Se a prevalência é 1%, uma AUC PR de 0,20 é, na verdade, muito forte.
Acurácia balanceada (balanced accuracy)
[ \text{Balanced accuracy} = \frac{1}{2}(\text{TPR} + \text{TNR}) ] Ela pondera sensibilidade e especificidade de forma igual, reduzindo o domínio da classe majoritária.
Coeficiente de Correlação de Matthews (Matthews Correlation Coefficient, MCC)
O MCC é uma medida semelhante a correlação que usa as quatro entradas da matriz de confusão. Ele costuma ser robusto sob desbalanceamento e é um bom resumo “de um número só” se você quiser apenas um.
Métricas sensíveis a custo (cost-sensitive metrics) (perda esperada (expected loss))
Se você consegue quantificar custos, calcule:
[ \mathbb{E}[\text{cost}] = C_{FN}\cdot FN + C_{FP}\cdot FP ]
Isso alinha a avaliação com impacto de negócio/clínico melhor do que métricas genéricas.
Avaliação dependente de limiar vs independente de limiar
Muitos classificadores produzem uma pontuação ou probabilidade (s(x)). Você então escolhe um limiar (threshold) (t) para classificar:
- prever positivo se (s(x)\ge t)
O desbalanceamento torna a escolha de limiar especialmente importante porque:
- o padrão (t=0.5) raramente é ótimo quando a prevalência é baixa
- o melhor limiar depende de custos, restrições de capacidade e prevalência
Um bom fluxo de trabalho é:
- Avaliar ranqueamento (AUC ROC / AUC PR)
- Escolher limiares de operação com base em custo ou restrições
- Reportar métricas da matriz de confusão nesses limiares
Para um desenho de avaliação confiável, veja Validação e Validação Cruzada.
Exemplo prático: por que acurácia falha (detecção de fraude)
Suponha que você tenha 10.000 transações, 100 são fraude (1%).
Um modelo ingênuo prevê “não é fraude” para todas:
- TN = 9.900
- FN = 100
- TP = 0
- FP = 0
Métricas:
- Acurácia = 9.900 / 10.000 = 99%
- Revocação = 0 / (0 + 100) = 0
- Precisão é indefinida (sem previsões positivas)
Um modelo um pouco melhor sinaliza 80 transações como fraude, capturando 60 fraudes reais:
- TP = 60, FP = 20, FN = 40, TN = 9.880
Métricas:
- Acurácia = (60 + 9.880) / 10.000 = 99,4% (quase não mudou)
- Revocação = 60 / 100 = 60%
- Precisão = 60 / 80 = 75%
O segundo modelo é dramaticamente melhor para o objetivo real, mas a acurácia quase não muda.
Lidando com desbalanceamento de classes durante o treinamento
Não existe uma única melhor técnica. Muitas vezes você combina:
- métricas apropriadas
- seleção de limiar
- treinamento sensível a custo (cost-sensitive training)
- reamostragem (resampling)
- dados e atributos (features) melhores
1) Estratégias de reamostragem
Subamostragem aleatória (random undersampling) (reduzir classe majoritária)
Prós:
- treinamento mais rápido
- pode ajudar alguns modelos a focar em padrões da classe minoritária
Contras:
- descarta informação da classe majoritária
- pode aumentar a variância
É bom quando a classe majoritária é enorme e redundante.
Superamostragem aleatória (random oversampling) (duplicar amostras minoritárias)
Prós:
- simples, frequentemente eficaz
- preserva os dados da classe majoritária
Contras:
- pode superajustar (overfit) ao repetir exemplos minoritários
Superamostragem sintética (synthetic oversampling) (SMOTE/ADASYN)
Cria pontos sintéticos da classe minoritária no espaço de atributos.
Prós:
- pode reduzir superajuste vs duplicação ingênua
Contras:
- pode criar amostras irreais, especialmente com atributos categóricos ou variedades (manifolds) complexas
- pode borrar fronteiras de classe e aumentar FPs
Importante: a reamostragem deve ser feita dentro de cada dobra (fold) de treinamento para evitar vazamento de dados (leakage). Não faça superamostragem antes de dividir, ou duplicatas/vizinhos sintéticos podem “vazar” para validação.
2) Ponderação de classes / aprendizado sensível a custo
Muitos algoritmos suportam pesos de classe (class weights) para que erros na classe minoritária contem mais na perda.
Exemplos:
- Regressão logística (logistic regression) / SVM linear (linear SVM):
class_weight='balanced' - Modelos de árvore: pesos de classe ou pesos de amostra (sample weights)
- XGBoost/LightGBM:
scale_pos_weight/is_unbalance
Prós:
- sem dados duplicados
- frequentemente uma linha de base forte
Contras:
- ainda exige ajuste de limiar; pesos afetam a calibração de pontuações e o ranqueamento de formas específicas do modelo
3) Perdas especializadas (comum em aprendizado profundo (deep learning))
Perda focal (focal loss)
Reduz o peso de negativos fáceis e foca em exemplos difíceis. Frequentemente usada em tarefas de detecção com desbalanceamento extremo.
Útil quando:
- você tem enormes quantidades de negativos fáceis
- positivos são raros e diversos
4) Enquadramento como detecção de anomalias (anomaly detection) (quando positivos são extremamente raros)
Se positivos são tão raros que você tem poucos exemplos rotulados, considere:
- métodos de uma classe (one-class methods)
- detecção de anomalias não supervisionada (unsupervised) ou semissupervisionada (semi-supervised)
- supervisão fraca (weak supervision) / funções de rotulagem (labeling functions)
Mas observe: detecção de anomalias otimiza para “diferente do normal”, o que pode não se alinhar com sua classe positiva.
5) Correções no nível de dados: coletar melhores positivos e melhorar rótulos
Frequentemente os maiores ganhos vêm de:
- coletar mais exemplos da classe minoritária (amostragem direcionada)
- melhorar a qualidade dos rótulos (rótulos minoritários frequentemente são mais ruidosos)
- adicionar atributos que separem melhor as classes
- redefinir o alvo de previsão (por exemplo, prever “precisa de revisão” vs “fraude”)
Seleção de limiar sob desbalanceamento
Use custos ou restrições, não 0,5
Se você consegue quantificar custos:
- escolha (t) que minimiza o custo esperado nos dados de validação
Se você tem restrições de capacidade:
- “Podemos revisar 500 casos/dia” → escolha um limiar para sinalizar os 500 itens de maior risco (uma abordagem de ranqueamento + corte)
Isso se conecta naturalmente a métricas de ranqueamento e métricas operacionais como:
- Precisão@K (Precision@K)
- Revocação@K (Recall@K)
- Lift (lift) (o quanto melhor do que seleção aleatória)
Calibre probabilidades se você as usa para decisões
Ponderação de classes e reamostragem podem distorcer estimativas de probabilidade. Se você precisa de probabilidades bem calibradas para tomada de decisão:
- avalie calibração (gráficos de confiabilidade (reliability plots), ECE)
- considere calibração pós-hoc (post-hoc) como escalonamento de Platt (Platt scaling) ou regressão isotônica (isotonic regression) em um conjunto separado (held-out)
Veja Calibração.
Exemplo prático de código (scikit-learn)
A seguir, um fluxo compacto mostrando: divisão estratificada, modelo com pesos de classe, AUC PR e ajuste de limiar.
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
average_precision_score, precision_recall_curve,
confusion_matrix, classification_report
)
# Synthetic imbalanced data: 1% positives
X, y = make_classification(
n_samples=50_000, n_features=20, n_informative=10,
weights=[0.99, 0.01], flip_y=0.001, random_state=0
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=0
)
clf = LogisticRegression(
max_iter=2000,
class_weight="balanced" # cost-sensitive baseline
)
clf.fit(X_train, y_train)
scores = clf.predict_proba(X_test)[:, 1]
# Threshold-free metric for rare positives
ap = average_precision_score(y_test, scores)
print("PR AUC (Average Precision):", ap)
# Choose a threshold to hit a target recall (e.g., >= 0.80)
precision, recall, thresholds = precision_recall_curve(y_test, scores)
target_recall = 0.80
idx = np.where(recall >= target_recall)[0][-1]
t = thresholds[max(idx - 1, 0)] # thresholds has length-1 vs precision/recall
print("Chosen threshold:", t)
y_pred = (scores >= t).astype(int)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred, digits=3))
Notas:
- Usamos AUC PR em vez de acurácia.
- Selecionamos um limiar com base em um requisito de revocação; você poderia, em vez disso, otimizar custo esperado ou impor um orçamento de revisão.
- Para uma avaliação robusta, faça a seleção de limiar em dobras de validação e reporte métricas finais em um conjunto de teste separado (held-out).
Boas práticas de avaliação específicas para desbalanceamento
1) Use divisão estratificada (normalmente)
Para classificação i.i.d. (independentes e identicamente distribuídos (independent and identically distributed, i.i.d.)), prefira divisões estratificadas e validação cruzada estratificada para que cada dobra contenha positivos. Veja Validação e Validação Cruzada.
Exceções:
- séries temporais / previsão de eventos (event forecasting): use divisões baseadas em tempo
- dados agrupados (múltiplas amostras por usuário/dispositivo): use divisões cientes de grupo (group-aware splits)
2) Reporte incerteza e intervalos de confiança
Com poucos positivos, métricas têm alta variância. Uma mudança de 10 para 13 TPs pode parecer grande na revocação.
Abordagens comuns:
- intervalos de confiança via bootstrap (bootstrap) para AUC PR, revocação@limiar
- validação cruzada repetida
- análise de poder (power analysis) cuidadosa para testes online/em campo (veja Desenho de Experimentos e Poder)
3) Fatie desempenho por coortes
O desbalanceamento frequentemente esconde falhas em subgrupos (por exemplo, a classe minoritária se concentra em certas regiões ou tipos de dispositivo). Use fatiamento por coortes (cohort slicing):
- precisão/revocação por segmento
- curvas PR por segmento
- inspeção de erros de FPs e FNs
Veja Análise de Erros (Fatiamento).
4) Evite vazamento ao reamostrar
A reamostragem deve acontecer depois da divisão:
- Em validação cruzada: reamostre apenas dentro de cada dobra de treinamento.
- Se estiver usando pipelines (pipelines), coloque a reamostragem dentro da etapa do pipeline aplicada durante
fit.
5) Cuidado com ruído de rótulo (label noise) e rótulos atrasados (delayed labels)
Em muitos domínios desbalanceados:
- positivos são descobertos mais tarde (por exemplo, estornos por fraude)
- rótulos são incompletos (positivos desconhecidos rotulados como negativos)
Isso cria “positivos ocultos” que inflacionam taxas aparentes de FP e distorcem o treinamento.
Desbalanceamento multiclasse e de cauda longa (long-tailed imbalance)
O desbalanceamento não é apenas binário. Em problemas multiclasse você pode ter uma “cabeça (head)” de classes frequentes e uma “cauda (tail)” de classes raras (reconhecimento de cauda longa (long-tailed recognition)).
Orientação de métricas:
- F1 macro-médio (macro-averaged F1): trata cada classe igualmente; evidencia desempenho na cauda
- F1 macro ponderado (weighted macro F1): pondera pela frequência da classe (pode mascarar a cauda)
- F1 micro-médio (micro-averaged F1): dominado por classes frequentes (frequentemente similar à acurácia)
- Precisão/revocação por classe (per-class precision/recall): essencial para visibilidade
- Mapas de calor da matriz de confusão: revelam quais classes de cauda colapsam em classes de cabeça
Estratégias de treinamento:
- reponderação balanceada por classe (class-balanced reweighting)
- variantes de perda focal
- treinamento em duas etapas (aprendizado de representações e depois ajuste fino balanceado (balanced fine-tuning))
- aumento de dados (data augmentation) direcionado para classes de cauda
Armadilhas comuns
- Otimizar a métrica errada: por exemplo, maximizar acurácia para uma tarefa de evento raro.
- Usar um limiar padrão: (t=0.5) raramente é significativo sob desbalanceamento.
- Avaliar apenas AUC ROC: você pode não perceber baixa precisão em níveis de revocação utilizáveis.
- Comparar modelos em pontos de operação diferentes: sempre compare sob as mesmas restrições (mesma revocação, mesma precisão ou mesmo orçamento de revisão).
- Vazamento por reamostragem: superamostrar antes da divisão contamina a avaliação.
- Ignorar mudança de prevalência (prevalence shift): a precisão em produção pode diferir substancialmente dos dados de teste.
- Tratar probabilidades como calibradas quando não são: especialmente após reponderação/superamostragem.
Um checklist prático
- Defina o objetivo e os custos: O que importa mais, FN ou FP? Existe um orçamento de revisão?
- Escolha métricas de acordo:
- AUC PR + precisão/revocação nos limiares escolhidos
- acurácia balanceada / MCC como resumos secundários
- Use divisões robustas: estratificadas/por grupo/baseadas em tempo conforme apropriado.
- Comece com linhas de base fortes: pesos de classe + ajuste de limiar.
- Teste reamostragem com cuidado: dentro das dobras, observando superajuste.
- Calibre se necessário: especialmente se decisões usam probabilidades previstas.
- Fatie os resultados: encontre segmentos em que o desempenho na classe minoritária colapsa.
- Quantifique incerteza: intervalos de confiança e experimentos com atenção a poder.
Artigos relacionados
- Métricas
- Validação e Validação Cruzada
- Calibração
- Análise de Erros (Fatiamento)
- Desenho de Experimentos e Poder
- Estimativa de Incerteza