Variable Wichtigkeit von GLMNET

18

Ich möchte das Lasso als Methode zur Auswahl von Merkmalen und zur Anpassung eines Vorhersagemodells an ein binäres Ziel verwenden. Im Folgenden ist ein Code aufgeführt, mit dem ich die Methode mit regulierter logistischer Regression ausprobiert habe.

Meine Frage ist, dass ich eine Gruppe von "signifikanten" Variablen erhalte, aber bin ich in der Lage, diese zu sortieren, um die relative Wichtigkeit der einzelnen zu schätzen? Können die Koeffizienten für diesen Zweck der Rangordnung nach Absolutwert normiert werden (ich verstehe, dass sie durch die coefFunktion auf der ursprünglichen variablen Skala angezeigt werden)? Wenn ja, wie geht das? (Unter Verwendung der Standardabweichung von x und y) Regressionskoeffizienten standardisieren .

BEISPIELCODE:

    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
quelle

Antworten:

14

Soweit ich weiß, berechnet glmnet die Standardfehler der Regressionskoeffizienten nicht (da es die Modellparameter mithilfe der zyklischen Koordinatenabsenkung anpasst). Wenn Sie standardisierte Regressionskoeffizienten benötigen, müssen Sie eine andere Methode anwenden (z. B. glm).

Wenn die erklärenden Variablen jedoch vor dem Aufruf von fit und glmnet mit "standardize = FALSE" standardisiert werden, sind die weniger wichtigen Koeffizienten kleiner als die wichtigeren - Sie können sie also einfach nach ihrer Größe einstufen. Dies wird mit nicht trivialer Mengenschrumpfung (dh Lambda ungleich Null) noch deutlicher.

Hoffe das hilft..

Jewgeni
quelle
2
Vielen Dank. Ich glaube, die Koeffizienten werden auf der ursprünglichen Skala zurückgegeben. Man müsste sie also neu skalieren (ich nehme an, ich verwende die Technik, die ich zum Beispiel gepostet habe).
B_Miner
user6129 ist richtig! Sie erhalten keine Möglichkeit, die ausgewählten Variablen einzustufen. Es ist ein aktives Forschungsgebiet.
Suncoolsu
3
@B_Miner: Sie haben Recht, wenn mit "standardize = TRUE" aufgerufen wird, liefert glmnet Koeffizienten auf der ursprünglichen Skala. Eine Möglichkeit, dies zu umgehen, besteht darin, die erklärenden Variablen außerhalb zu standardisieren (z. B. mit der Funktion "scale ()") und glmnet mit "standardize = FALSE" aufzurufen. Die resultierenden Koeffizienten könnten dann nach Größe sortiert werden, um ihre Wichtigkeit zu beurteilen.
Jewgeni
@ suncoolsu: pls siehe meine aktualisierte Antwort oben
Jewgeni
@ Jewgeni Ich habe eine Frage. Dann sollten die Leistungsergebnisse (z. B. Fläche unter der Kurve) technisch die gleichen sein, unabhängig davon, ob wir 'standardize = FALSE' und die Variablen selbst standardisieren oder einfach 'standardize = TRUE' verwenden. (Nur die zurückgegebenen Beta-Koeffizienten wären unterschiedlich). Dies ist, was ich theoretisch denke, aber in der Praxis erhalte ich etwas bessere Ergebnisse, wenn ich 'standardize = TRUE' verwende. Daher sind sowohl die Koeffizienten als auch die Leistung unterschiedlich. Ist das so, wie es sein sollte?
Michelle
7

Um den Koeffizienten in einem Raum zu erhalten, mit dem Sie ihre Wichtigkeit direkt vergleichen können, müssen Sie sie standardisieren. Ich schrieb eine Notiz über Thinklab, um die Standardisierung der logistischen Regressionskoeffizienten zu diskutieren.

(Sehr) Kurz gesagt, ich empfehle die Agresti- Methode:

# 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

Wenn Sie sich auf die interne Standardisierung durch glmnet (Standardoption standardize = TRUE) verlassen haben, sind diese standardisierten Koeffizienten tatsächlich diejenigen, die sich aus dem Anpassungsschritt ergeben, bevor sie durch glmnet im ursprünglichen Raum erneut transformiert werden (siehe einen anderen Hinweis :-)).

Antoine Lizée
quelle
2
std_coefs <- coefs[-1, 1] * sds
b=bσx
Antoine - Können Sie bestätigen, dass Multiplikation und nicht Division hier richtig ist?
B_Miner
1
σx+bx+=+(bσx)(x-μ)/σx+bσx=x
Ja, es ist ein Tippfehler (Noch eine Erinnerung daran, niemals Beispiele zu schreiben, ohne den Code auszuführen ;-)) Vielen Dank, dass Sie ihn abgefangen haben.
Antoine Lizée
Dies ergibt die korrekten standardisierten Koeffizienten, ob das glmnetObjekt mit standardize = TRUEoder standardize = FALSEja erstellt wurde?
James Hirschorn