您观察到的差异是由于GLMNET在其目标函数中使用的观察数N的额外除法,以及通过其样本标准偏差对Y的隐式标准化,如下所示。
1个2 N∥∥∥ÿsÿ- Xβ∥∥∥22+ λ ∥ β∥22/ 2
在这里我们使用代替为,
1 /(ñ - 1 )小号Ŷ 小号Ŷ = Σ 我(ÿ 我 - ˉ ÿ)21 / n1 /(n − 1 )sÿ
sÿ= ∑一世(y一世- ÿ¯)2ñ
通过对beta进行微分,将等式设置为零,
XŤXβ- XŤÿsÿ+ Nλ β= 0
然后求解beta,我们得到了估算值,
β〜ģ 大号中号ñËŤ= (XŤX+ Nλ 我p)− 1XŤÿsÿ
为了恢复对Y的原始度量的估计(及其相应的惩罚),GLMNET将估计和lambda乘以并将这些结果返回给用户,sÿ
λùÑ小号吨d。=šÿλ
β^ģ 大号中号ñËŤ= 秒ÿβ〜ģ 大号中号ñËŤ= (XŤX+ Nλ 我p)− 1XŤÿ
λü Ñ 小号吨d。= 秒ÿλ
将此解决方案与岭回归的标准推导进行比较。
β^= (XŤX+ λ 我p)− 1XŤÿ
请注意,的缩放系数为N。此外,当使用or 函数时,代价将隐式缩放为。就是说,当我们使用这些函数获得某个的系数估计时,我们正在有效地获得估计。1 / 小号ý λ * λ = λ * / 小号ÿλpredict()
coef()
1 / 秒ÿλ∗λ = λ∗/ 秒ÿ
基于这些观察,需要将的因数缩放到GLMNET中使用的惩罚。sÿ/ 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
结果概括为包含截距和标准化的X变量。我们修改了标准化的X矩阵以包括一列1和对角矩阵,使其在[1,1]位置具有一个附加的零项(即,不对截距进行惩罚)。然后,您可以通过它们各自的样本标准偏差来使估算值标准化(再次确保在计算标准偏差时使用1 / n)。
β^Ĵ= βĴ〜sXĴ
β^0= β0〜− x¯Ťβ^
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
添加了代码以显示标准X且没有拦截:
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