glmnet ridge回帰が手動計算とは異なる答えを与えるのはなぜですか?


28

glmnetを使用して、リッジ回帰推定値を計算しています。glmnetが本当に思っていることを実際に行っているという点で、私は疑わしい結果になりました。これを確認するために、簡単なRスクリプトを作成し、solveとglmnetで行われたリッジ回帰の結果を比較しました。違いは重要です。

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

違いの標準は通常20前後であり、これは数値的に異なるアルゴリズムが原因ではないため、何か間違ったことをしているに違いありません。glmnetridgeと同じ結果を得るために設定する必要がある設定は何ですか?



1
はい。ただし、正規化を使用しても同じ結果が得られません。
ジョン14

コードを投稿していただけますか?
シャドウトーカー

同じ問題が発生しました!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 = sample(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))結果はかなり異なっており、 glmnetには非常に高いラムダを使用します。
a11msp

興味深い。係数はおおよそ10の係数で異なるようです。
tomka16年

回答:


27

観察している違いは、以下に示すように、GLMNETが目的関数で使用する観測数Nによる追加の除算と、サンプル標準偏差によるYの暗黙的な標準化によるものです。

12NysyXβ22+λβ22/2

ここで、s y1 /n 1 )の代わりにを使用します1/n1/(n1)sy

sy=i(yiy¯)2n

ベータに関して微分することにより、方程式をゼロに設定して、

XTXβXTysy+Nλβ=0

そして、ベータを解いて、推定値を取得します。

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

Yの元のメトリックの推定値(および対応するペナルティ)を回復するために、GLMNETは推定値とラムダの両方にを乗算し、これらの結果をユーザーに返します。sy

λ uのN 、S 、T 、D = s y

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

このソリューションをリッジ回帰の標準的な導出と比較してください。

β^=(XTX+λIp)1XTy

はNの余分な係数でスケーリングされることに注意してください。さらに、or 関数を使用すると、ペナルティは暗黙的に1 / s yでスケーリングされます。つまり、これらの関数を使用していくつかのλ ∗の係数推定値を取得する場合、λ = λ / s yの推定値を効果的に取得しています。λpredict()coef()1/syλλ=λ/sy

これらの観察に基づいて、GLMNETで使用されるペナルティは、s y / N 係数でスケーリングする必要があります。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

結果は、インターセプトと標準化されたX変数の包含に一般化されます。標準化されたX行列を変更して、1の列と対角行列を追加し、[1,1]位置に追加のゼロエントリを追加します(つまり、切片にペナルティを課しません)。その後、それぞれのサンプル標準偏差によって推定値を標準化解除できます(標準偏差の計算時に1 / 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

インターセプトなしで標準化された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

3
+6。CVへようこそ。この古い質問に明確に答えてくれてありがとう。
アメーバは、モニカを復活させる

1
これは、代わりの単位行列であるべきの溶液中で〜のβ、正しいですか?ββ~
-user1769197

また、「結果は、インターセプトと標準化されたX変数の包含に一般化される」と言った2番目の部分にも気付きました。この部分では、インターセプトを除外し、同じ計算を実行すると、glmnetの結果は手動計算とは異なります。
-user1769197

β

3

https://web.stanford.edu/~hastie/glmnet/glmnet_alpha.htmlによるとgaussianglmnet()

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

glmnet(x, y, alpha=1)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

何が起こるかは、関数が最初に標準化することですyy0

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

For the lasso (α=1), scaling η back to report the penalty as ηsy makes sense. Then for all α, ηsy has to be reported as the penalty to maintain continuity of the results across α. This probably is the cause of the problem above. This is partly due to using (2) to solve (1). Only when α=0 or α=1 there is some equivalence between problems (1) and (2) (i.e., a correspondence between the λ in (1) and the η in (2)). For any other α(0,1), problems (1) and (2) are two different optimization problems, and there is no one-to-one correspondence between the λ in (1) and the η in (2).


1
I can't see where does your answer differ from the previous one. Could you explain, please?
Firebug

1
@Firebug I wanted to shed light on why the function reports the lambda this way, which appears unnatural when viewed solely from the perspective of ridge regression, but makes sense (or has to be this way) when viewed from the perspective of the whole spectrum including both ridge and the lasso.
Chun Li
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.