Importanza variabile da GLMNET


18

Sto cercando di utilizzare il lazo come metodo per selezionare le caratteristiche e adattare un modello predittivo con un obiettivo binario. Di seguito è riportato un codice con cui stavo giocando per provare il metodo con regressione logistica regolarizzata.

La mia domanda è che ottengo un gruppo di variabili "significative" ma sono in grado di classificarle per stimare l'importanza relativa di ciascuna? I coefficienti possono essere standardizzati a questo scopo di rango in base al valore assoluto (capisco che sono mostrati sulla scala variabile originale attraverso la coeffunzione)? In tal caso, come fare (utilizzando la deviazione standard di xey) Standardizzare i coefficienti di regressione .

CODICE D'ESEMPIO:

    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)

Risposte:


14

Per quanto ne so glmnet non calcola gli errori standard dei coefficienti di regressione (poiché si adatta ai parametri del modello usando la discesa ciclica delle coordinate). Quindi, se hai bisogno di coefficienti di regressione standardizzati, dovrai utilizzare un altro metodo (ad esempio glm)

Detto questo, se le variabili esplicative sono standardizzate prima che fit e glmnet siano chiamati con "standardize = FALSE", i coefficienti meno importanti saranno più piccoli di quelli più importanti, in modo da poterli classificare in base alla loro grandezza. Questo diventa ancora più pronunciato con un restringimento della quantità non banale (cioè lambda diverso da zero)

Spero che sia di aiuto..


2
Grazie. Credo che i coeff siano tornati sulla scala originale. Quindi bisognerebbe ridimensionarli (presumo usando la tecnica che ho pubblicato per esempio).
B_Miner

user6129 ha ragione! non si ottiene alcun mezzo per classificare le variabili selezionate. È un'area attiva di ricerca.
suncoolsu,

3
@B_Miner: hai ragione, se chiamato con "standardize = TRUE" restituisce i coefficienti glmnet sulla scala originale. Un modo per aggirare il problema è standardizzare le variabili esplicative esterne (ad esempio utilizzando la funzione "scale ()") e chiamare glmnet con "standardize = FALSE". I coefficienti risultanti potrebbero quindi essere classificati in ordine di grandezza per giudicarne l'importanza.
Evgenij

@suncoolsu: per favore vedi la mia risposta aggiornata sopra
Yevgeny

@Yevgeny ho una domanda. Quindi tecnicamente, i risultati delle prestazioni (ad es. Area sotto la curva) dovrebbero essere gli stessi se impostiamo 'standardize = FALSE' e standardizziamo noi stessi le variabili o usiamo semplicemente 'standardize = TRUE'? (Solo i coefficienti beta restituiti sarebbero diversi). Questo è ciò che teoricamente penso, ma in pratica ottengo risultati leggermente migliori quando uso "standardize = TRUE". Quindi, sia i coefficienti che le prestazioni sono diversi. È così che dovrebbe essere?
Michelle,

7

Per ottenere il coefficiente in uno spazio che ti consente di confrontare direttamente la loro importanza, devi standardizzarli. Ho scritto una nota su Thinklab per discutere la standardizzazione dei coefficienti di regressione logistica.

(Molto) Per farla breve, consiglio di usare il metodo 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

Se hai fatto affidamento sulla standardizzazione interna tramite glmnet (opzione predefinita standardize = TRUE), questi coefficienti standardizzati sono effettivamente quelli risultanti dalla fase di adattamento, prima della ritrasformazione di glmnet nello spazio originale (vedi un'altra nota :-)).


2
std_coefs <- coefs[-1, 1] * sds
b=bσX

Antoine - Puoi confermare che la moltiplicazione e non la divisione qui è corretta?
B_Miner

1
σX+BX+=+(BσX)(X-μ)/σX+..., cioè: BσX= coefficiente di standardizzato X.
VictorZurkowski il

Sì, è un refuso (ancora un altro promemoria per non scrivere mai esempi senza eseguire il codice ;-)) Grazie per averlo catturato, è stato risolto.
Antoine Lizée,

Ciò fornisce i coefficienti standardizzati corretti, sia che l' glmnetoggetto sia stato creato con standardize = TRUEo standardize = FALSE, sì?
James Hirschorn,
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.