Làm thế nào để giải thích glmnet?


36

Tôi đang cố gắng phù hợp với mô hình hồi quy tuyến tính đa biến với khoảng 60 biến dự đoán và 30 quan sát, vì vậy tôi đang sử dụng gói glmnet để hồi quy chính quy vì p> n.

Tôi đã xem qua tài liệu và các câu hỏi khác nhưng tôi vẫn không thể giải thích kết quả, đây là mã mẫu (với 20 dự đoán và 10 quan sát để đơn giản hóa):

Tôi tạo một ma trận x với các hàng num = num quan sát và num cols = num dự đoán và một vectơ y đại diện cho biến trả lời

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

Tôi phù hợp với mô hình glmnet để mặc định alpha (= 1 cho hình phạt lasso)

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

Tôi hiểu rằng tôi nhận được các dự đoán khác nhau với việc giảm giá trị của lambda (tức là hình phạt)

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

Bây giờ tôi dự đoán các giá trị Beta của mình, ví dụ: giá trị lambda nhỏ nhất được đưa ra từ 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

Nếu thay vào đó tôi chọn lambda với

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

Tất cả các biến sẽ là (.).

Nghi ngờ và câu hỏi:

  1. Tôi không chắc chắn về cách chọn lambda.
  2. Tôi có nên sử dụng các biến không (.) Để phù hợp với mô hình khác không? Trong trường hợp của tôi, tôi muốn giữ càng nhiều biến càng tốt.
  3. Làm thế nào để tôi biết giá trị p, tức là biến nào dự đoán đáng kể phản ứng?

Tôi xin lỗi vì kiến ​​thức thống kê kém của tôi! Và cảm ơn bạn đã giúp đỡ.


Có thể có một cái nhìn về gói CRAN hdi , rằng người ta cung cấp suy luận cho các mô hình chiều cao ...
Tom Wenseleers

Để giải thích đầy đủ về các phương pháp được sử dụng, tôi giới thiệu bạn đến bài viết này: projecteuclid.org/euclid.ss/1449670857
Tom Wenseleers

Câu trả lời:


40

Đây là một thực tế không trực quan - bạn thực sự không cần phải cung cấp cho glmnet một giá trị duy nhất của lambda. Từ tài liệu ở đây :

Không cung cấp một giá trị duy nhất cho lambda (để dự đoán sau khi sử dụng CV dự đoán () thay thế). Cung cấp thay vì một chuỗi giảm giá trị lambda. glmnet dựa vào sự ấm lên của nó bắt đầu cho tốc độ và nó thường nhanh hơn toàn bộ đường dẫn hơn là tính toán một lần duy nhất.

cv.glmnetsẽ giúp bạn chọn lambda, như bạn đã nói trong ví dụ của mình. Các tác giả của gói glmnet đề nghị cv$lambda.1sethay vì cv$lambda.min, nhưng trong thực tế tôi đã thành công với phần sau.

Sau khi chạy cv.glmnet, bạn không phải chạy lại glmnet! Mỗi lambda trong lưới ( cv$lambda) đã được chạy. Kỹ thuật này được gọi là "Khởi đầu ấm áp" và bạn có thể đọc thêm về nó ở đây . Diễn giải từ phần giới thiệu, kỹ thuật Khởi động ấm giúp giảm thời gian chạy các phương pháp lặp bằng cách sử dụng giải pháp cho một vấn đề tối ưu hóa khác (ví dụ: glmnet với lambda lớn hơn) làm giá trị khởi đầu cho vấn đề tối ưu hóa sau này (ví dụ: glmnet với lambda nhỏ hơn ).

Để giải nén chạy mong muốn cv.glmnet.fit, hãy thử điều này:

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

Sửa đổi (1/28/2017)

Không cần phải hack vào đối tượng glmnet như tôi đã làm ở trên; lấy lời khuyên của @ alex23lemm bên dưới và chuyển s = "lambda.min", s = "lambda.1se"hoặc một số số khác (ví dụ s = .007:) cho cả hai coefpredict. Lưu ý rằng các hệ số và dự đoán của bạn phụ thuộc vào giá trị này được đặt bằng xác thực chéo. Sử dụng hạt giống để tái sản xuất! Và đừng quên rằng nếu bạn không cung cấp một "s"trong coefpredict, bạn sẽ được sử dụng mặc định của s = "lambda.1se". Tôi đã làm nóng đến mặc định đó sau khi thấy nó hoạt động tốt hơn trong một tình huống dữ liệu nhỏ.s = "lambda.1se"cũng có xu hướng cung cấp chính quy hơn, vì vậy nếu bạn đang làm việc với alpha> 0, thì nó cũng sẽ có xu hướng hướng tới một mô hình khác biệt hơn. Bạn cũng có thể chọn một giá trị số của s với sự trợ giúp của plot.glmnet để đến một nơi nào đó ở giữa (chỉ cần đừng quên lũy thừa các giá trị từ trục x!).


1
Cảm ơn bạn! Điều này giúp ... bạn có thể có câu trả lời cho câu hỏi 2 và 3 không?
Alice

3
Hà không lo lắng. (.) S đại diện cho số không. Vì bạn đã đi với Lasso, bạn đã chỉ định rằng bạn muốn một giải pháp "thưa thớt" (nghĩa là nhiều số không). Nếu bạn muốn tất cả chúng đều có giá trị, hãy đặt alpha = 0. Bây giờ bạn đã đi từ hồi quy Lasso sang Ridge. giá trị p cho glmnet về mặt khái niệm là khó khăn. Ví dụ, nếu bạn tìm kiếm "giá trị p cho lasso", bạn sẽ thấy rất nhiều nghiên cứu và tranh luận gần đây. Tôi thậm chí đã đọc một tài khoản (mất trí nhớ nguồn) trong đó tác giả lập luận rằng giá trị p không có ý nghĩa đối với các hồi quy sai lệch như lasso và hồi quy sườn.
Ben Ogorek

6
Một cách khác để trích xuất các hệ số liên quan đến giá trị của lambda cung cấp cvm tối thiểu là như sau:small.lambda.betas <- coef(cv, s = "lambda.min")
alex23lemm

1
@BenOgorek, cập nhật tuyệt vời! Một tài liệu tham khảo hữu ích khác là Friedman J, Hastie T, Hoefling H, Tibshirani R. Tối ưu hóa phối hợp Pathwise. Biên niên sử thống kê ứng dụng. 2007; 2 (1): 302 Hàng32. ( arxiv.org/pdf/0708.1485.pdf )
dv_bn

1
@erosennin, hãy xem đối số lambda của cv.glmnet: "Trình tự lambda do người dùng cung cấp tùy chọn; mặc định là NULL và glmnet chọn trình tự riêng." Bạn sẽ muốn sử dụng nguyên tắc khởi động ấm áp và bắt đầu chuỗi với một số giá trị lớn hơn của lambda trước khi giảm xuống phạm vi bạn quan tâm.
Ben Ogorek

2

Q1) Tôi không chắc chắn về cách chọn lambda. Câu 2) Tôi có nên sử dụng các biến không (.) Để phù hợp với mô hình khác không? Trong trường hợp của tôi, tôi muốn giữ càng nhiều biến càng tốt.

Theo câu trả lời tuyệt vời của @ BenOgorek, thông thường bạn cho phép sử dụng toàn bộ chuỗi lambda, sau đó khi trích xuất các hệ số tối ưu, hãy sử dụng giá trị lambda.1se (không giống như những gì bạn đã làm).

Miễn là bạn tuân theo ba cảnh báo dưới đây, thì đừng chống lại việc chính quy hóa hoặc điều chỉnh mô hình: nếu một biến bị bỏ qua, thì đó là vì nó đưa ra mức phạt chung thấp hơn. Hãy cẩn thận là:

  1. Để các hệ số được chuẩn hóa có ý nghĩa, hãy đảm bảo rằng bạn đã chuẩn hóa rõ ràng giá trị trung bình của biến và stdev trước đó với scale(); đừng dựa vào glmnet(standardize=T). Để biện minh, xem tiêu chuẩn hóa trước khi Lasso thực sự cần thiết? ; về cơ bản, một biến có giá trị lớn có thể bị trừng phạt không công bằng khi chính quy hóa.

  2. Để có thể tái sản xuất, hãy chạy với set.seedmột số hạt ngẫu nhiên và kiểm tra các hệ số chính quy cho sự ổn định.

  3. Nếu bạn muốn ít chính quy hóa hơn, tức là bao gồm nhiều biến hơn, hãy sử dụng alpha <1 (nghĩa là lưới đàn hồi thích hợp) thay vì sườn đơn giản. Tôi khuyên bạn nên quét alpha từ 0 đến 1. Nếu bạn sẽ làm điều đó, thì để tránh làm quá mức alpha siêu tham số và lỗi hồi quy, bạn phải sử dụng tính năng chéo, nghĩa là sử dụng cv.glmnet()thay vì đơn giản 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...
}

Nếu bạn muốn tự động hóa việc tìm kiếm lưới như vậy với CV, bạn có thể tự viết mã hoặc sử dụng gói caret trên đầu trang của glmnet; Caret làm điều này tốt. Đối với cv.glmnet nfoldsgiá trị tham số, chọn 3 (tối thiểu) nếu tập dữ liệu của bạn nhỏ hoặc 5 hoặc 10 nếu lớn.

Câu 3) Làm thế nào để tôi biết giá trị p, tức là biến nào dự đoán đáng kể phản ứng?

Đừng, chúng không có ý nghĩa . Như đã giải thích chi tiết tại sao không thể lấy thông tin tóm tắt thống kê cho các hệ số hồi quy từ mô hình glmnet?

Chỉ cần để cv.glmnet()thực hiện lựa chọn biến tự động. Với những cảnh báo ở trên. Và tất nhiên, việc phân phối biến trả lời phải bình thường (giả sử bạn đang sử dụng family='gaussian').


Cảm ơn các bình luận rất hữu ích! Bản thân tôi cũng đã trải nghiệm rằng việc chuẩn hóa các biến dường như hoạt động hơn là sử dụng glmnet (standardize = T).
Michelle

Tôi có một câu hỏi @smci, về các giá trị beta được trả về bởi cvglmnet. Tôi hiểu rằng chúng là các giá trị beta tại mỗi điểm lưới của các giá trị lambda đã thử. Tuy nhiên, các giá trị beta được trả về cho mỗi giá trị lambda (1) các giá trị hệ số trung bình từ 10 lần (giả sử tôi đã sử dụng 10 FoldCV), (2) các giá trị beta từ nếp gấp cho độ chính xác cao nhất hoặc (3) các hệ số từ Chạy lại mô hình trên toàn bộ dữ liệu?
Michelle
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.