Quando as suas features "melhores" pioram o seu modelo

Quando as suas features "melhores" pioram o seu modelo

Sabe aquela sensação? Você passa dias construindo uma feature linda. Ela captura exatamente o sinal que você queria. Você treina, avalia, e o F1 da Classe 2 pula de 0,72 para 0,78. Você sorri. Aí você submete no leaderboard e o score cai. O que aconteceu? Você acabou de conhecer o trade-off da engenharia de features.

É uma armadilha em que quase todo cientista de dados cai pelo menos uma vez. Eu caí nessa há alguns meses, e isso me custou uma semana inteira de debugging. Então deixa eu te mostrar o que está acontecendo por baixo dos panos, por que as suas features manuais espertas podem sair pela culatra e como montar um fluxo de avaliação de features que não te engana.

A Armadilha Clássica: O que é vitória para uma métrica é derrota para outra

Deixa eu desenhar o cenário exato. Eu estava construindo um modelo de classificação multiclasse para um cliente. O baseline era ok. Aí adicionei duas features feitas à mão: **Impact Severity** e **Energy Ratio**. As duas foram derivadas de dados brutos de sensores, pensadas para capturar uma classe de falha rara. Elas faziam sentido físico. Na validação, o F1 da Classe 2 subiu de 0,72 para 0,78. Bonito, né?

Calma. Quando eu olhei o quadro completo, o F1 da Classe 0 e da Classe 1 tinham caído. O leaderboard — que usava uma média ponderada entre todas as classes — ficou mais baixo que o baseline. O modelo tinha efetivamente aprendido a sacrificar as classes majoritárias para fazer a classe minoritária parecer melhor.

Isso não é azar. É a realidade matemática de um orçamento probabilístico compartilhado. Na maioria dos modelos multiclasse, aumentar a confiança de uma classe reduz a confiança de outra. Se as suas features novas estão altamente correlacionadas com as que já existem, você não está adicionando informação — você está amplificando ruído e viés.

Por que features manuais saem pela culatra?

Multicolinearidade é uma assassina silenciosa

Quando a sua feature nova está correlacionada com duas ou três features existentes, o modelo divide o crédito entre elas. Em modelos baseados em árvore, isso pode esconder splits importantes. Em modelos lineares, infla os coeficientes. O resultado? Previsões menos estáveis, principalmente em dados não vistos.

A pior parte é que a multicolinearidade nem sempre atrapalha a acurácia de treino. Ela pode até ajudar você a memorizar ruído. Mas no momento em que a distribuição de teste muda um pouquinho, sua feature querida vira um passivo.

O trade-off entre precisão e recall

Se você criou uma feature para encontrar a Classe 2, provavelmente está aumentando o recall da Classe 2 enquanto destrói a precisão da Classe 1. Suponha que seu threshold mude. Mais exemplos são classificados como Classe 2, mas muitos deles são, na verdade, Classe 1 ou Classe 0. Seu score macro cai, mesmo que a sua "classe alvo" pareça melhor.

Vejo isso toda hora em detecção de fraude. Alguém cria uma feature que pega mais fraude, mas ela também marca um monte de transações legítimas. O recall do modelo para fraude sobe, mas a taxa de falso positivo dobra. No mundo real, isso significa clientes irritados e um time de suporte muito estressado.

Métricas de leaderboard geralmente são agregadas

A maioria dos leaderboards usa uma única métrica escalar — acurácia, F1 macro, kappa ponderado ou log loss. Esse valor esconde o detalhamento por classe. Se você otimiza para uma fatia, você não está otimizando para o todo. Um ganho de cinco pontos no F1 da Classe 2 pode ser apagado por uma queda de três pontos em duas outras classes, dependendo dos pesos.

Por isso, a primeira coisa que eu faço hoje é ler com muito cuidado a métrica da competição ou do projeto. Se for F1 ponderada, melhorias em uma classe rara são pequenas. Se for F1 macro, toda classe importa igualmente, até as que você não liga.

Um Exemplo Real: O Caso dos Sensores

Deixa eu dar um exemplo concreto. Imagine uma planta industrial com sensores medindo temperatura, vibração e pressão. Modelo baseline: 0,85 de F1 macro em três classes de falha.

Eu criei uma **energy ratio** = amplitude de vibração / variância de pressão. Fazia sentido físico. Impactos de alta energia deveriam indicar falhas severas. No conjunto de treino, o F1 da Classe 2 subiu para 0,81. Mas na validação cruzada, o ganho não se sustentou. Por quê? A energy ratio estava altamente correlacionada com a vibração e a pressão brutas — multicolinearidade de novo. Em dados de teste, o ruído do sensor em pressão baixa fazia a razão explodir, empurrando o modelo para previsões falsas de Classe 2.

A correção foi contraintuitiva: em vez de adicionar a razão bruta, usei uma feature residual — a parte da vibração que *não* era explicada pela pressão. Esse sinal ortogonalizado realmente adicionou informação nova, e o score no leaderboard melhorou em todas as classes. Lição: não pergunte "essa feature faz sentido?" Pergunte "essa feature entrega informação que meu modelo atual ainda não tem?"

Outro Exemplo: Previsão de Churn no E-commerce

Trabalhei com uma empresa de assinatura. O time de marketing queria um **customer engagement score** que combinasse frequência de login, tickets de suporte e menções em redes sociais. Parecia ótimo. Mas o score era só uma soma ponderada de features que já existiam. Quando adicionei ao modelo, as importâncias das features se embaralharam, mas a AUC ficou estável. Pior: a calibração piorou para usuários de baixo engajamento, porque o score dominava a função de perda.

No fim, substituímos o score artesanal por uma contagem simples de categorias distintas com as quais o cliente tinha interagido nos últimos sete dias. Essa feature pequena, menos correlacionada, deu um ganho real. A lição se repetiu: às vezes a feature menos chamativa é a melhor.

Como Avaliar Features Sem Se Enganar

1. Monte um scorecard com várias métricas

Não acompanhe apenas o F1 da Classe 2. Monte um scorecard que inclua:

- F1 macro e F1 ponderada
- Precisão e recall de cada classe
- Log loss ou Brier score (para calibração)
- Uma anotação sobre se as métricas por classe andaram na mesma direção

Aqui está o que eu costumo imprimir depois de cada experimento:

| Métrica | Baseline | Nova Feature | Veredito |
|---|---|---|---|
| F1 Classe 0 | 0,88 | 0,84 | Ruim |
| F1 Classe 1 | 0,82 | 0,79 | Ruim |
| F1 Classe 2 | 0,72 | 0,78 | Bom |
| F1 macro | 0,81 | 0,80 | Ruim |

Um olhar e a história fica clara. A feature nova e brilhante ajudou uma classe, mas prejudicou as outras. Sem esse scorecard, eu teria submetido o modelo e levado uma surpresa desagradável.

2. Faça uma auditoria de correlação

Antes de adicionar uma feature manual, verifique a correlação dela com as features existentes. Use `df.corr()` do pandas e procure valores absolutos acima de 0,7. Se a sua feature nova estiver próxima demais das existentes, considere:

- Remover uma das features redundantes
- Usar residualização (regrida a feature nova sobre as antigas e fique com o resíduo)
- Usar seleção de features com `SelectKBest` ou `RFECV` do scikit-learn

O guia oficial de seleção de features do scikit-learn está cheio de abordagens práticas: https://scikit-learn.org/stable/modules/feature_selection.html

3. Use SHAP para entender efeitos direcionais

Depois de treinar, calcule valores SHAP para ver exatamente como a sua feature nova afeta cada classe. Às vezes uma feature é útil para a Classe 2, mas ativamente prejudicial para a Classe 1. Um summary plot do SHAP mostra isso na hora. A biblioteca é open-source e bem mantida: https://github.com/shap/shap.

Já peguei várias features "ótimas" que tinham valores SHAP positivos fortes para uma classe, mas valores negativos ainda mais fortes para outra. Esse é o trade-off que você precisa enxergar antes de submeter.

4. Tente ablações

Ablação significa remover uma feature e observar o que acontece. É surpreendentemente rara na engenharia manual de features. Eu sempre rodo três experimentos:

- Baseline com as features antigas
- Baseline + feature nova
- Baseline + feature nova, menos uma feature antiga correlacionada

Se o terceiro experimento ganhar do segundo, você resolveu um problema de multicolinearidade. Se o segundo for pior que o primeiro, remova a feature. Se o segundo for melhor, mas a avaliação do leaderboard disser o contrário, investigue a sua validação.

Um Terceiro Exemplo: Classificação de Triagem Médica

Certa vez, trabalhei com um protótipo de checador de sintomas. O objetivo era classificar pacientes em três níveis de urgência. Eu criei um **escore de comorbidade** somando o número de condições pré-existentes. Ele melhorou a detecção de pacientes de alta urgência, mas também fez o modelo ignorar a gravidade do *sintoma atual*. Um paciente com um sintoma leve e uma comorbidade era classificado como alta urgência, mesmo com risco real baixo.

O problema era que a minha feature era dominante demais. O modelo se agarrou a ela porque era fácil de dividir, e ignorou features textuais mais ricas e cheias de nuance. Esse é outro trade-off importante: **dominância de feature**. Uma feature artesanal forte pode ofuscar outras mais fracas, porém mais informativas. Regularização e interações entre features ajudam, mas muitas vezes o simples é melhor.

A Lição Maior: Features Não São De Graça

Cada feature que você adiciona aumenta a complexidade do modelo, o tempo de treino e a chance de overfitting. A regularização ajuda, mas não conserta uma feature fundamentalmente redundante. Você precisa tratar cada feature como uma aposta: ela tem que justificar o lugar dela adicionando sinal novo e estável em várias métricas.

Também aprendi que, quando o leaderboard cai depois de adicionar uma feature, a causa raiz quase nunca é "a métrica está errada". É que eu estava perseguindo um ótimo local. O modelo não é burro — ele está fazendo exatamente o que eu pedi. Eu só pedi a coisa errada.

FAQ

Por que meu F1 subiu em uma classe, mas o score total no leaderboard caiu?

Porque o leaderboard provavelmente usa uma média ponderada ou macro. Seu modelo pode estar sacrificando precisão ou recall em outras classes para ganhar na classe em que você focou. Sempre avalie a matriz de confusão completa antes de ficar animado.

Qual é a melhor forma de lidar com features multicolineares?

Verifique a correlação primeiro. Se duas features são altamente correlacionadas, remova uma ou use uma versão residualizada da feature nova. Regularização, como L1 ou L2, pode ajudar a estabilizar o modelo, mas remover redundância costuma ser mais eficaz do que tentar consertar com penalidades.

Engenharia manual de features ainda é útil no machine learning moderno?

Sim, mas só quando ela codifica conhecimento de domínio que ainda não está no modelo. Se uma feature é apenas uma combinação matemática de features existentes, geralmente não ajuda. Se ela captura um sinal genuinamente novo, pode ser poderosa. O segredo é verificar se ela realmente está adicionando informação independente.

Como saber se uma feature está realmente ajudando?

Compare o modelo baseline com o modelo com a feature usando várias métricas e validação cruzada. Faça uma ablação. Olhe a importância das features e os valores SHAP. Se a melhora não for consistente entre folds ou métricas, provavelmente é overfitting de ruído.

Considerações Finais

Eu sei o barato de construir a feature perfeita. Parece que você decifrou o código. Mas o leaderboard é o árbitro final. Quanto antes você colocar avaliação multi-métrica no seu fluxo, menos tempo vai perder com features que só ajudam uma fatia do problema.

Da próxima vez que você estiver prestes a mandar aquela feature genial de "impact severity", pare. Pergunte a si mesmo: "Isso está adicionando informação nova, ou só amplificando um sinal que eu já tenho?" Seu eu do futuro — e sua posição no leaderboard — vão agradecer.

Comments (0)

No comments yet. Be the first to comment!

Leave a Comment