Importancia variable de GLMNET

18

Estoy buscando usar el lazo como método para seleccionar características y ajustar un modelo predictivo con un objetivo binario. A continuación se muestra un código con el que estaba jugando para probar el método con regresión logística regularizada.

Mi pregunta es si obtengo un grupo de variables "significativas", pero ¿puedo ordenarlas por orden para estimar la importancia relativa de cada una? ¿Se pueden estandarizar los coeficientes para este propósito de rango por valor absoluto (entiendo que se muestran en la escala variable original a través de la coeffunción)? Si es así, cómo hacerlo (usando la desviación estándar de x e y) Estandarizar los coeficientes de regresión .

CÓDIGO DE MUESTRA:

    library(glmnet)

    #data comes from

#http://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Diagnostic)

    datasetTest <- read.csv('C:/Documents and Settings/E997608/Desktop/wdbc.data.txt',head=FALSE)


#appears to use the first level as the target success
   datasetTest$V2<-as.factor(ifelse(as.character(datasetTest$V2)=="M","0","1"))


#cross validation to find optimal lambda
#using the lasso because alpha=1

    cv.result<-cv.glmnet(       
              x=as.matrix(dataset[,3:ncol(datasetTest)]),
              y=datasetTest[,2],        
              family="binomial",        
              nfolds=10,        
              type.measure="deviance",       
              alpha=1      
              )

#values of lambda used

    histogram(cv.result$lambda)

#plot of the error measure (here was deviance)
#as a CI from each of the 10 folds
#for each value of lambda (log actually)

    plot(cv.result) 

#the mean cross validation error (one for each of the
#100 values of lambda

    cv.result$cvm

#the value of lambda that minimzes the error measure
#result: 0.001909601

    cv.result$lambda.min
    log(cv.result$lambda.min)

#the value of lambda that minimzes the error measure
#within 1 SE of the minimum
#result: 0.007024236

    cv.result$lambda.1se

#the full sequence was fit in the object called cv.result$glmnet.fit
#this is same as a call to it directly.
#here are the coefficients from the min lambda

    coef(cv.result$glmnet.fit,s=cv.result$lambda.1se)
B_Miner
fuente

Respuestas:

14

Hasta donde sé, glmnet no calcula los errores estándar de los coeficientes de regresión (ya que se ajusta a los parámetros del modelo utilizando el descenso de coordenadas cíclicas). Entonces, si necesita coeficientes de regresión estandarizados, deberá usar algún otro método (por ejemplo, glm)

Dicho esto, si las variables explicativas se estandarizan antes del ajuste y se llama glmnet con "estandarizar = FALSO", entonces los coeficientes menos importantes serán más pequeños que los más importantes, por lo que podría clasificarlos solo por su magnitud. Esto se vuelve aún más pronunciado con la reducción de la cantidad no trivial (es decir, lambda no cero)

Espero que esto ayude..

Yevgeny
fuente
2
Gracias. Creo que los coeff vuelven a la escala original. Por lo tanto, uno debería volver a escalarlos (supongo que usando la técnica que publiqué, por ejemplo).
B_Miner
user6129 tiene razón! no obtienes ningún medio para clasificar las variables seleccionadas. Es un área activa de investigación.
suncoolsu
3
@B_Miner: tiene razón, si se llama con "estandarizar = VERDADERO" glmnet devuelve coeficientes en la escala original. Una forma de evitar esto es estandarizar las variables explicativas fuera (por ejemplo, utilizando la función "scale ()") y llamar a glmnet con "standardize = FALSE". Los coeficientes resultantes podrían clasificarse por magnitud para juzgar su importancia.
Yevgeny
@suncoolsu: por favor vea mi respuesta actualizada arriba
Yevgeny
@Yevgeny tengo una pregunta. Entonces, técnicamente, ¿deberían ser los mismos resultados de rendimiento (por ejemplo, el área bajo la curva) si establecemos 'estandarizar = FALSO' y estandarizamos las variables nosotros mismos o simplemente usamos 'estandarizar = VERDADERO'? (Solo los coeficientes beta devueltos serían diferentes). Esto es lo que teóricamente pienso, pero en la práctica obtengo resultados ligeramente mejores cuando uso 'estandarizar = VERDADERO'. Por lo tanto, tanto los coeficientes como el rendimiento son diferentes. ¿Es así como debería ser?
Michelle
7

Para obtener el coeficiente en un espacio que le permite comparar directamente su importancia, debe estandarizarlos. Escribí una nota en Thinklab para discutir la estandarización de los coeficientes de regresión logística.

(Muy) Larga historia corta, aconsejo usar el método Agresti :

# if X is the input matrix of the glmnet function,
# and cv.result is your glmnet object:
sds <- apply(X, 2, sd)
cs <- as.matrix(coef(cv.result, s = "lambda.min"))
std_coefs <- coefs[-1, 1] * sds

Si confió en la estandarización interna por glmnet (opción predeterminada standardize = TRUE), estos coeficientes estandarizados son en realidad los que resultan del paso de ajuste, antes de la retransformación por glmnet en el espacio original (vea otra nota :-)).

Antoine Lizée
fuente
2
std_coefs <- coefs[-1, 1] * sds
si=siσX
Antoine: ¿Puedes confirmar que la multiplicación y no la división es correcta aquí?
B_Miner
1
σX+siX+=+(siσX)(X-μ)/ /σX+...siσX=X
Sí, es un error tipográfico (Otro recordatorio para nunca escribir ejemplos sin ejecutar el código ;-)) Gracias por atraparlo, está solucionado.
Antoine Lizée
Esto proporciona los coeficientes estandarizados correctos, si el glmnetobjeto fue creado con standardize = TRUEo standardize = FALSE, ¿sí?
James Hirschorn