【问题标题】:Is there a way in R to determine AIC from cv.glmnet?R中有没有办法从cv.glmnet确定AIC?
【发布时间】:2020-11-20 03:00:05
【问题描述】:

我在 R 中使用 glmnet 包,而不是(!)caret 包用于我的二进制 ElasticNet 回归。我已经到了想要比较模型的地步(例如,lambda 设置为 lambda.1selambda.min,以及 k-fold 设置为 5 或 10 的模型)。但是,我还没有为我的模型计算AICcBIC。我怎么做?我试过thisthis 但它对我不起作用,我只得到一个空列表。 代码:

set.seed(123)
foldid <- sample(rep(seq(10), length.out = nrow(x.train)))
list.of.fits.df <- list()
for (i in 0:10){
     fit.name <- paste0("alpha", i/10) 
     list.of.fits.df[[fit.name]] <- cv.glmnet(x.train, y.train, type.measure = c("auc"), alpha = i/10, family = "binomial", nfolds = 10, foldid = foldid, parallel = TRUE)
 }
best.fit <- coef(list.of.fits.df[[fit.name]], s = list.of.fits.df[[fit.name]]$lambda.1se)
best.fit.min <- coef(list.of.fits.df[[fit.name]], s = list.of.fits.df[[fit.name]]$lambda.min)

#AICc & BIC
#???

如何找到最适合我的模型的 AICcBIC

【问题讨论】:

    标签: r machine-learning regression model-comparison


    【解决方案1】:

    您可以稍微更改this 答案中给出的解决方案以获得所需的结果它不能“开箱即用”的原因是cv.glmnet 函数返回多次拟合的结果,但个人结果存储在x$glmnet.fit中,我们可以用它来创建一个简单的函数来计算AICcBIC

    glmnet_cv_aicc <- function(fit, lambda = 'lambda.1se'){
      whlm <- which(fit$lambda == fit[[lambda]])
      with(fit$glmnet.fit,
           {
             tLL <- nulldev - nulldev * (1 - dev.ratio)[whlm]
             k <- df[whlm]
             n <- nobs
             return(list('AICc' = - tLL + 2 * k + 2 * k * (k + 1) / (n - k - 1),
                         'BIC' = log(n) * k - tLL))
           })
    }
    

    我们接下来要做的就是提供模型并获得我们估计的AICc

    best.aicc <- glmnet_cv_aicc(list.of.fits.df[[fit.name]])
    best.aicc.min <- glmnet_cv_aicc(list.of.fits.df[[fit.name]], 'lambda.min')
    

    对于可重现的示例,可以使用help(glmnet) 中提供的众多示例之一

    n = 500
    p = 30
    nzc = trunc(p/10)
    x = matrix(rnorm(n * p), n, p)
    beta3 = matrix(rnorm(30), 10, 3)
    beta3 = rbind(beta3, matrix(0, p - 10, 3))
    f3 = x %*% beta3
    p3 = exp(f3)
    p3 = p3/apply(p3, 1, sum)
    g3 = glmnet:::rmult(p3)
    set.seed(10101)
    cvfit = cv.glmnet(x, g3, family = "multinomial")
    print(glmnet_cv_aicc(cvfit))
    # Output
    #$AICc
    #[1] -556.2404
    #
    #$BIC
    #[1] -506.3058
    print(glmnet_cv_aicc(cvfit, 'lambda.min'))
    # Output
    #$AICc
    #[1] -601.0234
    #
    #$BIC
    #[1] -506.4068
    

    【讨论】:

    • 哇!太棒了,使用 cv.glmnet 在 R 中进行真正的插入和操作。我认为它与交叉验证部分有关,因为它仅适用于 glmnet。谢谢你。感谢您的时间。
    • 别担心,我很抱歉在我第一次浏览时没有正确阅读您的问题。 :-)
    • 可以是 nulldev - nulldev * dev.ratio,而不是 nulldev - nulldev * (1 - dev.ratio)?
    • nulldev - nulldev (1 - dev.ratio) = nulldev(1 - (1 - dev ratio)) = dev.ratio * nulldev,所以不,在这种情况下。
    猜你喜欢
    • 2019-11-08
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2012-08-03
    • 2012-01-27
    相关资源
    最近更新 更多