suppressPackageStartupMessages( require(tidyverse) )
suppressPackageStartupMessages( require(pryr) )
suppressPackageStartupMessages( require('recipes') )
caret offers unified modelling syntax for a variety of modelling packages and it offers to be compatible with recipes
, rsample
.
data = rsample::attrition
formula = Attrition ~ JobSatisfaction + Gender + MonthlyIncome
grid = expand.grid( cp = 2^c(-10:10) )
car = caret::train( formula
, data = data
, method = 'rpart'
, tuneGrid = grid
)
car
## CART
##
## 1470 samples
## 3 predictor
## 2 classes: 'No', 'Yes'
##
## No pre-processing
## Resampling: Bootstrapped (25 reps)
## Summary of sample sizes: 1470, 1470, 1470, 1470, 1470, 1470, ...
## Resampling results across tuning parameters:
##
## cp Accuracy Kappa
## 9.765625e-04 0.7889875 0.06750448
## 1.953125e-03 0.7958955 0.07026647
## 3.906250e-03 0.8099298 0.07156791
## 7.812500e-03 0.8269818 0.07289258
## 1.562500e-02 0.8360317 0.01851284
## 3.125000e-02 0.8384850 0.00000000
## 6.250000e-02 0.8384850 0.00000000
## 1.250000e-01 0.8384850 0.00000000
## 2.500000e-01 0.8384850 0.00000000
## 5.000000e-01 0.8384850 0.00000000
## 1.000000e+00 0.8384850 0.00000000
## 2.000000e+00 0.8384850 0.00000000
## 4.000000e+00 0.8384850 0.00000000
## 8.000000e+00 0.8384850 0.00000000
## 1.600000e+01 0.8384850 0.00000000
## 3.200000e+01 0.8384850 0.00000000
## 6.400000e+01 0.8384850 0.00000000
## 1.280000e+02 0.8384850 0.00000000
## 2.560000e+02 0.8384850 0.00000000
## 5.120000e+02 0.8384850 0.00000000
## 1.024000e+03 0.8384850 0.00000000
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was cp = 1024.
recipes
The recipe can be used to replace the formula in the caret syntax
rec = recipes::recipe(formula, data) %>%
recipes::step_center( all_numeric() )
car = caret::train( rec
, data
, method = 'rpart'
, tuneGrid = grid
)
car
## CART
##
## 1470 samples
## 30 predictor
## 2 classes: 'No', 'Yes'
##
## Recipe steps: center
## Resampling: Bootstrapped (25 reps)
## Summary of sample sizes: 1470, 1470, 1470, 1470, 1470, 1470, ...
## Resampling results across tuning parameters:
##
## cp Accuracy Kappa
## 9.765625e-04 0.7855593 0.062057222
## 1.953125e-03 0.7935167 0.065357391
## 3.906250e-03 0.8095335 0.069442569
## 7.812500e-03 0.8276583 0.074730075
## 1.562500e-02 0.8356320 0.040784077
## 3.125000e-02 0.8387912 0.009979790
## 6.250000e-02 0.8405723 0.001571582
## 1.250000e-01 0.8410226 0.000000000
## 2.500000e-01 0.8410226 0.000000000
## 5.000000e-01 0.8410226 0.000000000
## 1.000000e+00 0.8410226 0.000000000
## 2.000000e+00 0.8410226 0.000000000
## 4.000000e+00 0.8410226 0.000000000
## 8.000000e+00 0.8410226 0.000000000
## 1.600000e+01 0.8410226 0.000000000
## 3.200000e+01 0.8410226 0.000000000
## 6.400000e+01 0.8410226 0.000000000
## 1.280000e+02 0.8410226 0.000000000
## 2.560000e+02 0.8410226 0.000000000
## 5.120000e+02 0.8410226 0.000000000
## 1.024000e+03 0.8410226 0.000000000
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was cp = 1024.
rsample
rs = rsample::vfold_cv( data, v = 10, repeats = 10) %>%
rsample::rsample2caret()
car = caret::train( formula
, data = data
, method = 'rpart'
, tuneGrid = grid
, trControl = caret::trainControl(index = rs$index
, indexOut = rs$indexOut
, method = 'cv'
, verboseIter = T
, savePredictions = T)
)
## + Repeat01.Fold01: cp=0.0009766
## - Repeat01.Fold01: cp=0.0009766
## + Repeat01.Fold02: cp=0.0009766
## - Repeat01.Fold02: cp=0.0009766
## + Repeat01.Fold03: cp=0.0009766
## - Repeat01.Fold03: cp=0.0009766
## + Repeat01.Fold04: cp=0.0009766
## - Repeat01.Fold04: cp=0.0009766
## + Repeat01.Fold05: cp=0.0009766
## - Repeat01.Fold05: cp=0.0009766
## + Repeat01.Fold06: cp=0.0009766
## - Repeat01.Fold06: cp=0.0009766
## + Repeat01.Fold07: cp=0.0009766
## - Repeat01.Fold07: cp=0.0009766
## + Repeat01.Fold08: cp=0.0009766
## - Repeat01.Fold08: cp=0.0009766
## + Repeat01.Fold09: cp=0.0009766
## - Repeat01.Fold09: cp=0.0009766
## + Repeat01.Fold10: cp=0.0009766
## - Repeat01.Fold10: cp=0.0009766
## + Repeat02.Fold01: cp=0.0009766
## - Repeat02.Fold01: cp=0.0009766
## + Repeat02.Fold02: cp=0.0009766
## - Repeat02.Fold02: cp=0.0009766
## + Repeat02.Fold03: cp=0.0009766
## - Repeat02.Fold03: cp=0.0009766
## + Repeat02.Fold04: cp=0.0009766
## - Repeat02.Fold04: cp=0.0009766
## + Repeat02.Fold05: cp=0.0009766
## - Repeat02.Fold05: cp=0.0009766
## + Repeat02.Fold06: cp=0.0009766
## - Repeat02.Fold06: cp=0.0009766
## + Repeat02.Fold07: cp=0.0009766
## - Repeat02.Fold07: cp=0.0009766
## + Repeat02.Fold08: cp=0.0009766
## - Repeat02.Fold08: cp=0.0009766
## + Repeat02.Fold09: cp=0.0009766
## - Repeat02.Fold09: cp=0.0009766
## + Repeat02.Fold10: cp=0.0009766
## - Repeat02.Fold10: cp=0.0009766
## + Repeat03.Fold01: cp=0.0009766
## - Repeat03.Fold01: cp=0.0009766
## + Repeat03.Fold02: cp=0.0009766
## - Repeat03.Fold02: cp=0.0009766
## + Repeat03.Fold03: cp=0.0009766
## - Repeat03.Fold03: cp=0.0009766
## + Repeat03.Fold04: cp=0.0009766
## - Repeat03.Fold04: cp=0.0009766
## + Repeat03.Fold05: cp=0.0009766
## - Repeat03.Fold05: cp=0.0009766
## + Repeat03.Fold06: cp=0.0009766
## - Repeat03.Fold06: cp=0.0009766
## + Repeat03.Fold07: cp=0.0009766
## - Repeat03.Fold07: cp=0.0009766
## + Repeat03.Fold08: cp=0.0009766
## - Repeat03.Fold08: cp=0.0009766
## + Repeat03.Fold09: cp=0.0009766
## - Repeat03.Fold09: cp=0.0009766
## + Repeat03.Fold10: cp=0.0009766
## - Repeat03.Fold10: cp=0.0009766
## + Repeat04.Fold01: cp=0.0009766
## - Repeat04.Fold01: cp=0.0009766
## + Repeat04.Fold02: cp=0.0009766
## - Repeat04.Fold02: cp=0.0009766
## + Repeat04.Fold03: cp=0.0009766
## - Repeat04.Fold03: cp=0.0009766
## + Repeat04.Fold04: cp=0.0009766
## - Repeat04.Fold04: cp=0.0009766
## + Repeat04.Fold05: cp=0.0009766
## - Repeat04.Fold05: cp=0.0009766
## + Repeat04.Fold06: cp=0.0009766
## - Repeat04.Fold06: cp=0.0009766
## + Repeat04.Fold07: cp=0.0009766
## - Repeat04.Fold07: cp=0.0009766
## + Repeat04.Fold08: cp=0.0009766
## - Repeat04.Fold08: cp=0.0009766
## + Repeat04.Fold09: cp=0.0009766
## - Repeat04.Fold09: cp=0.0009766
## + Repeat04.Fold10: cp=0.0009766
## - Repeat04.Fold10: cp=0.0009766
## + Repeat05.Fold01: cp=0.0009766
## - Repeat05.Fold01: cp=0.0009766
## + Repeat05.Fold02: cp=0.0009766
## - Repeat05.Fold02: cp=0.0009766
## + Repeat05.Fold03: cp=0.0009766
## - Repeat05.Fold03: cp=0.0009766
## + Repeat05.Fold04: cp=0.0009766
## - Repeat05.Fold04: cp=0.0009766
## + Repeat05.Fold05: cp=0.0009766
## - Repeat05.Fold05: cp=0.0009766
## + Repeat05.Fold06: cp=0.0009766
## - Repeat05.Fold06: cp=0.0009766
## + Repeat05.Fold07: cp=0.0009766
## - Repeat05.Fold07: cp=0.0009766
## + Repeat05.Fold08: cp=0.0009766
## - Repeat05.Fold08: cp=0.0009766
## + Repeat05.Fold09: cp=0.0009766
## - Repeat05.Fold09: cp=0.0009766
## + Repeat05.Fold10: cp=0.0009766
## - Repeat05.Fold10: cp=0.0009766
## + Repeat06.Fold01: cp=0.0009766
## - Repeat06.Fold01: cp=0.0009766
## + Repeat06.Fold02: cp=0.0009766
## - Repeat06.Fold02: cp=0.0009766
## + Repeat06.Fold03: cp=0.0009766
## - Repeat06.Fold03: cp=0.0009766
## + Repeat06.Fold04: cp=0.0009766
## - Repeat06.Fold04: cp=0.0009766
## + Repeat06.Fold05: cp=0.0009766
## - Repeat06.Fold05: cp=0.0009766
## + Repeat06.Fold06: cp=0.0009766
## - Repeat06.Fold06: cp=0.0009766
## + Repeat06.Fold07: cp=0.0009766
## - Repeat06.Fold07: cp=0.0009766
## + Repeat06.Fold08: cp=0.0009766
## - Repeat06.Fold08: cp=0.0009766
## + Repeat06.Fold09: cp=0.0009766
## - Repeat06.Fold09: cp=0.0009766
## + Repeat06.Fold10: cp=0.0009766
## - Repeat06.Fold10: cp=0.0009766
## + Repeat07.Fold01: cp=0.0009766
## - Repeat07.Fold01: cp=0.0009766
## + Repeat07.Fold02: cp=0.0009766
## - Repeat07.Fold02: cp=0.0009766
## + Repeat07.Fold03: cp=0.0009766
## - Repeat07.Fold03: cp=0.0009766
## + Repeat07.Fold04: cp=0.0009766
## - Repeat07.Fold04: cp=0.0009766
## + Repeat07.Fold05: cp=0.0009766
## - Repeat07.Fold05: cp=0.0009766
## + Repeat07.Fold06: cp=0.0009766
## - Repeat07.Fold06: cp=0.0009766
## + Repeat07.Fold07: cp=0.0009766
## - Repeat07.Fold07: cp=0.0009766
## + Repeat07.Fold08: cp=0.0009766
## - Repeat07.Fold08: cp=0.0009766
## + Repeat07.Fold09: cp=0.0009766
## - Repeat07.Fold09: cp=0.0009766
## + Repeat07.Fold10: cp=0.0009766
## - Repeat07.Fold10: cp=0.0009766
## + Repeat08.Fold01: cp=0.0009766
## - Repeat08.Fold01: cp=0.0009766
## + Repeat08.Fold02: cp=0.0009766
## - Repeat08.Fold02: cp=0.0009766
## + Repeat08.Fold03: cp=0.0009766
## - Repeat08.Fold03: cp=0.0009766
## + Repeat08.Fold04: cp=0.0009766
## - Repeat08.Fold04: cp=0.0009766
## + Repeat08.Fold05: cp=0.0009766
## - Repeat08.Fold05: cp=0.0009766
## + Repeat08.Fold06: cp=0.0009766
## - Repeat08.Fold06: cp=0.0009766
## + Repeat08.Fold07: cp=0.0009766
## - Repeat08.Fold07: cp=0.0009766
## + Repeat08.Fold08: cp=0.0009766
## - Repeat08.Fold08: cp=0.0009766
## + Repeat08.Fold09: cp=0.0009766
## - Repeat08.Fold09: cp=0.0009766
## + Repeat08.Fold10: cp=0.0009766
## - Repeat08.Fold10: cp=0.0009766
## + Repeat09.Fold01: cp=0.0009766
## - Repeat09.Fold01: cp=0.0009766
## + Repeat09.Fold02: cp=0.0009766
## - Repeat09.Fold02: cp=0.0009766
## + Repeat09.Fold03: cp=0.0009766
## - Repeat09.Fold03: cp=0.0009766
## + Repeat09.Fold04: cp=0.0009766
## - Repeat09.Fold04: cp=0.0009766
## + Repeat09.Fold05: cp=0.0009766
## - Repeat09.Fold05: cp=0.0009766
## + Repeat09.Fold06: cp=0.0009766
## - Repeat09.Fold06: cp=0.0009766
## + Repeat09.Fold07: cp=0.0009766
## - Repeat09.Fold07: cp=0.0009766
## + Repeat09.Fold08: cp=0.0009766
## - Repeat09.Fold08: cp=0.0009766
## + Repeat09.Fold09: cp=0.0009766
## - Repeat09.Fold09: cp=0.0009766
## + Repeat09.Fold10: cp=0.0009766
## - Repeat09.Fold10: cp=0.0009766
## + Repeat10.Fold01: cp=0.0009766
## - Repeat10.Fold01: cp=0.0009766
## + Repeat10.Fold02: cp=0.0009766
## - Repeat10.Fold02: cp=0.0009766
## + Repeat10.Fold03: cp=0.0009766
## - Repeat10.Fold03: cp=0.0009766
## + Repeat10.Fold04: cp=0.0009766
## - Repeat10.Fold04: cp=0.0009766
## + Repeat10.Fold05: cp=0.0009766
## - Repeat10.Fold05: cp=0.0009766
## + Repeat10.Fold06: cp=0.0009766
## - Repeat10.Fold06: cp=0.0009766
## + Repeat10.Fold07: cp=0.0009766
## - Repeat10.Fold07: cp=0.0009766
## + Repeat10.Fold08: cp=0.0009766
## - Repeat10.Fold08: cp=0.0009766
## + Repeat10.Fold09: cp=0.0009766
## - Repeat10.Fold09: cp=0.0009766
## + Repeat10.Fold10: cp=0.0009766
## - Repeat10.Fold10: cp=0.0009766
## Aggregating results
## Selecting tuning parameters
## Fitting cp = 1024 on full training set
unique(car$pred$cp)
## [1] 9.765625e-04 1.953125e-03 3.906250e-03 7.812500e-03 1.562500e-02
## [6] 3.125000e-02 6.250000e-02 1.250000e-01 2.500000e-01 5.000000e-01
## [11] 1.000000e+00 2.000000e+00 4.000000e+00 8.000000e+00 1.600000e+01
## [16] 3.200000e+01 6.400000e+01 1.280000e+02 2.560000e+02 5.120000e+02
## [21] 1.024000e+03
unique(car$pred$Resample)
## [1] "Repeat01.Fold01" "Repeat01.Fold02" "Repeat01.Fold03"
## [4] "Repeat01.Fold04" "Repeat01.Fold05" "Repeat01.Fold06"
## [7] "Repeat01.Fold07" "Repeat01.Fold08" "Repeat01.Fold09"
## [10] "Repeat01.Fold10" "Repeat02.Fold01" "Repeat02.Fold02"
## [13] "Repeat02.Fold03" "Repeat02.Fold04" "Repeat02.Fold05"
## [16] "Repeat02.Fold06" "Repeat02.Fold07" "Repeat02.Fold08"
## [19] "Repeat02.Fold09" "Repeat02.Fold10" "Repeat03.Fold01"
## [22] "Repeat03.Fold02" "Repeat03.Fold03" "Repeat03.Fold04"
## [25] "Repeat03.Fold05" "Repeat03.Fold06" "Repeat03.Fold07"
## [28] "Repeat03.Fold08" "Repeat03.Fold09" "Repeat03.Fold10"
## [31] "Repeat04.Fold01" "Repeat04.Fold02" "Repeat04.Fold03"
## [34] "Repeat04.Fold04" "Repeat04.Fold05" "Repeat04.Fold06"
## [37] "Repeat04.Fold07" "Repeat04.Fold08" "Repeat04.Fold09"
## [40] "Repeat04.Fold10" "Repeat05.Fold01" "Repeat05.Fold02"
## [43] "Repeat05.Fold03" "Repeat05.Fold04" "Repeat05.Fold05"
## [46] "Repeat05.Fold06" "Repeat05.Fold07" "Repeat05.Fold08"
## [49] "Repeat05.Fold09" "Repeat05.Fold10" "Repeat06.Fold01"
## [52] "Repeat06.Fold02" "Repeat06.Fold03" "Repeat06.Fold04"
## [55] "Repeat06.Fold05" "Repeat06.Fold06" "Repeat06.Fold07"
## [58] "Repeat06.Fold08" "Repeat06.Fold09" "Repeat06.Fold10"
## [61] "Repeat07.Fold01" "Repeat07.Fold02" "Repeat07.Fold03"
## [64] "Repeat07.Fold04" "Repeat07.Fold05" "Repeat07.Fold06"
## [67] "Repeat07.Fold07" "Repeat07.Fold08" "Repeat07.Fold09"
## [70] "Repeat07.Fold10" "Repeat08.Fold01" "Repeat08.Fold02"
## [73] "Repeat08.Fold03" "Repeat08.Fold04" "Repeat08.Fold05"
## [76] "Repeat08.Fold06" "Repeat08.Fold07" "Repeat08.Fold08"
## [79] "Repeat08.Fold09" "Repeat08.Fold10" "Repeat09.Fold01"
## [82] "Repeat09.Fold02" "Repeat09.Fold03" "Repeat09.Fold04"
## [85] "Repeat09.Fold05" "Repeat09.Fold06" "Repeat09.Fold07"
## [88] "Repeat09.Fold08" "Repeat09.Fold09" "Repeat09.Fold10"
## [91] "Repeat10.Fold01" "Repeat10.Fold02" "Repeat10.Fold03"
## [94] "Repeat10.Fold04" "Repeat10.Fold05" "Repeat10.Fold06"
## [97] "Repeat10.Fold07" "Repeat10.Fold08" "Repeat10.Fold09"
## [100] "Repeat10.Fold10"
car$pred %>%
as_tibble() %>%
dplyr::group_by(rowIndex) %>%
dplyr::count() %>%
head()
## # A tibble: 6 x 2
## # Groups: rowIndex [6]
## rowIndex n
## <int> <int>
## 1 1 210
## 2 2 210
## 3 3 210
## 4 4 210
## 5 5 210
## 6 6 210
nrow(data)
## [1] 1470
nrow(grid)
## [1] 21
car$pred %>%
as_tibble() %>%
dplyr::group_by(rowIndex) %>%
dplyr::count() %>%
nrow()
## [1] 1470
pryr::object_size(car)
## 10.7 MB
pryr::object_size(data)
## 275 kB
using all three packages and fitting two different kinds of models using two different formulas in a modelling dataframe
require(recipes)
data = rsample::attrition
formula1 = Attrition ~ JobSatisfaction + Gender + MonthlyIncome
formula2 = Attrition ~ JobSatisfaction + Gender + MonthlyIncome + DistanceFromHome
grid_tree = expand.grid( cp = 2^c(-10:10), method = 'rpart', stringsAsFactors = FALSE) %>%
as_tibble() %>%
nest( cp, .key = 'grid' ) %>%
mutate()
grid_svm = expand.grid( mtry = c(1:3), method = 'rf', stringsAsFactors = FALSE ) %>%
as_tibble() %>%
nest( mtry, .key = 'grid' )
df = expand.grid( formula = list(formula1, formula2)
, grid = list( grid_tree, grid_svm )
) %>%
unnest(grid) %>%
as.tibble()
df = df %>%
mutate( rec = map( formula, recipe, data)
, rec = map( rec, step_scale, all_numeric() )
, rec = map( rec, step_center, all_numeric() )
, cv = list(rsample::vfold_cv(data, v = 5, repeats = 1) )
, cv_rs = map( cv, rsample::rsample2caret )
)
object_size(df)
## 4.26 MB
object_size(data)
## 275 kB
caret::train()
car = function( recipe, rsample, method, grid, data){
grid = as.data.frame(grid)
car = caret::train( recipe
, data
, method = method
, tuneGrid = grid
, trControl = caret::trainControl(index = rsample$index
, indexOut = rsample$indexOut
, method = 'cv'
, verboseIter = T
, savePredictions = T
, classProbs = T )
)
return( as.tibble(car$pred) )
}
df = df %>%
mutate( preds = pmap(list(rec, cv_rs, method, grid), car, data = data) )
## Preparing recipe
## + Fold1: cp=0.0009766
## - Fold1: cp=0.0009766
## + Fold2: cp=0.0009766
## - Fold2: cp=0.0009766
## + Fold3: cp=0.0009766
## - Fold3: cp=0.0009766
## + Fold4: cp=0.0009766
## - Fold4: cp=0.0009766
## + Fold5: cp=0.0009766
## - Fold5: cp=0.0009766
## Aggregating results
## Selecting tuning parameters
## Fitting cp = 1024 on full training set
## Preparing recipe
## + Fold1: cp=0.0009766
## - Fold1: cp=0.0009766
## + Fold2: cp=0.0009766
## - Fold2: cp=0.0009766
## + Fold3: cp=0.0009766
## - Fold3: cp=0.0009766
## + Fold4: cp=0.0009766
## - Fold4: cp=0.0009766
## + Fold5: cp=0.0009766
## - Fold5: cp=0.0009766
## Aggregating results
## Selecting tuning parameters
## Fitting cp = 1024 on full training set
## Preparing recipe
## + Fold1: mtry=1
## - Fold1: mtry=1
## + Fold1: mtry=2
## - Fold1: mtry=2
## + Fold1: mtry=3
## - Fold1: mtry=3
## + Fold2: mtry=1
## - Fold2: mtry=1
## + Fold2: mtry=2
## - Fold2: mtry=2
## + Fold2: mtry=3
## - Fold2: mtry=3
## + Fold3: mtry=1
## - Fold3: mtry=1
## + Fold3: mtry=2
## - Fold3: mtry=2
## + Fold3: mtry=3
## - Fold3: mtry=3
## + Fold4: mtry=1
## - Fold4: mtry=1
## + Fold4: mtry=2
## - Fold4: mtry=2
## + Fold4: mtry=3
## - Fold4: mtry=3
## + Fold5: mtry=1
## - Fold5: mtry=1
## + Fold5: mtry=2
## - Fold5: mtry=2
## + Fold5: mtry=3
## - Fold5: mtry=3
## Aggregating results
## Selecting tuning parameters
## Fitting mtry = 1 on full training set
## Preparing recipe
## + Fold1: mtry=1
## - Fold1: mtry=1
## + Fold1: mtry=2
## - Fold1: mtry=2
## + Fold1: mtry=3
## - Fold1: mtry=3
## + Fold2: mtry=1
## - Fold2: mtry=1
## + Fold2: mtry=2
## - Fold2: mtry=2
## + Fold2: mtry=3
## - Fold2: mtry=3
## + Fold3: mtry=1
## - Fold3: mtry=1
## + Fold3: mtry=2
## - Fold3: mtry=2
## + Fold3: mtry=3
## - Fold3: mtry=3
## + Fold4: mtry=1
## - Fold4: mtry=1
## + Fold4: mtry=2
## - Fold4: mtry=2
## + Fold4: mtry=3
## - Fold4: mtry=3
## + Fold5: mtry=1
## - Fold5: mtry=1
## + Fold5: mtry=2
## - Fold5: mtry=2
## + Fold5: mtry=3
## - Fold5: mtry=3
## Aggregating results
## Selecting tuning parameters
## Fitting mtry = 1 on full training set
df
## # A tibble: 4 x 7
## formula method grid rec cv
## <list> <chr> <list> <list> <list>
## 1 <S3: formula> rpart <tibble [21 x 1]> <S3: recipe> <tibble [5 x 2]>
## 2 <S3: formula> rpart <tibble [21 x 1]> <S3: recipe> <tibble [5 x 2]>
## 3 <S3: formula> rf <tibble [3 x 1]> <S3: recipe> <tibble [5 x 2]>
## 4 <S3: formula> rf <tibble [3 x 1]> <S3: recipe> <tibble [5 x 2]>
## # ... with 2 more variables: cv_rs <list>, preds <list>