ML Atlas

Machine learning desde cero · Lección 5.3 · 28 de 33 lecciones listas · 12 min

Gradient boosting: árboles que corrigen errores

En pocas palabras

Cada árbol corrige los errores de los anteriores. Tras 200 árboles con paso 1 el entrenamiento baja a 2287 y la prueba sube a 5944, peor que una recta (4095).

Calentamiento Dos preguntas de lecciones anteriores. Un minuto, y no bloquea la lección.
De la lección 5.2: Ensambles: por qué muchos árboles superan a uno Aumentas un random forest de 300 a 3000 árboles. ¿Cuál es el efecto más probable?

Ver la respuesta

Respuesta correcta: La exactitud queda casi igual, pero el entrenamiento tarda mucho más

Cuando la parte independiente del error ya se ha promediado, más árboles añaden cálculo, pero poca exactitud y ninguna memorización extra.

De la lección 5.1: Árboles de decisión: veinte preguntas con datos ¿Cómo elige un árbol de decisión la pregunta en cada paso?

Ver la respuesta

Respuesta correcta: Prueba las preguntas posibles y se queda con la que deja los grupos más puros

La búsqueda voraz evalúa las divisiones candidatas y se queda con la que más reduce la impureza, por ejemplo el índice de Gini.

En la lección 5.2 un bosque aleatorio promediaba muchos árboles construidos de forma independiente, y añadir árboles no hacía daño. El gradient boosting construye los árboles uno tras otro. Cada árbol nuevo aprende los residuos, es decir, cuánto se sigue equivocando el conjunto de árboles anterior en cada ejemplo. Suma su corrección multiplicada por la tasa de aprendizaje, un número entre 0 y 1. Los árboles son pequeños, a menudo con una sola pregunta (un tocón) o con tres. En tablas de tamaño medio, los modelos de árboles, con el boosting a la cabeza, suelen ganar a las redes neuronales (Grinsztajn et al., 2022). Pero el boosting tiene un rasgo que el bosque no tiene: las correcciones posteriores pueden empezar a corregir ruido.

Predice y comprueba Predecimos la progresión de la diabetes al cabo de un año solo a partir del IMC. Una regresión lineal tiene en los pacientes de prueba un error cuadrático medio (MSE) de 4095. El gradient boosting añade árboles con tres preguntas como mucho, cada uno con el paso completo 1. Tras 200 árboles el MSE de entrenamiento baja de 3713 (un árbol) a 2287. ¿Qué pasa en la prueba?
¿Qué tan seguro estás?

Experimento interactivo

Este experimento interactivo funciona en un navegador con JavaScript activado. El texto que lo rodea describe lo que muestra.

Ver la respuesta

Respuesta correcta: Peor que la recta, porque los árboles posteriores empezaron a corregir el ruido

Peor: el MSE de prueba sube a 5944, aunque el de entrenamiento bajó a 2287. Cada árbol aprende los residuos de los anteriores, y tras unas cuantas rondas en los residuos queda sobre todo el ruido aleatorio de pacientes concretos. En otras 20 particiones, 200 árboles así siempre pierden contra la recta en la prueba.

Prueba

  • Empieza donde abre el lab: paso 1, profundidad 2, 200 árboles. ¿Cuántos escalones tiene la función del conjunto y qué tan separadas están las curvas de entrenamiento y validación?
  • Baja el número de árboles. ¿Con cuántos árboles es más bajo el error de validación? Solo entonces mira la prueba.
  • Baja el paso a 0,1 y toma un tocón. ¿Cómo se ve ahora la curva de validación a medida que se añaden árboles?
  • Compara la mejor validación del boosting con la línea discontinua de la recta. ¿Cuál está más abajo?

Cuando lo hayas comprobado en el lab, pongamos nombre a lo que ves.

La idea en palabras sencillas

El primer árbol hace unas cuantas preguntas sobre el IMC y predice la progresión media de la enfermedad en cada grupo. Se equivoca, así que calculamos los residuos: cuánto falta hasta la verdad en cada paciente. El segundo árbol ya no predice la enfermedad, sino esos residuos. Su resultado multiplicado por la tasa de aprendizaje se suma al primero. El tercer árbol aprende lo que queda tras los dos, y así sucesivamente. El conjunto crece a base de pequeñas correcciones.

Al principio las correcciones capturan el patrón real: más IMC, más progresión. Una vez capturado, en los residuos queda sobre todo ruido, las desviaciones aleatorias de los pacientes con los que aprende el modelo. Los árboles posteriores aprenden justo eso. Con paso 1 y árboles de tres preguntas, el entrenamiento baja de 3713 con un árbol a 2287 con 200, mientras la prueba sube de 4319 a 5944. Es sobreajuste, como con un árbol demasiado profundo, solo que esta vez crece con el número de árboles. En un bosque aleatorio cada árbol ve los datos por su cuenta y el promedio anula sus errores. En el boosting cada árbol se suma a los errores de los anteriores.

Por eso el número de árboles, el paso y la profundidad los elige la validación, no la prueba. El lab calcula el error de validación con una validación cruzada de 5 partes dentro de los 309 pacientes de entrenamiento. Lo más bajo es un tocón con paso 0,1 y 50 árboles: validación 3960. La recta obtiene 3823 en la misma validación, así que solo con el IMC gana la recta. La prueba lo confirma solo al final: 4154 para el boosting frente a 4095 para la recta.

Jak to policzono
  • Datos: Diabetes (Efron et al., 2004), en scikit-learn con licencia BSD-3-Clause. 442 pacientes, 10 medidas, progresión de la enfermedad al año. Tomamos solo el IMC. Partición: 309 pacientes para aprender, 133 para la prueba.
  • Modelo: gradient boosting con árboles de regresión de profundidad 1 o 2 solo sobre el IMC, pérdida cuadrática, paso de 0,05 a 1, hasta 200 árboles; una regresión lineal sobre el IMC para comparar. Los números del lab coinciden con GradientBoostingRegressor de scikit-learn.
  • Validación: validación cruzada de 5 partes dentro de los 309 pacientes de entrenamiento, las mismas partes para cada ajuste y para la recta.

Por qué funciona

El residuo y − F(x) es la dirección en la que hay que mover la predicción para que el error cuadrático baje lo más rápido posible. Cada árbol da, por tanto, un pequeño paso de descenso de gradiente, solo que en el espacio de las funciones y no de los pesos. De ahí el nombre: gradient boosting. Un paso pequeño significa que un árbol corrige solo parte del error. Hacen falta más árboles, pero cada uno añade menos ruido. En otras 20 particiones, 200 árboles de tres preguntas con paso 0,1 tienen en la prueba un MSE de 3747 a 4802, siempre menos que los mismos árboles con paso 1 (de 4617 a 6983).

Esto no significa que el boosting siempre gane a una recta. Solo con el IMC, la relación con la enfermedad es casi lineal, y los árboles solo pueden imitar una recta con escalones. En otras 20 particiones, el boosting elegido por validación gana a la recta en la prueba en 7. El boosting brilla donde hay muchas variables y su efecto es de umbral y enredado. Entonces los árboles posteriores capturan dependencias que una recta no puede expresar.

Un pariente más antiguo, AdaBoost, en lugar de residuos cambia los pesos de los ejemplos. Los ejemplos en los que el conjunto se equivoca pesan más en la siguiente ronda. En la entrada del Atlas sobre AdaBoost, el primer tocón con tumores de mama clasifica mal el 10,3% de los tumores de entrenamiento. Antes de la segunda ronda esos tumores mal clasificados llevan exactamente el 50% del peso total, así que el segundo tocón aprende sobre todo de ellos.

Un error frecuente

Verdadero o falso: «más rondas de boosting siempre ayudan». Falso. Cada ronda mejora el entrenamiento, pero la prueba solo hasta cierto punto. Con paso 1 y árboles de tres preguntas, en validación lo mejor es 1 árbol, y 200 árboles dan 5944 en la prueba en vez de 4319. En el código de abajo la prueba sube de 4079 tras un árbol a 6437 tras 200, mientras el entrenamiento baja de 3827 a 2044.

El camino seguro es un paso pequeño, muchos árboles y la parada temprana de la lección 3.6: deja de añadir árboles cuando el error de validación deja de bajar. En el código de abajo la parada se queda con 83 de 1000 árboles.

Test

Tres preguntas para comprobar lo aprendido. Elige una respuesta o despliega la solución bajo cada pregunta. Con el teclado: las flechas eligen, Enter o Espacio confirma.

1. ¿Qué aprende el segundo árbol en el gradient boosting?
Ver la respuesta

Respuesta correcta: Los residuos del primer árbol, es decir, cuánto se sigue equivocando este

Cada árbol siguiente recibe los residuos del conjunto anterior y suma una corrección por la tasa de aprendizaje. Las muestras aleatorias y los árboles independientes son el bosque aleatorio.

2. Paso 1, árboles de tres preguntas: el entrenamiento baja de 3713 a 2287, la prueba sube de 4319 a 5944. ¿Qué ocurre?
Ver la respuesta

Respuesta correcta: Sobreajuste: los árboles tardíos corrigen el ruido de los pacientes

Una vez capturado el patrón real, en los residuos queda ruido. Los árboles posteriores lo aprenden, y en pacientes nuevos ese ruido no se repite.

3. Verdadero o falso: «más rondas de boosting siempre ayudan».
Ver la respuesta

Respuesta correcta: Falso, porque pasado un tiempo las rondas extra solo corrigen el ruido restante

El entrenamiento baja con cada ronda, la prueba no. Con paso 1, en validación lo mejor es 1 árbol, y 200 árboles dan 5944 en la prueba.

Ideas clave

  • El gradient boosting construye árboles por turnos: cada uno aprende los residuos del conjunto anterior y suma una corrección por la tasa de aprendizaje.
  • A diferencia del bosque, el boosting puede sobreajustarse: con paso 1 la prueba sube de 4319 a 5944 mientras el entrenamiento baja.
  • Elige el número de árboles, el paso y la profundidad por validación o parada temprana, nunca por la prueba.
  • El boosting no siempre gana a una recta: solo con el IMC la recta obtiene 3823 en validación y el mejor boosting 3960.

Más a fondo: fórmula, código, práctica

Las matemáticas

El conjunto tras m árboles: F_m(x) = F_{m−1}(x) + η · h_m(x), donde F_0 es la media de y en el entrenamiento, η es la tasa de aprendizaje y el árbol h_m ajusta los residuos r_i = y_i − F_{m−1}(x_i).

Para la pérdida cuadrática L = (y − F)² / 2 la derivada respecto a F es −(y − F), así que el residuo es menos el gradiente de la pérdida. Cada árbol da un paso de descenso de gradiente en el espacio de las funciones. En AdaBoost el peso de un ejemplo mal clasificado se multiplica por e^α, donde α = ln((1 − ε) / ε) y ε es el error ponderado del tocón.

En código (Python)

El mismo experimento en scikit-learn: 200 árboles con paso 1, etapa por etapa, luego tres ajustes comparados con validación cruzada dentro del entrenamiento, y parada temprana.

from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error as mse

X, y = load_diabetes(return_X_y=True, as_frame=True)
x_tr, x_te, y_tr, y_te = train_test_split(X[["bmi"]], y, test_size=0.3, random_state=0)
big = GradientBoostingRegressor(n_estimators=200, max_depth=2, learning_rate=1.0, random_state=0).fit(x_tr, y_tr)
for m, (p_tr, p_te) in enumerate(zip(big.staged_predict(x_tr), big.staged_predict(x_te)), start=1):
    if m in (1, 10, 50, 200):
        print(f"step 1, depth 2, {m:3d} trees: train MSE {mse(y_tr, p_tr):.0f}, test MSE {mse(y_te, p_te):.0f}")
cv = KFold(5, shuffle=True, random_state=0)
models = {"line": LinearRegression(), "step 1, 200 trees": big,
          "step 0.1, 50 stumps": GradientBoostingRegressor(n_estimators=50, max_depth=1, learning_rate=0.1, random_state=0)}
for name, model in models.items():
    val = -cross_val_score(model, x_tr, y_tr, cv=cv, scoring="neg_mean_squared_error").mean()  # validación solo dentro del entrenamiento
    print(f"{name}: validation MSE {val:.0f}")
stop = GradientBoostingRegressor(n_estimators=1000, max_depth=1, learning_rate=0.1, validation_fraction=0.2, n_iter_no_change=10, random_state=0).fit(x_tr, y_tr)
print(f"early stopping kept {stop.n_estimators_} of 1000 trees; test MSE {mse(y_te, stop.predict(x_te)):.0f}, line {mse(y_te, models['line'].fit(x_tr, y_tr).predict(x_te)):.0f}")

Resultado

step 1, depth 2,   1 trees: train MSE 3827, test MSE 4079
step 1, depth 2,  10 trees: train MSE 3013, test MSE 4798
step 1, depth 2,  50 trees: train MSE 2122, test MSE 6233
step 1, depth 2, 200 trees: train MSE 2044, test MSE 6437
line: validation MSE 3956
step 1, 200 trees: validation MSE 5728
step 0.1, 50 stumps: validation MSE 4030
early stopping kept 83 of 1000 trees; test MSE 4062, line 3921

La partición es distinta de la del lab, así que los números también son algo distintos. La imagen es la misma: con paso 1 el entrenamiento baja de 3827 a 2044 y la prueba sube de 4079 a 6437. En validación la recta (3956) gana al paso pequeño (4030), y 200 árboles con paso 1 quedan los peores (5728). La parada temprana se queda con 83 árboles.

Para profesionales
  • En scikit-learn: HistGradientBoostingRegressor y HistGradientBoostingClassifier son rápidos en tablas grandes, manejan solos los datos faltantes y tienen parada temprana (early_stopping). Fuera de scikit-learn: XGBoost, LightGBM, CatBoost.
  • Un inicio típico: paso de 0,05–0,1, árboles poco profundos, muchos árboles y parada temprana en validación. Ajusta la profundidad y el paso con validación cruzada (lección 3.5) y deja la prueba para el final.
  • El boosting es más sensible al ruido en las etiquetas que un bosque: cada ejemplo erróneo se queda en los residuos y los árboles posteriores intentan corregirlo. Con datos sucios ayudan un paso menor, el muestreo de filas (subsample) y una regularización más fuerte de los árboles.
  • Antes de recurrir al boosting, mide un punto de referencia sencillo (lección 1.3). Cuando la relación es casi lineal, una recta puede ganar.

Profundiza en el Atlas

Entradas de la enciclopedia sobre las ideas de esta lección: