Використання LASSO з пакету lars (або glmnet) в R для вибору змінної


39

Вибачте, якщо це питання стикається з невеликим принципом.

Я хочу використовувати вибір змінної LASSO для множинної лінійної регресійної моделі в Р. У мене є 15 предикторів, один з яких є категоричним (це спричинить проблему?). Після встановлення і я використовую такі команди:уxy

model = lars(x, y)
coef(model)

Моя проблема, коли я використовую coef(model). Це повертає матрицю з 15 рядками, кожен раз додаючи один додатковий предиктор. Однак немає пропозицій щодо того, яку модель вибрати. Я щось пропустив? Чи є спосіб, коли я можу отримати пакет lars повернути лише одну " найкращу " модель?

Є й інші повідомлення, які пропонують використовувати glmnetзамість цього, але це здається складнішим. Спроба полягає в наступному, використовуючи ті ж і . Я щось тут пропустив ?: уxy

cv = cv.glmnet(x, y)
model = glmnet(x, y, type.gaussian="covariance", lambda=cv$lambda.min)
predict(model, type="coefficients")

Остаточна команда повертає список моїх змінних, більшість з коефіцієнтом, хоча деякі з них = 0. Це правильний вибір " найкращої " моделі, обраної LASSO? Якщо я підходити до лінійної моделі з усіма своїми змінними, які мали коефіцієнти, not=0я отримую дуже схожі, але дещо інші оцінки коефіцієнтів. Чи є причина цієї різниці? Чи було б прийнятним переглянути лінійну модель за допомогою цих змінних, обраних LASSO, і прийняти це як мою остаточну модель? Інакше я не бачу жодних p-значень за значимістю. Я щось пропустив?

Чи

type.gaussian="covariance" 

переконайтеся, що для цього glmnetвикористовується безліч лінійних регресій?

Чи впливає автоматична нормалізація змінних взагалі на коефіцієнти? Чи є спосіб включити терміни взаємодії в процедуру LASSO?

Я хочу використовувати цю процедуру більше як демонстрацію того, як можна використовувати LASSO, ніж для будь-якої моделі, яка фактично буде використовуватися для будь-якого важливого висновку / прогнозування, якщо це щось змінить.

Дякую, що знайшли час, щоб прочитати це. Будь-які загальні коментарі щодо LASSO / lars / glmnet також будуть дуже вдячні.


4
Як бічний коментар, якщо ви хочете інтерпретувати результат, не забудьте продемонструвати, що набір змінних, вибраних ласо, є стабільним. Це можна зробити за допомогою моделювання Монте-Карло або завантажуючи власний набір даних.
Френк Харрелл

Відповіді:


28

Використовувати glmnetце дуже просто, коли ви зрозумієте його завдяки чудовій віньєтці на веб-сторінці http://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html (ви також можете перевірити сторінку пакунка CRAN). Що стосується найкращої лямбда для glmnet, правилом є використання

cvfit <- glmnet::cv.glmnet(x, y)
coef(cvfit, s = "lambda.1se")

замість lambda.min.

Щоб зробити те ж саме, larsви повинні зробити це вручну. Ось моє рішення

cv <- lars::cv.lars(x, y, plot.it = FALSE, mode = "step")
idx <- which.max(cv$cv - cv$cv.error <= min(cv$cv))
coef(lars::lars(x, y))[idx,]

Майте на увазі, що це не зовсім те саме, тому що це зупинка у вузлі ласо (коли входить змінна) замість будь-якої точки.

Зверніть увагу, що glmnetзараз це кращий пакет, він активно підтримується, тим більше lars, і що раніше були питання щодо glmnetvs larsвідповіді (використовувані алгоритми відрізняються).

Що стосується вашого питання щодо використання ласо для вибору змінних, а потім підходити до OLS, то це триває дискусія. Google for OLS дописує Лассо, і є деякі статті, що обговорюють цю тему. Навіть автори Елементів статистичного навчання визнають, що це можливо.

Редагувати : Ось код для більш точного відтворення того, що glmnetвідбуваєтьсяlars

  cv <- lars::cv.lars(x, y, plot.it = FALSE)
  ideal_l1_ratio <- cv$index[which.max(cv$cv - cv$cv.error <= min(cv$cv))]
  obj <- lars::lars(x, y)
  scaled_coefs <- scale(obj$beta, FALSE, 1 / obj$normx)
  l1 <- apply(X = scaled_coefs, MARGIN = 1, FUN = function(x) sum(abs(x)))
  coef(obj)[which.max(l1 / tail(l1, 1) > ideal_l1_ratio),]

+1 Відмінна відповідь! Чи можете ви чи хтось детальніше розібратися в тому, чому lambda.1se - це правило, а не lambda.min?
Єросеннін

Після 4 років написання цього (і не використовуючи ласо певний час) моя пам’ять просто зникла. Вибачте!
Juancentro

8

Повертаюсь до цього питання ще деякий час тому, оскільки думаю, що я вирішив правильне рішення.

Ось репліка за допомогою набору даних mtcars:

library(glmnet)
`%ni%`<-Negate(`%in%')
data(mtcars)

x<-model.matrix(mpg~.,data=mtcars)
x=x[,-1]

glmnet1<-cv.glmnet(x=x,y=mtcars$mpg,type.measure='mse',nfolds=5,alpha=.5)

c<-coef(glmnet1,s='lambda.min',exact=TRUE)
inds<-which(c!=0)
variables<-row.names(c)[inds]
variables<-variables[variables %ni% '(Intercept)']

'змінні' дає вам список змінних, які вирішують найкраще рішення.


1
Я шукав код і виявляю, що "тестування" ще не було визначено, і тому код: "final.list <-тестування [-перемовлено] # змінні змінні" дає помилку: об'єкт не знайдено припустимо, що замість використання "тестування" слід використовувати "cp.list", так що код буде: final.list <-cp.list [-removed] #removing змінних final.list <-c (final.list, дублікатів) #adding в тих варіантах, які обидва вилучено, потім додано пізніше Повідомте мене, чи це правильно. З повагою

3
`% ni%` <-Negate (`% ni%`); ## виглядає неправильно. Тоді як `% ni%` <-Negate (`% у%`); ## виглядає правильно. Я думаю, форматник stackexchange зіпсував це ...
Кріс,

Чи можете ви уточнити, як ви вибрали параметри nfolds=5та alpha=0.5параметри?
colin

7

Можливо, порівняння з поступовою регресією вибору допоможе (див. Наступне посилання на сайт одного з авторів http://www-stat.stanford.edu/~tibs/lasso/simple.html). Такий підхід використовується в главі 3.4.4 Елементів статистичного навчання (доступна в Інтернеті безкоштовно). Я подумав, що глава 3.6 цієї книги допомагає зрозуміти взаємозв'язок між найменшими квадратами, кращими підмножинами та ласо (плюс пару інших процедур). Я також вважаю корисним взяти транспонент коефіцієнта, t (coef (модель)) та write.csv, щоб я міг відкрити його в Excel разом із копією сюжету (моделі) збоку. Ви можете сортувати за останнім стовпцем, який містить оцінку найменших квадратів. Тоді ви чітко бачите, як кожна змінна додається на кожному кусковому кроці та як змінюються коефіцієнти в результаті. Звичайно, це не вся історія, але, сподіваємось, це буде початком.


3

larsі glmnetоперують сировинними матрицями. Щоб включити умови взаємодії, вам доведеться будувати матриці самостійно. Це означає один стовпчик на взаємодію (що є рівнем на фактор, якщо у вас є фактори). Загляньте, lm()щоб побачити, як це робиться (попередження: є дракони).

Щоб зробити це прямо зараз, зробіть щось на кшталт: Щоб зробити термін взаємодії вручну, ви могли (але, можливо, не варто , тому що це повільно):

int = D["x1"]*D["x2"]
names(int) = c("x1*x2")
D = cbind(D, int)

Потім скористайтеся цим у ларах (якщо припустити, що ви yб'єтесь):

lars(as.matrix(D), as.matrix(y))

Я б хотів, щоб я міг вам більше допомогти з іншими питаннями. Я знайшов цю, тому що Ларс приносить мені горе, а документація в ньому та в Інтернеті дуже тонка.


2
"Попередження: бути драконами" З цим досить легко model.matrix().
Грегор

2

LARS вирішує ВСІЙ шлях рішення. Шлях рішення кусочно лінійний - існує кінцева кількість точок "висічки" (тобто значень параметра регуляризації), при яких рішення змінюється.

Отже матриця рішень, які ви отримуєте, - це всі можливі рішення. У списку, який він повертає, він також повинен дати вам значення параметра регуляризації.


Спасибі за вашу відповідь. Чи існує спосіб відображення значень параметра регуляризації? Додатково чи є спосіб вибрати між рішеннями на основі цього параметра? (Також параметр лямбда?)
Джеймс

Зауважте, що кусочно-лінійність не означає, що лінії є горизонтальними, і таким чином рішення постійно змінюється лямбда. Наприклад, для прогнозних цілей може бути сітка значень лямбда не тільки на, але і між вузлами. Цілком можливо, що деяка точка між вузлами дає найкращі кращі показники прогнозування.
Річард Харді
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.