【问题标题】:Extract Formula From RIDGE, LASSO, and Net Elastic Regression with Coefficients (R) for many variables从 RIDGE、LASSO 和带系数 (R) 的网络弹性回归中提取公式,用于许多变量
【发布时间】:2021-03-15 03:23:16
【问题描述】:

我正在尝试修改我在这篇文章的一个答案中找到的一些代码:

Extract Formula From lm with Coefficients (R)

AlexB 提供了这些精彩的代码行:

get_formula <- function(model) {
  broom::tidy(model)[, 1:2] %>%
    mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
    mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
    mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
    summarise(formula = paste(a, collapse = '')) %>%
    as.character
}

虽然这适用于我的某些代码,但我在调整它以使用 RIDGE、LASSO 和 Net Elastic Regression 打印来自 glmnet 模型的公式时遇到问题。

下面附上我要提供的示例:

library(caret)
library(glmnet)
library(mlbench)
library(psych)
data("BostonHousing")
data <- BostonHousing
set.seed(23)
ind <- sample(2, nrow(data), replace = T, prob = c(0.7, 0.3))
train <- data[ind==1,]
test <- data[ind==2,]
custom <- trainControl(method = "repeatedcv",number = 10,repeats = 5,verboseIter = T)
set.seed(23)
ridge <- train(medv~., train,method = "glmnet",tuneGrid = expand.grid(alpha = 0,lambda = seq(0.0001,1,length = 5)),trControl = custom)
ridge
coef(ridge$finalModel, ridge$bestTune$lambda) # the coefficient estimates

get_formula <- function(model) {
  broom::tidy(model)[, 1:2] %>%
    mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
    mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
    mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
    summarise(formula = paste(a, collapse = '')) %>%
    as.character
}
get_formula(ridge$finalModel)

但是,鉴于它的格式与上一篇文章中的不同,我在修改函数时遇到了问题,以便它可以打印出我正在寻找的方程。

给出错误:

Error: Problem with `mutate()` input `sign`.
x object 'estimate' not found
i Input `sign` is `ifelse(sign(estimate) == 1, " + ", " - ")`.
Run `rlang::last_error()` to see where the error occurred. 

感谢您的帮助。

【问题讨论】:

    标签: r linear-regression formula glmnet


    【解决方案1】:

    稍加更新,即可得到岭回归方程,如下:

    as.matrix(coef(ridge$finalModel, ridge$bestTune$lambda)) %>%
      as.data.frame() %>%
      tibble::rownames_to_column('term') %>%
      rename(estimate = 2) %>%
      mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
      mutate(across(where(is.numeric), ~abs(round(., 2)))) %>% #for improving formatting
      mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) %>%
      summarise(formula = paste(a, collapse = ''))
      
    

    【讨论】:

      【解决方案2】:

      broom 包具有a tidy variant for glmnet - 您无需使用[, 1:2] 对整理后的数据进行索引。

      只需使用tidy(model),管道的其余部分就可以正常工作。

      这里是函数的关键部分,拿出来演示一下:

      
      broom::tidy(ridge$finalModel) %>%
        mutate(sign = ifelse(sign(estimate) == 1, ' + ', ' - ')) %>% #coeff signs
        mutate_if(is.numeric, ~ abs(round(., 2))) %>% #for improving formatting
        mutate(a = ifelse(term == '(Intercept)', paste0('y ~ ', estimate), paste0(sign, estimate, ' * ', term))) 
      
      # A tibble: 1,400 x 7
         term         step estimate lambda dev.ratio sign  a        
         <chr>       <dbl>    <dbl>  <dbl>     <dbl> <chr> <chr>    
       1 (Intercept)     1     21.7  6655.      0    " + " y ~ 21.68
       2 (Intercept)     2     21.7  6064.      0.01 " + " y ~ 21.73
       3 (Intercept)     3     21.7  5525.      0.01 " + " y ~ 21.73
       4 (Intercept)     4     21.7  5034.      0.01 " + " y ~ 21.74
       5 (Intercept)     5     21.7  4587.      0.01 " + " y ~ 21.74
       6 (Intercept)     6     21.8  4180.      0.01 " + " y ~ 21.75
       7 (Intercept)     7     21.8  3808.      0.01 " + " y ~ 21.75
       8 (Intercept)     8     21.8  3470.      0.01 " + " y ~ 21.76
       9 (Intercept)     9     21.8  3162.      0.01 " + " y ~ 21.77
      10 (Intercept)    10     21.8  2881.      0.02 " + " y ~ 21.78
      # … with 1,390 more rows
      

      小提示:across 现在可以替换 mutate_if,例如

      mutate(across(where(is.numeric), ~abs(round(., 2))))
      

      【讨论】:

      • 亲爱的 Andrew,非常感谢您的及时回复。如果您能进一步提供有关构建代码以接收带有最终模型的方程的任何建议,我将不胜感激。它将仅包含来自此代码的信息: coef(ridge$finalModel, ridge$bestTune$lambda) # 系数估计
      猜你喜欢
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      • 2020-09-19
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      相关资源
      最近更新 更多