Repensando la codificación por impacto

Hay una entrada mía, esta, que me ronda la cabeza y con la que no sé si estoy completamente de acuerdo. Trata de justificar la codificación por impacto de variables categóricas en modelos lineales (generalizados o no) y cuanto más la releo, menos me la creo. O, más bien, comienzo a cuestinarme más seriamente contextos en los que funciona y contextos en los que no.

Pero comencemos por uno simple: los árboles. Es moda pensar que, dado un predictor categórico, un árbol explora todas las permutaciones posibles de categorías y que por eso algunas implementaciones de, por ejemplo, bosques aleatorios no permiten variables categóricas de más de cierto número no particularmente generoso de niveles.

Esto remite a la página 101 del mítico libro de Breiman et al. donde, al parecer, sugiere que

[f]or categorical predictors that has many levels \{b_1,\dots, b_L\}, one way to reduce the number of splits is to rank the levels as \{b_{l_1}, \dots, b_{l_L}\} according to the occurrence rate within each node p\{1|b_{l_1}\} \le p\{1|b_{l_2}\} \le \dots \le p\{1|b_{l_L}\} and then treat it as an ordinal input.

Es decir, sugiere esencialmente la codificación por impacto. Y diríase que rpart la trae de serie si es que leo correctamente el código en anova.c y gini.c.

Por si acaso, un experimento. Primero, datos:

Con el código anterior construyo una tabla con una variable objetivo numérica, y y dos variables indpendientes: x1 categórica y x2 continua.

Ahora,

Corredlo cuantas veces queráis y veréis: pura diagonal.

Podéis probar con party, pero no tendréis tanta suerte. Es casi diagonal, pero con excepcioncitas (¿qué hará?):

¿A dónde va todo esto? A que en principio, la codificación por importancia no debería afectar a ningún método basado en árboles (¡y eso incluye a muchos de los métodos boost!) y, si lo hace, debería ser más por una cuestión de implementación que por otra cosa.

4 comentarios sobre “Repensando la codificación por impacto

  1. rvaquerizo 11 enero, 2017 9:47

    Curioso:

    library(nnet)
    modelo.0 <- predict(nnet(y ~ x1 + x2, data = dat,size=2, linout=T))
    modelo.1 <- predict(nnet(y ~ x2 + x3, data = dat,size=2, linout=T))
    plot(modelo.0,modelo.1)

  2. Carlos J. Gil Bellosta 11 enero, 2017 16:06

    Haz lm y verás. Ah, y calcula el RMSE. Será todavía más curioso.

  3. rvaquerizo 12 enero, 2017 11:15

    Lo hice y salió lo que me esperaba y lo que tiene que salir, pero con un sencillo árbol una sencilla red neuronal, se me escapa.

  4. Carlos J. Gil Bellosta 12 enero, 2017 19:43

    Hummm… ¿es tan evidente lo que debería salir con lm? A mí me soprendió.

Comenta

Your email address will not be published.

Puedes usar estas etiquetas y atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">