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.
12N∥∥∥ysy−Xβ∥∥∥22+λ∥β∥22/2
trong đó chúng tôi sử dụng thay cho cho ,
1/n1/(n−1)sy
sy=∑i(yi−y¯)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