在 `tidymodels` 中,我如何进行 F 检验来比较两个模型?

In `tidymodels` how do I do an F test to compare two models?

在基础 R 中,很容易使用 anova() 函数比较两个模型并进行 F 检验。

library(MASS)
lm.fit1 <- lm(medv ~ . , data = Boston)
lm.fit1a <- update(lm.fit1, ~ . - age - black)

anova(lm.fit1a, lm.fit1)

如果我正在使用 tidymodels 工作流程。我如何进行相同的比较?我有这样的代码:

library(tidymodels)
lm_spec <- linear_reg() %>%
  set_mode("regression") %>%
  set_engine("lm")

the_rec <- recipe(medv ~ ., data = Boston)

the_workflow <- workflow() %>% 
  add_recipe(the_rec) %>% 
  add_model(lm_spec)

the_workflow_fit1 <- 
  fit(the_workflow, data = Boston)
tidy(the_workflow_fit1)


the_workflow_fit1a <- 
  the_workflow_fit1  %>% 
  update_recipe(the_rec %>% step_rm(age, black)) %>% 
  fit(data = Boston) 
tidy(the_workflow_fit1a)

我不知道如何提取正确的对象(thingy)来提供这样的语句:

anova(the_workflow_fit1a$thingy, the_workflow_fit1$thingy)

我需要什么东西?在 tidymodels 生态系统中是否有一种优雅的方式来做到这一点?

我不完全熟悉 tidymodels 生态系统,因此我不确定这是否是您寻找的完美解决方案。

我深入研究了对象 the_workflow_fit1a,发现子集 .$fit$fit$fit 服务于 anova 函数所需的 lm 对象。

所以,可以考虑采用这种方式解决;

models <- list(the_workflow_fit1,the_workflow_fit1a)

models2 <- lapply(models,function(x) x$fit$fit$fit)
                  
anova(models2[[1]],models2[[2]])

输出;

  Res.Df    RSS    Df `Sum of Sq`     F `Pr(>F)`
   <dbl>  <dbl> <dbl>       <dbl> <dbl>    <dbl>
1    492 11079.    NA         NA  NA    NA      
2    494 11351.    -2       -272.  6.05  0.00254

许多小时后,来自@juliasilge https://github.com/tidymodels/workflows/issues/54 的 post 向我介绍了 pull_workflow_fit() 我有一个 tidymodels 解决方案。

基础 R 代码:

library(MASS)
lm.fit1 <- lm(medv ~ . , data = Boston)
lm.fit1a <- update(lm.fit1, ~ . - age - black)
anova(lm.fit1a, lm.fit1)

可以在 tidymodels 中完成:

library(tidymodels)
lm_spec <- linear_reg() %>%
  set_mode("regression") %>%
  set_engine("lm")

the_rec <- recipe(medv ~ ., data = Boston)

the_workflow <- workflow() %>% 
  add_recipe(the_rec) %>% 
  add_model(lm_spec)

the_workflow_fit1 <- 
  fit(the_workflow, data = Boston) %>% 
  extract_fit_parsnip()

the_workflow_fit1a <- 
  the_workflow  %>% 
  update_recipe(
    the_rec %>% step_rm(age, black)
  ) %>% 
  fit(data = Boston) %>% 
  extract_fit_parsnip()

anova(the_workflow_fit1a$fit, the_workflow_fit1$fit)