Construção da árvore de decisão e do Random Forest

A primeira árvore que treinei atingiu ROC AUC de 0,99997. Na base de treino. Na validação, caiu para 0,6148. Esse gap de 0,385 é a definição visual de overfitting — e o caminho para consertá-lo produziu o resultado mais instrutivo do projeto.

Encontrando o tamanho certo

Catorze profundidades testadas com o mesmo protocolo. O padrão é clássico e vale gravar:

max_depthROC AUC validaçãoROC AUC treinoGap
30,8044090,8061640,0018
50,8434370,8455230,0021
70,8458380,8577090,0119
100,8111310,8765300,0654
200,6098350,9786300,3688
sem limite0,6148170,9999970,3852

A curva de validação sobe, atinge o pico em 7 e desaba, enquanto a de treino só sobe. Ganho sobre a árvore sem poda: +0,231 de ROC AUC, e o gap caindo de 0,385 para 0,012. Nenhum dos catorze tamanhos, porém, atinge a meta de 0,85 — a árvore sozinha não resolve este problema.

Curva de ROC AUC em treino e validação por profundidade da árvore
Treino e validação separando-se conforme a árvore cresce: o retrato do overfitting acontecendo. O pico da validação está em max_depth=7.

Pela regra de um desvio-padrão, max_depth=5 (0,8434) já seria suficiente — com metade da complexidade e praticamente o mesmo desempenho. Complexidade só se paga quando compra alguma coisa.

A árvore de 3 níveis, que cabe num slide

Limitada a três níveis, a árvore usa apenas 3 das 16 features e produz oito folhas legíveis. A folha mais arriscada tem 68,77% de inadimplência — 10,3 vezes a taxa da base; a mais segura, 2,10%. Não é o modelo de produção, mas é a ferramenta de comunicação: o comitê de crédito consegue ler o caminho da decisão.

Desenho da árvore de decisão de três níveis
A versão explicável do modelo: três features, oito folhas, e uma separação de risco que vai de 2,10% a 68,77% de inadimplência.

A floresta e a armadilha do class_weight

24 configurações de Random Forest: 8 profundidades × 3 tratamentos de desbalanceamento. 17 delas batem a meta de 0,85. A melhor foi max_depth=10 sem nenhum ajuste de peso, com ROC AUC 0,862885.

E aqui está o achado que contraria o conselho de internet. Todo tutorial manda usar class_weight='balanced' em base desbalanceada. Nesta base, isso destrói a calibração:

class_weightROC AUCBrierProb. médiaNegaria com p*=9,09%
sem peso0,8667440,0486690,06696818,80%
balanced0,8611740,1250510,30430386,97%

Sem peso, a probabilidade média prevista (0,066968) bate com a taxa real (0,066844) na terceira casa decimal. Com balanced, o modelo prevê 30,4% de inadimplência onde a real é 6,7% — e o limiar econômico de 9,09% definido na primeira fase negaria 87% da carteira. A empresa fecharia.

Desempenho do Random Forest por profundidade e tratamento de desbalanceamento
ROC AUC, PR AUC e acurácia ao longo das profundidades. O ganho do ajuste de peso no ROC AUC é nulo ou negativo — e o custo na calibração é enorme.
⚠️

Balancear classe melhora o ranqueamento em alguns problemas, mas distorce a probabilidade. Se a sua decisão usa um limiar econômico — e em crédito usa — a probabilidade calibrada vale mais que qualquer ganho marginal de AUC. Decisão do projeto: nenhum tratamento de peso, em nenhum modelo.

📊

Parte 7 de 12 da série Aurora — um modelo de risco de crédito do zero ao deploy. O mapa completo da série reúne todas as partes e os números finais. Veja também a documentação técnica e o código no GitHub ↗.