25 · AdaBoost: recorrido de implementación paso a paso
Recorre cada paso de AdaBoost en un dataset de 6 puntos — actualizaciones de pesos, pesos del aprendiz y una segunda iteración — luego verifica contra sklearn.
Recorre cada paso de AdaBoost en un dataset de 5 puntos — y la matemática deja de ser misteriosa.
Sin esto:
Sin ver AdaBoost paso a paso, las actualizaciones de pesos y los pesos del aprendiz se sienten arbitrarios.
La lección anterior introdujo AdaBoost conceptualmente. Esta lección lo hace concreto trazando el algoritmo a través de dos iteraciones completas en un pequeño dataset binario de 6 puntos. Después de seguir los números, la regla de actualización ya no parece magia — es solo una reponderación exponencial guiada por la precisión de cada aprendiz.
El algoritmo de 6 pasos (recapitulación)
Dado datos de entrenamiento (xᵢ, yᵢ) con yᵢ ∈ {−1, +1} y T aprendices débiles:
- Inicializa: wᵢ = 1/n para todo i.
- Para t = 1 a T: a. Entrena hₜ en el dataset ponderado. b. Calcula εₜ = Σᵢ wᵢ · 𝟙[hₜ(xᵢ) ≠ yᵢ] c. Calcula αₜ = 0.5 · log((1 − εₜ) / εₜ) d. Actualiza: wᵢ ← wᵢ · exp(−αₜ · yᵢ · hₜ(xᵢ)) e. Normaliza: wᵢ ← wᵢ / Σⱼ wⱼ
- Final: H(x) = sign(Σₜ αₜ · hₜ(x))
Nota: en el algoritmo SAMME de sklearn para clasificación, la codificación de etiquetas usa {0, 1} en lugar de {−1, +1}, pero la lógica de actualización de pesos es equivalente.
¿Por qué actualizaciones exponenciales?
La regla de actualización proviene de minimizar una pérdida exponencial:
L = Σᵢ exp(−yᵢ · F(xᵢ))
donde F(xᵢ) = Σₜ αₜ · hₜ(xᵢ) es la puntuación acumulativa del ensemble. En cada paso, el minimizador codicioso de esta pérdida elige hₜ y αₜ exactamente como se describe arriba. Esta lente de pérdida exponencial es el puente entre AdaBoost y el gradient boosting — en gradient boosting, puedes intercambiar cualquier pérdida diferenciable.
Python (in browser)
Iteración 1 de AdaBoost en detalle completo. Después de ajustar el primer stump, los puntos mal clasificados reciben pesos mayores que 1/n mientras que los puntos correctamente clasificados se reducen por debajo de 1/n. La nueva distribución de pesos le dice al segundo stump exactamente qué ejemplos importan más.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
La iteración 2 entrena en los datos reponderados — el segundo stump se enfoca en los ejemplos que el primero erró. La combinación ponderada de ambos stumps a menudo clasifica correctamente los 6 puntos de entrenamiento, demostrando cómo la reponderación secuencial convierte dos aprendices débiles en un aprendiz fuerte perfecto (en datos de entrenamiento).
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
`ada.estimator_weights_` expone los valores αₜ internos de sklearn. Deben coincidir aproximadamente con los alfas calculados manualmente de las celdas anteriores — cualquier pequeña discrepancia se debe a la convención de codificación de etiquetas de sklearn ({0,1} vs {−1,+1}) y la normalización interna. Las características y umbrales de split del stump confirman que se aprendieron los mismos árboles.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
La derivación de la pérdida exponencial es la razón por la que AdaBoost es el ancestro conceptual de todas las máquinas de gradient boosting: reemplaza la pérdida exponencial con log-loss y obtienes boosting de regresión logística; reemplázala con error cuadrático y obtienes árboles de regresión con gradient boosting. El árbol familiar es una idea elegante iterada.
Después de una iteración de AdaBoost, los ejemplos mal etiquetados tienen pesos que son __ comparados con los correctamente etiquetados.
- La actualización de pesos de AdaBoost wᵢ ← wᵢ · exp(−αₜ · yᵢ · hₜ(xᵢ)) multiplica los pesos de los puntos mal clasificados por exp(+αₜ) > 1 y los pesos de los puntos correctos por exp(−αₜ) < 1 — enfocando precisamente el siguiente stump en los casos difíciles.
- El peso del aprendiz αₜ = 0.5·log((1−εₜ)/εₜ) es grande cuando εₜ es pequeño (stump preciso) y se acerca a 0 cuando εₜ → 0.5 (stump aleatorio). Solo contribuyen los stumps mejores que el azar.
- AdaBoost es descenso de gradiente en pérdida exponencial L = Σᵢ exp(−yᵢ·F(xᵢ)) — el puente conceptual al gradient boosting, donde intercambias cualquier pérdida diferenciable.
- Usa `algorithm='SAMME'` para aprendices base de etiqueta dura sin `predict_proba`; usa `algorithm='SAMME.R'` (default) para actualizaciones basadas en probabilidad cuando el estimador base lo soporta.
- Dos iteraciones de AdaBoost en un dataset de 6 puntos pueden clasificar correctamente todos los ejemplos de entrenamiento — cada stump corrige un subconjunto diferente de errores a través de la reponderación.
El ancestro conceptual de todas las máquinas modernas de gradient boosting. Entender AdaBoost es el prerrequisito para entender los internos de XGBoost.
Si lo quitas: Tratarías XGBoost como una caja negra.