我阅读了 tidymodels 的介绍,我对食谱包对数据的作用prep(), bake()
和作用感到困惑。juice()
各自做什么?老实说,我发现为函数命名这样的名称令人困惑,在烹饪类比中,每个函数的名称会更直观吗?
1 回答
让我们来看看每个函数的作用。首先,让我们通过几个步骤定义一个配方。请注意,进入配方的数据是训练数据。
library(recipes)
cars_train <- mtcars[1:20,]
cars_test <- mtcars[21:32,]
cars_rec <- recipe(mpg ~ ., data = cars_train) %>%
step_log(disp) %>%
step_center(all_predictors())
cars_rec
#> Data Recipe
#>
#> Inputs:
#>
#> role #variables
#> outcome 1
#> predictor 10
#>
#> Operations:
#>
#> Log transformation on disp
#> Centering for all_predictors
预处理配方cars_rec
已定义,但未估算任何值。例如,没有为 取对数disp
,也没有计算预测变量的平均值,因此它们可以居中。
该prep()
函数采用该定义的对象并计算所有内容,以便可以执行预处理步骤。例如,在此示例中计算了每个预测变量的平均值,因此可以使预测变量居中。这是通过训练数据完成的。
cars_prep <- prep(cars_rec)
cars_prep
#> Data Recipe
#>
#> Inputs:
#>
#> role #variables
#> outcome 1
#> predictor 10
#>
#> Training data contained 20 data points and no missing data.
#>
#> Operations:
#>
#> Log transformation on disp [trained]
#> Centering for cyl, disp, hp, drat, wt, qsec, vs, am, ... [trained]
请注意,之前,对于未准备好的配方,它只是说Centering for all_predictors
因为它还没有被评估。现在已经对其进行了评估,我们知道哪些列是预测变量以及它们的平均值是什么。
和函数都返回数据,bake()
而juice()
不是预处理配方对象。该bake()
函数采用一个准备好的配方(一个已经从训练数据中估算出所有数量的配方)并将其应用于new_data
. 那new_data
可能又是训练数据...
bake(cars_prep, new_data = cars_train)
#> # A tibble: 20 x 11
#> cyl disp hp drat wt qsec vs am gear carb mpg
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 -0.2 -0.222 -26.2 0.355 -0.778 -1.98 -0.5 0.7 0.5 1.30 21
#> 2 -0.2 -0.222 -26.2 0.355 -0.523 -1.42 -0.5 0.7 0.5 1.30 21
#> 3 -2.2 -0.615 -43.2 0.305 -1.08 0.169 0.5 0.7 0.5 -1.7 22.8
#> 4 -0.2 0.256 -26.2 -0.465 -0.183 0.999 0.5 -0.3 -0.5 -1.7 21.4
#> 5 1.8 0.589 38.8 -0.395 0.0415 -1.42 -0.5 -0.3 -0.5 -0.7 18.7
#> 6 -0.2 0.119 -31.2 -0.785 0.0615 1.78 0.5 -0.3 -0.5 -1.7 18.1
#> 7 1.8 0.589 109. -0.335 0.172 -2.60 -0.5 -0.3 -0.5 1.30 14.3
#> 8 -2.2 -0.309 -74.2 0.145 -0.208 1.56 0.5 -0.3 0.5 -0.7 24.4
#> 9 -2.2 -0.350 -41.2 0.375 -0.248 4.46 0.5 -0.3 0.5 -0.7 22.8
#> 10 -0.2 -0.176 -13.2 0.375 0.0415 -0.141 0.5 -0.3 0.5 1.30 19.2
#> 11 -0.2 -0.176 -13.2 0.375 0.0415 0.459 0.5 -0.3 0.5 1.30 17.8
#> 12 1.8 0.323 43.8 -0.475 0.672 -1.04 -0.5 -0.3 -0.5 0.300 16.4
#> 13 1.8 0.323 43.8 -0.475 0.332 -0.841 -0.5 -0.3 -0.5 0.300 17.3
#> 14 1.8 0.323 43.8 -0.475 0.382 -0.441 -0.5 -0.3 -0.5 0.300 15.2
#> 15 1.8 0.860 68.8 -0.615 1.85 -0.461 -0.5 -0.3 -0.5 1.30 10.4
#> 16 1.8 0.834 78.8 -0.545 2.03 -0.621 -0.5 -0.3 -0.5 1.30 10.4
#> 17 1.8 0.790 93.8 -0.315 1.95 -1.02 -0.5 -0.3 -0.5 1.30 14.7
#> 18 -2.2 -0.932 -70.2 0.535 -1.20 1.03 0.5 0.7 0.5 -1.7 32.4
#> 19 -2.2 -0.970 -84.2 1.38 -1.78 0.079 0.5 0.7 0.5 -0.7 30.4
#> 20 -2.2 -1.03 -71.2 0.675 -1.56 1.46 0.5 0.7 0.5 -1.7 33.9
或者它可能是测试数据。在这种情况下,来自训练数据的列均值应用于测试数据,因为这就是 IRL 在建模工作流程中发生的情况。否则就是数据泄露。
bake(cars_prep, new_data = cars_test)
#> # A tibble: 12 x 11
#> cyl disp hp drat wt qsec vs am gear carb mpg
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 -2.2 -0.509 -39.2 0.155 -0.933 1.57 0.5 -0.3 -0.5 -1.7 21.5
#> 2 1.8 0.465 13.8 -0.785 0.122 -1.57 -0.5 -0.3 -0.5 -0.7 15.5
#> 3 1.8 0.420 13.8 -0.395 0.0366 -1.14 -0.5 -0.3 -0.5 -0.7 15.2
#> 4 1.8 0.561 109. 0.185 0.442 -3.03 -0.5 -0.3 -0.5 1.30 13.3
#> 5 1.8 0.694 38.8 -0.465 0.447 -1.39 -0.5 -0.3 -0.5 -0.7 19.2
#> 6 -2.2 -0.928 -70.2 0.535 -1.46 0.459 0.5 0.7 0.5 -1.7 27.3
#> 7 -2.2 -0.507 -45.2 0.885 -1.26 -1.74 -0.5 0.7 1.5 -0.7 26
#> 8 -2.2 -0.742 -23.2 0.225 -1.89 -1.54 0.5 0.7 1.5 -0.7 30.4
#> 9 1.8 0.564 128. 0.675 -0.228 -3.94 -0.5 0.7 1.5 1.30 15.8
#> 10 -0.2 -0.320 38.8 0.075 -0.628 -2.94 -0.5 0.7 1.5 3.3 19.7
#> 11 1.8 0.410 199. -0.00500 0.172 -3.84 -0.5 0.7 1.5 5.3 15
#> 12 -2.2 -0.501 -27.2 0.565 -0.618 0.159 0.5 0.7 0.5 -0.7 21.4
该juice()
功能是一个不错的小捷径。因为准备好的配方是根据训练数据估计的,所以您只能从它处理训练数据。想象一下自己挤压准备好的配方以获取训练数据,这些数据用于估计预处理参数。
juice(cars_prep)
#> # A tibble: 20 x 11
#> cyl disp hp drat wt qsec vs am gear carb mpg
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 -0.2 -0.222 -26.2 0.355 -0.778 -1.98 -0.5 0.7 0.5 1.30 21
#> 2 -0.2 -0.222 -26.2 0.355 -0.523 -1.42 -0.5 0.7 0.5 1.30 21
#> 3 -2.2 -0.615 -43.2 0.305 -1.08 0.169 0.5 0.7 0.5 -1.7 22.8
#> 4 -0.2 0.256 -26.2 -0.465 -0.183 0.999 0.5 -0.3 -0.5 -1.7 21.4
#> 5 1.8 0.589 38.8 -0.395 0.0415 -1.42 -0.5 -0.3 -0.5 -0.7 18.7
#> 6 -0.2 0.119 -31.2 -0.785 0.0615 1.78 0.5 -0.3 -0.5 -1.7 18.1
#> 7 1.8 0.589 109. -0.335 0.172 -2.60 -0.5 -0.3 -0.5 1.30 14.3
#> 8 -2.2 -0.309 -74.2 0.145 -0.208 1.56 0.5 -0.3 0.5 -0.7 24.4
#> 9 -2.2 -0.350 -41.2 0.375 -0.248 4.46 0.5 -0.3 0.5 -0.7 22.8
#> 10 -0.2 -0.176 -13.2 0.375 0.0415 -0.141 0.5 -0.3 0.5 1.30 19.2
#> 11 -0.2 -0.176 -13.2 0.375 0.0415 0.459 0.5 -0.3 0.5 1.30 17.8
#> 12 1.8 0.323 43.8 -0.475 0.672 -1.04 -0.5 -0.3 -0.5 0.300 16.4
#> 13 1.8 0.323 43.8 -0.475 0.332 -0.841 -0.5 -0.3 -0.5 0.300 17.3
#> 14 1.8 0.323 43.8 -0.475 0.382 -0.441 -0.5 -0.3 -0.5 0.300 15.2
#> 15 1.8 0.860 68.8 -0.615 1.85 -0.461 -0.5 -0.3 -0.5 1.30 10.4
#> 16 1.8 0.834 78.8 -0.545 2.03 -0.621 -0.5 -0.3 -0.5 1.30 10.4
#> 17 1.8 0.790 93.8 -0.315 1.95 -1.02 -0.5 -0.3 -0.5 1.30 14.7
#> 18 -2.2 -0.932 -70.2 0.535 -1.20 1.03 0.5 0.7 0.5 -1.7 32.4
#> 19 -2.2 -0.970 -84.2 1.38 -1.78 0.079 0.5 0.7 0.5 -0.7 30.4
#> 20 -2.2 -1.03 -71.2 0.675 -1.56 1.46 0.5 0.7 0.5 -1.7 33.9
由reprex 包(v0.3.0)于 2020-06-04 创建
它与bake(cars_prep, new_data = cars_train)
并且只是一个快捷方式相同。