Trilha 19 · Machine Learning

Árvores de decisão

Uma sequência de perguntas sim/não que particiona o espaço em regiões. Diferente do perceptron, a árvore captura padrões não-lineares — e é uma das técnicas mais usadas em dados tabulares.

① Intuição

Vinte perguntas com os dados

Uma árvore de decisão classifica fazendo perguntas simples em sequência: "a área é maior que 80m²? Se sim, o preço é alto?". Cada pergunta divide os dados em dois, e cada divisão tenta deixar os grupos resultantes mais puros — idealmente, cada folha contém apenas uma classe.

O resultado é o espaço cortado em retângulos, cada um com uma previsão. Como pode fazer um corte por vez em qualquer eixo, a árvore captura padrões que uma reta única jamais capturaria — incluindo o XOR, onde as classes ficam em cantos opostos.

A maior força: interpretabilidade. Você pode ler a árvore inteira como uma lista de regras "se... então...". Num banco ou hospital, isso importa muito: o modelo não só decide, ele explica a decisão. O custo é a tendência a sobreajustar — uma árvore profunda demais decora o treino.
② Visualização interativa

A árvore cresce, o espaço se divide

Aumente a profundidade e veja a árvore (à direita) crescer enquanto o espaço (à esquerda) é cortado por linhas tracejadas. Os dados formam um XOR: profundidade 0 ou 1 não passa de 50% de acurácia, mas profundidade 2 separa tudo. Folhas com anel amarelo ainda estão impuras.

ESPAÇO DE DECISÃO
ÁRVORE DE DECISÃO

Profundidade 0 = "chute" da classe maioritária. A cada nível a árvore escolhe o corte (feature + limiar) que mais reduz a impureza de Gini. Aqui os dados formam um XOR — uma reta única nunca passa de 50%, mas a árvore de profundidade 2 separa tudo. Folhas com anel amarelo ainda estão impuras.

③ Explicação técnica

Escolhendo o corte: impureza de Gini

// Como a árvore escolhe um corte: impureza de Gini

// Gini mede o quão "misturado" é um conjunto de rótulos:
//   Gini = 1 − Σ pₖ²   (pₖ = proporção da classe k)
//   0.0 = puro (uma só classe)   0.5 = 50/50 (máxima mistura, 2 classes)

def gini(amostras):
    n = len(amostras)
    if n == 0: return 0
    p1 = sum(1 for a in amostras if a.classe == 1) / n
    return 1 - (p1**2 + (1-p1)**2)

// Para cada corte candidato (feature + limiar) a árvore calcula
// a impureza ponderada dos dois lados e escolhe a MENOR:
//   Gini_corte = (nₑ·Gini(esq) + nₐ·Gini(dir)) / n
// O "ganho" é a redução de impureza em relação ao nó pai.

Construção recursiva (CART)

// Construção recursiva (CART) — pseudocódigo

def construir(amostras, profundidade):
    // casos de parada: puro, raso demais, ou poucos exemplos
    if gini(amostras) == 0 or profundidade >= MAX:
        return Folha(classe = maioria(amostras))

    corte = melhor_corte(amostras)        // menor Gini ponderado
    if corte is None:
        return Folha(classe = maioria(amostras))

    esq, dir = dividir(amostras, corte)
    return No(
        corte,
        construir(esq, profundidade+1),   // recursão à esquerda
        construir(dir, profundidade+1),   // recursão à direita
    )

// Prever = caminhar da raiz até uma folha respondendo sim/não.
// Profunda demais → decora o treino (sobreajuste): por isso
// limitamos profundidade ou podamos (pruning) a árvore.
De uma árvore a uma floresta: uma árvore sozinha é instável (muda muito com pequenas mudanças nos dados). O Random Forest treina centenas de árvores, cada uma sobre uma amostra aleatória dos dados e das features, e faz votação. Já o Gradient Boosting (XGBoost, LightGBM) treina árvores em sequência, cada nova corrigindo os erros das anteriores — é o que mais vence competições com dados tabulares.
④ Projeto para programar

Plantando uma árvore

Mini projeto: com sklearn, treine um DecisionTreeClassifier no dataset Titanic (sobreviveu ou não). Visualize a árvore com plot_tree() e leia as regras. Varie max_depth de 1 a 15 e plote acurácia de treino vs. teste — você verá o treino subir sempre e o teste subir e depois cair (sobreajuste).

Projeto principal: implemente uma árvore de decisão do zero em Python: a função gini(), a busca pelo melhor corte (testando limiares em cada feature) e a construção recursiva com um max_depth. Valide reproduzindo o padrão XOR da visualização acima — sua árvore deve atingir 100% com profundidade 2.

Desafio extra: implemente um Random Forest sobre sua árvore: treine N árvores em amostras bootstrap (sorteadas com reposição) e com um subconjunto aleatório de features por corte, e classifique por voto majoritário. Compare a acurácia de teste de 1 árvore vs. 50 árvores e meça quanto a variância (instabilidade entre rodadas) diminui.

⑤ Exercícios rápidos

Teste sua intuição

Como uma árvore de decisão escolhe onde cortar?
Por que uma árvore resolve o XOR e um perceptron não?
Qual a relação entre profundidade da árvore e sobreajuste?
⑥ Aplicações no mundo real

Onde você encontra isso

🏆

Campeãs em dados tabulares

XGBoost e LightGBM (ensembles de árvores com boosting) dominam competições do Kaggle e sistemas de produção com dados em tabela: risco de crédito, previsão de demanda, ranking de busca. Para dados estruturados, costumam bater redes neurais com muito menos esforço de ajuste.

🩺

Decisões que precisam de explicação

Em medicina e crédito, regras "se... então..." legíveis são exigidas por reguladores e por médicos. Árvores e suas regras extraídas oferecem transparência que modelos "caixa-preta" não dão — você consegue justificar cada decisão.

🛒

Detecção de fraude

Cada transação de cartão passa por centenas de árvores votando "fraude ou não" em milissegundos. O ensemble combina sinais (valor, local, horário, histórico) de formas não-lineares que regras manuais nunca capturariam com a mesma precisão.

← Anterior: O perceptron Próxima: k-means →