繁体   English   中英

关于 R 中 glmnet 包的“标准化”选项的混淆

[英]Confusion about 'standardize' option of glmnet package in R

我对Rglmnet包的standardize选项感到困惑。 我得到不同的系数,当我规范协矩阵和一套standardize=FALSE主场迎战的时候,不规范协矩阵和一套standardize=TRUE 我以为它们是一样的! 通过创建以下ridge.mod1ridge.mod2模型,通过示例展示了这两个模型。 我还创建了一个模型 ( ridge.mod3 ) 来标准化结果(和协变量矩阵)并使用选项standardize=FALSE 我只是在检查是否也需要对结果进行标准化以获得与ridge.mod1相同的系数。

set.seed(1)
y <- rnorm(30, 20, 10) 
x1 <- rnorm(30, 5, 2)
x2 <- x1 + rnorm(30, 0, 5)
cor(x1,x2)
x <- as.matrix(cbind(x1,x2))
z1 <- scale(x1)
z2 <- scale(x2)
z <- as.matrix(cbind(z1,z2))
y.scale <- scale(y)
n <- 30
# Fixing foldid for proper comparison
foldid=sample(rep(seq(5),length=n))
table(foldid)

library(glmnet)
cv.ridge.mod1 <- cv.glmnet(x, y, alpha = 0, nfolds = 5, foldid=foldid, standardize = TRUE)
ridge.mod1 <- glmnet(x, y, alpha = 0, standardize = TRUE)
coef(ridge.mod1, s=cv.ridge.mod1$lambda.min)

> coef(ridge.mod1, s=cv.ridge.mod1$lambda.min)
3 x 1 sparse Matrix of class "dgCMatrix"
                       1
(Intercept) 2.082458e+01
x1          2.856136e-37
x2          4.334910e-38

cv.ridge.mod2 <- cv.glmnet(z, y, alpha = 0, nfolds = 5, foldid=foldid, standardize = FALSE)
ridge.mod2 <- glmnet(z, y, alpha = 0, standardize = FALSE)
coef(ridge.mod2, s=cv.ridge.mod2$lambda.min)

> coef(ridge.mod2, s=cv.ridge.mod2$lambda.min)
3 x 1 sparse Matrix of class "dgCMatrix"
                       1
(Intercept) 2.082458e+01
V1          4.391657e-37
V2          2.389751e-37

cv.ridge.mod3 <- cv.glmnet(z, y.scale, alpha = 0, nfolds = 5, foldid=foldid, standardize = FALSE)
ridge.mod3 <- glmnet(z, y.scale, alpha = 0, standardize = FALSE)
coef(ridge.mod3, s=cv.ridge.mod3$lambda.min)

> coef(ridge.mod3, s=cv.ridge.mod3$lambda.min)
3 x 1 sparse Matrix of class "dgCMatrix"
                       1
(Intercept) 1.023487e-16
V1          4.752255e-38
V2          2.585973e-38

任何人都可以告诉我那里发生了什么,如果(或如何)我可以获得与ridge.mod1相同的系数和事先标准化(在数据处理步骤中),然后使用standardize=FALSE

更新:(我根据下面的评论尝试过)

因此,我尝试通过 SS/n 而不是 SS/(n-1) 进行标准化。 我尝试对 y 和 x 进行标准化。 两者都没有给我等于模型 1 的非标准化系数的系数。

## Standadizing by sqrt(SS(X)/n) like glmnet instead of sqrt(SS(X)/(n-1)) which is done by the scale command
Xs <- apply(x, 2, function(m) (m - mean(m)) / sqrt(sum(m^2) / n))
Ys <- (y-mean(y)) / sqrt(sum(y^2) / n)

# Standadizing only X by sqrt(SS(X)/n)
cv.ridge.mod4 <- cv.glmnet(Xs, y, alpha = 0, nfolds = 5, foldid=foldid, standardize = FALSE)
ridge.mod4 <- glmnet(Xs, y, alpha = 0, standardize = FALSE)
coef(ridge.mod4, s=cv.ridge.mod4$lambda.min)

> coef(ridge.mod4, s=cv.ridge.mod4$lambda.min)[2]/sd(x1)
[1] 7.995171e-38
> coef(ridge.mod4, s=cv.ridge.mod4$lambda.min)[3]/sd(x2)
[1] 2.957854e-38

# Standadizing both Y and X by sqrt(SS(X)/n) but neither is centered
cv.ridge.mod6 <- cv.glmnet(Xs.noncentered, Ys.noncentered, alpha = 0, nfolds = 5, foldid=foldid, standardize = FALSE)
ridge.mod6 <- glmnet(Xs.noncentered, Ys.noncentered, alpha = 0, standardize = FALSE)
coef(ridge.mod6, s=cv.ridge.mod6$lambda.min)

> coef(ridge.mod6, s=cv.ridge.mod6$lambda.min)[2] / (sqrt(sum(x1^2) / n))
[1] 1.019023e-39
> coef(ridge.mod6, s=cv.ridge.mod6$lambda.min)[3] / (sqrt(sum(x2^2) / n))
[1] 9.189263e-40

那里还有什么问题?

我调整了您的代码,以便我可以处理更明智的问题。 为了重现更改standardize=TRUEstandardize=FALSE选项的系数,您需要首先使用 (1/N) 方差估计器公式对变量进行标准化。 在这个例子中,我还将变量居中以摆脱常量。 我只关注变量的系数。 之后你必须注意到公式 因此,您必须反转该公式以获得非标准化系数。 我在下面的代码中这样做。

set.seed(1)

x1 <- rnorm(300, 5, 2)
x2 <- x1 + rnorm(300, 0, 5)
x3 <- rnorm(300, 6, 5)
e= rnorm(300, 0, 1)
y <- 0.3*x1+3.5*x2+x3+e

x <- as.matrix(cbind(x1,x2,x3))


sdN=function(x){
sigma=sqrt( (1/length(x)) * sum((x-mean(x))^2))
return(sigma)
}

n=300
foldid=sample(rep(seq(5),length=n))

g1=(x1-mean(x1))/sdN(x1)
g2=(x2-mean(x2))/sdN(x2)
g3=(x3-mean(x3))/sdN(x3)
gy=(y-mean(y))/sdN(y)
equis <- as.matrix(cbind(g1,g2,g3))



library(glmnet)
cv.ridge.mod1 <- cv.glmnet(x, y, alpha = 0, nfolds = 5, foldid=foldid,standardize = TRUE)
coef(cv.ridge.mod1, s=cv.ridge.mod1$lambda.min)


cv.ridge.mod2 <- cv.glmnet(equis, gy, alpha = 0, nfolds = 5, foldid=foldid, standardize = FALSE, intercept=FALSE)
beta=coef(cv.ridge.mod2, s=cv.ridge.mod2$lambda.min)


beta[2]*sdN(y)/sdN(x1)
beta[3]*sdN(y)/sdN(x2)
beta[4]*sdN(y)/sdN(x3)

coef(cv.ridge.mod1, s=cv.ridge.mod1$lambda.min)

这产生了结果:

> beta[2]*sdN(y)/sdN(x1)
[1] 0.5984356
> beta[3]*sdN(y)/sdN(x2)
[1] 3.166033
> beta[4]*sdN(y)/sdN(x3)
[1] 0.9145646
> 
> coef(cv.ridge.mod1, s=cv.ridge.mod1$lambda.min)
4 x 1 sparse Matrix of class "dgCMatrix"
                    1
(Intercept) 0.5951423
x1          0.5984356
x2          3.1660328
x3          0.9145646

如您所见,系数在 4 位小数处相同。 所以我希望这能回答你的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM