Random Forests

"Generalized random forests": una introducción

Los generalized random forests (GRF en lo sucesivo) han cobrado cierta relevancia recientemente porque una de sus potenciales variantes son los llamados causal forests: RRFF adaptados para medir el tamaño de una intervención causal.

Lo que voy a contar aquí es un resumen de lo que aprendí echándole un vistazo al artículo relevante de la cosa.

[Nota: voy a simplificar un poco con respecto a lo que aparecen en el artículo por aligerar la introducción; recuérdese: este es un mapa del territorio y el territorio en sí mismo.]

¿Cómo aleatorizan las columnas los RRFF?: un experimento mental y una coda histórica

I. El experimento mental

Tienes una variable binaria y y 100 variables predictoras de las cuales 99 son puro ruido y la última es igual a y. En código,

n <- 1000
y <- as.factor(rbinom(n, 1, .4))
x <- matrix(rnorm(n*100), n, 100)
x[,100] <- y

El objetivo consiste, obviamente, en predecir y en función de x.

II. RRFF

Los RRFF, como es bien sabido, son conjuntos de n árboles construidos sobre los mismos datos. La predicción final se realiza por consenso. Obviamente, si todos los árboles se construyen sobre las mismas filas y las mismas columnas, el resultado es equivalente a construir un único árbol. Por eso, aleatorizan. Aleatorizan filas y columnas. Voy a obviar el asunto de las filas y me voy a concentrar en el de las columnas.

¿Quién inventó los "random forests"?

[Este artículo tiene una corrección —tachado en el texto que sigue— posterior a la fecha de publicación original. Véase la entrada "¿Cómo aleatorizan las columnas los RRFF?: un experimento mental y una coda histórica" para obtener más información al respecto.]

Si hacemos caso, por ejemplo, a la gente que estaba allí entonces, la que estaba al día de todo lo que se publicaba en la época, la que conocía personalmente a los presuntos implicados y la que seguramente había tenido constancia previa de la idea en alguna pizarra o en la servilleta de una cafetería, fue Leo Breiman en 2001. Así nos lo cuentan, por ejemplo, Hastie et al. al principio del capítulo 15 de The Elements of Statistical Learning (2ª edición):

Interacciones y selección de modelos

Desafortunadamente, el concepto de interacción, muy habitual en modelización estadística, no ha penetrado la literatura del llamado ML. Esencialmente, el concepto de interacción recoge el hecho de que un fenómeno puede tener un efecto distinto en subpoblaciones distintas que se identifican por un nivel en una variable categórica.

El modelo lineal clásico,

$$ y \sim x_1 + x_2 + \dots$$

no tiene en cuenta las interacciones (aunque extensiones suyas, sí, por supuesto).

"Para razonar rigurosamente bajo incertidumbre hay que recurrir al lenguaje de la probabilidad"

Así arranca este artículo, que presenta una extensión de XGBoost para predicciones probabilísticas. Es decir, un paquete que promete no solo una estimación del valor central de la predicción sino de su distribución.

La versión equivalente de lo anterior en el mundo de los random forests está descrito aquí, disponible aquí y mucho me temo que muy pronto voy a poder contar por aquí si está a la altura de las expectativas.

ranger (o cómo el truco para hacerlo rápido es hacerlo, subrepticiamente, mal)

ranger llegó para hacerlo mismo que [randomForest](https://cran.r-project.org/package=randomForest), solo que más deprisa y usando menos memoria.

Lo que no nos contaron es que lo consiguió haciendo trampas. En particular, en el tratamiento de las variables categóricas. Si no andas con cuidado, las considera ordenadas (y ordenadas alfabéticamente).

[Si te da igual ocho que ochenta, no te preocupará el asunto. Tranquilo: hay muchos como tú.]

El diagnóstico dado (por eso lo omito) está contado aquí. La solución, a pesar de la aparente pretensión de los autores, no.

gam vs rrff (y, en general, modelos generativos vs cajas negras)

Para modelizar una serie temporal, y simplificándolo mucho, ¿gam o rrff? Como todo, depende. El otro día oí de un caso en el que los segundos vencían a los primeros claramente. Natural.

Hay contextos con una estructura matemática clara y potente. En particular, muchos en los que trabajo actualmente. ¿Para qué usar una herramienta genérica cuando cuento con una específica? Esos datos, mis datos, exigen estructura matemática.

Luego hay otros casos en los que uno se lanza al río. Luego uno siempre quiere invertir el proceso y ver qué carajos está ocurriendo con los datos (véase esto).

Selección de variables con bosques aleatorios

R

Desde el principio de mis tiempos he seleccionado variables relevantes como subproducto de los árboles primero y de los bosques aleatorios después. Cierto que he hecho casi inconfesables incursiones en los métodos stepwise, pero han sido marginales y anecdóticas.

La idea es casi siempre la misma, se haga a mano o con ayuda de paquetes ad hoc: las variables importantes tienden a aparecer en el modelo (o submodelos), las otras no. Todo se reduce a contar y ponderar. Hay que discurrir un poco más cuando se sospecha (o consta) que existen variables altamente correlacionadas.

¿Se puede explicar la predicción de un modelo de caja negra?

Imaginemos un banco que construye modelos para determinar si se concede o no un crédito. Este banco tiene varias opciones para crear el modelo. Sin embargo, en algunos países el regulador exige que el banco pueda explicar el motivo de la denegación de un crédito cuando un cliente lo solicite.

Esa restricción impediría potencialmente usar modelos de caja negra como el que construyo a continuación:

library(randomForest)

raw <- read.table("http://archive.ics.uci.edu/ml/machine-learning-databases/credit-screening/crx.data",
    sep = ",", na.strings = "?")

dat <- raw
dat$V14 <- dat$V6 <- NULL    # me da igual
dat <- na.omit(dat)          # ídem

modelo <- randomForest(V16 ~ ., data = dat)

Fijémonos en el sujeto 100, a quien se le deniega el crédito (suponiendo, ¡mal hecho!, que el punto de corte de la probabilidad para concederlo es el 50%), y la variable $V8$. Podemos ver cuál sería el score del cliente modificando esa variable entre su valor real y el máximo del rango dejando las demás tal cual:

Modelos mixtos por doquier

Los códigos postales, por ejemplo, son un problema a la hora de crear modelos predictivos: son variables categóricas con demasiados niveles. Así, por ejemplo, los bosques aleatorios de R solo admiten variables categóricas con no más de 32 niveles.

Hay trucos de todo tipo para mitigar el problema. Hace un año, Jorge Ayuso me puso sobre la pista de uno de los que tiene más recorrido. Consiste en [su versión más simplificada en]:

Victoria o diferencia de puntos, ahora con "random forests"

Después de hablar con tirios y troyanos sobre mi entrada sobre los efectos de binarizar una variable objetivo continua, he decidido tomarme la justicia por mi mano y llamar a la caballería. Es decir, utilizar random forests.

Aquí va el código:

library(randomForest)

set.seed(1234)

my.coefs <- -2:2
n <- 200
train.n <- floor(2*n/3)

test.error <- function(){
  X <- matrix(rnorm(n*5), n, 5)
  Y <- 0.2 + X %*% my.coefs + rnorm(n)
  Y.bin <- factor(Y>0)

  train <- sample(1:n, train.n)

  X <- as.data.frame(X)
  X$Y <- Y

  modelo <- randomForest(Y ~ .,
    data = X[train,])
  pred <- predict(modelo, X[-train,])
  error.cont <- length(pred) -
    sum(diag(table(pred >0, Y[-train]>0)))

  X$Y <- Y.bin
  modelo <- randomForest(Y ~ .,
    data = X[train,])
  pred <- predict(modelo, X[-train,])
  error.bin <- length(pred) -
    sum(diag(table(pred, Y.bin[-train])))

  data.frame(error.cont = error.cont,
    error.bin = error.bin)
}

errores <- do.call(rbind,
  replicate(1000, test.error(), simplify = F))

sapply(errores, fivenum)

El resultado, si te interesa, en tu pantalla.

En recuerdo de Leo Breiman

Recomiendo leer esto. Es un artículo que repasa la labor de Leo Breiman, pionero en esa nueva forma de plantear el análisis de datos que acabó convirtiéndose en la minería de datos y de algunos de los algoritmos y métodos más comunes que conforman la caja de herramientas de quienes lo practican hoy en día. Entre ellos, los árboles de decisión y de regresión y los random forests.

Así comienza el artículo:

How many theoretical probabilists walk away from a tenured faculty position at a top university and set out to make their living as consultants? How many applied consultants get hired into senior faculty positions in first-rate research universities? How many professors with a fine reputation in their field, establish an equally fine reputation in a different field, after retirement? Leo Breiman did all of these things and more.

Algoritmos genéticos para la caracterización de máximos en random forests

R

En minería de datos se buscan modelos que permitan hacer predicciones acerca del comportamiento de los sujetos del estudio. Pero, típicamente, cuanto más complejas son las técnicas, menos intuición ofrecen acerca del porqué de la predicción, pierden inteligibilidad. Existe una omnipresente tensión entre inteligibilidad (una propiedad altamente deseable, incluso, en ocasiones, por requisito legal) y precisión.

Un modelo puede resumir mejor o peor una colección enorme de observaciones, pero en ocasiones los mismos modelos son demasiado complejos o herméticos como para ofrecer una interpretación plausible de los datos: ¿qué caracteriza a las observaciones para las que mi modelo predice los valores más altos (o bajos)?