Một ví dụ: Hồi quy LASSO bằng glmnet cho kết quả nhị phân


77

Tôi bắt đầu say mê với việc sử dụng glmnetvới LASSO Regression trong đó kết quả quan tâm của tôi là phân đôi. Tôi đã tạo một khung dữ liệu giả nhỏ bên dưới:

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)

Các cột (biến) trong bộ dữ liệu trên như sau:

  • age (tuổi của trẻ trong năm) - liên tục
  • gender - nhị phân (1 = nam; 0 = nữ)
  • bmi_p (Phân vị BMI) - liên tục
  • m_edu (trình độ học vấn cao nhất của mẹ) - thứ tự (0 = ít hơn trường trung học; 1 = bằng tốt nghiệp trung học; 2 = bằng cử nhân; 3 = bằng sau tú tài)
  • p_edu (trình độ học vấn cao nhất của cha) - thứ tự (giống như m_edu)
  • f_color (màu chính yêu thích) - danh nghĩa ("xanh", "đỏ" hoặc "vàng")
  • asthma (tình trạng hen suyễn ở trẻ em) - nhị phân (1 = hen; 0 = không hen)

Mục đích của ví dụ này là tận dụng Lasso để tạo ra một mô hình dự đoán tình trạng hen suyễn trẻ từ danh sách 6 biến dự báo tiềm năng ( age, gender, bmi_p, m_edu, p_edu, và f_color). Rõ ràng kích thước mẫu là một vấn đề ở đây, nhưng tôi hy vọng sẽ hiểu rõ hơn về cách xử lý các loại biến khác nhau (nghĩa là liên tục, thứ tự, danh nghĩa và nhị phân) trong glmnetkhung khi kết quả là nhị phân (1 = hen ; 0 = không hen suyễn).

Như vậy, liệu có ai sẵn sàng cung cấp một Rtập lệnh mẫu cùng với các giải thích cho ví dụ giả này bằng cách sử dụng LASSO với dữ liệu trên để dự đoán tình trạng hen suyễn không? Mặc dù rất cơ bản, tôi biết tôi, và có thể nhiều người khác trong CV, sẽ đánh giá rất cao điều này!


2
Bạn có thể nhận được may mắn hơn nếu bạn gửi dữ liệu như một dputcủa một thực tế đối tượng R; đừng bắt độc giả phủ sương lên trên cũng như nướng bánh cho bạn!. Nếu bạn tạo khung dữ liệu phù hợp trong R, giả sử foo, sau đó chỉnh sửa thành câu hỏi đầu ra của dput(foo).
Gavin Simpson

Cảm ơn @GavinSimpson! Tôi đã cập nhật bài đăng với một khung dữ liệu để hy vọng tôi có thể ăn một ít bánh mà không bị đóng băng! :)
Matt Reichenbach

2
Bằng cách sử dụng phân vị BMI, bạn có ý thức thách thức các định luật vật lý. Béo phì ảnh hưởng đến các cá nhân theo các phép đo vật lý (chiều dài, khối lượng, trọng lượng) không theo số lượng cá nhân tương tự như đối tượng hiện tại, đó là những gì phần trăm đang làm.
Frank Harrell

3
Tôi đồng ý, phân vị BMI không phải là số liệu mà tôi thích sử dụng; tuy nhiên, hướng dẫn của CDC khuyến nghị sử dụng tỷ lệ phần trăm BMI so với BMI (cũng là một số liệu đáng nghi ngờ!) cho trẻ em và thanh thiếu niên dưới 20 tuổi vì nó tính đến tuổi và giới tính ngoài chiều cao và cân nặng. Tất cả các biến và giá trị dữ liệu này đã được nghĩ ra hoàn toàn cho ví dụ này. Ví dụ này không phản ánh bất kỳ công việc hiện tại nào của tôi khi tôi làm việc với dữ liệu lớn. Tôi chỉ muốn xem một ví dụ về glmnethành động với kết quả nhị phân.
Matt Reichenbach

Cắm vào đây một gói bởi Patrick Breheny gọi là ncvreg phù hợp với mô hình hồi quy tuyến tính và logistic bị MCP, SCAD hoặc LASSO phạt. ( cran.r-project.org/web/packages/ncvreg/index.html )
bdeonovic

Câu trả lời:


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")

nhập mô tả hình ảnh ở đây

Các biến phân loại thường được chuyển đổi đầu tiên thành các yếu tố, sau đó một ma trận biến giả của các yếu tố dự đoán được tạo ra và cùng với các yếu tố dự đoán liên tục, được truyền cho mô hình. Hãy nhớ rằng, glmnet sử dụng cả hình phạt sườn núi và lasso, nhưng có thể được đặt thành một mình.

Một số kết quả:

# 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
# ...

Các hệ số có thể được trích xuất từ ​​glmmod. Ở đây hiển thị với 3 biến được chọn.

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 

Cuối cùng, xác nhận chéo cũng có thể được sử dụng để chọn lambda.

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

nhập mô tả hình ảnh ở đây

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

4
đây chính xác là những gì tôi đang tìm kiếm +1, câu hỏi duy nhất tôi có là 1) bạn có thể làm gì với lambda xác thực chéo là 0,2732972? và 2) Từ glmmod, các biến được chọn có màu sắc yêu thích (màu vàng), giới tính và giáo dục của cha (bằng cử nhân) không? Cám ơn rất nhiều!
Matt Reichenbach

4
1) Xác thực chéo được sử dụng để chọn lambda và hệ số (tại lỗi tối thiểu). Trong mockup này, không có min địa phương (có một cảnh báo cũng liên quan đến quá ít obs); Tôi sẽ giải thích rằng tất cả các hệ số đã được thu nhỏ về 0 với các hình phạt co rút (mô hình tốt nhất chỉ có đánh chặn) và chạy lại với các quan sát (thực tế) hơn và có thể tăng phạm vi lambda. 2) Có, trong ví dụ tôi chọn coef (glmmod) [, 10] ... bạn chọn lambda cho mô hình thông qua CV hoặc giải thích kết quả. Bạn có thể đánh dấu là đã giải quyết nếu bạn cảm thấy tôi đã giải quyết câu hỏi của bạn? cảm ơn.
vỗ

2
Tôi có thể hỏi làm thế nào điều này xử lý các f_colorbiến? Là yếu tố cấp 1 đến 4 được coi là một bước lớn hơn từ 1 đến 2, hay tất cả đều có trọng số như nhau, không định hướng và phân loại? (Tôi muốn áp dụng nó cho một phân tích với tất cả các dự đoán không có thứ tự.)
beroe

3
Dòng xfactors <- model.matrix(asthma ~ gender + m_edu + p_edu + f_color)[,-1]mã biến phân loại f_color (như được khai báo as.factortrong các dòng trước). Nó nên sử dụng mã hóa biến giả R mặc định, trừ khi contrasts.argđối số được cung cấp. Điều này có nghĩa là tất cả các cấp độ của f_color đều có trọng số như nhau và không định hướng, ngoại trừ cấp độ đầu tiên được sử dụng làm lớp tham chiếu và được hấp thụ vào phần chặn.
Alex

1
@Alex sẽ không model.matrix(asthma ~ gender + m_edu + p_edu + f_color + age + bmi_p)[, -1]cho kết quả giống như hai dòng trên? Tại sao sử dụng một bước bổ sung để nối các biến liên tục với data.frame?
jiggunjer

6

Tôi sẽ sử dụng gói enet vì đó là phương thức được ưu tiên của tôi. Nó linh hoạt hơn một chút.

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
cảm ơn đã chia sẻ elasticnet; tuy nhiên, tôi không biết phải làm gì cho đầu ra từ Rtập lệnh trên . Bạn có thể vui lòng làm rõ? Cảm ơn trước!
Matt Reichenbach

4

Chỉ để mở rộng trên ví dụ tuyệt vời được cung cấp bởi pat. Vấn đề ban đầu đặt ra các biến số thứ tự (m_edu, p_edu), với một trật tự vốn có giữa các cấp độ (0 <1 <2 <3). Trong câu trả lời ban đầu của pat tôi nghĩ rằng chúng được coi là các biến phân loại danh nghĩa không có thứ tự giữa chúng. Tôi có thể sai, nhưng tôi tin rằng các biến này nên được mã hóa sao cho mô hình tôn trọng trật tự vốn có của chúng. Nếu các yếu tố này được mã hóa thành các yếu tố theo thứ tự (chứ không phải là các yếu tố không được sắp xếp như trong câu trả lời của pat) thì glmnet cho kết quả hơi khác nhau ... Tôi nghĩ rằng mã dưới đây bao gồm chính xác các biến thứ tự là các yếu tố được đặt hàng và nó cho kết quả hơi khác:

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")

nhập mô tả hình ảnh ở đây


1
đôi khi_sci, nắm bắt tốt - đây sẽ là cách thích hợp hơn để mô hình hóa các biến cấp độ giáo dục. Cảm ơn sự đóng góp của bạn.
Matt Reichenbach

Làm thế nào người ta có thể thêm một huyền thoại cốt truyện cho các biến? Ví dụ, dòng màu đỏ trong ví dụ này là gì?
jiggunjer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.