tidymodel 错误,当调用预测函数时要求目标变量

tidymodel error, when calling predict function is asking for target variable

我用客户数据(超过 200 列)训练了一个客户流失模型。 使用 xgbboost 获得了相当不错的指标,但问题是在尝试预测新数据时。

预测函数要求目标变量(流失),我有点困惑,因为这个变量不应该出现在真实场景数据中,因为这是我想要预测的变量。

下面的示例代码,也许我错过了程序的重点。出现了一些问题:

  1. 我应该在配方结束时执行 prep() 吗?

  2. 我应该在预测之前对我的新数据执行配方吗?

  3. 为什么从配方中删除有关目标变量的行使预测有效?

  4. 为什么要我的目标变量?

        churn_recipe <- recipes::recipe(churn ~ ., data = churn_train) %>%
           recipes::step_naomit(everything(), skip = TRUE) %>% 
           recipes::step_rm(c(v1, v2, v3, v4, v5, v6)) %>%
        #  removing/commenting the next 2 lines makes predict() work
           recipes::step_string2factor(churn) %>%  
           themis::step_downsample(churn) %>%
           recipes::step_dummy(all_nominal_predictors()) %>% 
           recipes::step_novel(all_nominal(), -all_outcomes())  ### %>% prep()
    
            xgboost_model <-
               parsnip::boost_tree(
                 mode = "classification",
                 trees = 100
               ) %>%
               set_engine("xgboost") %>% 
               set_mode("classification")
    
             xgboost_workflow <-
               workflows::workflow() %>%
               add_recipe(churn_recipe) %>% 
               add_model(xgboost_model) 
    
               my_fit <- last_fit(xgboost_workflow, churn_split)
    
               collect_metrics(my_fit)
    
    
               churn_wf_model <- my_fit$.workflow[[1]]
    
             predict(churn_wf_model, new_data[1,])
             Error: Can't subset columns that don't exist.
             x Column `churn` doesn't exist.
    

我很确定我这边有些误解,但无法解决这个问题。

我无法将我的模型投入生产。 Tidymodels 文档缺乏这样的主题是巨大的。

您收到此错误是因为 recipes::step_string2factor(churn)

当您训练数据时,此步骤工作正常。但是当需要对训练集应用相同的转换时,step_string2factor() 会报错,因为它被要求将 churn 从字符串转换为因子,但数据集不包含 churn 变量。您可以通过两种方式处理此问题。

skip = FALSEstep_string2factor()(较差)

通过在 step_string2factor() 中设置 skip = FALSE,您告诉步骤 o 仅适用于 prepping/training 配方。这是不利的,因为这种方法可能会在某些使用 {tune} 的重采样场景中产生错误,而响应应该是一个因子而不是字符串。

library(tidymodels)

data("mlc_churn")

set.seed(1234)
churn_split <- initial_split(mlc_churn)

churn_train <- training(churn_split)
churn_test <- testing(churn_split)


churn_recipe <- recipes::recipe(churn ~ ., data = churn_train) %>%
   recipes::step_naomit(everything(), skip = TRUE) %>% 
   recipes::step_string2factor(churn, skip = TRUE) %>%  
   themis::step_downsample(churn) %>%
   recipes::step_dummy(all_nominal_predictors()) %>% 
   recipes::step_novel(all_nominal(), -all_outcomes())

xgboost_model <-
  parsnip::boost_tree(
    mode = "classification",
    trees = 100
  ) %>%
  set_engine("xgboost") %>% 
  set_mode("classification")

xgboost_workflow <-
  workflows::workflow() %>%
  add_recipe(churn_recipe) %>% 
  add_model(xgboost_model) 

my_fit <- last_fit(xgboost_workflow, churn_split)

churn_wf_model <- my_fit$.workflow[[1]]

predict(churn_wf_model, churn_test)
#> # A tibble: 1,250 x 1
#>    .pred_class
#>    <fct>      
#>  1 no         
#>  2 no         
#>  3 no         
#>  4 no         
#>  5 no         
#>  6 no         
#>  7 no         
#>  8 no         
#>  9 no         
#> 10 yes        
#> # … with 1,240 more rows

reprex package (v2.0.0)

于 2021-06-10 创建

在拆分之前将响应作为一个因素(推荐)

解决此问题的推荐方法是确保您的响应 churn 是一个因素,然后再将其传递到{recipes}。我发现这样做最简单,因为我像这样使用 initial_split() 创建验证拆分。那么你就不需要在你的食谱

中对你的回应使用step_string2factor()
churn_split <- mlc_churn %>%
  mutate(churn = factor(churn)) %>%
  initial_split()