【问题标题】:How to apply the trained & tested random forest model to a new dataset in tidymodels?如何将经过训练和测试的随机森林模型应用于 tidymodels 中的新数据集?
【发布时间】:2021-07-26 18:24:18
【问题描述】:

我已经使用 tidymodels 在 R 中训练和测试了一个随机森林模型。现在我想使用相同的模型来预测一个全新的数据集(不是训练数据集)。

例如 Julia silge,在这篇博文中解释了训练、测试和评估模型的步骤:Juliasilge's palmer penguins。我想将此模型应用于具有相同列的全新数据集(预测列(此处为性别)除外)

谁能帮我编写预测新数据集的代码。

我可以用示例数据集解释我尝试过的内容

library(palmerpenguins)

penguins <- penguins %>%
  filter(!is.na(sex)) %>%
  select(-year, -island)

#选择最适合的233行进行训练和测试

penguins_train_test<-penguins[1:233,]

#从父数据中拆分其他几行,并假设这是需要预测(而不是测试)的新数据集。因此,对于这个假设,我删除了名为“Sex”的列,需要通过拟合模型来预测(不是测试)

penguins_newdata<-penguins[233:333,-6]


set.seed(123)
penguin_split <- initial_split(penguins_train_test, strata = sex)
penguin_train <- training(penguin_split)
penguin_test <- testing(penguin_split)

创建模型规范。

rf_spec <- rand_forest() %>%
  set_mode("classification") %>%
  set_engine("ranger")

penguin_wf <- workflow() %>%
  add_formula(sex ~ .)

应用于测试数据

penguin_final <- penguin_wf %>%
  add_model(rf_spec) %>%
  last_fit(penguin_split)

collect_metrics(penguin_final)

同样适用于新数据集“penguins_newdata”

penguins_newdata

penguin_wf %>%
  add_model(rf_spec) %>%
  fit(penguins_newdata)

我得到的结果是以下错误

Error: The following outcomes were not found in `data`: 'sex'.

我也试过这种方法

 fit(penguin_wf, penguins_newdata)

这是我遇到的错误

Error: The workflow must have a model. Provide one with `add_model()`.

提前谢谢你。

【问题讨论】:

  • 您需要在使用整个数据的工作流上使用fit 才能使用预测。见this
  • 但是您提供的链接给出了一个在现有(trining+ 测试)数据集 @missuse 上拟合模型的示例。我对我的新数据集(不用于训练和测试,但具有相同的列)采用了类似的方法。我得到了一个类似的错误: UseMethod("fit") 中的错误:没有适用于 'fit' 的方法应用于类 "c('last_fit', 'resample_results', 'tune_results', 'tbl_df', 'tbl' , 'data.frame')"
  • 您是否浏览了链接中的整个示例?或者在问题中提供一个最小的可重现示例,我将尝试回答它。
  • @missuse ,我已经添加了示例数据集以及我尝试过的任何内容。提前致谢

标签: r random-forest predict tidymodels


【解决方案1】:

您的代码中的问题是您试图将最终模型拟合到缺少目标变量 sex 的新数据上,这就是错误告诉您的内容。

Error: The following outcomes were not found in `data`: 'sex'.

毕竟你的工作流程有以下行add_formula(sex ~ .) %&gt;%

library(tidyverse)
library(palmerpenguins)
library(tidymodels)

对训练和测试数据进行预处理和拆分

penguins <- penguins %>%
  filter(!is.na(sex)) %>%
  select(-year, -island)

penguins_train_test <- penguins[1:233,]
penguins_newdata <- penguins[233:333,-6]

定义工作流程

rf_spec <- rand_forest() %>%
  set_mode("classification") %>%
  set_engine("ranger")

penguin_wf <- workflow() %>%
  add_formula(sex ~ .) %>%
  add_model(rf_spec) %>%

使用工作流在训练数据上拟合模型

penguin_wf %>%      
  fit(penguins_train_test) -> model

使用模型预测新数据

predict(model, penguins_newdata)

输出

# A tibble: 101 x 1
   .pred_class
   <fct>      
 1 female     
 2 male       
 3 male       
 4 male       
 5 female     
 6 male       
 7 female     
 8 male       
 9 male       
10 female     
# ... with 91 more rows

这里没有进行调整,模型是使用默认参数制作的。当您通过某种重采样来调整超参数时,您可以按照我从您的问题中收集到的方法进行调整,您可以根据特定指标从调整结果中提取它们

param_final <- rf_tune_results %>%
  select_best(metric = "auc")

并在工作流程中设置它们

rf_workflow <- rf_workflow %>%
  finalize_workflow(param_final)

这样,当您在训练数据上拟合模型时,将使用最佳超参数。

link I posted in the comment 中提供了更多详细信息。

【讨论】:

    【解决方案2】:

    @missuse 上面的答案看起来不错,但我只想添加一些关于哪个工作流程不适合以及哪个工作流程适合的澄清信息。如果您有没有结果的新数据,您希望使用 fitted 工作流程对其进行预测

    library(tidymodels)
    #> Registered S3 method overwritten by 'tune':
    #>   method                   from   
    #>   required_pkgs.model_spec parsnip
    library(palmerpenguins)
    
    penguins <- penguins %>%
      filter(!is.na(sex)) %>%
      select(-year, -island)
    
    penguins_newdata <- penguins[233:333,-6]
    
    
    set.seed(123)
    penguin_split <- initial_split(penguins, strata = sex)
    penguin_train <- training(penguin_split)
    penguin_test <- testing(penguin_split)
    
    rf_spec <- rand_forest() %>%
      set_mode("classification") %>%
      set_engine("ranger")
    
    unfitted_wf <- workflow() %>%
      add_formula(sex ~ .) %>%
      add_model(rf_spec)
    
    
    penguin_final <- last_fit(unfitted_wf, penguin_split)
    
    collect_metrics(penguin_final)
    #> # A tibble: 2 x 4
    #>   .metric  .estimator .estimate .config             
    #>   <chr>    <chr>          <dbl> <chr>               
    #> 1 accuracy binary         0.940 Preprocessor1_Model1
    #> 2 roc_auc  binary         0.983 Preprocessor1_Model1
    
    
    # can predict on this fitted workflow
    fitted_wf <- pluck(penguin_final$.workflow, 1)
    
    predict(fitted_wf, new_data = penguins_newdata)
    #> # A tibble: 101 x 1
    #>    .pred_class
    #>    <fct>      
    #>  1 female     
    #>  2 male       
    #>  3 female     
    #>  4 male       
    #>  5 female     
    #>  6 male       
    #>  7 female     
    #>  8 male       
    #>  9 male       
    #> 10 female     
    #> # … with 91 more rows
    

    reprex package (v2.0.0) 于 2021-05-06 创建

    我使用变量名希望能更清楚地说明哪个工作流是哪个。它类似于模型,您可以在其中指定模型,但在将其拟合到某些训练数据之前,它不能用于预测。

    【讨论】:

      猜你喜欢
      • 2016-07-22
      • 2020-10-31
      • 1970-01-01
      • 2017-12-15
      • 2019-04-24
      • 2021-07-06
      • 2021-10-10
      • 2013-02-13
      • 2019-08-12
      相关资源
      最近更新 更多