Importance variable de GLMNET

18

Je cherche à utiliser le lasso comme méthode pour sélectionner des entités et ajuster un modèle prédictif avec une cible binaire. Voici un code avec lequel je jouais pour essayer la méthode avec régression logistique régularisée.

Ma question est de savoir si j'obtiens un groupe de variables "significatives", mais suis-je en mesure de classer ces variables pour estimer l'importance relative de chacune? Les coefficients peuvent-ils être standardisés à cet effet de classement par valeur absolue (je comprends qu'ils sont montrés sur l'échelle variable d'origine à travers la coeffonction)? Si tel est le cas, comment procéder (en utilisant l'écart type de x et y) Standardiser les coefficients de régression .

EXEMPLE DE CODE:

    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
la source

Réponses:

14

Pour autant que je sache, glmnet ne calcule pas les erreurs standard des coefficients de régression (car il correspond aux paramètres du modèle en utilisant la descente de coordonnées cycliques). Donc, si vous avez besoin de coefficients de régression standardisés, vous devrez utiliser une autre méthode (par exemple glm)

Cela dit, si les variables explicatives sont normalisées avant l'ajustement et que glmnet est appelé avec "standardize = FALSE", alors les coefficients les moins importants seront plus petits que les plus importants - vous pouvez donc les classer juste en fonction de leur ampleur. Cela devient encore plus prononcé avec un retrait non négligeable (c.-à-d. Lambda non nul)

J'espère que cela t'aides..

Yevgeny
la source
2
Merci. Je crois que le coeff est retourné sur l'échelle d'origine. Il faudrait donc les redimensionner (je suppose en utilisant la technique que j'ai postée par exemple).
B_Miner
user6129 a raison! vous n'avez aucun moyen de classer les variables sélectionnées. C'est un domaine de recherche actif.
suncoolsu
3
@B_Miner: vous avez raison, s'il est appelé avec "standardize = TRUE", glmnet renvoie des coefficients sur l'échelle d'origine. Une façon de contourner cela est de standardiser les variables explicatives à l'extérieur (par exemple en utilisant la fonction "scale ()") et d'appeler glmnet avec "standardize = FALSE". Les coefficients résultants pourraient ensuite être classés par ordre d'importance pour juger de leur importance.
Yevgeny
@suncoolsu: les pls voient ma réponse mise à jour ci
Yevgeny
@Yevgeny J'ai une question. Ensuite, techniquement, les résultats de performance (par exemple, l'aire sous la courbe) devraient-ils être les mêmes, que nous définissions «standardize = FALSE» et normalisions les variables nous-mêmes ou que nous utilisons simplement «standardize = TRUE»? (Seuls les coefficients bêta renvoyés seraient différents). C'est ce que je pense théoriquement, mais dans la pratique, j'obtiens des résultats légèrement meilleurs lorsque j'utilise 'standardize = TRUE'. Par conséquent, les coefficients et les performances sont différents. Est-ce ainsi que ça devrait être?
Michelle
7

Pour obtenir le coefficient dans un espace qui vous permet de comparer directement leur importance, vous devez les standardiser. J'ai écrit une note sur Thinklab pour discuter de la standardisation des coefficients de régression logistique.

(Très) Bref, je conseille d'utiliser la méthode 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

Si vous vous êtes appuyé sur la standardisation interne par glmnet (option par défaut standardize = TRUE), ces coefficients standardisés sont en fait ceux résultant de l'étape d'ajustement, avant retransformation par glmnet dans l'espace d'origine (voir une autre note :-)).

Antoine Lizée
la source
2
std_coefs <- coefs[-1, 1] * sds
b=bσX
Antoine - Pouvez-vous confirmer que la multiplication et non la division est appropriée ici?
B_Miner
1
σX+bX+=+(bσX)(X-μ)/σX+bσX=X
Oui, c'est une faute de frappe (Encore un rappel pour ne jamais taper d'exemples sans exécuter le code ;-)) Merci de l'avoir attrapé, c'est corrigé.
Antoine Lizée
Cela donne les coefficients standardisés corrects, que l' glmnetobjet ait été créé avec standardize = TRUEou standardize = FALSE, oui?
James Hirschorn