7. Árvores de Decisão
As Árvores de Decisão são um algoritmo de aprendizado supervisionado utilizado para classificação e regressão. Elas representam o conhecimento como um conjunto de regras SE–ENTÃO, organizadas em um gráfico hierárquico no formato de árvore — fácil de interpretar e muito usado em finanças, vendas, operações e RH.
Aplicações
- Finanças: concessão de crédito e análise de risco.
- Vendas: prever se o cliente vai comprar ou não.
- Operações: previsão de demanda.
- RH: apoio à contratação de candidatos.
Estrutura da árvore
Cada árvore é composta por:
- Raiz: nó principal, onde começa a divisão dos dados.
- Nós internos: testes sobre os atributos (ex.:
Renda < 15?). - Galhos: resultados de cada teste (sim/não, faixas de valor).
- Folhas: classificação final (ex.: Risco Alto, Moderado ou Baixo).
A partir de uma base histórica, o algoritmo constrói automaticamente essa sequência de condições até chegar à classe prevista para cada registro.
Exemplo: base de risco de crédito
A tabela abaixo resume os atributos usados para classificar o risco de um solicitante de crédito:
| História de Crédito | Dívida | Garantias | Renda Anual | Risco |
|---|---|---|---|---|
| Ruim | Alta | Nenhuma | < 15.000 | Alto |
| Desconhecida | Alta | Nenhuma | 15.000 – 35.000 | Alto |
| Desconhecida | Baixa | Nenhuma | 15.000 – 35.000 | Moderado |
| Desconhecida | Baixa | Nenhuma | > 35.000 | Baixo |
| Boa | Alta | Nenhuma | > 35.000 | Baixo |
| Boa | Alta | Adequada | > 35.000 | Baixo |
| … | … | … | … | … |
A árvore gerada para essa base segue a lógica:
- Primeira divisão (Renda):
< 15,>= 15 e <= 35,> 35. - Divisões internas: História de Crédito e Dívida refinam a classificação em cada faixa de renda.
Teste 1: História = Ruim, Dívida = Baixa, Garantia = Adequada, Renda = 15.000–35.000 → Moderado.
Teste 2: História = Desconhecida, Dívida = Baixa, Garantia = Nenhuma, Renda > 35.000 → Baixo.
Como dividir a árvore: Entropia e Ganho de Informação
Para escolher o melhor atributo em cada nó, o algoritmo mede a impureza dos dados. A medida mais usada é a Entropia E(S):
E(S) = - Σ pi · log2(pi)onde pi é a proporção de exemplos da classe i no conjunto S.
Exemplo com 14 registros:
- Alto = 6/14, Baixo = 5/14, Moderado = 3/14
E(S) = -6/14·log2(6/14) - 5/14·log2(5/14) - 3/14·log2(3/14) ≈ 1,53
O Ganho de Informação mede quanto a entropia diminui após dividir pelo atributo. O atributo com maior ganho é escolhido para o nó:
| Atributo | Ganho de Informação |
|---|---|
| História | 0,26 |
| Dívida | 0,06 |
| Garantia | 0,20 |
| Renda | 0,66 |
Como Renda tem o maior ganho, ela forma a raiz. O processo se repete em cada subconjunto para construir os nós internos.
Outros critérios de divisão também são comuns:
- Índice de Gini: mede impureza; valores menores indicam divisões mais puras.
- Índice de Ganho (C4.5): corrige o viés de atributos com muitas categorias.
Algoritmos clássicos: ID3, C4.5 e CART.
Poda da árvore
Árvores muito profundas tendem ao overfitting: memorizam o treino e erram no teste. A poda remove ramos com ganho próximo de zero, reduzindo a complexidade.
- Pré-poda (pruning): interrompe o crescimento com limites de profundidade ou número mínimo de amostras por nó.
- Pós-poda: constrói a árvore completa e remove ramos que não melhoram a validação.
Random Forest
O Random Forest é um ensemble que combina várias árvores de decisão:
- Cada árvore é treinada com um subconjunto aleatório dos dados e dos atributos.
- A classificação final segue o voto da maioria entre as árvores.
- O parâmetro
n_estimatorsdefine quantas árvores serão geradas.
Isso reduz o overfitting e costuma superar uma única árvore em bases maiores.
Vantagens e desvantagens
Vantagens
- Simples de entender e interpretar.
- Não exige escalonamento dos atributos.
- Gera regras explícitas (SE–ENTÃO).
Desvantagens
- Pode gerar árvores muito complexas sem poda.
- Pequenas mudanças nos dados podem alterar a estrutura da árvore.
Implementação em Python (Scikit-learn)
- Classe:
DecisionTreeClassifier(classificação) eDecisionTreeRegressor(regressão). - Treinamento (
fit): constrói a árvore a partir dos dados de treino (X) e das classes (Y). - Previsão (
predict): classifica novas entradas. - Avaliação (
accuracy_score): compara previsões com os valores reais.
Talk is cheap, show me the code:
Bases utilizadas nesta aula (disponíveis no Google Drive): censo.pkl · censoSE.pkl · mb.pkl
EXERCÍCIOS – ÁRVORES DE DECISÃO
from sklearn.tree import DecisionTreeClassifier
import pickle
with open('/content/drive/MyDrive/Colab Notebooks/censo.pkl', 'rb') as f:
X_censo_treinamento, Y_censo_treinamento, X_censo_teste, Y_censo_teste = pickle.load(f)
dt_censo = DecisionTreeClassifier()
dt_censo.fit(X_censo_treinamento, Y_censo_treinamento)
previsao = dt_censo.predict(X_censo_teste)
from sklearn.metrics import accuracy_score #faz a comparação
accuracy_score(Y_censo_teste, previsao)
Agora com a base de dados censoSE.pkl
with open('/content/drive/MyDrive/Colab Notebooks/censoSE.pkl', 'rb') as f:
X_censoSE_treinamento, Y_censoSE_treinamento, X_censoSE_teste, Y_censoSE_teste = pickle.load(f)
dt_censoSE = DecisionTreeClassifier()
dt_censoSE.fit(X_censoSE_treinamento, Y_censoSE_treinamento)
previsaoSE = dt_censoSE.predict(X_censoSE_teste)
accuracy_score(Y_censoSE_teste, previsaoSE)
Agora com RANDOM FOREST
from sklearn.ensemble import RandomForestClassifier
rf_censo = RandomForestClassifier()
rf_censo.fit(X_censo_treinamento, Y_censo_treinamento)
previsao = rf_censo.predict(X_censo_teste)
accuracy_score(Y_censo_teste, previsao)
PARTE II - BASE DE DADOS PREFERÊNCIAS MOUNTAIN x PRAIA
with open('/content/drive/MyDrive/Colab Notebooks/mb(2).pkl', 'rb') as f:
X_censo_treinamento_mb, Y_censo_treinamento_mb, X_censo_teste_mb, Y_censo_teste_mb = pickle.load(f)
rf_censo_mb = RandomForestClassifier()
rf_censo_mb.fit(X_censo_treinamento_mb, Y_censo_treinamento_mb)
previsao_mb = rf_censo_mb.predict(X_censo_teste_mb)
accuracy_score(Y_censo_teste_mb, previsao_mb)
Comparação com estimadores (10, 50 e 100)
rf_mb_10 = RandomForestClassifier(n_estimators=10)
rf_mb_10.fit(X_censo_treinamento_mb, Y_censo_treinamento_mb)
prev_mb_10 = rf_mb_10.predict(X_censo_teste_mb)
accuracy_score(Y_censo_teste_mb, prev_mb_10)
rf_mb_50 = RandomForestClassifier(n_estimators=50)
rf_mb_50.fit(X_censo_treinamento_mb, Y_censo_treinamento_mb)
prev_mb_50 = rf_mb_50.predict(X_censo_teste_mb)
accuracy_score(Y_censo_teste_mb, prev_mb_50)
rf_mb_100 = RandomForestClassifier(n_estimators=100)
rf_mb_100.fit(X_censo_treinamento_mb, Y_censo_treinamento_mb)
prev_mb_100 = rf_mb_100.predict(X_censo_teste_mb)
accuracy_score(Y_censo_teste_mb, prev_mb_100)