Machine Learning with tidymodels
Prerequisites: Generalized linear models, dplyr: mutate, summarise, and group_by
tidymodels is a collection of packages for building machine-learning models with a consistent, tidyverse-style interface — whatever the underlying algorithm.
install.packages("tidymodels")
The workflow
A sound modeling workflow protects you from fooling yourself:
- Split the data into training and test sets. The test set is locked away until the very end.
- Preprocess with a recipe (scaling, encoding categories, handling missing values), learned from the training data only.
- Specify a model with parsnip.
- Resample (cross-validation) on the training set to compare and tune models.
- Evaluate once on the test set to estimate real-world performance.
An example: predicting penguin species
library(tidymodels)
tidymodels_prefer()
penguins <- modeldata::penguins |> tidyr::drop_na()
set.seed(123)
split <- initial_split(penguins, prop = 0.75, strata = species)
train <- training(split)
test <- testing(split)
rec <- recipe(species ~ bill_length_mm + bill_depth_mm + flipper_length_mm + body_mass_g,
data = train) |>
step_normalize(all_numeric_predictors())
model_spec <- rand_forest(trees = 500) |>
set_engine("ranger") |>
set_mode("classification")
wf <- workflow() |>
add_recipe(rec) |>
add_model(model_spec)
folds <- vfold_cv(train, v = 5, strata = species)
cv_results <- fit_resamples(wf, folds, metrics = metric_set(accuracy, roc_auc))
collect_metrics(cv_results)
final_fit <- last_fit(wf, split)
collect_metrics(final_fit)
# A tibble: 2 × 6
.metric .estimator mean n std_err .config
<chr> <chr> <dbl> <int> <dbl> <chr>
1 accuracy multiclass 0.980 5 0.00898 Preprocessor1_Model1
2 roc_auc hand_till 0.999 5 0.00100 Preprocessor1_Model1
(Exact numbers will vary slightly with package versions.)
initial_split(..., strata = species)keeps species proportions similar in both sets.- The recipe normalizes numeric predictors; because it's part of the workflow, it's re-learned inside each cross-validation fold, preventing data leakage from the validation data.
rand_forest()describes the model;set_engine("ranger")picks the implementation. Swapping tologistic_reg(),boost_tree(), orsvm_rbf()changes one line.last_fittrains on the full training set and evaluates on the test set — the number to report.
Tuning
Mark hyperparameters with tune() — for example,
rand_forest(mtry = tune(), min_n = tune()) — and tune_grid(wf, folds)
tries combinations with cross-validation; select_best() picks the
winner.
Common mistakes
- Data leakage — preprocessing (like scaling or imputing) using the whole dataset before splitting, or peeking at the test set while tuning. Performance then looks better than it will be in reality.
- Chasing accuracy without checking what the model gets wrong, or whether it's fair across groups.