Perché LASSO non trova la mia coppia predittiva perfetta ad alta dimensionalità?


20

Sto eseguendo un piccolo esperimento con la regressione di LASSO in R per testare se è in grado di trovare una coppia predittiva perfetta. La coppia è definita in questo modo: f1 + f2 = risultato

Il risultato qui è un vettore predeterminato chiamato 'età'. F1 e f2 vengono creati prendendo la metà del vettore di età e impostando il resto dei valori su 0, ad esempio: age = [1,2,3,4,5,6], f1 = [1,2,3, 0,0,0] e f2 = [0,0,0,4,5,6]. Combino questa coppia di predittori con una quantità crescente di variabili create casualmente campionando da una normale distribuzione N (1,1).

Quello che vedo è quando colpisco 2 ^ 16 variabili, LASSO non trova più la mia coppia. Vedi i risultati qui sotto.

Numero di funzioni per piega per dimensione dei datiCoefficienti della coppia perfetta

Perché sta succedendo? È possibile riprodurre i risultati con lo script seguente. Ho notato che quando scelgo un vettore di età diverso, ad esempio: [1: 193], LASSO trova la coppia in alta dimensionalità (> 2 ^ 16).

Il copione:

## 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')

piccolo commento: a causa dell'uso di 'createFolds', è necessario caricare anche il pacchetto 'caret'.
IWS,

2
Vedi il teorema 2a di "Wainwright: Soglie definite per il recupero di sparsità ad alta dimensione e rumorose". Nel regime in cui ci si trova, in cui il vero supporto ha fisso la cardinalità 2 e p cresce con n fisso, sembra probabile che potrebbero esserci correlazioni molto alte se ci sono abbastanza funzionalità, il che porta alla bassa probabilità di un successo del recupero del supporto che noti. (Tuttavia, poiché i vettori non nel supporto vero sono piuttosto piccoli (media 0 varianza 1) sembra che questo potrebbe non essere il motivo poiché la funzione età reale ha voci molto grandi.)
user795305

1
@Ben, penso che questa sia la spiegazione corretta, e data la popolarità di questa domanda, sarebbe fantastico se tu potessi fornire una risposta che spieghi perché è così.
NRH

1
@Maddenker ^restituisce sempre un doppio per interi o doppi argomenti in R. R passa anche a double se si verifica un overflow di numeri interi.
Roland,

1
Cordiali saluti: Ho aggiunto uno script aggiornato sulla mia pagina github. In questo script uso meno esempi, il che induce il problema già a 2 ^ 5 variabili. Ciò consente tempi di esecuzione rapidi e consente di sperimentare di più con i dati: github.com/sjorsvanheuveln/LASSO_pair_problem
Ansjovis86

Risposte:


4

p>n

Il lazo è uno strumento popolare per la regressione lineare sparsa, in particolare per i problemi in cui il numero di variabili supera il numero di osservazioni. Ma quando p> n, il criterio del lazo non è strettamente convesso, e quindi potrebbe non avere un minimizzatore unico.

Come accennato da @ben, quando hai 2e16 covariate, non è diverso dal fatto che alcune siano abbastanza simili alle vere covariate. Ecco perché il punto precedente è rilevante: LASSO è indifferente a sceglierne uno.

Forse in modo più pertinente e più recente (2013), c'è un altro articolo di Candes su come, anche quando le condizioni statistiche sono ideali (predittori non correlati, solo alcuni grandi effetti), il LASSO produce ancora falsi positivi, come quello che vedi nei tuoi dati:

Nelle impostazioni di regressione in cui le variabili esplicative hanno correlazioni molto basse e ci sono relativamente pochi effetti, ognuno di grande entità, ci aspettiamo che il Lazo trovi le variabili importanti con pochi errori, se presenti. Questo documento mostra che in un regime di sparsità lineare --- il che significa che la frazione di variabili con un effetto non-dissolvente tende a una costante, per quanto piccola --- questo non può essere realmente il caso, anche quando le variabili di progettazione sono stocasticamente indipendenti .


Non lo sapevo. Pensavo che LASSO fosse uno strumento standard e affidabile per identificare il modello sparso (o almeno quella era la mia impressione leggendo i due libri di Hastie e Tibshirani e usando il metodo me stesso). Dato che dici che il problema è noto, sai se ci sono anche soluzioni / o approcci alternativi?
DeltaIV,

Se ho capito bene, questi risultati sembrano essere solo per la scarsità lineare, mentre il problema
attuale

@Ben, certo, ma ciò non rende la carta irrilevante. È una delle opere letterarie più recenti che conosco che tocca questo problema. Penso che possa mostrare qualcosa di semplice: anche con condizioni statistiche ideali, LASSO non ha le migliori proprietà.
Mustafa S Eisa,

@DeltaIV, LASSO è un euristico convesso di ottimizzazione ai fini della selezione variabile. Nel libro di Tibshirani, mostrano che può seguire un percorso simile a quello dell'AIC o dei metodi graduali, ma questa non è una garanzia. Secondo me, la maggior parte dei suoi problemi deriva dal fatto che si tratta di un'euristica e non della cosa reale, ma si rinuncia a ottenere convessità che ha altre belle proprietà.
Mustafa S Eisa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.