¿Cómo medir / clasificar "importancia variable" cuando se utiliza CART? (específicamente usando {rpart} de R)

27

Cuando se construye un modelo CART (específicamente un árbol de clasificación) usando rpart (en R), a menudo es interesante saber cuál es la importancia de las diversas variables introducidas en el modelo.

Por lo tanto, mi pregunta es: ¿Qué medidas comunes existen para clasificar / medir la importancia variable de las variables participantes en un modelo CART? ¿Y cómo se puede calcular esto usando R (por ejemplo, cuando se usa el paquete rpart)

Por ejemplo, aquí hay un código ficticio, creado para que pueda mostrar sus soluciones en él. Este ejemplo está estructurado para que quede claro que las variables x1 y x2 son "importantes", mientras que (en cierto sentido) x1 es más importante que x2 (ya que x1 debería aplicarse a más casos, por lo tanto, influye más en la estructura de los datos, entonces x2).

set.seed(31431)
n <- 400
x1 <- rnorm(n)
x2 <- rnorm(n)
x3 <- rnorm(n)
x4 <- rnorm(n)
x5 <- rnorm(n)

X <- data.frame(x1,x2,x3,x4,x5)

y <- sample(letters[1:4], n, T)
y <- ifelse(X[,2] < -1 , "b", y)
y <- ifelse(X[,1] < 0 , "a", y)

require(rpart)
fit <- rpart(y~., X)
plot(fit); text(fit)

info.gain.rpart(fit) # your function - telling us on each variable how important it is

(las referencias son siempre bienvenidas)

Tal Galili
fuente
¿Cómo difiere esta pregunta de stats.stackexchange.com/questions/5443/… ?
steffen
Esa pregunta se refiere a saber qué predictor era relevante para un valor categórico particular de la variable dependiente. Esta pregunta es más amplia (importancia / clasificación variable sin detectar a qué valor nominal afecta). Desde esa pregunta no fue respondida pensé que vale la pena expresarlo de una manera más general, con la esperanza de que alguien pueda ser capaz de ayuda ...
Tal Galili

Respuestas:

43

La importancia variable generalmente se puede calcular en función de la reducción correspondiente de la precisión predictiva cuando se elimina el predictor de interés (con una técnica de permutación, como en Random Forest) o alguna medida de disminución de la impureza del nodo, pero consulte (1) para obtener una descripción general de Métodos disponibles. Una alternativa obvia a CART es RF, por supuesto ( randomForest , pero vea también party ). Con RF, el índice de importancia de Gini se define como la disminución promedio de Gini en las impurezas de los nodos sobre todos los árboles en el bosque (se deduce del hecho de que el índice de impurezas de Gini para un nodo padre dado es mayor que el valor de esa medida para sus dos nodos hijos, ver p. ej. (2)).

Sé que Carolin Strobl y coll. han contribuido con una gran cantidad de estudios de simulación y experimentales sobre la importancia variable (condicional) en RF y CART (por ejemplo, (3-4), pero hay muchos otros, o su tesis, Problemas estadísticos en el aprendizaje automático - Hacia una selección dividida confiable y Medidas de importancia variable ).

Que yo sepa, el paquete de caret (5) solo considera una función de pérdida para el caso de regresión (es decir, error cuadrático medio). Tal vez se agregará en un futuro próximo (de todos modos, un ejemplo con un caso de clasificación de k-NN está disponible en la ayuda en línea para dotPlot).

Sin embargo, Noel M O'Boyle parece tener algún código R para la importancia Variable en CART .

Referencias

  1. Sandri y Zuccolotto. Un algoritmo de corrección de sesgo para la medida de importancia variable de Gini en árboles de clasificación . 2008
  2. Izenman Técnicas estadísticas modernas multivariantes . Springer 2008
  3. Strobl, Hothorn y Zeilis. ¡Fiesta! . R Journal 2009 1/2
  4. Strobl, Boulesteix, Kneib, Augustin y Zeilis. Importancia variable condicional para bosques aleatorios . BMC Bioinformatics 2008, 9: 307
  5. Kuhn Construyendo modelos predictivos en R usando el paquete caret . JSS 2008 28 (5)
chl
fuente
1
Realmente, merece muchos más votos de los que tiene.
Matt Parker el
+1 por la gran respuesta. Y la actualización para los recién llegados (como yo) importance()en randomForest tiene una importancia variable individual con una disminución promedio en la precisión y una disminución media de gini.
Zhubarb
3

La siguiente función (del paquete Caret) se puede usar para evaluar la importancia variable en los árboles rpart. Corregí un error en la función Caret cuando este único nodo raíz en el árbol.

varImp <- function(object, surrogates = FALSE, competes = TRUE, ...)
  {
tmp <- rownames(object$splits)

 allVars <- colnames(attributes(object$terms)$factors)
if(is.null(tmp))
  {
  out<-NULL
    zeros <- data.frame(x = rep(0, length(allVars)),
                        Variable = allVars)
    out <- rbind(out, zeros)
  }

else {

rownames(object$splits) <- 1:nrow(object$splits)
splits <- data.frame(object$splits)
    splits$var <- tmp
splits$type <- ""

frame <- as.data.frame(object$frame)
    index <- 0
    for(i in 1:nrow(frame))
      {
        if(frame$var[i] != "<leaf>")
          {
            index <- index + 1
            splits$type[index] <- "primary"
            if(frame$ncompete[i] > 0)
              {
                for(j in 1:frame$ncompete[i])
                  {
                    index <- index + 1
                    splits$type[index] <- "competing"
                  }
              }
            if(frame$nsurrogate[i] > 0)
              {
                for(j in 1:frame$nsurrogate[i])
                  {
                    index <- index + 1
                    splits$type[index] <- "surrogate"
                  }
              }
          }
      }
    splits$var <- factor(as.character(splits$var))
    if(!surrogates) splits <- subset(splits, type != "surrogate")
    if(!competes) splits <- subset(splits, type != "competing")
    out <- aggregate(splits$improve,
                 list(Variable = splits$var),
                 sum,
                 na.rm = TRUE)

allVars <- colnames(attributes(object$terms)$factors)
if(!all(allVars %in% out$Variable))
      {
        missingVars <- allVars[!(allVars %in% out$Variable)]
        zeros <- data.frame(x = rep(0, length(missingVars)),
                            Variable = missingVars)
        out <- rbind(out, zeros)
      }
    }
    out2 <- data.frame(Overall = out$x)
rownames(out2) <- out$Variable
out2

}

El siguiente código r producirá puntajes de importancia para un "ajuste" del árbol rpart

 varImp(fit)
inundaciones
fuente
1
Gracias. ¿Reportaste el error a Max? (el mantenedor del paquete caret)
Tal Galili
1

Creo que chl respondió bastante bien la primera parte:

¿Qué medidas comunes existen para clasificar / medir la importancia variable de las variables participantes en un modelo CART?

Con respecto a la segunda parte de su pregunta:

¿Y cómo se puede calcular esto usando R (por ejemplo, cuando se usa el paquete rpart)

Puede encontrar la importancia variable usando rpart usando el resumen (ajuste). Esto genera la importancia variable entre varias otras cosas. Puede leer más sobre esto aquí: https://cran.r-project.org/web/packages/rpart/rpart.pdf . Consulte la página 25.

Jash Shah
fuente
0

names(result) muestra variable.importance

result$variable.importance ¿debería ayudar?

shubh
fuente
3
Creo que la pregunta tiene más que ver con las ventajas o la popularidad de algunas medidas de importancia variable que con la forma de imprimir las disponibles en R para un método en particular.
chl