Tại sao hồi quy sườn glmnet cho tôi một câu trả lời khác với tính toán thủ công?


28

Tôi đang sử dụng glmnet để tính toán ước tính hồi quy sườn núi. Tôi đã nhận được một số kết quả khiến tôi nghi ngờ trong glmnet đó thực sự đang làm những gì tôi nghĩ nó làm. Để kiểm tra điều này, tôi đã viết một tập lệnh R đơn giản trong đó tôi so sánh kết quả của hồi quy sườn được thực hiện bằng cách giải và tập lệnh trong glmnet, sự khác biệt rất đáng kể:

n    <- 1000
p.   <-  100
X.   <- matrix(rnorm(n*p,0,1),n,p)
beta <- rnorm(p,0,1)
Y    <- X%*%beta+rnorm(n,0,0.5)

beta1 <- solve(t(X)%*%X+5*diag(p),t(X)%*%Y)
beta2 <- glmnet(X,Y, alpha=0, lambda=10, intercept=FALSE, standardize=FALSE, 
                family="gaussian")$beta@x
beta1-beta2

Định mức của sự khác biệt thường là khoảng 20 mà không thể là do các thuật toán khác nhau về số lượng, tôi phải làm gì đó sai. Các cài đặt tôi phải đặt glmnetđể có được kết quả tương tự như với sườn núi là gì?


1
Bạn đã thấy câu hỏi này ?
cdeterman

1
Có, nhưng tôi vẫn không nhận được kết quả tương tự khi sử dụng chuẩn hóa.
Giăng

Bạn có thể gửi mã của bạn sau đó?
Shadowtalker

Tôi cũng gặp vấn đề tương tự! a = data.frame (a = jitter (1:10), b = jitter (1:10), c = jitter (1:10), d = jitter (1:10), e = jitter (1:10) , f = jitter (1:10), g = mẫu (jitter (1:10)), y = seq (10,100,10)); coef (lm.ridge (y ~ a + b + c + d + e + f + g, a, lambda = 2.57)); coef (glmnet (as.matrix (a [, 1: 7]), a $ y, Family = "gaussian", alpha = 0, lambda = 2.57 / 10)) Kết quả khác nhau một chút và trở nên giống nhau hơn nhiều khi Tôi sử dụng lambdas cao hơn nhiều cho glmnet.
a11msp

Hấp dẫn. Các hệ số dường như khác nhau khoảng bởi hệ số 10.
tomka

Câu trả lời:


27

Sự khác biệt mà bạn đang quan sát là do sự phân chia bổ sung theo số lượng quan sát, N, mà GLMNET sử dụng trong hàm mục tiêu của họ và ngầm định tiêu chuẩn hóa Y theo độ lệch chuẩn của mẫu như dưới đây.

12NysyXβ22+λβ22/2

trong đó chúng tôi sử dụng thay cho cho , 1/n1/(n1)sy

sy=i(yiy¯)2n

Bằng cách phân biệt với beta, đặt phương trình về 0,

XTXβXTysy+Nλβ=0

Và giải quyết beta, chúng tôi có được ước tính,

β~GLMNET=(XTX+NλIp)1XTysy

Để khôi phục các ước tính (và hình phạt tương ứng của chúng) trên số liệu ban đầu của Y, GLMNET nhân cả hai ước tính và lambdas bằng và trả lại các kết quả này cho người dùng,sy

β^GLMNET=syβ~GLMNET=(XTX+NλIp)1XTy
λunstd.=syλ

So sánh giải pháp này với đạo hàm chuẩn của hồi quy sườn núi.

β^=(XTX+λIp)1XTy

Lưu ý rằng được chia tỷ lệ theo hệ số phụ của N. Ngoài ra, khi chúng tôi sử dụng hàm hoặc hàm, hình phạt sẽ được nhân rộng theo tỷ lệ . Điều đó có nghĩa là, khi chúng tôi sử dụng các hàm này để có được ước tính hệ số cho một số , chúng tôi có được các ước tính cho một cách hiệu quả .λpredict()coef()1/syλλ=λ/sy

Dựa trên những quan sát, hình phạt được sử dụng trong GLMNET cần được nhân rộng bởi một yếu tố của .sy/N

set.seed(123)

n    <- 1000
p   <-  100
X   <- matrix(rnorm(n*p,0,1),n,p)
beta <- rnorm(p,0,1)
Y    <- X%*%beta+rnorm(n,0,0.5)

sd_y <- sqrt(var(Y)*(n-1)/n)[1,1]

beta1 <- solve(t(X)%*%X+10*diag(p),t(X)%*%(Y))[,1]

fit_glmnet <- glmnet(X,Y, alpha=0, standardize = F, intercept = FALSE, thresh = 1e-20)
beta2 <- as.vector(coef(fit_glmnet, s = sd_y*10/n, exact = TRUE))[-1]
cbind(beta1[1:10], beta2[1:10])

           [,1]        [,2]
[1,]  0.23793862  0.23793862
[2,]  1.81859695  1.81859695
[3,] -0.06000195 -0.06000195
[4,] -0.04958695 -0.04958695
[5,]  0.41870613  0.41870613
[6,]  1.30244151  1.30244151
[7,]  0.06566168  0.06566168
[8,]  0.44634038  0.44634038
[9,]  0.86477108  0.86477108
[10,] -2.47535340 -2.47535340

Các kết quả tổng quát hóa để bao gồm một biến X chặn và tiêu chuẩn hóa. Chúng tôi sửa đổi ma trận X được tiêu chuẩn hóa để bao gồm một cột của ma trận và ma trận đường chéo để có thêm một mục nhập 0 ở vị trí [1,1] (nghĩa là không xử phạt chặn). Sau đó, bạn có thể không chuẩn hóa các ước tính bằng độ lệch chuẩn mẫu tương ứng của chúng (một lần nữa đảm bảo bạn đang sử dụng 1 / n khi tính toán độ lệch chuẩn).

β^j=βj~sxj

β^0=β0~x¯Tβ^
mean_x <- colMeans(X)
sd_x <- sqrt(apply(X,2,var)*(n-1)/n)
X_scaled <- matrix(NA, nrow = n, ncol = p)
for(i in 1:p){
    X_scaled[,i] <- (X[,i] - mean_x[i])/sd_x[i] 
}
X_scaled_ones <- cbind(rep(1,n), X_scaled)

beta3 <- solve(t(X_scaled_ones)%*%X_scaled_ones+1000*diag(x = c(0, rep(1,p))),t(X_scaled_ones)%*%(Y))[,1]
beta3 <- c(beta3[1] - crossprod(mean_x,beta3[-1]/sd_x), beta3[-1]/sd_x)

fit_glmnet2 <- glmnet(X,Y, alpha=0, thresh = 1e-20)
beta4 <- as.vector(coef(fit_glmnet2, s = sd_y*1000/n, exact = TRUE))

cbind(beta3[1:10], beta4[1:10])
             [,1]        [,2]
 [1,]  0.24534485  0.24534485
 [2,]  0.17661130  0.17661130
 [3,]  0.86993230  0.86993230
 [4,] -0.12449217 -0.12449217
 [5,] -0.06410361 -0.06410361
 [6,]  0.17568987  0.17568987
 [7,]  0.59773230  0.59773230
 [8,]  0.06594704  0.06594704
 [9,]  0.22860655  0.22860655
[10,]  0.33254206  0.33254206

Đã thêm mã để hiển thị X được chuẩn hóa mà không bị chặn:

set.seed(123)

n <- 1000
p <-  100
X <- matrix(rnorm(n*p,0,1),n,p)
beta <- rnorm(p,0,1)
Y <- X%*%beta+rnorm(n,0,0.5)

sd_y <- sqrt(var(Y)*(n-1)/n)[1,1]

mean_x <- colMeans(X)
sd_x <- sqrt(apply(X,2,var)*(n-1)/n)

X_scaled <- matrix(NA, nrow = n, ncol = p)
for(i in 1:p){
    X_scaled[,i] <- (X[,i] - mean_x[i])/sd_x[i] 
}

beta1 <- solve(t(X_scaled)%*%X_scaled+10*diag(p),t(X_scaled)%*%(Y))[,1]

fit_glmnet <- glmnet(X_scaled,Y, alpha=0, standardize = F, intercept = 
FALSE, thresh = 1e-20)
beta2 <- as.vector(coef(fit_glmnet, s = sd_y*10/n, exact = TRUE))[-1]
cbind(beta1[1:10], beta2[1:10])

             [,1]        [,2]
 [1,]  0.23560948  0.23560948
 [2,]  1.83469846  1.83469846
 [3,] -0.05827086 -0.05827086
 [4,] -0.04927314 -0.04927314
 [5,]  0.41871870  0.41871870
 [6,]  1.28969361  1.28969361
 [7,]  0.06552927  0.06552927
 [8,]  0.44576008  0.44576008
 [9,]  0.90156795  0.90156795
[10,] -2.43163420 -2.43163420

3
+6. Chào mừng bạn đến với CV và cảm ơn vì đã trả lời câu hỏi cũ này một cách rõ ràng như vậy.
amip nói Phục hồi lại

1
Nó phải là ma trận danh tính thay vì trong giải pháp của , đúng không? ββ~
dùng1769197

Tôi cũng lưu ý rằng đối với phần thứ hai mà bạn đã nói "Các kết quả tổng quát hóa bao gồm một biến X chặn và tiêu chuẩn hóa"; đối với phần này, nếu bạn loại trừ việc chặn, sau đó thực hiện theo các tính toán tương tự, kết quả của glmnet sẽ khác với tính toán thủ công.
dùng1769197

Chính xác, tôi đã cập nhật giải pháp với ma trận danh tính thay cho khi cần. Tôi đã kiểm tra giải pháp cho X được chuẩn hóa mà không bị chặn và vẫn thu được kết quả giống hệt nhau (xem mã bổ sung ở trên). β
skijunkie

3

Theo https://web.stanford.edu/~hastie/glmnet/glmnet_alpha.html , khi gia đình là gaussian, glmnet()nên giảm thiểu

(1)12ni=1n(yiβ0xiTβ)2+λj=1p(α|βj|+(1α)βj2/2).

Khi sử dụng glmnet(x, y, alpha=1)để phù hợp với Lasso với các cột trong chuẩn hóa, giải pháp cho hình phạt được báo cáo là giải pháp để giảm thiểu Tuy nhiên, ít nhất là trong khi sử dụng để phù hợp với hồi quy sườn, giải pháp cho hình phạt được báo cáo là giải pháp để giảm thiểu trong đó là độ lệch chuẩn của . Ở đây, hình phạt nên được báo cáo là .xλ

12ni=1n(yiβ0xiTβ)2+λj=1p|βj|.
glmnet_2.0-13glmnet(x, y, alpha=0)λ
12ni=1n(yiβ0xiTβ)2+λ12syj=1pβj2.
syyλ/sy

Điều có thể xảy ra là chức năng trước tiên chuẩn hóa thành và sau đó thu nhỏ có hiệu quả là giảm thiểu hoặc tương đương, để giảm thiểu yy0

(2)12ni=1n(y0ixiTγ)2+ηj=1p(α|γj|+(1α)γj2/2),
12nsy2i=1n(yiβ0xiTβ)2+ηαsyj=1p|βj|+η1α2sy2j=1pβj2,
12ni=1n(yiβ0xiTβ)2+ηsyαj=1p|βj|+η(1α)j=1pβj2/2.

Đối với lasso ( ), thu nhỏ lại để báo cáo hình phạt vì có ý nghĩa. Sau đó, đối với tất cả , phải được báo cáo là hình phạt để duy trì tính liên tục của kết quả trên toàn bộ . Đây có lẽ là nguyên nhân của vấn đề trên. Điều này một phần là do sử dụng (2) để giải quyết (1). Chỉ khi hoặc có sự tương đương giữa các vấn đề (1) và (2) (nghĩa là sự tương ứng giữa trong (1) và trong (2)). Đối với bất kỳα=1ηηsyαηsyαα=0α=1ληα(0,1), các vấn đề (1) và (2) là hai vấn đề tối ưu hóa khác nhau và không có sự tương ứng một-một giữa trong (1) và trong (2).λη


1
Tôi không thể thấy câu trả lời của bạn khác với câu trả lời trước. Bạn có thể giải thích?
Firebug

1
@Fireorms Tôi muốn làm sáng tỏ lý do tại sao hàm báo cáo lambda theo cách này, có vẻ không tự nhiên khi chỉ nhìn từ góc độ của hồi quy sườn, nhưng có ý nghĩa (hoặc phải theo cách này) khi nhìn từ phối cảnh của toàn phổ bao gồm cả sườn núi và lasso.
Chun Li
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.