【问题标题】:What is the difference among prep/bake/juice in the R package "recipes"?R 包“食谱”中的 prep/bake/juice 有什么区别?
【发布时间】:2020-09-23 03:47:01
【问题描述】:

我阅读了 tidymodels 的介绍,我对食谱包中的 prep(), bake()juice() 对数据的作用感到困惑。各自做什么?老实说,我发现给函数起这样的名字很困惑,从烹饪类比中每个函数的名称会更直观吗?

【问题讨论】:

    标签: r tidyverse tidymodels r-recipes


    【解决方案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_datanew_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 package (v0.3.0) 于 2020 年 6 月 4 日创建

    bake(cars_prep, new_data = cars_train)一样,只是一个快捷方式。

    【讨论】:

    • 非常感谢,解释清楚了!现在我想我只需要一些练习。作为 R 中 ML 的初学者,恕我直言,我仍然认为更好的名称会通过 tidymodels 缓解学习曲线;食谱,尤其是这部分,我花了大部分时间一遍又一遍地阅读以掌握其背后的想法。
    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 2017-04-20
    相关资源
    最近更新 更多