cv.glmnet vs glmnet结果;衡量解释力

时间:2017-11-30 21:07:51

标签: r glmnet

当通过glmnet包估计套索模型时,我想知道是否更好:(a)直接从cv.glmnet采购的cv.fit对象拉出系数/预测/偏差,或(b)使用cv.glmnet中的最小lambda重新运行glmnet并从glmnet进程中提取这些对象。 (请耐心等待 - 我有一种感觉,这是记录在案的,但我在网上看到的示例/教程,并没有坚实的逻辑,无论是这种方式还是其他方式。)

也就是说,对于系数,我可以运行(a):

cvfit = cv.glmnet(x=xtrain, y=ytrain, alpha=1, type.measure = "mse", nfolds = 20)
coef.cv <- coef(cvfit, s = "lambda.min")

或者之后我可以跑(b):

fit = glmnet(x=xtrain, y=ytrain, alpha=1, lambda=cvfit$lambda.min)
coef <- coef(fit, s = "lambda.min")

虽然这两个过程选择相同的模型变量,但它们不会产生相同的系数。同样,我可以通过以下两个过程之一进行预测:

prdct <- predict(fit,newx=xtest)
prdct.cv <- predict(cvfit, newx=xtest, s = "lambda.min")

他们预测相似但不相同的载体。

最后,我会通过以下两种方法中的任何一种来解释%deviance:

percdev <- fit$dev.ratio
percdev.cv <- cvfit$glmnet.fit$dev.ratio[cvfit$cvm==mse.min.cereal]

但实际上,不可能以这种方式提取percdev.cv,因为如果cv.glmnet使用的lamda序列少于100个元素,则cvfit$glmnet.fit$dev.ratio和{{1的长度不匹配。所以我不太确定如何从cvfit $ glmnet.fit中拉出最小lambda dev.ratio。

所以我想我想知道哪个过程最好,为什么,以及人们通常如何得出相应的dev.ratio统计数据。谢谢!

1 个答案:

答案 0 :(得分:2)

正如注释中指出的那样,它与所提供的lambda序列有关,因为如果您查看cv.glmnet的源代码,它将调用glmnet:::cv.glmnet.raw,该代码在前几行中运行glmnet()定义的lambda值。

所以我们可以使用以下示例:

library(mlbench)
data(BostonHousing)
data = BostonHousing
data$chas=as.numeric(data$chas)

cvfit = cv.glmnet(x=as.matrix(data[,-14]),y=data[,14])
coef.cv <- coef(cvfit, s = "lambda.min")

fit = glmnet(x=as.matrix(data[,-14]), y=data[,14], alpha=1, lambda=cvfit$lambda.min)
coef <- coef(fit, s = "lambda.min")

head(cbind(coef.cv,coef))
6 x 2 sparse Matrix of class "dgCMatrix"
                       1            1
(Intercept)  31.74123706  31.86654225
crim         -0.09834634  -0.09869320
zn            0.04144161   0.04158829
indus         .            .         
chas          2.68518774   2.68163334
nox         -16.30664523 -16.35459059

它们稍有不同,并且如果您提供cv.glmnet中使用的lambda序列:

fit = glmnet(x=as.matrix(data[,-14]), y=data[,14], alpha=1, lambda=cvfit$lambda)
coef <- coef(fit, s = cvfit$lambda.min)
head(cbind(coef.cv,coef))

6 x 2 sparse Matrix of class "dgCMatrix"
                       1            1
(Intercept)  31.74123706  31.74123706
crim         -0.09834634  -0.09834634
zn            0.04144161   0.04144161
indus         .            .         
chas          2.68518774   2.68518774
nox         -16.30664523 -16.30664523

它们现在相同。并且dev.ratio也将匹配:

fit$dev.ratio[fit$lambda==cvfit$lambda.min]
[1] 0.7401482
cvfit$glmnet.fit$dev.ratio[which.min(cvfit$cvm)]
[1] 0.7401482