Змінна важливість від 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)

Відповіді:


14

Наскільки я знаю, glmnet не обчислює стандартні похибки коефіцієнтів регресії (оскільки він відповідає параметрам моделі за допомогою циклічного координатного спуску). Отже, якщо вам потрібні стандартизовані коефіцієнти регресії, вам потрібно буде використовувати якийсь інший метод (наприклад, glm)

Сказавши, що, якщо пояснювальні змінні стандартизуються до придатності, а glmnet називається "стандартизація = ЛАСКА", то менш важливі коефіцієнти будуть меншими, ніж більш важливі - тож ви могли б класифікувати їх за величиною. Це стає ще більш вираженим при усадці нетривіальної кількості (тобто ненульової лямбда)

Сподіваюся, це допомагає ..


2
Спасибі. Я вважаю, що коефіцієнт повертається назад у вихідній шкалі. Таким чином, потрібно змінити їх масштаб (я припускаю, використовуючи техніку, яку я розмістив, наприклад).
B_Miner

user6129 вірно! ви не отримуєте жодних засобів ранжування вибраних змінних. Це активна область досліджень.
suncoolsu

3
@B_Miner: ти маєш рацію, якщо його викликають "стандартизувати = ІСТИНА", glmnet повертає коефіцієнти у вихідній шкалі. Один із способів обійти це стандартизація пояснювальних змінних назовні (наприклад, використання функції "scale ()" та виклик glmnet за допомогою "стандартизації = ЛЖА". Отримані коефіцієнти можна було б класифікувати за величиною, щоб оцінити їх важливість.
Євген

@suncoolsu: pls дивіться мою оновлену відповідь вище
Євгеній

@ Євгеній У мене питання. Тоді технічно чи повинні результати роботи (наприклад, область під кривою) бути однаковими, чи встановимо ми «стандартизувати = ЛОЖУ» та самі стандартизувати змінні чи просто використаємо «стандартизація = ІСТИНА»? (Тільки повернені бета-коефіцієнти були б різними). Теоретично я вважаю, але на практиці я отримую трохи кращі результати, коли використовую 'стандартизація = ІСТИНА'. Отже, і коефіцієнти, і продуктивність різні. Це так має бути?
Мішель

7

Щоб отримати коефіцієнт у просторі, який дозволяє безпосередньо порівнювати їх значення, вам доведеться їх стандартизувати. Я написав записку на Thinklab, щоб обговорити стандартизацію коефіцієнтів логістичної регресії.

(Дуже короткий огляд), я раджу використовувати метод 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

Якщо ви покладалися на внутрішню стандартизацію за допомогою glmnet (опція за замовчуванням standardize = TRUE), ці стандартизовані коефіцієнти є фактично тими, що є результатом кроку підгонки, перед ретрансформацією glmnet у вихідному просторі (див. Іншу примітку :-)).


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

Антуан - Чи можете ви підтвердити, що множення, а не ділення тут належне?
B_Miner

1
Дійсно, ви помножите коефіцієнт на . Лінійна оцінка має вигляд + b x + σx+bx+=+(bσx)(xμ)/σx+bσx=x

Так, це друкарська помилка (Ще одне нагадування про те, що ніколи не вводити приклади без запуску коду ;-)) Дякую, що впіймали його, це виправлено.
Антуан Лізе

Це дає правильні стандартизовані коефіцієнти, чи glmnetоб’єкт створений за допомогою, standardize = TRUEчи standardize = FALSEтак?
Джеймс Гіршорн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.