glmnet 능형 회귀 분석이 왜 수동 계산과 다른 답변을 제공합니까?


28

능선 회귀 추정치를 계산하기 위해 glmnet을 사용하고 있습니다. 나는 glmnet이 실제로 내가 생각하는 것을하고 있다는 것을 의심하게 만드는 몇 가지 결과를 얻었습니다. 이를 확인하기 위해 solve에서 수행 한 능선 회귀와 glmnet의 결과를 비교하는 간단한 R 스크립트를 작성했습니다.

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 정도이며 수치 적으로 다른 알고리즘으로 인해 발생할 수 없으므로 잘못된 일을해야합니다. glmnet릿지와 동일한 결과를 얻으려면 어떤 설정을해야 합니까?


1
이 질문을 보셨습니까 ?
cdeterman

1
예,하지만 여전히 정규화를 사용하여 동일한 결과를 얻지 못합니다.
John

그런 다음 코드를 게시 할 수 있습니까?
shadowtalker

방금 같은 문제가있었습니다! a = data.frame (a = 지터 (1:10), b = 지터 (1:10), c = 지터 (1:10), d = 지터 (1:10), e = 지터 (1:10) , f = 지터 (1:10), g = 샘플 (지터 (1:10)), y = seq (10,100,10)); 계수 (lm.ridge (y ~ a + b + c + d + e + f + g, a, λ = 2.57)); coef (glmnet (as.matrix (a [, 1 : 7]), a $ y, family = "gaussian", alpha = 0, lambda = 2.57 / 10)) 결과는 조금씩 다르고 더 비슷해집니다 나는 glmnet에 훨씬 높은 람다를 사용합니다.
a11msp 2016 년

흥미로운. 계수는 대략 10의 계수만큼 차이가있는 것으로 보입니다.
tomka

답변:


27

관찰하는 차이는 GLMNET이 목적 함수에서 사용하는 관측치 수 N의 추가 분할과 아래에 표시된 샘플 표준 편차에 의한 Y의 암시 적 표준화로 인한 것입니다.

12NysyXβ22+λβ22/2

우리가 사용하는 곳 대신에, 에 대한 , 1/n1/(n1)sy

sy=i(yiy¯)2n

베타에 대해 미분하고 방정식을 0으로 설정하면

XTXβXTysy+Nλβ=0

베타를 해결하면 추정치를 얻습니다.

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

Y의 원래 측정 항목에 대한 추정치 (및 해당 처벌)를 복구하기 위해 GLMNET은 추정치와 람다에 결과를 사용자에게 반환합니다.sy

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

이 솔루션을 표준 능형 회귀 분석과 비교하십시오.

β^=(XTX+λIp)1XTy

것을 알 수 우리가 사용하는 경우, 또한 N의 추가 요인에 의해 조정됩니다 또는 기능, 페널티 암시 적으로 확장 할 것입니다 . 즉,이 함수를 사용하여 일부 대한 계수 추정치를 얻으면 대한 추정치를 효과적으로 얻는 입니다.λpredict()coef()1/syλλ=λ/sy

이러한 관찰에 기초하여 GLMNET에 사용 된 페널티는 계수로 조정되어야합니다 .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에 오신 것을 환영합니다.이 오래된 질문에 명확하게 답변 해 주셔서 감사합니다.
amoeba는

1
솔루션에서 대신 ID 행렬이어야합니다. 맞습니까? ββ~
user1769197

또한 두 번째 부분에서 "결과는 절편 및 표준화 된 X 변수를 포함하는 것으로 일반화됩니다"라고 언급했습니다. 이 부분에서 절편을 제외하면 동일한 계산에 따라 glmnet의 결과가 수동 계산과 달라집니다.
user1769197

맞습니다 . 필요에 따라 대신 ID 행렬로 솔루션을 업데이트했습니다 . 인터셉트없이 표준화 된 X에 대한 솔루션을 확인했지만 여전히 동일한 결과를 얻습니다 (위의 추가 코드 참조). β
skijunkie

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),
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.

올가미 ( )의 경우 다시 스케일링 하여 가 의미가있는 것처럼 페널티를보고합니다 . 그런 다음 모든 에 대해 는 걸쳐 결과의 연속성을 유지하기위한 페널티로보고되어야 합니다. 이것은 아마도 위 문제의 원인 일 것입니다. 이것은 부분적으로 (2)를 사용하여 (1)을 해결하기 때문입니다. 또는 경우 에만 문제 (1)과 (2) 사이에 동등성이 있습니다 (즉, (1) 의 와 (2)의 간의 대응 ). 다른 모든α=1ηηsyαηsyαα=0α=1ληα(0,1)문제 (1)과 (2)는 서로 다른 두 가지 최적화 문제이며 (1) 의 와 (2)의 사이에는 일대일 대응이 없습니다 .λη


1
귀하의 답변이 이전 답변과 어떻게 다른지 알 수 없습니다. 설명해 주시겠습니까?
Firebug

1
@Firebug 나는 왜 함수가 람다를 이런 식으로보고하는지에 대해 밝히고 싶었습니다. 이는 릿지 회귀 관점에서만 볼 때 부자연 스럽지만 전체 스펙트럼 관점에서 볼 때 의미가 있습니다 (또는 이런 식이어야 함). 능선과 올가미를 포함합니다.
Chun Li
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.