
Árbol de decisión explicado: 15 nodos que se leen, 8.524 hojas que memorizan
Qué es un árbol de decisión, cómo elige sus preguntas y cuándo memoriza, medido con clima diario de siete ciudades de Chile entre 1984 y 2026. Sin límite de profundidad acertó todo lo que vio y en días nuevos bajó a AUC 0,689; con profundidad 7, elegida en validación, llegó a 0,862.
Un árbol de decisión sin límite de profundidad acertó todos los días con que aprendió: AUC 1,000 sobre 74.145 filas. En los días de 2016-2026, que no había visto, bajó a 0,689, peor que una regresión logística. El mismo algoritmo, detenido en la séptima pregunta, llegó a 0,862.
Es la quinta entrega de la serie, con los mismos datos diarios de NASA POWER de siete ciudades de Chile que usé en Random Forest, regresión lineal, K-Means y regresión logística. La pregunta es la de siempre: ¿lloverá al menos 1 mm mañana? Entrené con 1984-2012, elegí cada parámetro con un período de validación y evalué en 2016-2026, en un contenedor con 8 CPU.
¿Qué es un árbol de decisión?
Un árbol de decisión es una lista de preguntas encadenadas. La primera pregunta divide todos los días en dos grupos; cada grupo recibe su propia pregunta, y así hasta llegar a una hoja. La hoja entrega la fracción de días con lluvia que terminaron ahí en el entrenamiento, que se usa como probabilidad.
Cada pregunta compara una sola variable con un umbral: «¿llovió hoy 0,44 mm o menos?». Para elegirla, el algoritmo prueba cada variable con los cortes candidatos que salen de sus valores observados y se queda con la división que deja los dos grupos más puros, medido con el índice de Gini. Es la idea de CART, el método que Breiman, Friedman, Olshen y Stone publicaron en 1984, y la que implementa scikit-learn.
desliza el árbol hacia el lado →
- lluvia hoy 3,15 > 0,44 → no
- lluvia hoy 3,15 ≤ 3,54 → sí
- viento N-S (cos) 0,19 > -0,15 → no
probabilidad 53 % · llovió · acierta
- lluvia hoy 0,46 > 0,44 → no
- lluvia hoy 0,46 ≤ 3,54 → sí
- viento N-S (cos) 0,35 > -0,15 → no
probabilidad 53 % · llovió · acierta
- lluvia hoy 0,05 ≤ 0,44 → sí
- latitud -36,83 > -37,79 → no
- lluvia hoy 0,05 > 0,04 → no
probabilidad 12 % · no llovió · acierta
- lluvia hoy 0,92 > 0,44 → no
- lluvia hoy 0,92 ≤ 3,54 → sí
- viento N-S (cos) 0,30 > -0,15 → no
probabilidad 53 % · no llovió · falla
Cada día recorre tres preguntas: con este árbol, el 38 % de los días de 2016-2026 termina en la hoja de días secos de Concepción al norte (lluvia en el 3 % de sus días de entrenamiento). AUC en 2016-2026: 0,831. El cuarto día muestra su límite: 0,92 mm de lluvia y un componente norte-sur del viento sobre -0,15 lo mandan a una hoja con 53 % de lluvia, y no llovió.
Con profundidad 3, el árbol tiene 15 nodos y cabe en una página. Su primera pregunta es la lluvia de hoy. Si llovió poco, la segunda separa por latitud las ciudades desde Temuco al sur de las que están de Concepción al norte; si llovió, pregunta cuánto. Las últimas preguntas miran la lluvia otra vez o el componente norte-sur de la dirección del viento. Con esas tres preguntas llegó a AUC 0,831 en 2016-2026.
La lectura también muestra el límite. El cuarto día del ejemplo, en Punta Arenas, tuvo 0,92 mm y un viento que lo mandó a una hoja con 53 % de lluvia. No llovió. Ocho hojas son ocho probabilidades posibles, y todos los días de una hoja reciben la misma.
Mientras más pregunta, más memoriza
Nada obliga al árbol a detenerse en tres preguntas. Si lo dejo seguir, divide hasta que cada hoja tenga días de una sola clase.
hojas (escala log.)
- días con que aprendió
- validación
- 2016-2026
profundidad 1: 2 hojas · AUC entrenamiento 0,776 · validación 0,731 · 2016-2026 0,741 · pérdida log. 0,423
profundidad 2: 4 hojas · AUC entrenamiento 0,833 · validación 0,790 · 2016-2026 0,803 · pérdida log. 0,399
profundidad 3: 8 hojas · AUC entrenamiento 0,855 · validación 0,826 · 2016-2026 0,831 · pérdida log. 0,380
profundidad 4: 16 hojas · AUC entrenamiento 0,866 · validación 0,842 · 2016-2026 0,843 · pérdida log. 0,371
profundidad 5: 32 hojas · AUC entrenamiento 0,875 · validación 0,853 · 2016-2026 0,855 · pérdida log. 0,361
profundidad 6: 64 hojas · AUC entrenamiento 0,883 · validación 0,859 · 2016-2026 0,860 · pérdida log. 0,359
profundidad 7: 127 hojas · AUC entrenamiento 0,890 · validación 0,863 · 2016-2026 0,862 · pérdida log. 0,362
profundidad 8: 245 hojas · AUC entrenamiento 0,898 · validación 0,862 · 2016-2026 0,862 · pérdida log. 0,370
profundidad 9: 461 hojas · AUC entrenamiento 0,907 · validación 0,857 · 2016-2026 0,853 · pérdida log. 0,412
profundidad 10: 804 hojas · AUC entrenamiento 0,918 · validación 0,846 · 2016-2026 0,839 · pérdida log. 0,518
profundidad 11: 1.283 hojas · AUC entrenamiento 0,930 · validación 0,827 · 2016-2026 0,822 · pérdida log. 0,659
profundidad 12: 1.879 hojas · AUC entrenamiento 0,943 · validación 0,800 · 2016-2026 0,802 · pérdida log. 0,841
profundidad 13: 2.568 hojas · AUC entrenamiento 0,956 · validación 0,780 · 2016-2026 0,777 · pérdida log. 1,067
profundidad 14: 3.367 hojas · AUC entrenamiento 0,967 · validación 0,766 · 2016-2026 0,748 · pérdida log. 1,349
profundidad 15: 4.131 hojas · AUC entrenamiento 0,977 · validación 0,736 · 2016-2026 0,727 · pérdida log. 1,577
profundidad 16: 4.903 hojas · AUC entrenamiento 0,985 · validación 0,724 · 2016-2026 0,708 · pérdida log. 1,834
profundidad 17: 5.590 hojas · AUC entrenamiento 0,990 · validación 0,711 · 2016-2026 0,695 · pérdida log. 2,066
profundidad 18: 6.233 hojas · AUC entrenamiento 0,994 · validación 0,704 · 2016-2026 0,702 · pérdida log. 2,297
profundidad 19: 6.808 hojas · AUC entrenamiento 0,997 · validación 0,695 · 2016-2026 0,694 · pérdida log. 2,517
profundidad 20: 7.280 hojas · AUC entrenamiento 0,998 · validación 0,687 · 2016-2026 0,695 · pérdida log. 2,654
profundidad sin límite: 8.524 hojas · AUC entrenamiento 1,000 · validación 0,700 · 2016-2026 0,689 · pérdida log. 3,107
La validación tocó su máximo en profundidad 7 (127 hojas, AUC 0,863); en 2016-2026 ese árbol dio 0,862. Sin límite de profundidad creció hasta 8.524 hojas, llegó a AUC 1,000 en los días con que aprendió y cayó a 0,689 en 2016-2026, con una pérdida logarítmica de 3,107: las hojas puras dan probabilidades de 0 o 1, y un 0 equivocado cuesta mucho.
Con cada nivel extra, el AUC en los días de entrenamiento sube. En validación sube hasta la profundidad 7 y después cae. Elegí la profundidad con esa curva, sin mirar 2016-2026: el árbol de profundidad 7 tiene 127 hojas y en 2016-2026 dio AUC 0,862.
Sin límite, el árbol llegó a profundidad 31 y 8.524 hojas, en promedio menos de nueve días de entrenamiento por hoja. Muchas hojas son puras, así que devuelven probabilidades de 0 o de 1. Cuando se equivocan, se equivocan con certeza total, y eso se ve en la pérdida logarítmica: 3,11 contra 0,36 del árbol de profundidad 7.
Detener la profundidad no es la única forma de frenarlo. Probé dos más, elegidas también con validación.
- 10,700 · 8.524 hojas
- 50,767 · 5.047 hojas
- 200,839 · 1.889 hojas
- 500,857 · 892 hojas
- 1000,864 · 478 hojas
- 2000,863 · 256 hojas
- 5000,860 · 110 hojas
Ajuste elegido, en 2016-2026: 478 hojas, AUC 0,863, pérdida log. 0,384.
- 0.0e+00,767 · 4.519 hojas
- 4.7e-60,743 · 4.101 hojas
- 1.2e-50,764 · 3.554 hojas
- 1.7e-50,775 · 3.060 hojas
- 2.5e-50,796 · 2.513 hojas
- 3.3e-50,813 · 1.880 hojas
- 4.2e-50,834 · 1.201 hojas
- 5.9e-50,856 · 458 hojas
- 7.7e-50,863 · 205 hojas
Ajuste elegido, en 2016-2026: 167 hojas, AUC 0,861, pérdida log. 0,358.
- 20,790 · 4 hojas
- 40,842 · 16 hojas
- 60,859 · 64 hojas
- 70,863 · 127 hojas
- 80,862 · 245 hojas
- 100,846 · 804 hojas
- 140,766 · 3.367 hojas
- ∞0,700 · 8.524 hojas
Ajuste elegido, en 2016-2026: 127 hojas, AUC 0,862, pérdida log. 0,362.
Los tres frenos quedan con AUC entre 0,861 y 0,863 en 2016-2026, con 127 a 478 hojas. Lo que importa es frenar; cuál freno, aquí importó poco.
Exigir al menos 100 días por hoja dejó 478 hojas y AUC 0,863 en 2016-2026. La poda por costo-complejidad, que recorta ramas que aportan poco (partiendo de un árbol con al menos 5 días por hoja), dejó 167 hojas y AUC 0,861. Las tres terminaron en el mismo lugar.
El criterio para medir pureza importó poco. Con profundidad 8, Gini dio AUC 0,8615 y la entropía 0,8655, con la misma variable en la raíz.
La raíz se sostiene; las predicciones se mueven
Los árboles tienen fama de inestables: cambias un poco los datos y cambia el árbol entero. Lo medí de dos maneras distintas, porque no es lo mismo que cambie la estructura a que cambien las respuestas.
primera pregunta en 50 de 50 remuestreos: lluvia hoy ≤ umbral (mm)
rango en los remuestreos por bloques: de 0,40 a 0,71 mm
días sin acuerdo entre lluvia y no lluvia
La estructura de arriba casi no se mueve: la lluvia de hoy fue siempre la primera pregunta. Las predicciones sí: con la profundidad elegida en validación, los 50 árboles remuestreados no coincidieron en el 34,8 % de los días de 2016-2026, contra el 17,6 % con profundidad 3. Promediar ese ruido es lo que hace un bosque aleatorio.
Remuestreé los datos 50 veces por bloques de ciudad y año, para que los días vecinos no quedaran repartidos como si fueran independientes. La primera pregunta fue la lluvia de hoy en los 50 casos; el umbral se movió entre 0,40 y 0,71 mm. Entrenando un árbol por cada bloque consecutivo de hasta tres años (el último, 2011-2012, tiene dos), pasó lo mismo: siempre la lluvia de hoy, con umbrales de 0,39 a 0,97 mm.
Las predicciones sí se movieron. Los 50 árboles de profundidad 7 no coincidieron en la etiqueta de lluvia o no lluvia en el 34,8 % de los días de 2016-2026; los de profundidad 3, en el 17,6 %. Con otra medida, no comparable con esas, dos árboles sin límite entrenados con mitades al azar de las filas discreparon en el 24,1 % de los días. Un bosque aleatorio existe justamente para promediar esas diferencias, como se vio en el post de Random Forest.
¿Qué variables importan? Permuté familias de variables juntas en el período de validación, para que una variable correlacionada no tapara a otra. Desordenar la lluvia de hoy y de ayer bajó el AUC del árbol de profundidad 7 en 0,133; la estación y la latitud, en 0,059; el viento, en 0,056; la presión, en 0,029. Humedad y punto de rocío juntos apenas lo movieron (0,002): las predicciones de este árbol casi no dependieron de ellas. Eso describe este árbol, no qué causa la lluvia.
Un árbol de regresión predice a escalones
Un árbol también puede predecir números. Cada hoja devuelve el promedio de sus días, así que la predicción es una escalera.
La profundidad 2 tiene 4 escalones y erra en 2016-2026 por 2,50 °C en promedio; la 4, 16 escalones y 1,89 °C; la 8, 252 escalones y 1,85 °C. Pasados los 39,5 °C del día más caluroso que vio, la predicción ya no sube; en el post de Random Forest medí el mismo techo en un bosque.
Para predecir la máxima de mañana con la de hoy, un árbol de profundidad 2 tiene 4 escalones y erra por 2,50 °C en promedio en 2016-2026; con profundidad 4, 16 escalones y 1,89 °C; con profundidad 8, 252 escalones y 1,85 °C. Más allá de los 39,5 °C del día más caluroso de entrenamiento, la predicción es plana: un árbol no extrapola. En el post de Random Forest medí ese mismo techo en un bosque.
Qué tan bien calibra y cuánto cuesta
Cada hoja entrega una sola probabilidad, así que el árbol da solo 118 valores distintos. En promedio predijo 23,4 % de lluvia y llovió en el 20,3 % de los días. Solo el tramo más bajo coincide (13.554 días bajo 10 %, lluvia en el 3,5 %); de ahí para arriba la predicción queda sobre lo observado: en los días a los que dio entre 50 y 60 %, llovió en el 44 %.
El árbol de profundidad 7 da 118 probabilidades distintas. Predijo en promedio 23,4 % de lluvia y llovió en el 20,3 % de los días de 2016-2026. Salvo en el tramo más bajo, predijo más lluvia de la que cayó: en los días a los que dio entre 50 y 60 %, llovió en el 44 %.
A la mitad del tiempo real.
Serializados con pickle, el árbol ocupa 21,6 KB, la logística 1,8 KB y el bosque 124 MB. Es tamaño en disco, no memoria en uso.
El árbol quedó entre la logística y el bosque en casi todo: ordenó mejor que la logística y peor que el bosque, entrenó 7 veces más lento que la logística y 67 veces más rápido que el bosque. Su ventaja es otra: se puede leer, y se puede reescribir.
Dónde vive un árbol de decisión en un sistema real
el árbol de profundidad 3 exportado como reglas
|--- precip <= 0.44
| |--- lat <= -37.79
| | |--- wind_cos <= -0.09
| | | |--- class: 0.0
| | |--- wind_cos > -0.09
| | | |--- class: 0.0
| |--- lat > -37.79
| | |--- precip <= 0.03
| | | |--- class: 0.0
| | |--- precip > 0.03
| | | |--- class: 0.0
|--- precip > 0.44
| |--- precip <= 3.53
| | |--- wind_cos <= -0.15
| | | |--- class: 0.0
| | |--- wind_cos > -0.15
| | | |--- class: 1.0
| |--- precip > 3.53
| | |--- wind_cos <= 0.76
| | | |--- class: 1.0
| | |--- wind_cos > 0.76
| | | |--- class: 1.0
Medido con un hilo: el árbol de profundidad 7 entrena en 0,37 s y serializado ocupa 21,6 KB; la regresión logística, 0,05 s y 1,8 KB; el bosque de 200 árboles, 24,7 s y 124 MB. Reescrito como if/else en Python puro, el árbol de profundidad 3 puntúa un día en 0,0042 ms, contra 0,253 ms pasando por scikit-learn, con el mismo resultado en los primeros 2.000 días.
- Reglas exportadas. Un árbol chico se traduce a if/else o a un
CASEde SQL y corre donde no hay librerías de machine learning. Reescrito en Python puro, el de profundidad 3 puntuó un día en 0,0044 ms, contra 0,25 ms pasando por scikit-learn. - Triage explicable. Cuando alguien tiene que justificar una decisión, el camino por el árbol es la justificación: tres preguntas, tres respuestas.
- Pieza base de otros modelos. Los bosques aleatorios y el boosting combinan muchos árboles; entender uno es entender la pieza que repiten.
- Exploración. Un árbol de profundidad 2 o 3 muestra rápido qué variable separa mejor, antes de entrenar algo más grande.
Cuándo lo elegiría: cuando la regla tiene que poder leerse o exportarse, o como primer vistazo a los datos. Cuándo no: cuando importa la probabilidad fina o la estabilidad de cada predicción, donde aquí un bosque de 200 árboles rindió más, ni cuando hay que extrapolar.
Fuentes
- Breiman, L., Friedman, J. H., Olshen, R. A. y Stone, C. J. (1984). Classification and Regression Trees. Wadsworth. Reedición: Routledge, 2017. DOI 10.1201/9781315139470.
- Quinlan, J. R. (1986). «Induction of decision trees». Machine Learning, 1(1), 81–106. DOI 10.1007/BF00116251.
- scikit-learn, árboles de decisión,
DecisionTreeClassifiery poda por costo-complejidad. - NASA POWER, Daily API y fuentes de datos.
Comentarios
Todavía no hay comentarios. El primero es tuyo.