Curso / fast.ai / Lección 6
● piloto de formato

fast.ai · Practical Deep Learning for Coders · Lección 6

Random forests: 20 años de vigencia sin necesitar un gradiente

Ningún .backward(), ningún learning rate, ningún epoch en esta lección — random forests construyen un modelo entero sin gradient descent, y siguen siendo, dos décadas después de su invención, un baseline casi imbatible para datos tabulares.

1. El dataset: subasta de bulldozers

El caso de estudio es la competencia Kaggle Blue Book for Bulldozers: predecir SalePrice de maquinaria pesada usada, a partir de uso, tipo de equipo y configuración. Como Kaggle evalúa con RMSLE (root mean squared log error), se trabaja directamente con el logaritmo del precio — así el RMSE normal sobre esa columna transformada ya da la métrica de la competencia.

Dos detalles de preprocesamiento específicos de datos tabulares que no aparecen con imágenes o texto:

  • Categorías ordinales: una columna como ProductSize (S/M/L) tiene un orden natural que Pandas no conoce por defecto — hay que declararlo explícitamente (cat.set_categories(sizes, ordered=True)) para que el árbol pueda usar ese orden en sus splits en vez de un orden arbitrario de aparición.
  • Fechas: una fecha no es solo un número ordinal — contiene señal cualitativa (día de la semana, si es feriado, mes). add_datepart() descompone una columna de fecha en Year, Month, Week, Dayofweek, Is_month_end, etc., dándole al árbol variables nuevas sobre las que hacer preguntas binarias sensatas.

La validación se define por tiempo, no al azar: entrenamiento hasta cierta fecha, validación después — porque es una serie temporal, y una validación aleatoria filtraría información del futuro al entrenamiento de forma artificial.

2. Cómo construye un split un árbol de decisión

Un árbol de decisión hace preguntas binarias sucesivas sobre una variable. El algoritmo de construcción es completamente greedy: en cada nodo, recorre cada columna, prueba cada punto de corte posible, y para cada uno calcula qué tan bien el promedio del target en los dos grupos resultantes predice los valores reales. Elige el split que más reduce el error entre todas las columnas y valores probados, y repite recursivamente en cada subgrupo.

Sin restricciones, sklearn sigue partiendo hasta que cada hoja tiene un solo dato — memoriza el training set en vez de generalizar, el equivalente tabular de overfitting (análogo a jugar "20 preguntas" con más de 20 objetos posibles: al final cada pregunta identifica un único objeto, sin haber aprendido ningún patrón general). El remedio simple es min_samples_leaf=25: exigir un mínimo de registros por hoja, lo cual reduce drásticamente el error de validación aunque el de entrenamiento suba un poco.

3. Random forest: bagging de árboles no correlacionados

Un random forest entrena muchos árboles, cada uno sobre (a) un subconjunto aleatorio de filas (bootstrap, con reemplazo) y (b) en cada split, un subconjunto aleatorio de columnas candidatas. La predicción final es simplemente el promedio de todos los árboles.

RandomForestRegressor(
    n_jobs=-1, n_estimators=40,
    max_samples=200_000, max_features=0.5,
    min_samples_leaf=5, oob_score=True).fit(xs, y)

La razón por la que esto funciona no es intuición vaga sino una idea estadística precisa: cada árbol individual comete errores, pero esos errores no están correlacionados entre árboles distintos, porque cada uno vio un subconjunto distinto de filas y columnas. El promedio de errores no correlacionados tiende a cero a medida que se agregan más árboles, mientras que el bias de cada árbol individual no cambia — por eso promediar reduce varianza sin aumentar bias. Random forests son notablemente insensibles a sus hiperparámetros: n_estimators más alto casi nunca perjudica (a diferencia de más epochs en una red, que sí puede sobreajustar).

4. Out-of-bag error: validación gratis

Como cada árbol se entrena solo con un subconjunto bootstrap de filas, las filas que un árbol dado no vio son, para ese árbol específico, un conjunto de validación gratuito. El out-of-bag (OOB) error calcula, para cada fila del training set, la predicción promediando únicamente los árboles que no la vieron durante su entrenamiento — permite detectar overfitting sin sacrificar datos reales para un validation set separado, especialmente valioso con datasets chicos.

5. Interpretar el bosque: feature importance y partial dependence

Acá está la ventaja real de random forests frente a redes neuronales en datos tabulares: son mucho más fáciles de interpretar, con dos herramientas concretas.

Feature importance (m.feature_importances_): para cada split de cada árbol se registra qué variable se usó y cuánto mejoró el error, ponderado por cuántas filas afectó; se suma todo por variable y se normaliza. Permite eliminar variables poco importantes sin perder precisión — un modelo más simple e igual de bueno.

Partial dependence responde una pregunta distinta: "¿cómo cambiaría la predicción si solo variara esta columna, dejando todo lo demás constante?" No alcanza con promediar por valor real de la variable (eso mezcla el efecto de otras variables correlacionadas); en cambio, se reemplaza artificialmente esa columna con cada valor posible para todas las filas y se promedia la predicción resultante. En el dataset de bulldozers esto reveló una relación casi exponencial entre año de fabricación y precio, y en un caso alertó sobre una fuga de datos (data leakage) al mostrar que el grupo "dato faltante" de una columna tenía un precio anómalamente bajo — una señal de que esa "ausencia" en realidad codificaba información del futuro.

📜 Una tercera herramienta: tree interpreter

Para explicar una predicción individual (no el modelo en general), el libro usa un tree interpreter: descompone esa predicción puntual en un bias (la predicción del nodo raíz, la media global) más la contribution de cada variable a lo largo del camino recorrido en cada árbol, sumado sobre todo el bosque — visualizado como un waterfall chart que muestra cómo cada variable empuja la predicción hacia arriba o abajo desde el bias hasta el valor final.

6. El problema de extrapolación

Un árbol (y por lo tanto un random forest) predice siempre el promedio de las hojas que vio en entrenamiento — nunca puede predecir un valor fuera del rango del target que observó. Con una relación creciente en el tiempo (inflación, tendencia de precios), al testear fuera del rango de entrenamiento las predicciones quedan sistemáticamente por debajo de la tendencia real. Esto es crítico en datos con tendencia temporal fuerte como precios de subasta.

Para detectar este tipo de domain shift entre entrenamiento y validación, una técnica simple: se entrena un random forest cuyo target es "¿esta fila es de validación o de entrenamiento?" — las variables con mayor importancia en ese modelo auxiliar son las que difieren sistemáticamente entre ambos conjuntos, y conviene tratarlas con cuidado (o directamente eliminarlas) en el modelo real.

7. Random forests vs. redes neuronales

Random forestRed neuronal
PreprocesamientoMínimo — tolera categóricas y outliers sin normalizarRequiere normalización cuidadosa
TuningMuy poco, insensible a hiperparámetrosSensible — learning rate, arquitectura, regularización
InterpretabilidadAlta: feature importance, partial dependence, tree interpreterBaja sin herramientas adicionales
Categóricas de alta cardinalidadDébilFuerte, vía entity embeddings
Extrapolación (tendencias)Mala — predice siempre dentro del rango vistoPuede generalizar mejor con la variable temporal como continua

El "mejor de ambos mundos" que sugiere el libro: entrenar embeddings categóricos con una red neuronal y usarlos como input numérico —en vez de las columnas categóricas crudas— para un random forest u otro método clásico. El paper de referencia (Guo & Berkhahn) mostró mejoras dramáticas en KNN, random forest y GBM al reemplazar categorías crudas por embeddings aprendidos, sin necesitar la red neuronal en el momento de inferencia. Ensamblar (promediar) las predicciones de un random forest y una red neuronal entrenados por separado también suele superar a cualquiera de los dos solo.

8. Resumen

  1. Un árbol de decisión elige, en cada nodo, el split que más reduce el error entre todas las variables y valores posibles — sin gradiente de por medio.
  2. Random forest = bagging: muchos árboles sobre subconjuntos aleatorios de filas y columnas, promediados. Funciona porque sus errores individuales no están correlacionados.
  3. OOB error da una validación casi gratis, usando las filas que cada árbol no vio.
  4. Feature importance y partial dependence son las dos herramientas de interpretación que hacen que random forests sigan siendo preferidos cuando explicar el modelo importa tanto como predecir bien.
  5. Random forests no pueden extrapolar fuera del rango de valores vistos — un problema real con datos que tienen tendencia temporal.
  6. Elegir entre random forest y red neuronal no es una decisión ideológica: depende de cardinalidad de categóricas, necesidad de extrapolar, y cuánto importa poder explicar cada predicción.