【问题标题】:Looping cv.glmnet and get the 'best' coefficients循环 cv.glmnet 并获得“最佳”系数
【发布时间】:2020-09-22 00:58:49
【问题描述】:

正如 cv.glmnet 的帮助中所指出的,“cv.glmnet 的结果是随机的,因为折叠是随机选择的。用户可以通过多次运行 cv.glmnet 并平均误差曲线来减少这种随机性。 ”。

如果我循环执行 n 次 cv.glmnet,如何提取“最佳”系数?我通常使用以下命令获取系数:

coe<- coef(cvfit, s = "lambda.min")

如果我使用所有“lambda.min”的平均值,那么我不知道如何从我生成的许多中选择正确的 cvfit。我必须使用 cvfit$cvm 或 MSE 或其他东西的平均值吗?

谢谢

【问题讨论】:

  • 或者你可以增加接近LOOCV的折叠次数,这样你就不必重复CV了。

标签: r cross-validation glmnet coefficients


【解决方案1】:

当您执行 coef(cvfit, s = "lambda.min") 时,您将得到 lambda,即最佳 lambda 的 1 个标准误差,请参阅 this discusssion 因此您可以在不同的 cv 运行中平均 MSE

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)

我们可以总结一下结果,标准差是通过取平均值来近似的,但是如果你想精确,可能需要查看formula for pooled standard deviation

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 2015-09-16
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多