Machine Learning — Módulo 7: Gradient Boosting — XGBoost y LightGBM, el caballo de batalla
Séptimo módulo del Curso de Machine Learning: qué es el boosting y en qué se diferencia del bagging, por qué XGBoost y LightGBM dominan el ML tabular y ganan Kaggle, los hiperparámetros clave y el early stopping, con código real.
☰ Índice del contenido
En el Módulo 6 vimos el Random Forest: cientos de árboles entrenados en paralelo, cada uno sobre datos distintos, votando todos por igual. Es robusto y difícil de arruinar. Pero hay una forma más astuta de combinar árboles, y da modelos aún más precisos. En vez de entrenarlos en paralelo e ignorando lo que hacen los demás, ¿y si los entrenáramos en fila, y cada árbol nuevo se dedicara a arreglar exactamente los errores que dejó el anterior? Esa idea se llama boosting, y su implementación estrella — XGBoost — es, sin exagerar, el modelo que más competencias de datos tabulares ha ganado en la última década. Este es el caballo de batalla del machine learning clásico.
La tesis del módulo
El bagging junta árboles que trabajan en paralelo y por su cuenta; el boosting los pone en fila, y cada árbol se dedica a corregir el error del anterior. Esa corrección secuencial, paso a paso, es lo que hace del gradient boosting el modelo más preciso para datos tabulares — y también el más fácil de sobreajustar si no lo tuneas.
Boosting: corregir errores en cadena
El boosting (glosamos: entrenar modelos en secuencia, donde cada uno se enfoca en corregir los errores que cometió el conjunto de los anteriores) es la idea opuesta al bagging del módulo pasado.
La intuición del gradient boosting con árboles va así:
- Empiezas con una predicción tonta (por ejemplo, el promedio de todos los valores).
- Calculas el error de esa predicción: cuánto le erraste a cada ejemplo. A esos errores se les llama residuales (glosamos: lo que falta para llegar a la respuesta correcta, la diferencia entre lo real y lo predicho).
- Entrenas un árbol chico que no predice la respuesta, sino el residual: aprende dónde y cuánto te estás equivocando.
- Le sumas ese árbol a tu predicción (multiplicado por un factor pequeño). Ahora yerras un poco menos.
- Vuelves al paso 2 con los nuevos errores, ahora más chicos, y repites cientos de veces.
Cada árbol es un pequeño arreglo sobre lo que quedó mal. La suma de muchos arreglos pequeños termina siendo un modelo muy afinado.
predicción inicial (promedio)
│
▼
┌─────────┐ residual ┌─────────┐
│ árbol 1 │ ───────────► │ árbol 2 │
└─────────┘ (el error └────┬────┘
que quedó) │ residual
▼
┌─────────┐
│ árbol 3 │ ... cientos
└────┬────┘
▼
predicción final = suma de todos los árboles
La diferencia con el Random Forest es de fondo: allá los árboles no se hablaban (paralelo); acá cada árbol depende del anterior (secuencial). Por eso el boosting no se paraleliza tan fácil entre árboles, pero suele ganar en precisión.
XGBoost y LightGBM: por qué dominan
Gradient boosting como idea existe hace rato, pero dos implementaciones lo llevaron a otro nivel y se comieron el mundo del ML tabular:
- XGBoost (eXtreme Gradient Boosting): el que popularizó la técnica en Kaggle a partir de 2015. Rápido, con regularización incorporada y muy afinado. Durante años, casi toda competencia tabular la ganaba un XGBoost.
- LightGBM (de Microsoft): más nuevo, típicamente más rápido y con menor uso de memoria, sobre todo en datasets grandes, gracias a trucos como crecer los árboles por hoja (leaf-wise) y agrupar los valores en bins (histogramas).
Ambos comparten API con scikit-learn, así que se usan casi igual que un Random Forest. ¿Por qué dominan el ML tabular (tablas de filas y columnas, lo típico de una empresa: clientes, transacciones, sensores)? Porque capturan interacciones complejas entre variables, manejan bien datos heterogéneos, y con buen tuning exprimen la última gota de precisión. En datos tabulares, un gradient boosting bien ajustado suele ganarle incluso a las redes neuronales.
Hiperparámetros clave
Aquí está la contracara: el gradient boosting hay que tunearlo. Los que más importan:
| Hiperparámetro | Qué controla | Efecto |
|---|---|---|
n_estimators | Cuántos árboles (rondas) | Más = más capacidad, más riesgo de overfit |
learning_rate | Cuánto suma cada árbol | Bajo = aprende lento pero generaliza mejor |
max_depth | Profundidad de cada árbol | Bajo (3–8) para árboles “débiles” a propósito |
subsample | Fracción de filas por árbol | <1 agrega azar, reduce overfit |
colsample_bytree | Fracción de columnas por árbol | Similar, diversifica |
La pareja que más importa es learning_rate con n_estimators, y funcionan en tensión: un learning_rate bajo hace que cada árbol corrija poquito, así que necesitas más árboles para llegar. La receta clásica es poner un learning_rate chico (0.05–0.1) y muchos árboles, pero dejar que el early stopping decida cuántos usar de verdad.
El early stopping (glosamos: detener el entrenamiento automáticamente cuando el error en un conjunto de validación deja de mejorar, para no seguir agregando árboles que solo memorizan) es la herramienta que te salva del overfitting sin adivinar el n_estimators a mano.
XGBoost en código
Con xgboost.XGBClassifier. Fíjate en el early stopping usando un set de validación.
from xgboost import XGBClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X, y = load_breast_cancer(return_X_y=True)
# separamos train, validación (para early stopping) y test
X_temp, X_test, y_temp, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(
X_temp, y_temp, test_size=0.2, random_state=42
)
modelo = XGBClassifier(
n_estimators=1000, # techo alto: el early stopping decidirá
learning_rate=0.05, # aprende de a poco
max_depth=4, # árboles chicos a propósito
subsample=0.8, # 80% de las filas por árbol
colsample_bytree=0.8, # 80% de las columnas por árbol
early_stopping_rounds=50, # corta si 50 rondas sin mejorar
eval_metric="logloss",
random_state=42,
)
# el eval_set le da el conjunto que vigila para el early stopping
modelo.fit(X_train, y_train, eval_set=[(X_val, y_val)], verbose=False)
print("mejor ronda:", modelo.best_iteration) # cuántos árboles usó
print("test:", accuracy_score(y_test, modelo.predict(X_test)))
La versión LightGBM es casi idéntica: from lightgbm import LGBMClassifier y LGBMClassifier(n_estimators=1000, learning_rate=0.05, ...). Misma lógica de fit y predict; la única diferencia de forma es que el early stopping va como callback en el fit — fit(X_train, y_train, eval_set=[(X_val, y_val)], callbacks=[lightgbm.early_stopping(50)]) — en vez de como parámetro del constructor. Aprender uno es aprender el otro.
Ojo: el early stopping necesita un conjunto de validación separado del test. Si validas sobre el test, estás filtrando información y tu evaluación final deja de ser honesta — un tipo de data leakage que veremos en el módulo 8.
Bagging vs boosting, cara a cara
| Bagging (Random Forest) | Boosting (XGBoost) | |
|---|---|---|
| Cómo entrena | Árboles en paralelo, independientes | Árboles en secuencia, dependientes |
| Cada árbol | Profundo, completo | Chico, débil a propósito |
| Qué combate | Sobre todo la varianza | Varianza y sesgo |
| Precisión típica | Muy buena, robusta | La más alta con buen tuning |
| Tuning | Poco: anda casi solo | Bastante: sensible a los hiperparámetros |
| Riesgo | Difícil de arruinar | Overfittea fácil si te pasas |
| Paraleliza árboles | Sí, trivial | No entre árboles (sí por dentro) |
En una frase: Random Forest es el modelo seguro que anda bien sin pensar mucho; XGBoost es el modelo campeón que, bien tuneado, gana — pero exige que lo tunees.
Errores comunes
learning_ratealto con muchos árboles. Es la receta del overfitting: cada árbol corrige demasiado y el modelo memoriza. Baja ellearning_ratey usa early stopping.- Fijar
n_estimatorsa mano y rezar. Pon un techo alto y deja que el early stopping elija. Adivinar el número es trabajo perdido. - Validar el early stopping sobre el conjunto de test. Contamina tu evaluación (data leakage). Usa un set de validación aparte.
- Árboles muy profundos. En boosting los árboles deben ser débiles (
max_depth3–8). Árboles profundos + boosting = overfitting rápido. - Creer que XGBoost siempre le gana al Random Forest. Sin tunear, un Random Forest suele ganarle a un XGBoost mal configurado. La ventaja del boosting aparece con tuning.
La frase para llevarse
“El bagging vota en paralelo; el boosting corrige en fila. Por eso XGBoost es tan preciso — y por eso, si no lo frenas con learning_rate bajo y early stopping, memoriza.”
Qué viene
Ya tienes en el bolsillo los modelos que ganan competencias. Pero hay un secreto incómodo: en el mundo real, la diferencia entre un modelo mediocre y uno excelente casi nunca está en elegir XGBoost sobre Random Forest — está en los datos que le das. En el Módulo 8: feature engineering y pipelines veremos cómo transformar datos crudos en variables que el modelo pueda aprovechar, y cómo empaquetar todo ese preprocesamiento en un Pipeline de scikit-learn para que no se te cuele un data leakage.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.