正如cv.glmnet的帮助中所指出的,"cv.glmnet的结果是随机的,因为折线是随机选择的。用户可以通过多次运行cv.glmnet,并对误差曲线进行平均来减少这种随机性。".
如果我做了一个循环,做了n次cv.glmnet,如何提取 "最佳 "系数?我通常使用这个命令来提取系数。
coe<- coef(cvfit, s = "lambda.min")
如果我使用所有 "lambda.min "的平均值 我不知道如何从众多生成的cvfit中选择正确的cvfit. 我是否必须使用cvfit$cvm的平均值或MSE或其他东西?
谅谅
当你做 coef(cvfit, s = "lambda.min")
,你取的lambda是最佳lambda的1个标准误差,见 本次讨论 因此,你可以在不同的cv运行中平均MSEs。
library(glmnet)
library(mlbench)
data(BostonHousing)
X = as.matrix(BostonHousing[,-c(4,14)])
Y = BostonHousing[,14]
nfolds = 5
nreps = 10
res = lapply(1:nreps,function(i){
fit = cv.glmnet(x=X,y=Y,nfolds=nfolds)
data.frame(MSE_mean=fit$cvm,lambda=fit$lambda,se=fit$cvsd)
})
res = do.call(rbind,res)
我们可以总结一下结果,标准差只是取平均值来近似,但如果你想精确的话,可能要研究一下。综合标准差公式:
library(dplyr)
summarized_res = res %>%
group_by(lambda) %>%
summarise(MSE=mean(MSE_mean),se=mean(se)) %>%
arrange(desc(lambda))
idx = which.min(summarized_res$MSE)
lambda.min = summarized_res$lambda[idx]
lambda.min
[1] 0.019303
index_1se = with(summarized_res,which(MSE < MSE[idx]+se[idx])[1])
lambda_1se = summarized_res$lambda[index_1se]
lambda_1se
[1] 0.3145908
我们可以绘制这个。
library(ggplot2)
ggplot(res,aes(x=log(lambda),y=MSE_mean)) + stat_summary(fun=mean,size=2,geom="point") +
geom_vline(xintercept=c(lambda.min,lambda_1se))