Machine learning do zero · Aula 5.1 · 26 de 33 aulas prontas · 10 min
Árvores de decisão: vinte perguntas com dados
Em resumo
Uma árvore de decisão classifica com perguntas de sim ou não que separam os dados da forma mais limpa possível. O exemplo: quem sobreviveu ao Titanic.
Aquecimento Duas perguntas de aulas anteriores. Um minuto, e a aula nunca fica bloqueada.
Lembra do jogo das vinte perguntas? “É um ser vivo?” “É maior que um gato?” Um bom jogador não faz perguntas aleatórias; faz aquela que corta as possibilidades restantes mais ou menos pela metade. Uma árvore de decisão é um modelo que joga esse jogo com dados — e, como as perguntas dela são escritas em linguagem simples, é um dos poucos modelos que dá para ler como um fluxograma.
Escolha uma resposta e o seu grau de certeza.
Responda para liberar o experimento.
Experimento interativo
Este experimento interativo funciona em um navegador com JavaScript ativado. O texto ao redor descreve o que ele mostra.
Ver a resposta
Resposta certa: A rasa (profundidade 1)
A profundidade 20 tem 98,7% no treino, mas 73,9% no teste. A profundidade 1 tem 79,3% no treino e 77,2% no teste. A árvore profunda decorou os passageiros (114 das suas 145 folhas cobrem no máximo 5 pessoas) em vez de aprender uma regra; o melhor resultado de teste, 79,5%, vem da profundidade 3.
Experimente
- Coloque o controle de profundidade máxima em 1. A árvore só pode fazer uma pergunta. Leia-a na lista de divisões: qual atributo o algoritmo considerou mais informativo?
- Aumente a profundidade máxima um passo de cada vez. Veja a acurácia de treino subir e compare-a com a acurácia de teste em cada profundidade.
- Leve a profundidade máxima ao limite. A acurácia de treino chega perto da perfeição? O que aconteceu com a acurácia de teste?
- Encontre a profundidade com a melhor acurácia de teste e leia as principais divisões ali. Você conseguiria explicar essa árvore para alguém em duas frases?
A ideia em poucas palavras
Vamos ver agora, em palavras simples, o que você acabou de manipular.
Uma árvore de decisão faz previsões com uma sequência de perguntas de sim ou não sobre os atributos: “A idade do passageiro é menor que certo valor?”, “Ele viajava na primeira classe?”. Cada resposta manda o exemplo por um galho, e a pergunta seguinte depende das respostas anteriores. No fim de cada caminho fica uma folha com uma previsão — normalmente o rótulo mais comum entre os exemplos de treino que foram parar ali.
Nesta lição usamos dados de 891 passageiros do Titanic, dos quais 342 sobreviveram. Os atributos incluem a classe da passagem, o sexo, a idade, o número de parentes a bordo e a tarifa paga. A árvore aprende quais perguntas sobre esses atributos separam melhor quem sobreviveu de quem não sobreviveu.
Pense numa enfermeira da triagem num pronto-socorro. Ela não calcula uma soma ponderada; segue uma cadeia curta de perguntas — está respirando? sangrando? consciente? —, cada uma estreitando o que fazer. Uma árvore é essa cadeia, aprendida a partir dos dados em vez de escrita por médicos.
Por que funciona
A árvore é construída de cima para baixo, uma pergunta de cada vez. A cada passo, o algoritmo testa cada atributo e cada ponto de corte possível e pergunta: qual pergunta divide este grupo em dois grupos o mais puros possível, ou seja, cada um com predominância de um rótulo? Uma medida popular de impureza é o índice de Gini de um grupo:
Gini = 1 − Σ pₖ²
em que pₖ é a fração do rótulo k no grupo. Um grupo em que todos têm o mesmo rótulo tem Gini 0; um grupo dividido meio a meio entre dois rótulos tem Gini 0,5, o pior valor possível com duas classes. O algoritmo escolhe a pergunta que mais reduz a impureza média e depois repete o procedimento separadamente dentro de cada galho. Essa busca gulosa, passo a passo, não garante a melhor árvore possível, mas é rápida e funciona bem na prática.
Deixada por conta própria, a árvore continua dividindo até todas as folhas ficarem puras — mesmo que uma folha tenha um único passageiro. Nesse ponto ela decorou os dados de treino, com ruído e tudo: o overfitting da lição 7 com outra fantasia. O principal controle é a profundidade máxima, o número de perguntas permitidas ao longo de qualquer caminho. Uma árvore rasa é fácil de ler, mas pode perder padrões reais; uma árvore profunda se ajusta quase perfeitamente aos dados de treino e generaliza pior. A validação cruzada da lição 8 é o jeito honesto de escolher a profundidade.
Erro comum
Uma divisão não é uma explicação de causa. A árvore pergunta sobre o atributo que melhor separa os rótulos nestes dados, e ele pode estar no lugar de outra coisa: a classe da passagem e a tarifa andam juntas, e as duas dizem algo sobre em que parte do navio o passageiro dormia. O segundo erro é confiar numa árvore profunda porque as regras dela parecem muito precisas. Uma regra como “idade entre 31,5 e 32,5 e tarifa acima de certo valor” geralmente é a árvore descrevendo um ou dois passageiros, não um padrão. Pequenas mudanças nos dados também podem mudar a primeira divisão e, com ela, a árvore inteira, o que torna árvores isoladas instáveis.
Essa instabilidade é uma fraqueza, mas pode virar uma força. Na próxima lição cultivamos muitas árvores diferentes e deixamos que elas votem.
Quiz
Três perguntas para você se testar. Escolha uma resposta ou abra a resposta embaixo de cada pergunta. No teclado: as setas escolhem, Enter ou Espaço confirma.
Pontos-chave
- Uma árvore de decisão prevê com uma cadeia de perguntas de sim ou não que se lê como um fluxograma.
- Cada divisão é escolhida de forma gulosa para deixar os grupos resultantes o mais puros possível, por exemplo pelo índice de Gini.
- A profundidade máxima controla a complexidade: árvores rasas fazem underfitting, árvores profundas decoram.
- Uma divisão mostra o que separa os rótulos nos dados, não o que causa o resultado.
Mais a fundo: fórmula, código, prática
A matemática
Para um grupo com proporções de rótulos pₖ, Gini = 1 − Σ pₖ². Com duas classes vai de 0 (um só rótulo) a 0,5 (metade e metade). A tabela inteira do Titanic, 342 sobreviventes de 891, tem Gini = 1 − (342/891)² − (549/891)² ≈ 0.473.
Uma divisão envia n_L linhas para a esquerda e n_R para a direita, n = n_L + n_R. Sua qualidade é a queda da impureza: Δ = G(parent) − (n_L/n) · G(left) − (n_R/n) · G(right). A árvore escolhe a pergunta com o maior Δ e depois repete dentro de cada ramo. A entropia, −Σ pₖ log₂ pₖ, é uma impureza alternativa que se comporta de forma parecida.
Uma árvore de profundidade d tem no máximo 2^d folhas. Uma folha prevê o rótulo majoritário de suas linhas de treino, então uma folha com um só passageiro prevê exatamente o rótulo desse passageiro.
No código (Python)
Os 891 passageiros com seis variáveis (sexo como 0/1, idades faltantes preenchidas com a mediana do treino) e uma divisão de teste estratificada de 30%. É o mesmo tipo de experimento do lab, mas com outra divisão, então os números diferem um pouco dos do lab. O notebook indicado abaixo da saída baixa os dados sozinho.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
df = pd.read_csv("data/raw/titanic.csv")
X = pd.DataFrame({"female": (df["sex"] == "female").astype(int)}).join(df[["pclass", "age", "sibsp", "parch", "fare"]])
Xtr, Xte, ytr, yte = train_test_split(X, df["survived"], test_size=0.3, stratify=df["survived"], random_state=1)
Xtr, Xte = Xtr.fillna({"age": Xtr["age"].median()}), Xte.fillna({"age": Xtr["age"].median()}) # mediana do treino para ambos
print(f"passengers {len(df)}, survived {df['survived'].sum()}")
for d in (1, 3, 20):
t = DecisionTreeClassifier(max_depth=d, random_state=0).fit(Xtr, ytr)
print(f"depth {d:2d}: train {t.score(Xtr, ytr):.3f}, test {t.score(Xte, yte):.3f}, leaves {t.get_n_leaves()}")
Saída
passengers 891, survived 342
depth 1: train 0.780, test 0.802, leaves 2
depth 3: train 0.833, test 0.802, leaves 8
depth 20: train 0.986, test 0.780, leaves 141
Uma árvore de profundidade 1 é uma única pergunta. A árvore de profundidade 20 é quase perfeita nos passageiros de treino e pior que a pergunta única nos passageiros de teste.
Baixar o notebook (.ipynb). Abra no Jupyter ou envie para o Google Colab; ele baixa sozinho os dados que faltarem.
Para quem pratica
- Limite a árvore:
max_depth,min_samples_leafouccp_alpha(poda). Escolha o valor por validação cruzada, não pela acurácia de treino. - Não leia uma árvore profunda como um conjunto de regras. Uma folha com um punhado de passageiros é memória, não um padrão.
- Árvores não precisam de variáveis escalonadas, mas precisam de números. Codifique as categorias (por exemplo, sexo como 0/1) e decida o que fazer com os valores faltantes. Ajuste a imputação apenas no conjunto de treino.
- Uma única árvore é instável: uma pequena mudança nos dados pode mudar a primeira divisão. Se você só precisa de acurácia, um conjunto de árvores é uma escolha mais segura.
- Uma divisão é uma afirmação sobre estes dados, não sobre a causa. A classe da passagem e a tarifa substituem uma à outra, então a árvore pode escolher qualquer uma das duas.
Isto foi útil?
Obrigado! Isso nos ajuda a melhorar.
Vá mais fundo no Atlas
Verbetes da enciclopédia sobre as ideias desta aula: