Як інтерпретувати glmnet?


36

Я намагаюся підходити до багатоваріантної лінійної регресійної моделі з приблизно 60 змінними предиктора та 30 спостереженнями, тому я використовую пакет glmnet для регульованої регресії, оскільки p> n.

Я переглядав документацію та інші питання, але все ще не можу інтерпретувати результати, ось зразок коду (з 20 прогнозовами та 10 спостереженнями для спрощення):

Я створюю матрицю x з числовими рядками = num спостереженнями і num cols = num preictors and vector y, який представляє змінну відповіді

> x=matrix(rnorm(10*20),10,20)
> y=rnorm(10)

Я підходить до моделі glmnet, яка залишає альфа за замовчуванням (= 1 для ласового штрафу)

> fit1=glmnet(x,y)
> print(fit1)

Я розумію, я отримую різні прогнози зі зменшенням значень лямбда (тобто штрафу)

Call:  glmnet(x = x, y = y) 

        Df    %Dev   Lambda
  [1,]  0 0.00000 0.890700
  [2,]  1 0.06159 0.850200
  [3,]  1 0.11770 0.811500
  [4,]  1 0.16880 0.774600
   .
   .
   .
  [96,] 10 0.99740 0.010730
  [97,] 10 0.99760 0.010240
  [98,] 10 0.99780 0.009775
  [99,] 10 0.99800 0.009331
 [100,] 10 0.99820 0.008907

Тепер я прогнозую свої бета-значення, вибираючи, наприклад, найменше значення лямбда, задане з glmnet

> predict(fit1,type="coef", s = 0.008907)

21 x 1 sparse Matrix of class "dgCMatrix"
                  1
(Intercept) -0.08872364
V1           0.23734885
V2          -0.35472137
V3          -0.08088463
V4           .         
V5           .         
V6           .         
V7           0.31127123
V8           .         
V9           .         
V10          .         
V11          0.10636867
V12          .         
V13         -0.20328200
V14         -0.77717745
V15          .         
V16         -0.25924281
V17          .         
V18          .         
V19         -0.57989929
V20         -0.22522859

Якщо замість цього я вибираю лямбда з

cv <- cv.glmnet(x,y)
model=glmnet(x,y,lambda=cv$lambda.min)

Усі змінні будуть (.).

Сумніви та питання:

  1. Я не впевнений, як вибрати лямбда.
  2. Чи варто використовувати не (.) Змінні, щоб відповідати іншій моделі? У моєму випадку я хотів би зберегти якомога більше змінних.
  3. Як я можу знати значення p, тобто які змінні значно прогнозують відповідь?

Прошу вибачення за свої слабкі статистичні знання! І дякую за будь-яку допомогу.


Можливо, подивіться на пакет CRAN hdi , який дає висновок для високомірних моделей ...
Том Венселер

Для повного пояснення використовуваних методів я посилаюсь на цей документ: projecteuclid.org/euclid.ss/1449670857
Том Венселерс

Відповіді:


40

Ось неінтуїтивний факт - ви насправді не повинні давати glmnet єдиного значення лямбда. З документації тут :

Не вводьте єдиного значення для лямбда (для прогнозів після використання CV передбачте () натомість). Натомість подайте зменшувану послідовність лямбда-значень. glmnet покладається на свої теплі пуски на швидкість, і його часто швидше пройти цілий шлях, ніж обчислити один fi t.

cv.glmnetдопоможе вам вибрати лямбда, як ви нагадали у своїх прикладах. Автори пакету glmnet пропонують cv$lambda.1seзамість цього cv$lambda.min, але на практиці я мав успіх з останнім.

Після запуску cv.glmnet вам не доведеться повторювати glmnet! Кожна лямбда в сітці ( cv$lambda) вже запущена. Ця методика називається «Теплий старт», і про неї ви можете прочитати більше тут . Перефразовуючи вступ, техніка «Теплий запуск» скорочує час запуску ітеративних методів, використовуючи рішення іншої задачі оптимізації (наприклад, glmnet з більшим лямбда) як вихідне значення для подальшої проблеми оптимізації (наприклад, glmnet із меншою лямбдаю ).

Щоб отримати потрібний запуск cv.glmnet.fit, спробуйте:

small.lambda.index <- which(cv$lambda == cv$lambda.min)
small.lambda.betas <- cv$glmnet.fit$beta[, small.lambda.index]

Редакція (28.01.2017)

Немає необхідності злому до об’єкта glmnet, як я це робив вище; прийняти @ рада alex23lemm в нижче і передати s = "lambda.min", s = "lambda.1se"або який - або інший номер (наприклад, s = .007) для обох coefі predict. Зауважте, що ваші коефіцієнти та прогнози залежать від цього значення, яке встановлюється перехресною валідацією. Використовуйте насіння для відтворення! І не забувайте , що якщо ви не надаєте "s"в coefі predict, ви будете використовувати значення за замовчуванням s = "lambda.1se". Я прогрівся до цього за замовчуванням, побачивши, що він працює краще в невеликій ситуації з даними.s = "lambda.1se"також має тенденцію до більшої регуляризації, тому якщо ви працюєте з альфа> 0, вона також буде спрямована на більш парсимоніальну модель. Ви також можете вибрати числове значення s за допомогою plot.glmnet, щоб дістатися десь посередині (просто не забудьте позначити значення по осі x!).


1
Дякую! Це допомагає ... Ви можете мати відповідь на питання 2 та 3?
Аліса

3
Ха не хвилюйся. (.) S позначають нулі. Оскільки ви поїхали з Лассо, ви вказали, що хочете "рідкого" рішення (тобто, багато нулів). Якщо ви хочете, щоб вони мали значення, встановіть альфа = 0. Тепер ви пройшли шлях від регресії Лассо до хребта. p-значення для glmnet концептуально складні. Наприклад, якщо ви шукаєте в Google "p-значення для ласо", ви побачите багато останніх досліджень та дискусій. Я навіть прочитав один рахунок (джерело амнезії), де автор стверджував, що p-значення не мають сенсу для упереджених регресій, таких як регресія ласо та хребта.
Бен Огорек

6
Альтернативний спосіб отримання коефіцієнтів, пов'язаних зі значенням лямбда, що дає мінімальний оберт, є наступним:small.lambda.betas <- coef(cv, s = "lambda.min")
alex23lemm

1
@BenOgorek, відмінне оновлення! Ще одна корисна посилання - Фрідман Дж, Хасті Т, Гоефлінг Н, Тібширані Р. Оптимізація координат шляхом. Літописи прикладної статистики. 2007; 2 (1): 302–332. ( arxiv.org/pdf/0708.1485.pdf )
dv_bn

1
@erosennin, ознайомтеся з аргументом лямбда cv.glmnet: "Необов'язкова послідовність лямбда, що надається користувачем; за замовчуванням NULL, і glmnet вибирає свою послідовність." Ви захочете скористатися принципом теплого старту і розпочати послідовність з деякими більшими значеннями лямбда, перш ніж зменшуватися до діапазону, який вас цікавить.
Бен Огорек,

2

Q1) Я не впевнений, як вибрати лямбда. Q2) Чи слід використовувати не (.) Змінні, щоб відповідати іншій моделі? У моєму випадку я хотів би зберегти якомога більше змінних.

Відповідно до чудової відповіді @ BenOgorek, ти, як правило, дозволяє дозволити використовувати всю лямбда-послідовність, тоді при вилученні оптимальних коефіцієнтів використовується значення lambda.1se (на відміну від того, що ти робив).

Поки ви дотримуєтеся трьох застережень, наведених нижче, тоді не боріться з регуляризацією та не змінюйте модель: якщо змінна була опущена, то це було тому, що вона дала менший загальний штраф. Застереженнями є:

  1. Щоб регульовані коефіцієнти були значимими, переконайтеся, що ви явно нормалізували середнє значення змінної та stdev заздалегідь з scale(); не покладатися на glmnet(standardize=T). Для обґрунтування див. Чи справді необхідна стандартизація перед Лассо? ; в основному змінна з великими значеннями може бути несправедливо покарана при регуляризації.

  2. Щоб відтворити, запустіть із set.seedкількома випадковими насінням та перевірте регульовані коефіцієнти на стійкість.

  3. Якщо ви хочете менше суворої регуляризації, тобто більше змінних, використовуйте альфа <1 (тобто належну еластичну сітку), а не просту грядку. Я пропоную вам розгорнути альфа від 0 до 1. Якщо ви збираєтесь це робити, то щоб уникнути перенавантаження альфа-гіперфактора та помилки регресії, ви повинні використовувати кросвалідизацію, тобто використовувати cv.glmnet()не просто glmnet():

.

for (alpha in c(0,.1,.3,.5,.7,.9,1)) {
  fit <- cv.glmnet(..., alpha=alpha, nfolds=...)
  # Look at the CVE at lambda.1se to find the minimum for this alpha value...
}

Якщо ви хочете автоматизувати таку пошукову мережу за допомогою CV, ви можете або кодувати її самостійно, або скористатися пакетом кареток поверх glmnet; caret робить це добре. Для cv.glmnet nfoldsзначення параметра виберіть 3 (мінімум), якщо ваш набір даних невеликий, або 5 або 10, якщо він великий.

Q3) Як я можу знати значення p, тобто які змінні істотно прогнозують відповідь?

Ні, вони не мають сенсу . Як детально пояснено у Чому не рекомендується отримувати статистичну підсумкову інформацію для коефіцієнтів регресії з моделі glmnet?

Дозвольте cv.glmnet()зробити вибір змінної автоматично. З застереженнями вище. І звичайно, розподіл змінної відповіді має бути нормальним (якщо ви користуєтесь family='gaussian').


Дякуємо за дуже корисний коментар! Я також зазначив, що стандартизація змінних сама по собі працює, а не використовувати glmnet (стандартизація = T).
Мішель

У мене питання @smci, щодо бета-значень, повернених cvglmnet, хоча. Я розумію, що вони бета-значення у кожній точці сітки спроб значень лямбда. Однак чи повертаються бета-значення для кожного значення лямбда (1) середні значення коефіцієнта з 10-ти кратних (якщо припустити, що я використовував 10-кратне значення CV), (2) бета-значення зі складки, що дало найкращу точність, або (3) коефіцієнти від повторний запуск моделі на цілому наборі даних?
Мішель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.