Приклад: регресія LASSO з використанням glmnet для двійкового результату


77

Я починаю балуватися з використанням glmnetз LASSO регресією , де мій результат становить інтерес дихотомический. Я створив невеликий макетний кадр даних нижче:

age     <- c(4, 8, 7, 12, 6, 9, 10, 14, 7) 
gender  <- c(1, 0, 1, 1, 1, 0, 1, 0, 0)
bmi_p   <- c(0.86, 0.45, 0.99, 0.84, 0.85, 0.67, 0.91, 0.29, 0.88)
m_edu   <- c(0, 1, 1, 2, 2, 3, 2, 0, 1)
p_edu   <- c(0, 2, 2, 2, 2, 3, 2, 0, 0)
f_color <- c("blue", "blue", "yellow", "red", "red", "yellow", "yellow", 
             "red", "yellow")
asthma  <- c(1, 1, 0, 1, 0, 0, 0, 1, 1)
# df is a data frame for further use!
df <- data.frame(age, gender, bmi_p, m_edu, p_edu, f_color, asthma)

Стовпці (змінні) у наведеному вище наборі даних є такими:

  • age (вік дитини в роках) - безперервний
  • gender - двійкові (1 = чоловік; 0 = жінка)
  • bmi_p (ІМТ перцентил) - безперервний
  • m_edu (рівень вищої освіти матері) - порядковий (0 = менше середньої школи; 1 = диплом середньої школи; 2 = ступінь бакалавра; 3 = ступінь бакалавра)
  • p_edu (рівень вищої освіти батька) - порядковий (такий же, як m_edu)
  • f_color (улюблений основний колір) - номінальний ("синій", "червоний" або "жовтий")
  • asthma (стан дитячої астми) - бінарний (1 = астма; 0 = відсутність астми)

Мета цього прикладу використовувати ласо , щоб створити модель прогнозування стану дитини астми зі списку 6 потенційних предикторів ( age, gender, bmi_p, m_edu, p_edu, і f_color). Очевидно, розмір вибірки тут є проблемою, але я сподіваюся отримати більше розуміння того, як поводитися з різними типами змінних (тобто безперервними, порядковими, номінальними та бінарними) в glmnetрамках, коли результат є двійковим (1 = астма ; 0 = відсутність астми).

Як такий, чи бажає хто-небудь надати зразковий Rсценарій разом з поясненнями для цього прикладного зразка, використовуючи LASSO з вищезазначеними даними для прогнозування стану астми? Хоча я дуже основна, я знаю, що я, і, ймовірно, багато хто з резюме, дуже вдячна б за це!


2
Ви можете отримати більше удачі , якщо ви вивісили дані як dputз фактичного об'єкта R; не змушуйте читачів ставити глазур зверху, а не пекти торт !. Якщо ви генеруєте відповідний кадр даних у R, скажімо foo, відредагуйте у питанні вихід dput(foo).
Гавін Сімпсон

Дякую @GavinSimpson! Я оновив публікацію за допомогою фрейму даних, тому, сподіваюся, я з'їм якийсь торт, не заморожуючи! :)
Метт Рейхенбах

2
Використовуючи ІМТ перцентил, ви певним чином протистоїть законам фізики. Ожиріння впливає на індивідів за фізичними вимірюваннями (довжини, обсяги, вагу), не залежно від того, наскільки особини схожі на поточний предмет, що і робить процентилінг.
Френк Харрелл

3
Я згоден, ІМТ перцентил не є показником, який я вважаю за краще використовувати; однак, рекомендації CDC рекомендують використовувати перцентилі ІМТ над ІМТ (також дуже сумнівним показником!) для дітей та підлітків молодше 20 років, оскільки він враховує вік і стать на додаток до зросту та ваги. Усі ці змінні та значення даних були повністю продумані для цього прикладу. Цей приклад не відображає жодної моєї поточної роботи, коли я працюю з великими даними. Я просто хотів побачити приклад glmnetдії з двійковим результатом.
Метт Райхенбах

Підключіть сюди пакет Patrick Breheny під назвою ncvreg, який відповідає лінійним та логістичним регресійним моделям, покараним MCP, SCAD або LASSO. ( cran.r-project.org/web/packages/ncvreg/index.html )
bdeonovic

Відповіді:


100
library(glmnet)

age     <- c(4, 8, 7, 12, 6, 9, 10, 14, 7) 
gender  <- as.factor(c(1, 0, 1, 1, 1, 0, 1, 0, 0))
bmi_p   <- c(0.86, 0.45, 0.99, 0.84, 0.85, 0.67, 0.91, 0.29, 0.88) 
m_edu   <- as.factor(c(0, 1, 1, 2, 2, 3, 2, 0, 1))
p_edu   <- as.factor(c(0, 2, 2, 2, 2, 3, 2, 0, 0))
f_color <- as.factor(c("blue", "blue", "yellow", "red", "red", "yellow", 
                       "yellow", "red", "yellow"))
asthma <- c(1, 1, 0, 1, 0, 0, 0, 1, 1)

xfactors <- model.matrix(asthma ~ gender + m_edu + p_edu + f_color)[, -1]
x        <- as.matrix(data.frame(age, bmi_p, xfactors))

# Note alpha=1 for lasso only and can blend with ridge penalty down to
# alpha=0 ridge only.
glmmod <- glmnet(x, y=as.factor(asthma), alpha=1, family="binomial")

# Plot variable coefficients vs. shrinkage parameter lambda.
plot(glmmod, xvar="lambda")

введіть тут опис зображення

Категоричні змінні зазвичай спочатку перетворюються на фактори, потім створюється макетна змінна матриця предикторів і разом з неперервними предикторами передається в модель. Майте на увазі, glmnet використовує як гребінні, так і ласо-штрафи, але їх можна встановити як окремо.

Деякі результати:

# Model shown for lambda up to first 3 selected variables.
# Lambda can have manual tuning grid for wider range.

glmmod
# Call:  glmnet(x = x, y = as.factor(asthma), family = "binomial", alpha = 1) 
# 
#        Df    %Dev   Lambda
#   [1,]  0 0.00000 0.273300
#   [2,]  1 0.01955 0.260900
#   [3,]  1 0.03737 0.249000
#   [4,]  1 0.05362 0.237700
#   [5,]  1 0.06847 0.226900
#   [6,]  1 0.08204 0.216600
#   [7,]  1 0.09445 0.206700
#   [8,]  1 0.10580 0.197300
#   [9,]  1 0.11620 0.188400
#  [10,]  3 0.13120 0.179800
#  [11,]  3 0.15390 0.171600
# ...

Коефіцієнти можуть бути вилучені з glmmod. Тут показано з обраними 3 змінними.

coef(glmmod)[, 10]
#   (Intercept)           age         bmi_p       gender1        m_edu1 
#    0.59445647    0.00000000    0.00000000   -0.01893607    0.00000000 
#        m_edu2        m_edu3        p_edu2        p_edu3    f_colorred 
#    0.00000000    0.00000000   -0.01882883    0.00000000    0.00000000 
# f_coloryellow 
#   -0.77207831 

Нарешті, перехресне підтвердження також може використовуватися для вибору лямбда.

cv.glmmod <- cv.glmnet(x, y=asthma, alpha=1)
plot(cv.glmmod)

введіть тут опис зображення

(best.lambda <- cv.glmmod$lambda.min)
# [1] 0.2732972

4
це саме те, що я шукав +1, єдині питання у мене є 1) що ви можете зробити з перехресною лямбда-валідією 0,2732972? і 2) Чи є вибрані змінні улюблені кольори (жовтий), стать та освіченість батька (бакалавр)? Дуже дякую!
Метт Рейхенбах

4
1) Перехресне підтвердження використовується для вибору лямбда та коефіцієнтів (при мінімальній помилці). У цьому макеті немає локальної хвилини (було і попередження, пов’язане з надто малою кількістю затримок); Я б інтерпретував, що всі коефіцієнти були зменшені до нуля за штрафи за усадку (найкраща модель має лише перехоплення) і повторно запускаються з більшою кількістю (реальних) спостережень і, можливо, збільшують дальність лямбда. 2) Так, у прикладі, коли я вибрав coef (glmmod) [, 10] ... ви вибираєте лямбда для моделі за допомогою CV або інтерпретації результатів. Не могли б ви позначити як вирішене, якби відчували, що я вирішую ваше питання? Дякую.
пт

2
Чи можу я запитати, як це обробляє f_colorзмінну? Чи вважається рівень фактора від 1 до 4 більшим кроком, ніж 1 - 2, чи всі вони однаково зважені, не спрямовані та категоричні? (Я хочу застосувати його до аналізу з усіма не
упорядкованими прогнозами

3
Рядок xfactors <- model.matrix(asthma ~ gender + m_edu + p_edu + f_color)[,-1]кодує категоричну змінну f_color (як заявлено as.factorу попередніх рядках). Він повинен використовувати стандартне кодування змінної R за замовчуванням, якщо contrasts.argаргумент не наданий. Це означає, що всі рівні f_color однаково зважені та не спрямовані, за винятком першого, який використовується як опорний клас та поглинається в перехоплення.
Олексій

1
@Alex не model.matrix(asthma ~ gender + m_edu + p_edu + f_color + age + bmi_p)[, -1]дасть такого ж результату, як два вище рядки? Навіщо використовувати додатковий крок для об'єднання безперервних змінних data.frame?
jiggunjer

6

Я буду використовувати пакет enet, оскільки це мій бажаний метод. Це трохи гнучкіше.

install.packages('elasticnet')
library(elasticnet)

age <- c(4,8,7,12,6,9,10,14,7) 
gender <- c(1,0,1,1,1,0,1,0,0)
bmi_p <- c(0.86,0.45,0.99,0.84,0.85,0.67,0.91,0.29,0.88)
m_edu <- c(0,1,1,2,2,3,2,0,1)
p_edu <- c(0,2,2,2,2,3,2,0,0)
#f_color <- c("blue", "blue", "yellow", "red", "red", "yellow", "yellow", "red", "yellow")
f_color <- c(0, 0, 1, 2, 2, 1, 1, 2, 1)
asthma <- c(1,1,0,1,0,0,0,1,1)
pred <- cbind(age, gender, bmi_p, m_edu, p_edu, f_color)



enet(x=pred, y=asthma, lambda=0)

4
дякую за обмін elasticnet; однак я не знаю, що робити з результатів із вищевказаного Rсценарію. Ви можете, будь ласка, уточнити? Спасибі заздалегідь!
Метт Райхенбах

4

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

library(glmnet)

age     <- c(4, 8, 7, 12, 6, 9, 10, 14, 7) 
gender  <- as.factor(c(1, 0, 1, 1, 1, 0, 1, 0, 0))
bmi_p   <- c(0.86, 0.45, 0.99, 0.84, 0.85, 0.67, 0.91, 0.29, 0.88) 
m_edu   <- factor(c(0, 1, 1, 2, 2, 3, 2, 0, 1), 
                  ordered = TRUE)
p_edu   <- factor(c(0, 2, 2, 2, 2, 3, 2, 0, 0), 
                  levels = c(0, 1, 2, 3), 
                  ordered = TRUE)
f_color <- as.factor(c("blue", "blue", "yellow", "red", "red", 
                       "yellow", "yellow", "red", "yellow"))
asthma <- c(1, 1, 0, 1, 0, 0, 0, 1, 1)

xfactors <- model.matrix(asthma ~ gender + m_edu + p_edu + f_color)[, -1]
x        <- as.matrix(data.frame(age, bmi_p, xfactors))

# Note alpha=1 for lasso only and can blend with ridge penalty down to
# alpha=0 ridge only.
glmmod <- glmnet(x, y=as.factor(asthma), alpha=1, family="binomial")

# Plot variable coefficients vs. shrinkage parameter lambda.
plot(glmmod, xvar="lambda")

введіть тут опис зображення


1
Іноді_sci, хороший улов - це був би більш підходящий спосіб моделювання змінних рівнів освіти. Дякую за ваш внесок.
Метт Райхенбах

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