45 votos

Uso de LASSO del paquete lars (o glmnet) en R para la selección de variables

Perdona si esta pregunta resulta un poco básica.

Quiero utilizar la selección de variables LASSO para un modelo de regresión lineal múltiple en R. Tengo 15 predictores, uno de los cuales es categórico (¿causará esto un problema?). Después de establecer mi $x$ y $y$ Utilizo los siguientes comandos:

model = lars(x, y)
coef(model)

Mi problema es que cuando uso coef(model) . Esto devuelve una matriz con 15 filas, con un predictor extra añadido cada vez. Sin embargo, no hay ninguna sugerencia sobre qué modelo elegir. ¿Me he perdido algo? ¿Hay alguna forma de conseguir que el paquete lars devuelva sólo un " mejor "¿Modelo?

Hay otros posts que sugieren el uso de glmnet pero esto parece más complicado. Un intento es el siguiente, utilizando el mismo $x$ y $y$ . ¿Me he perdido algo aquí?

cv = cv.glmnet(x, y)
model = glmnet(x, y, type.gaussian="covariance", lambda=cv$lambda.min)
predict(model, type="coefficients")

El comando final devuelve una lista de mis variables, la mayoría con un coeficiente aunque algunas son =0. ¿Es esta la elección correcta del " mejor "¿el modelo seleccionado por LASSO? Si a continuación, ajuste un modelo lineal con todas mis variables que tenían coeficientes not=0 Obtengo estimaciones de coeficientes muy similares, pero ligeramente diferentes. ¿Hay alguna razón para esta diferencia? ¿Sería aceptable volver a ajustar el modelo lineal con estas variables elegidas por LASSO y tomarlo como modelo final? Por lo demás, no veo ningún valor p de significación. ¿Me he perdido algo?

En

type.gaussian="covariance" 

garantizar que glmnet utiliza la regresión lineal múltiple?

¿Afecta la normalización automática de las variables a los coeficientes? ¿Hay alguna forma de incluir términos de interacción en un procedimiento LASSO?

Estoy buscando utilizar este procedimiento más como una demostración de cómo se puede utilizar LASSO que para cualquier modelo que realmente se utilizará para cualquier inferencia / predicción importante si eso cambia algo.

Gracias por tomarse el tiempo de leer esto. Cualquier comentario general sobre LASSO/lars/glmnet también sería muy apreciado.

33voto

CAFxX Puntos 165

Utilizando glmnet es realmente fácil una vez que te haces con él gracias a su excelente viñeta en http://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html (también puede consultar la página del paquete CRAN). En cuanto a la mejor lambda para glmnet la regla general es utilizar

cvfit <- glmnet::cv.glmnet(x, y)
coef(cvfit, s = "lambda.1se")

en lugar de lambda.min .

Para hacer lo mismo con lars hay que hacerlo a mano. Aquí está mi solución

cv <- lars::cv.lars(x, y, plot.it = FALSE, mode = "step")
idx <- which.max(cv$cv - cv$cv.error <= min(cv$cv))
coef(lars::lars(x, y))[idx,]

Tenga en cuenta que esto no es exactamente lo mismo, porque esto es parar en un nudo de lazo (cuando una variable entra) en lugar de en cualquier punto.

Tenga en cuenta que glmnet es el paquete preferido ahora, se mantiene activamente, más que lars y que ha habido preguntas sobre glmnet vs lars respondido antes (los algoritmos utilizados difieren).

En cuanto a tu pregunta sobre el uso de lasso para elegir las variables y luego ajustar OLS, es un debate en curso. Busca en Google OLS post Lasso y hay algunos artículos que discuten el tema. Incluso los autores de Elements of Statistical Learning admiten que es posible.

Editar : Aquí está el código para reproducir con mayor precisión lo que glmnet hace en lars

  cv <- lars::cv.lars(x, y, plot.it = FALSE)
  ideal_l1_ratio <- cv$index[which.max(cv$cv - cv$cv.error <= min(cv$cv))]
  obj <- lars::lars(x, y)
  scaled_coefs <- scale(obj$beta, FALSE, 1 / obj$normx)
  l1 <- apply(X = scaled_coefs, MARGIN = 1, FUN = function(x) sum(abs(x)))
  coef(obj)[which.max(l1 / tail(l1, 1) > ideal_l1_ratio),]

11voto

Jason Puntos 141

Vuelvo a esta pregunta de hace un tiempo ya que creo que he resuelto la solución correcta.

Aquí hay una réplica utilizando el conjunto de datos mtcars:

library(glmnet)
`%ni%`<-Negate(`%in%')
data(mtcars)

x<-model.matrix(mpg~.,data=mtcars)
x=x[,-1]

glmnet1<-cv.glmnet(x=x,y=mtcars$mpg,type.measure='mse',nfolds=5,alpha=.5)

c<-coef(glmnet1,s='lambda.min',exact=TRUE)
inds<-which(c!=0)
variables<-row.names(c)[inds]
variables<-variables[variables %ni% '(Intercept)']

'variables' te da la lista de las variables que resuelven la mejor solución.

7voto

Colin McLarty Puntos 128

Tal vez la comparación con la regresión escalonada de selección directa sea de ayuda (véase el siguiente enlace a un sitio de uno de los autores http://www-stat.stanford.edu/~tibs/lasso/simple.html ). Este es el enfoque utilizado en el capítulo 3.4.4 de The Elements of Statistical Learning (disponible en línea de forma gratuita). Me pareció que el capítulo 3.6 de ese libro ayudaba a entender la relación entre los mínimos cuadrados, el mejor subconjunto y el lazo (además de un par de otros procedimientos). También me resulta útil tomar la transposición del coeficiente, t(coef(model)) y escribir.csv, para poder abrirlo en Excel junto con una copia del plot(model) al lado. Es posible que desee ordenar por la última columna, que contiene la estimación de mínimos cuadrados. Entonces se puede ver claramente cómo se añade cada variable en cada paso a trozos y cómo cambian los coeficientes como resultado. Por supuesto, esto no es toda la historia, pero esperamos que sea un comienzo.

3voto

Andrew Puntos 4317

lars y glmnet operan sobre matrices en bruto. Para incluir los términos de interacción, tendrá que construir las matrices usted mismo. Eso significa una columna por interacción (que es por nivel por factor si tiene factores). Busque en lm() para ver cómo lo hace (aviso: hay dragones).

Para hacerlo ahora mismo, haz algo como Para hacer un término de interacción manualmente, usted podría (pero tal vez no debería porque es lento) lo hacen:

int = D["x1"]*D["x2"]
names(int) = c("x1*x2")
D = cbind(D, int)

Entonces para usar esto en lars (asumiendo que tienes un y pateando por ahí):

lars(as.matrix(D), as.matrix(y))

Me gustaría poder ayudarte más con las otras preguntas. Encontré esta porque lars me está dando pena y la documentación en ella y en la web es muy escasa.

2voto

Adam Puntos 21

LARS resuelve TODO el camino de la solución. La trayectoria de la solución es lineal a trozos: hay un número finito de puntos de "muesca" (es decir, valores del parámetro de regularización) en los que cambia la solución.

Así que la matriz de soluciones que obtiene son todas las soluciones posibles. En la lista que devuelve, también debería darte los valores del parámetro de regularización.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X