【问题标题】:Extract the coefficients for the best tuning parameters of a glmnet model in caret提取插入符号中 glmnet 模型的最佳调整参数的系数
【发布时间】:2018-06-13 06:17:54
【问题描述】:

我正在使用 glmnet 在插入符号中运行弹性网络正则化。

我将值序列传递给 trainControl 以获得 alpha 和 lambda,然后我执行 repeatedcv 以获得 alpha 和 lambda 的最佳调整。

这是一个示例,其中 alpha 和 lambda 的最佳调整分别为 0.7 和 0.5:

age     <- c(4, 8, 7, 12, 6, 9, 10, 14, 7, 6, 8, 11, 11, 6, 2, 10, 14, 7, 12, 6, 9, 10, 14, 7) 
gender  <-  make.names(as.factor(c(1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1)))
bmi_p   <- c(0.86, 0.45, 0.99, 0.84, 0.85, 0.67, 0.91, 0.29, 0.88, 0.83, 0.48, 0.99, 0.80, 0.85,
         0.50, 0.91, 0.29, 0.88, 0.99, 0.84, 0.80, 0.85, 0.88, 0.99) 
m_edu   <- make.names(as.factor(c(0, 1, 1, 2, 2, 3, 2, 0, 1, 1, 0, 1, 2, 2, 1, 2, 0, 1, 1, 2, 2, 0 , 1, 0)))
p_edu   <-  make.names(as.factor(c(0, 2, 2, 2, 2, 3, 2, 0, 0, 0, 1, 2, 2, 1, 3, 2, 3, 0, 0, 2, 0, 1, 0, 1)))
f_color <-  make.names(as.factor(c("blue", "blue", "yellow", "red", "red", "yellow", 
                   "yellow", "red", "yellow","blue", "blue", "yellow", "red", "red", "yellow", 
                   "yellow", "red", "yellow", "yellow", "red", "blue", "yellow", "yellow", "red")))
asthma <-  make.names(as.factor(c(1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1)))
x <- data.frame(age, gender, bmi_p, m_edu, p_edu, f_color, asthma)

tuneGrid <- expand.grid(alpha = seq(0, 1, 0.05), lambda = seq(0, 0.5, 0.05))
fitControl <- trainControl(method = 'repeatedcv', number = 3, repeats = 5, classProbs = TRUE, summaryFunction = twoClassSummary) 

set.seed(1352)
model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet", 
                       family = "binomial", trControl = fitControl, tuneGrid = tuneGrid, 
                       metric = "ROC")

model.test$bestTune

我的问题?

当我运行as.matrix(coef(model.test$finalModel)) 时,我假设它给出了与最佳模型相对应的系数,我得到了 100 组不同的系数。

那么如何得到最佳调优对应的系数呢?

我已经看到了获得最佳模型的建议 coef(model.test$finalModel, model.test$bestTune$lambda) 但是,这会返回 NULL 系数,并且无论如何,只会返回与 lambda 相关的最佳调整,而不是另外的 alpha。

编辑:

在互联网上到处搜索后,我现在只能找到指向正确答案方向的 this 博客文章,其中说 model.test$finalModel 返回与最佳 alpha 调整相对应的模型,而 @ 987654329@ 返回与 lambda 的最佳值对应的系数集。如果这是真的,那么这就是我的问题的答案。然而,由于这是一篇博客文章,我找不到其他任何东西来支持这一说法,我仍然持怀疑态度。任何人都可以验证 model.test$finalModel 返回与最佳 alpha 对应的模型的说法吗?如果是这样,那么这个问题将得到解决。谢谢!

【问题讨论】:

    标签: r machine-learning r-caret glmnet


    【解决方案1】:

    在玩了一会儿你的代码后,我发现 glmnet train 根据种子选择不同的 lambda 范围很奇怪。这是一个例子:

    library(caret)
    library(glmnet)
    set.seed(13)
    model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet", 
                               family = "binomial", trControl = fitControl, tuneGrid = tuneGrid, 
                               metric = "ROC")
    
    c(head(model.test$finalModel$lambda, 5), tail(model.test$finalModel$lambda, 5))
    #output
     [1] 3.7796447301 3.4438715094 3.1379274562 2.8591626295 2.6051625017 0.0005483617 0.0004996468 0.0004552595 0.0004148155
    [10] 0.0003779645
    

    最佳 lambda 是:

    model.test$finalModel$lambdaOpt
    #output
    #[1] 0.05
    

    这很有效:

    coef(model.test$finalModel, model.test$finalModel$lambdaOpt)
    #12 x 1 sparse Matrix of class "dgCMatrix"
                            1
    (Intercept)   -0.03158974
    age            0.03329806
    genderX1      -1.24093677
    bmi_p          1.65156913
    m_eduX1        0.45314106
    m_eduX2       -0.09934991
    m_eduX3       -0.72360297
    p_eduX1       -0.51949828
    p_eduX2       -0.80063642
    p_eduX3       -2.18231433
    f_colorred     0.87618211
    f_coloryellow -1.52699254
    

    给出最好的 alpha 和 lambda 系数

    当使用该模型预测时,一些 y 被预测为 X1,一些被预测为 X2

     [1] X1 X1 X0 X1 X1 X0 X0 X1 X1 X1 X0 X1 X1 X1 X0 X0 X0 X1 X1 X1 X1 X0 X1 X1
    Levels: X0 X1
    

    现在用你用的种子

    set.seed(1352)
    model.test <- caret::train(asthma ~ age + gender + bmi_p + m_edu + p_edu + f_color, data = x, method = "glmnet", 
                               family = "binomial", trControl = fitControl, tuneGrid = tuneGrid, 
                               metric = "ROC")
    
    c(head(model.test$finalModel$lambda, 5), tail(model.test$finalModel$lambda, 5))
    #output
     [1] 2.699746e-01 2.459908e-01 2.241377e-01 2.042259e-01 1.860830e-01 3.916870e-05 3.568906e-05 3.251854e-05 2.962968e-05
    [10] 2.699746e-05
    

    lambda 值小 10 倍,这给出了空系数,因为 lambdaOpt 不在测试的 lambda 范围内:

    coef(model.test$finalModel, model.test$finalModel$lambdaOpt)
    #output
    12 x 1 sparse Matrix of class "dgCMatrix"
                  1
    (Intercept)   .
    age           .
    genderX1      .
    bmi_p         .
    m_eduX1       .
    m_eduX2       .
    m_eduX3       .
    p_eduX1       .
    p_eduX2       .
    p_eduX3       .
    f_colorred    .
    f_coloryellow .
    
    model.test$finalModel$lambdaOpt
    #output
    0.5
    

    现在在此模型上进行预测时,仅预测 X0(第一级):

    predict(model.test, x)
    #output
     [1] X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0 X0
    Levels: X0 X1
    

    相当奇怪的行为,可能值得报告

    【讨论】:

    • 谢谢!这真的很奇怪......关于 lambda 和 alpha 的系数,人们怎么知道coef(model.test$finalModel, model.test$finalModel$lambdaOpt) 除了 lambda 之外还给出了与最佳 alpha 相对应的系数?这是在某处明确说明的吗? finalModel 会提供 lambda 的所有次优拟合的系数,但不提供 alpha 的所有次优拟合的系数,这很奇怪而且似乎是任意的。
    • @steve zissou 100 lambda 行为很可能是由默认 glmnet 行为引起的。默认情况下,在 glmnet 中,模型在任何指定的 alpha 处适合 100 个不同的 lambda。在调整超参数时,插入符号使最终模型使用任何模型的最佳参数组合。在我看来,插入符号通过了最好的alpha 来构建最终模型,然后在从该模型进行预测时,它通过了最好的lambda,就像glmnet 预期的那样。顺便说一句,我用一些相关信息更新了帖子,比如两个模型的预测。
    • 对于一个包含 24 个样本的数据集,我认为你在不同的种子上得到不同的结果并不令人惊讶。尝试使用重复的 CV 来降低变化。
    • 是的,glmnet 可以预测几乎任何lambda 的固定值alpha(有关更多信息,请参阅this article)。附加到模型拟合的 lambdaOpt 组件是 glmnet 工作方式的副作用,并确保在调整过程中找到的 lambda 用于预测。
    • 另外,您可以修改getModelInfo("glmnet", FALSE)[[1]]$varImp中的代码以获取系数
    猜你喜欢
    • 2017-07-18
    • 2020-01-09
    • 1970-01-01
    • 2019-08-06
    • 2016-07-20
    • 2015-08-14
    • 2016-11-07
    • 2013-11-15
    • 2020-07-09
    相关资源
    最近更新 更多