Árvores de decisão: base dos conjuntos
Construa e visualize árvores de decisão com rpart e entenda o compromisso entre viés e variância.
Árvores de decisão: base dos conjuntos é uma aula grátis de R Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de R Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de R Academy inclui 4 aulas no total.
Como as árvores de decisão fazem divisões
Uma árvore de decisão particiona recursivamente o espaço de atributos em regiões retangulares. Em cada nó, o algoritmo pesquisa todos os atributos e todos os pontos de divisão possíveis para encontrar a divisão que melhor separa a variável-alvo. O resultado é uma árvore de regras if-else.
library(rpart)
# Fit a classification tree
tree <- rpart(
Species ~ .,
data = iris,
method = 'class' # use 'anova' for regression
)
print(tree)Critérios de divisão GINI versus entropia
O critério de divisão mede a impureza de um nó. A impureza de Gini mede a probabilidade de classificar incorretamente um elemento escolhido aleatoriamente. A entropia (ganho de informação) mede a redução na desordem da informação. Normalmente, ambos produzem árvores semelhantes; GINI é mais rápido de calcular e é o padrão do rpart.
# Default: Gini impurity (parms = list(split = 'gini'))
tree_gini <- rpart(Species ~ ., data = iris, method = 'class')
# Using information gain (entropy)
tree_entropy <- rpart(
Species ~ ., data = iris, method = 'class',
parms = list(split = 'information')
)
cat('Gini root split:', tree_gini$frame$var[1])
cat('Entropy root split:', tree_entropy$frame$var[1])printcp() — Tabela de complexidade
printcp(tree) imprime a tabela do parâmetro de complexidade (CP). Cada linha mostra o tamanho da árvore (número de divisões), seu erro relativo nos dados de treinamento e seu erro validado cruzadamente (xerror). A tabela de CP é usada para encontrar o nível ideal de poda.
tree <- rpart(medv ~ ., data = MASS::Boston, method = 'anova',
control = rpart.control(minsplit = 5, cp = 0.001))
printcp(tree)
# Identify the CP with minimum cross-validated error
best_cp <- tree$cptable[
which.min(tree$cptable[, 'xerror']),
'CP'
]
cat('Best CP:', best_cp)prune() — Podar a árvore
prune(tree, cp) poda a árvore até o nível de complexidade especificado por cp. A poda evita o sobreajuste ao eliminar ramos que oferecem pouco valor preditivo. A abordagem padrão é encontrar o CP que minimiza o erro de CV e, em seguida, podar a árvore.
best_cp <- tree$cptable[
which.min(tree$cptable[, 'xerror']), 'CP'
]
pruned_tree <- prune(tree, cp = best_cp)
cat('Original tree nodes:', nrow(tree$frame))
cat('Pruned tree nodes:', nrow(pruned_tree$frame))rpart.plot() — Visualizar a árvore
rpart.plot(tree), do pacote rpart.plot, produz uma visualização clara e colorida da árvore de decisão. Cada nó interno mostra a regra de divisão; cada folha mostra a classe prevista e a proporção das amostras de treinamento.
library(rpart.plot)
tree <- rpart(Species ~ ., data = iris, method = 'class')
pruned <- prune(tree, cp = 0.02)
rpart.plot(
pruned,
type = 4, # split labels on branches
extra = 104, # show class + probability
fallen.leaves = TRUE
)Compromisso entre viés e variância
Uma árvore profunda e não podada tem baixo viés (ajusta-se quase perfeitamente aos dados de treinamento), mas alta variância (pequenas mudanças nos dados produzem árvores muito diferentes). Uma árvore rasa ou podada tem viés maior, mas variância menor. A árvore ideal equilibra essas duas fontes de erro.
Métodos de conjunto, como florestas aleatórias e boosting, abordam diretamente esse compromisso.
# Deep tree = low bias, high variance (overfits)
deep_tree <- rpart(medv ~ ., data = MASS::Boston,
control = rpart.control(minsplit = 2, cp = 0))
# Shallow tree = high bias, low variance (underfits)
shallow_tree <- rpart(medv ~ ., data = MASS::Boston,
control = rpart.control(maxdepth = 2))
cat('Deep nodes:', nrow(deep_tree$frame))
cat('Shallow nodes:', nrow(shallow_tree$frame))Sobreajuste de uma árvore de decisão
Uma árvore não podada pode alcançar erro de treinamento zero ao memorizar cada exemplo de treinamento. Quando a mesma árvore é avaliada em dados não vistos, seu desempenho desaba. Esse é o exemplo clássico de sobreajuste no aprendizado supervisionado.
set.seed(42)
train_idx <- sample(nrow(MASS::Boston), 400)
train_bos <- MASS::Boston[train_idx, ]
test_bos <- MASS::Boston[-train_idx, ]
# Fully grown tree
full <- rpart(medv ~ ., data = train_bos,
control = rpart.control(cp = 0, minsplit = 2))
train_pred <- predict(full, train_bos)
test_pred <- predict(full, test_bos)
cat('Train RMSE:', sqrt(mean((train_pred - train_bos$medv)^2)))
cat('Test RMSE:', sqrt(mean((test_pred - test_bos$medv)^2)))Importância das variáveis com rpart
rpart registra variable.importance para cada variável preditora: a melhoria total no critério de divisão atribuível a essa variável em todas as divisões. Isso fornece uma indicação rápida de quais características orientam as decisões do modelo.
tree <- rpart(medv ~ ., data = MASS::Boston, method = 'anova')
# Variable importance (sorted)
imp <- sort(tree$variable.importance, decreasing = TRUE)
print(imp)
# Quick barplot
barplot(imp, las = 2, main = 'Variable Importance',
col = 'steelblue', cex.names = 0.8)Das árvores aos conjuntos
Uma única árvore de decisão é instável: reamostrar os dados produz árvores muito diferentes. Métodos de conjunto exploram essa instabilidade:
- Bagging / Florestas aleatórias: calculam a média de muitas árvores ajustadas a amostras bootstrap.
- Boosting: constroem árvores sequencialmente, cada uma corrigindo os erros da árvore anterior.
- Ambos reduzem a variância e mantêm o poder expressivo das árvores.
# Demonstrating instability of a single tree
set.seed(1); t1 <- rpart(medv ~ ., data = MASS::Boston[sample(506, 400), ])
set.seed(2); t2 <- rpart(medv ~ ., data = MASS::Boston[sample(506, 400), ])
# Root split may differ between trees
cat('Tree 1 root split:', t1$frame$var[1])
cat('Tree 2 root split:', t2$frame$var[1])Parâmetros de controle do rpart
rpart.control() determina como a árvore cresce. Parâmetros principais: cp (penalidade de complexidade), minsplit (número mínimo de observações para tentar uma divisão), minbucket (tamanho mínimo da folha) e maxdepth. Compreender esses parâmetros é essencial para ajustar modelos baseados em árvores.
ctrl <- rpart.control(
cp = 0.005, # complexity penalty
minsplit = 20, # min obs to try a split
minbucket = 7, # min obs in any leaf
maxdepth = 10 # max tree depth
)
tree <- rpart(medv ~ ., data = MASS::Boston,
method = 'anova', control = ctrl)
printcp(tree)Avaliação do desempenho da árvore
Após a poda, avalie a árvore no conjunto de teste separado. Para regressão, calcule RMSE e R-quadrado; para classificação, calcule a acurácia e a matriz de confusão. Compare essas métricas com modelos de referência para compreender o valor oferecido por uma única árvore.
pruned_tree <- prune(tree, cp = best_cp)
test_pred <- predict(pruned_tree, newdata = test_bos)
rmse <- sqrt(mean((test_pred - test_bos$medv)^2))
ss_res <- sum((test_pred - test_bos$medv)^2)
ss_tot <- sum((test_bos$medv - mean(test_bos$medv))^2)
r2 <- 1 - ss_res / ss_tot
cat('RMSE:', round(rmse, 3))
cat('R2:', round(r2, 3))Verificação rápida
Qual afirmação descreve melhor a finalidade de chamar prune(tree, cp = best_cp)?
Recapitulação sobre árvores de decisão
Principais conclusões sobre Árvores de Decisão — Fundamento dos Conjuntos:
- As árvores particionam recursivamente o espaço de características; as divisões usam os critérios de Gini ou entropia.
rpart(y ~ ., data, method)ajusta a árvore;printcp()mostra a tabela de complexidade.- Encontre o CP com o menor erro validado cruzadamente e, em seguida, use
prune(tree, cp). rpart.plot()visualiza a estrutura da árvore.- Árvores profundas sofrem de sobreajuste (baixo viés, alta variância); árvores rasas sofrem de subajuste.
tree$variable.importanceclassifica as variáveis preditoras pela melhoria total nas divisões.- Métodos de conjunto (florestas aleatórias e boosting) superam a instabilidade de uma única árvore.
# Standard rpart workflow
tree <- rpart(y ~ ., data = train, method = 'anova',
control = rpart.control(cp = 0.001))
best_cp <- tree$cptable[which.min(tree$cptable[, 'xerror']), 'CP']
pruned <- prune(tree, cp = best_cp)
test_pred <- predict(pruned, newdata = test)
rmse <- sqrt(mean((test_pred - test$y)^2))
cat('Pruned Tree RMSE:', rmse)Perguntas Frequentes
A aula “Árvores de decisão: base dos conjuntos” é grátis?
Sim — o texto completo de “Árvores de decisão: base dos conjuntos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de R Academy, atualize para CoddyKit PRO. O curso de R Academy inclui 4 aulas no total.
O que vou aprender em “Árvores de decisão: base dos conjuntos”?
Construa e visualize árvores de decisão com rpart e entenda o compromisso entre viés e variância. Você pratica R Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar R Academy?
Nenhuma experiência prévia é necessária. R Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Árvores de decisão: base dos conjuntos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de R Academy?
Sim. Cada aula de R Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Árvores de decisão: base dos conjuntos
- Florestas aleatórias com ranger
- Boosting de gradiente com xgboost
- Importância de atributos e interpretação de modelos