¿Por qué LASSO no encuentra mi par predictor perfecto en alta dimensionalidad?

20

Estoy ejecutando un pequeño experimento con la regresión LASSO en R para probar si es capaz de encontrar un par de predictores perfecto. El par se define así: f1 + f2 = resultado

El resultado aquí es un vector predeterminado llamado 'edad'. F1 y f2 se crean tomando la mitad del vector de edad y estableciendo el resto de los valores en 0, por ejemplo: edad = [1,2,3,4,5,6], f1 = [1,2,3, 0,0,0] y f2 = [0,0,0,4,5,6]. Combino este par de predictores con una cantidad cada vez mayor de variables creadas al azar mediante el muestreo de una distribución normal N (1,1).

Lo que veo es que cuando golpeo 2 ^ 16 variables, LASSO ya no encuentra mi par. Vea los resultados a continuación.

Número de funciones por pliegue por tamaño de datosCoeficientes del par perfecto

¿Por qué está pasando esto? Puede reproducir los resultados con el siguiente script. Me di cuenta de que cuando elijo un vector de edad diferente, por ejemplo: [1: 193] entonces LASSO encuentra el par en alta dimensionalidad (> 2 ^ 16).

La secuencia de comandos:

## Setup ##
library(glmnet)
library(doParallel)
library(caret)

mae <- function(errors){MAE <- mean(abs(errors));return(MAE)}
seed = 1
n_start <- 2 #start at 2^n features
n_end <- 16 #finish with 2^n features
cl <- makeCluster(3)
registerDoParallel(cores=cl)

#storage of data
features <- list()
coefs <- list()
L <- list() 
P <- list() 
C <- list() 
RSS <- list() 

## MAIN ##
for (j in n_start:n_end){
  set.seed(seed)
  age <- c(55,31,49,47,68,69,53,42,58,67,60,58,32,52,63,31,51,53,37,48,31,58,36,42,61,49,51,45,61,57,52,60,62,41,28,45,39,47,70,33,37,38,32,24,66,54,59,63,53,42,25,56,70,67,44,33,50,55,60,50,29,51,49,69,70,36,53,56,32,43,39,43,20,62,46,65,62,65,43,40,64,61,54,68,55,37,59,54,54,26,68,51,45,34,52,57,51,66,22,64,47,45,31,47,38,31,37,58,66,66,54,56,27,40,59,63,64,27,57,32,63,32,67,38,45,53,38,50,46,59,29,41,33,40,33,69,42,55,36,44,33,61,43,46,67,47,69,65,56,34,68,20,64,41,20,65,52,60,39,50,67,49,65,52,56,48,57,38,48,48,62,48,70,55,66,58,42,62,60,69,37,50,44,61,28,64,36,68,57,59,63,46,36)
  beta2 <- as.data.frame(cbind(age,replicate(2^(j),rnorm(length(age),1,1))));colnames(beta2)[1] <-'age'

  f1 <- c(age[1:96],rep(0,97)) 
  f2 <- c(rep(0,96),age[97:193])
  beta2 <- as.data.frame(cbind(beta2,f1,f2))

  #storage variables
  L[[j]] <- vector()
  P[[j]] <- vector()
  C[[j]] <- list()
  RSS[[j]] <- vector()

  #### DCV LASSO ####
  set.seed(seed) #make folds same over 10 iterations
  for (i in 1:10){

    print(paste(j,i))
    index <- createFolds(age,k=10)
    t.train <- beta2[-index[[i]],];row.names(t.train) <- NULL
    t.test <- beta2[index[[i]],];row.names(t.test) <- NULL

    L[[j]][i] <- cv.glmnet(x=as.matrix(t.train[,-1]),y=as.matrix(t.train[,1]),parallel = T,alpha=1)$lambda.min #,lambda=seq(0,10,0.1)
    model <- glmnet(x=as.matrix(t.train[,-1]),y=as.matrix(t.train[,1]),lambda=L[[j]][i],alpha=1)
    C[[j]][[i]] <- coef(model)[,1][coef(model)[,1] != 0]
    pred <- predict(model,as.matrix(t.test[,-1]))
    RSS[[j]][i] <- sum((pred - t.test$age)^2)
    P[[j]][i] <- mae(t.test$age - pred)
    gc()
  }
}

##############
## PLOTTING ##
##############

#calculate plots features
beta_sum = unlist(lapply(unlist(C,recursive = F),function(x){sum(abs(x[-1]))}))
penalty = unlist(L) * beta_sum
RSS = unlist(RSS)
pair_coefs <- unlist(lapply(unlist(C,recursive = F),function(x){
  if('f1' %in% names(x)){f1 = x['f1']}else{f1=0;names(f1)='f1'}
  if('f2' %in% names(x)){f2 = x['f2']}else{f2=0;names(f2)='f2'}
  return(c(f1,f2))}));pair_coefs <- split(pair_coefs,c('f1','f2'))
inout <- lapply(unlist(C,recursive = F),function(x){c('f1','f2') %in% names(x)})
colors <- unlist(lapply(inout,function(x){if (x[1]*x[2]){'green'}else{'red'}}))
featlength <- unlist(lapply(unlist(C,recursive = F),function(x){length(x)-1}))

#diagnostics
plot(rep(n_start:n_end,each=10),pair_coefs$f1,col='red',xaxt = "n",xlab='n/o randomly generated features (log2)',main='Pair Coefficients',ylim=c(0,1),ylab='pair coefficients');axis(1, at=n_start:n_end);points(rep(n_start:n_end,each=10),pair_coefs$f2,col='blue');axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('bottomleft',fill=c('red','blue'),legend = c('f1','f2'),inset=.02)
plot(rep(n_start:n_end,each=10),RSS+penalty,col=colors,xaxt = "n",xlab='n/o randomly generated features (log2)',main='RSS+penalty');axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('topleft',fill=c('green','red'),legend = c('Pair Selected','Pair not Selected'),inset=.02)
plot(rep(n_start:n_end,each=10),penalty,col=colors,xaxt = "n",xlab='n/o randomly generated features (log2)',main='Penalty');axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('topleft',fill=c('green','red'),legend = c('Pair Selected','Pair not Selected'),inset=.02)
plot(rep(n_start:n_end,each=10),RSS,col=colors,xaxt = "n",xlab='n/o randomly generated features (log2)',main='RSS');axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('topleft',fill=c('green','red'),legend = c('Pair Selected','Pair not Selected'),inset=.02)
plot(rep(n_start:n_end,each=10),unlist(L),col=colors,xaxt = "n",xlab='n/o randomly generated features (log2)',main='Lambdas',ylab=expression(paste(lambda)));axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('topleft',fill=c('green','red'),legend = c('Pair Selected','Pair not Selected'),inset=.02)
plot(rep(n_start:n_end,each=10),featlength,ylab='n/o features per fold',col=colors,xaxt = "n",xlab='n/o randomly generated features (log2)',main='Features per Fold');axis(1, at=n_start:n_end, labels=(n_start:n_end));legend('topleft',fill=c('green','red'),legend = c('Pair Selected','Pair not Selected'),inset=.02)
plot(penalty,RSS,col=colors,main='Penalty vs. RSS')
Ansjovis86
fuente
comentario menor: debido al uso de 'createFolds', también necesita cargar el paquete 'caret'.
IWS
2
Ver el teorema 2a de 'Wainwright: umbrales agudos para la recuperación de escasez ruidosa y de alta dimensión'. En el régimen en el que se encuentra, donde el soporte real tiene una cardinalidad fija 2 y p crece con n fijo, parece probable que existan correlaciones muy altas si hay suficientes características, lo que conduce a una baja probabilidad de recuperación exitosa del soporte que te das cuenta (Sin embargo, ya que los vectores no en el verdadero apoyo son bastante pequeñas (media 0 varianza 1) parece que esto puede no ser la razón ya que la verdadera función de la edad tiene muy grandes entradas.)
user795305
1
@Ben, creo que esta es la explicación correcta, y dada la popularidad de esta pregunta, sería genial si pudieras proporcionar una respuesta que explique por qué es así.
NRH
1
@Maddenker ^siempre devuelve un doble para enteros o argumentos dobles en R. R también cambia a dobles si se produce un desbordamiento de enteros.
Roland
1
FYI: agregué un script actualizado en mi página de github. En este script utilizo menos muestras, lo que ya induce el problema en 2 ^ 5 variables. Esto permite tiempos de ejecución rápidos y le permite experimentar más con los datos: github.com/sjorsvanheuveln/LASSO_pair_problem
Ansjovis86

Respuestas:

4

Este problema es bien conocido por académicos e investigadores. Sin embargo, la respuesta no es simple y se refiere más, en mi opinión, a la optimización que a las estadísticas. Las personas han intentado superar estos inconvenientes al incluir una penalización de cresta adicional, de ahí la regresión neta elástica. Este artículo de Tibshirani trata sobre el problema (es decir, el número de covariables mayor que el número de observaciones):p>n

El lazo es una herramienta popular para la regresión lineal dispersa, especialmente para problemas en los que el número de variables excede el número de observación. Pero cuando p> n, el criterio de lazo no es estrictamente convexo, y por lo tanto puede no tener un minimizador único.

Como @ben mencionó, cuando tiene 2e16 covariables, no es diferente de que algunas sean bastante similares a las verdaderas covariables. Por lo tanto, por qué el punto anterior es relevante: LASSO es indiferente a elegir cualquiera de los dos.

Quizás de manera más relevante y más reciente (2013), hay otro documento de Candes sobre cómo, incluso cuando las condiciones estadísticas son ideales (predictores no correlacionados, solo unos pocos efectos importantes), el LASSO aún produce falsos positivos, como lo que ves en tus datos:

En entornos de regresión donde las variables explicativas tienen correlaciones muy bajas y hay relativamente pocos efectos, cada uno de gran magnitud, esperamos que el Lazo encuentre las variables importantes con pocos errores, si los hay. Este artículo muestra que, en un régimen de dispersión lineal, lo que significa que la fracción de variables con un efecto que no desaparece tiende a ser constante, por pequeña que sea, este no puede ser el caso, incluso cuando las variables de diseño son estocásticamente independientes .

Mustafa S Eisa
fuente
No lo sabia. Pensé que LASSO era una herramienta estándar y confiable para identificar modelos dispersos (o al menos esa fue mi impresión al leer los dos libros de Hastie y Tibshirani, y al usar el método yo mismo). Dado que usted dice que el problema es bien conocido, ¿sabe si también existen soluciones y / o enfoques alternativos?
DeltaIV
Si entiendo correctamente, estos resultados parecen ser solo para la dispersión lineal, mientras que el problema en cuestión se refiere a la dispersión sub lineal
usuario795305
@Ben, claro, pero eso no hace que el papel sea irrelevante. Es una de las publicaciones más recientes que conozco que toca este tema. Creo que puede mostrar algo simple: incluso con condiciones estadísticas ideales, LASSO no tiene las mejores propiedades.
Mustafa S Eisa
@DeltaIV, LASSO es una heurística de optimización convexa para fines de selección de variables. En el libro de Tibshirani, muestran que puede seguir un camino similar al AIC o los métodos paso a paso, pero esto no es una garantía. En mi opinión, la mayoría de sus problemas provienen del hecho de que es heurístico y no real, pero lo abandonas para ganar convexidad, que tiene otras propiedades agradables.
Mustafa S Eisa