代码之家  ›  专栏  ›  技术社区  ›  steve zissou

在插入符号中提取glmnet模型最佳调整参数的系数

  •  10
  • steve zissou  · 技术社区  · 7 年前

    我正在使用插入符号运行弹性网络正则化 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) 然而,这将返回空系数,并且在任何情况下,将只返回与lambda相关的最佳调谐,而不返回与alpha相关的最佳调谐。

    编辑:

    在互联网上到处搜索之后,我现在所能找到的能为我指明正确答案方向的是 this 博客帖子说 model.test$finalModel 返回与最佳alpha调整相对应的模型,以及 coef(model.test$finalModel, model.caret$bestTune$lambda) 返回与lambda的最佳值相对应的系数集。如果这是真的,那么这就是我问题的答案。然而,由于这只是一篇博客文章,我找不到任何其他东西来支持这一说法,我仍然持怀疑态度。有人能证实这一说法吗 模型测试$最终模型 返回与最佳alpha?对应的模型??如果是这样的话,这个问题就会得到解决。谢谢

    1 回复  |  直到 5 年前
        1
  •  7
  •   missuse    5 年前

    在对您的代码进行了一些处理后,我发现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
    

    最佳λ为:

    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
    

    给出最佳α和λ的系数

    当使用该模型预测时,一些y被预测为X1,一些y被预测为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
    

    很奇怪的行为,可能值得报道