Переменная важность от GLMNET

18

Я смотрю на использование лассо в качестве метода выбора признаков и подбора прогнозирующей модели с бинарной целью. Ниже приведен код, с которым я играл, чтобы опробовать метод с регуляризованной логистической регрессией.

Мой вопрос заключается в том, что я получил группу «значимых» переменных, но могу ли я упорядочить их, чтобы оценить относительную важность каждой из них? Можно ли стандартизировать коэффициенты для этой цели ранга по абсолютной величине (я понимаю, что они показаны в исходной переменной шкале через coefфункцию)? Если да, то как это сделать (используя стандартное отклонение x и y)? Стандартизировать коэффициенты регрессии .

ОБРАЗЕЦ КОДА:

    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
источник

Ответы:

14

Насколько мне известно, glmnet не вычисляет стандартные ошибки коэффициентов регрессии (поскольку он соответствует параметрам модели с использованием циклического спуска координат). Итак, если вам нужны стандартизированные коэффициенты регрессии, вам нужно будет использовать другой метод (например, glm)

Сказав это, если объясняющие переменные стандартизируются до того, как fit и вызывается glmnet с помощью "standardize = FALSE", то менее важные коэффициенты будут меньше, чем более важные - так что вы можете ранжировать их по величине. Это становится еще более выраженным с нетривиальной величиной усадки (то есть ненулевой лямбда)

Надеюсь это поможет..

Евгений
источник
2
Благодарю. Я полагаю, что кофф возвращаются в исходном масштабе. Таким образом, их нужно будет перемасштабировать (я полагаю, используя технику, которую я опубликовал, например).
B_Miner
user6129 прав! Вы не получаете никаких средств ранжирования выбранных переменных. Это активная область исследований.
Suncoolsu
3
@B_Miner: вы правы, если вызывается с "standardize = TRUE", glmnet возвращает коэффициенты в исходном масштабе. Один из способов обойти это - стандартизировать внешние переменные (например, с помощью функции scale ()) и вызвать glmnet с помощью standardize = FALSE. Полученные коэффициенты могут быть ранжированы по величине, чтобы судить об их важности.
Евгений
@suncoolsu: пожалуйста, смотрите мой обновленный ответ выше
Евгений
@ Евгений У меня есть вопрос. С технической точки зрения, должны ли результаты производительности (например, площадь под кривой) быть одинаковыми, независимо от того, устанавливаем ли мы «стандартизировать = ЛОЖЬ» и стандартизируем переменные сами или просто используем «стандартизировать = ИСТИНА»? (Только возвращенные бета-коэффициенты будут другими). Это то, что я теоретически думаю, но на практике я получаю немного лучшие результаты, когда использую «стандартизировать = ИСТИНА». Следовательно, и коэффициенты, и производительность разные. Это так и должно быть?
Мишель
7

Чтобы получить коэффициент в пространстве, который позволяет вам напрямую сравнивать их важность, вы должны стандартизировать их. Я написал заметку на Thinklab, чтобы обсудить стандартизацию коэффициентов логистической регрессии.

(Очень) Короче говоря, я советую использовать метод Агрести :

# 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

Если вы полагались на внутреннюю стандартизацию с помощью glmnet (опция по умолчанию standardize = TRUE), то эти стандартизированные коэффициенты фактически являются теми, которые получены на этапе подгонки, до ретрансформации с помощью glmnet в исходном пространстве (см. Другое примечание :-)).

Антуан Лизе
источник
2
std_coefs <- coefs[-1, 1] * sds
б*знак равнобσИкс
Антуан - Можете ли вы подтвердить, что умножение, а не деление здесь уместно?
B_Miner
1
σИкс+бИкс+знак равно+(бσИкс)(Икс-μ)/σИкс+...бσИксзнак равноИкс
Да, это опечатка (еще одно напоминание, чтобы никогда не печатать примеры без запуска кода ;-)) Спасибо, что поймали его, это исправлено.
Антуан Лизе
Это дает правильные стандартизированные коэффициенты, был ли glmnetобъект создан с standardize = TRUEили standardize = FALSE, да?
Джеймс Хиршорн