我尝试使用tidymodels R包来创建ml管道。(一个配方),并将其应用于我的交叉验证的每个重新样本。但这使用了(全局)训练数据来预处理褶皱。我认为正确的做法是在每个“分析”上定义一个预处理配方在一些实施例中,用户可以将其应用于折叠的“评估”(即,训练)部分,并将其应用于折叠的“评估”(即,测试)部分。
下面的代码给出了我的问题的一个例子:
library(tidyverse)
library(tidymodels)
set.seed(1000)
mtcars = mtcars |> select(mpg, hp)
init_split <- initial_split(mtcars, prop = 0.9)
preprocessing_recipe <- recipe(mpg ~ hp,
data = training(init_split)
) |>
step_normalize(all_predictors())
preprocessing_recipe = preprocessing_recipe %>% prep()
preprocessing_recipe
cv_folds <- bake(preprocessing_recipe, new_data = training(init_split)) %>%
vfold_cv(v = 3)
## these resamples are not properly scaled:
training(cv_folds$splits[[1]]) %>% lapply(mean)
## $hp
## [1] 0.1442218
training(cv_folds$splits[[1]]) %>% lapply(sd)
## $hp
## [1] 1.167365
## while the preprocessing on the training data leads to exactly scaled data:
preprocessing_recipe$template %>% lapply(mean)
## $hp
## [1] -1.249001e-16
preprocessing_recipe$template %>% lapply(sd)
## $hp
## [1] 1
上面失败的原因很清楚。但是我如何改变上面的管道(高效,优雅)来定义fold的每个train部分的配方,并将其应用到测试部分?在我看来,这是避免数据泄漏的方法。我在任何帖子的文档中没有找到任何提示。谢谢!
1条答案
按热度按时间nbewdwxp1#
当你使用一个配方时,你是整个生产线的一部分,您不太可能希望自己在诊断目的之外使用
prep()
或bake()
。我们推荐的是将配方与workflow()
一起使用,以便能够将其附加到建模模型。这里我添加了一个线性回归规范。这两个可以一起使用fit()
和predict()
。但是你也可以将它们放入你的交叉验证循环中,根据你的需要使用fit_resamples()
或tune_grid()
。有关详细信息,请参阅:
通过查看配方的估计值,我们可以看到工作流适合每个折叠。我在
control_resamples()
的extract
参数中添加了一个函数,可以提取配方中计算的训练均值和sd。我们可以看到它们与原始褶皱的均值和sd相匹配