tidymodels - predict() 和 fit() 在应用于同一数据集时给出不同的模型性能结果

tidymodels - predict() and fit() giving different model performance results when applied to the same dataset

目前正在使用 tidymodels 框架并努力理解我得到的模型预测和性能结果的一些差异,特别是当我在完全相同的数据集上同时使用 fitpredict 时(即训练模型的数据集)。

下面是一个可重现的示例 - 我正在使用细胞数据集并在数据上训练随机森林 (rf_fit)。对象 rf_fit$fit$predictions 是我评估其准确性的一组预测。然后,我使用 rf_fit 通过 predict 函数对相同数据进行预测(产生 rf_training_pred,我评估其准确性的另一组预测)。

我的问题是 - 为什么这些预测集彼此不同?为什么它们如此不同?

我猜想一定有一些我不知道的事情在幕后发生,但我希望这些是相同的,因为我假设 fit() 训练了一个模型(并且有一些与该训练模型关联的预测),然后 predict() 采用该精确模型并将其重新应用于(在本例中)相同的数据 - 因此两者的预测应该相同。

我错过了什么?非常感谢任何建议或帮助理解 - 提前致谢!

# Load required libraries 
library(tidymodels); library(modeldata) 
#> Registered S3 method overwritten by 'tune':
#>   method                   from   
#>   required_pkgs.model_spec parsnip

# Set seed 
set.seed(123)

# Split up data into training and test
data(cells, package = "modeldata")

# Define Model
rf_mod <- rand_forest(trees = 1000) %>% 
  set_engine("ranger") %>% 
  set_mode("classification")

# Fit the model to training data and then predict on same training data
rf_fit <- rf_mod %>% 
  fit(class ~ ., data = cells)
rf_training_pred <- rf_fit %>%
  predict(cells, type = "prob")

# Evaluate accuracy 
data.frame(rf_fit$fit$predictions) %>%
  bind_cols(cells %>% select(class)) %>%
  roc_auc(truth = class, PS)
#> # A tibble: 1 x 3
#>   .metric .estimator .estimate
#>   <chr>   <chr>          <dbl>
#> 1 roc_auc binary         0.903

rf_training_pred %>%   
  bind_cols(cells %>% select(class)) %>%
  roc_auc(truth = class, .pred_PS)
#> # A tibble: 1 x 3
#>   .metric .estimator .estimate
#>   <chr>   <chr>          <dbl>
#> 1 roc_auc binary          1.00

reprex package (v2.0.1)

于 2021-09-25 创建

首先,查看 ranger::ranger() returns 的文档,尤其是 predictions 是什么:

Predicted classes/values, based on out of bag samples (classification and regression only).

这与您在最终的整个拟合模型上进行预测时得到的结果不同。

其次,当您对最终模型进行预测时,无论您是对 tidymodels 对象还是底层 ranger 对象进行预测,都会得到相同的结果。

library(tidymodels)
#> Registered S3 method overwritten by 'tune':
#>   method                   from   
#>   required_pkgs.model_spec parsnip
library(modeldata) 

data(cells, package = "modeldata")

cells <- cells %>% select(-case)

# Define Model
rf_mod <- rand_forest(trees = 1000) %>% 
  set_engine("ranger") %>% 
  set_mode("classification")

# Fit the model to training data and then predict on same training data
rf_fit <- rf_mod %>% 
  fit(class ~ ., data = cells)

tidymodels_results <- predict(rf_fit, cells, type = "prob")
tidymodels_results
#> # A tibble: 2,019 × 2
#>    .pred_PS .pred_WS
#>       <dbl>    <dbl>
#>  1   0.929    0.0706
#>  2   0.764    0.236 
#>  3   0.222    0.778 
#>  4   0.920    0.0796
#>  5   0.961    0.0386
#>  6   0.0486   0.951 
#>  7   0.101    0.899 
#>  8   0.954    0.0462
#>  9   0.293    0.707 
#> 10   0.405    0.595 
#> # … with 2,009 more rows

ranger_results <- predict(rf_fit$fit, cells, type = "response")
as_tibble(ranger_results$predictions)
#> # A tibble: 2,019 × 2
#>        PS     WS
#>     <dbl>  <dbl>
#>  1 0.929  0.0706
#>  2 0.764  0.236 
#>  3 0.222  0.778 
#>  4 0.920  0.0796
#>  5 0.961  0.0386
#>  6 0.0486 0.951 
#>  7 0.101  0.899 
#>  8 0.954  0.0462
#>  9 0.293  0.707 
#> 10 0.405  0.595 
#> # … with 2,009 more rows

reprex package (v2.0.1)

于 2021-09-25 创建

注意: 这只有效,因为我们使用了非常简单的预处理。作为 we note here,您通常应该 预测基础 $fit 对象。