0Pricing
R Academy · Lección

Árboles de decisión: base de los ensamblajes

Construya y visualice árboles de decisión con rpart y comprenda el equilibrio entre sesgo y varianza.

Árboles de decisión: base de los ensamblajes es una lección gratuita de R Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de R Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de R Academy incluye 4 lecciones en total.

Cómo se dividen los árboles de decisión

Un árbol de decisión particiona recursivamente el espacio de características en regiones rectangulares. En cada nodo, el algoritmo busca entre todas las características y todos los puntos de división posibles para encontrar la división que mejor separe la variable objetivo. El resultado es un árbol de reglas if-else.

library(rpart)

# Fit a classification tree
tree <- rpart(
  Species ~ .,
  data   = iris,
  method = 'class'  # use 'anova' for regression
)

print(tree)

Criterios de división: GINI frente a entropía

El criterio de división mide la impureza de un nodo. La impureza de Gini mide la probabilidad de clasificar incorrectamente un elemento elegido al azar. La entropía (ganancia de información) mide la reducción del desorden informativo. Ambos suelen producir árboles similares; Gini es más rápido de calcular y es el valor predeterminado de 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() — Tabla de complejidad

printcp(tree) imprime la tabla del parámetro de complejidad (CP). Cada fila muestra el tamaño del árbol (número de divisiones), su error relativo en los datos de entrenamiento y su error validado mediante validación cruzada (xerror). La tabla de CP se utiliza para encontrar el nivel óptimo 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 el árbol

prune(tree, cp) poda el árbol hasta el nivel de complejidad especificado por cp. La poda evita el sobreajuste al colapsar las ramas que aportan poco valor predictivo. El enfoque estándar consiste en encontrar el CP que minimiza el error de validación cruzada y, a continuación, podar el árbol.

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 el árbol

rpart.plot(tree), del paquete rpart.plot, produce una visualización limpia y coloreada del árbol de decisión. Cada nodo interno muestra la regla de división y cada hoja muestra la clase predicha y la proporción de muestras de entrenamiento.

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
)

Compensación entre sesgo y varianza

Un árbol profundo y sin podar tiene bajo sesgo (se ajusta casi perfectamente a los datos de entrenamiento), pero alta varianza (pequeños cambios en los datos producen árboles muy diferentes). Un árbol poco profundo o podado tiene mayor sesgo, pero menor varianza. El árbol óptimo equilibra estas dos fuentes de error.

Los métodos de ensamblado, como los bosques aleatorios y el boosting, abordan directamente esta compensación.

# 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 un árbol de decisión

Un árbol sin podar puede alcanzar un error de entrenamiento igual a cero al memorizar cada ejemplo de entrenamiento. Cuando se evalúa el mismo árbol con datos no observados, su rendimiento se desploma. Este es el ejemplo clásico de sobreajuste en el aprendizaje supervisado.

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)))

Importancia de las variables con rpart

rpart registra variable.importance para cada predictor: la mejora total del criterio de división atribuible a esa variable en todas las divisiones. Esto proporciona una indicación rápida de qué características impulsan las decisiones del 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)

De los árboles a los ensamblados

Un único árbol de decisión es inestable: al volver a muestrear los datos se obtienen árboles muy diferentes. Los métodos de ensamblado aprovechan esta inestabilidad:

  • Bagging / bosques aleatorios: promedian muchos árboles entrenados con muestras bootstrap.
  • Boosting: construye árboles secuencialmente, de modo que cada uno corrige los errores del árbol anterior.
  • Ambos reducen la varianza y mantienen la capacidad expresiva de los árboles.
# 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 control de rpart

rpart.control() regula cómo crece el árbol. Parámetros clave: cp (penalización de complejidad), minsplit (número mínimo de observaciones para intentar una división), minbucket (tamaño mínimo de una hoja) y maxdepth. Comprender estos parámetros es esencial para ajustar modelos basados en árboles.

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)

Evaluar el rendimiento del árbol

Después de podar el árbol, evalúelo con el conjunto de prueba reservado. Para regresión, calcule RMSE y R cuadrado; para clasificación, calcule la exactitud y la matriz de confusión. Compare estas métricas con las de modelos de referencia para comprender el valor que aporta un único árbol.

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))

Comprobación rápida

¿Qué afirmación describe mejor el propósito de llamar a prune(tree, cp = best_cp)?

Repaso de los árboles de decisión

Ideas clave de Árboles de decisión — Fundamento de los ensamblados:

  • Los árboles particionan recursivamente el espacio de características; las divisiones utilizan criterios de Gini o entropía.
  • rpart(y ~ ., data, method) ajusta el árbol; printcp() muestra la tabla de complejidad.
  • Encuentre el CP con el menor error de validación cruzada y, a continuación, use prune(tree, cp).
  • rpart.plot() visualiza la estructura del árbol.
  • Los árboles profundos sufren sobreajuste (bajo sesgo, alta varianza); los árboles poco profundos sufren subajuste.
  • tree$variable.importance clasifica los predictores según su mejora total en las divisiones.
  • Los métodos de ensamblado (bosques aleatorios y boosting) superan la inestabilidad de un único árbol.
# 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)

Preguntas frecuentes

¿La lección «Árboles de decisión: base de los ensamblajes» es gratis?

Sí — el texto completo de «Árboles de decisión: base de los ensamblajes» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de R Academy, actualiza a CoddyKit PRO. El curso de R Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Árboles de decisión: base de los ensamblajes»?

Construya y visualice árboles de decisión con rpart y comprenda el equilibrio entre sesgo y varianza. Practicas R Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar R Academy?

No se requiere experiencia previa. R Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Árboles de decisión: base de los ensamblajes»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de R Academy?

Sí. Cada lección de R Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Árboles de decisión: base de los ensamblajes
  2. Bosques aleatorios con ranger
  3. Gradient boosting con xgboost
  4. Importancia de las características e interpretación de modelos
← Volver a R Academy