| name | model-tuning |
| description | Hyperparameter tuning in tidymodels with grids, Bayesian optimization, racing, and workflow finalization. |
Model Tuning Patterns
Overview
Comprehensive hyperparameter optimization using the tune package. Covers grid search, iterative search, racing methods, and Bayesian optimization.
Tunable Parameters
Marking Parameters for Tuning
library(tidymodels)
rf_spec <- rand_forest(
mtry = tune(),
trees = 1000,
min_n = tune()
) |>
set_engine("ranger") |>
set_mode("classification")
rec <- recipe(outcome ~ ., data = train) |>
step_pca(all_numeric_predictors(), num_comp = tune()) |>
step_normalize(all_numeric_predictors())
Parameter Objects (dials)
library(dials)
mtry()
min_n()
trees()
learn_rate()
penalty()
mtry(range = c(2, 20))
min_n(range = c(5, 50))
learn_rate(range = c(-3, -1), trans = log10_trans())
mtry_final <- finalize(mtry(), train_data)
Grid Search
Regular Grid
regular_grid <- grid_regular(
mtry(range = c(2, 10)),
min_n(range = c(2, 20)),
levels = 5
)
regular_grid <- grid_regular(
mtry(range = c(2, 10)),
min_n(range = c(2, 20)),
levels = c(mtry = 5, min_n = 3)
)
Random Grid
random_grid <- grid_random(
mtry(range = c(2, 10)),
min_n(range = c(2, 20)),
size = 50
)
Space-Filling Designs
lhs_grid <- grid_latin_hypercube(
mtry(range = c(2, 10)),
min_n(range = c(2, 20)),
size = 30
)
maxent_grid <- grid_max_entropy(
mtry(range = c(2, 10)),
min_n(range = c(2, 20)),
size = 30
)
Running Grid Search
tune_results <- workflow |>
tune_grid(
resamples = cv_folds,
grid = 20,
metrics = metric_set(roc_auc, accuracy),
control = control_grid(verbose = TRUE)
)
tune_results <- workflow |>
tune_grid(
resamples = cv_folds,
grid = my_grid,
metrics = metric_set(roc_auc, accuracy)
)
Bayesian Optimization
Basic Bayesian Tuning
tune_results <- workflow |>
tune_bayes(
resamples = cv_folds,
iter = 50,
initial = 10,
metrics = metric_set(roc_auc),
control = control_bayes(
verbose = TRUE,
no_improve = 20
)
)
Bayesian with Custom Initial Points
initial_grid <- workflow |>
tune_grid(
resamples = cv_folds,
grid = 10,
metrics = metric_set(roc_auc)
)
bayes_results <- workflow |>
tune_bayes(
resamples = cv_folds,
iter = 40,
initial = initial_grid,
metrics = metric_set(roc_auc)
)
Acquisition Functions
control_bayes(
objective = exp_improve(),
objective = prob_improve(),
objective = conf_bound(kappa = 2)
)
Racing Methods (finetune)
ANOVA Racing
library(finetune)
race_results <- workflow |>
tune_race_anova(
resamples = cv_folds,
grid = 50,
metrics = metric_set(roc_auc),
control = control_race(
verbose = TRUE,
burn_in = 3
)
)
plot_race(race_results)
Win/Loss Racing
race_results <- workflow |>
tune_race_win_loss(
resamples = cv_folds,
grid = 50,
metrics = metric_set(roc_auc),
control = control_race()
)
Simulated Annealing
library(finetune)
sa_results <- workflow |>
tune_sim_anneal(
resamples = cv_folds,
iter = 50,
initial = 5,
metrics = metric_set(roc_auc),
control = control_sim_anneal(
verbose = TRUE,
cooling_coef = 0.1
)
)
Analyzing Tuning Results
Best Parameters
best_params <- select_best(tune_results, metric = "roc_auc")
best_params <- select_by_one_std_err(
tune_results,
metric = "roc_auc",
mtry, min_n
)
best_params <- select_by_pct_loss(
tune_results,
metric = "roc_auc",
limit = 2
)
Visualizing Results
autoplot(tune_results)
autoplot(tune_results, type = "marginals")
autoplot(tune_results, type = "parameters")
metrics_df <- collect_metrics(tune_results)
Finalizing Model
final_wf <- workflow |>
finalize_workflow(best_params)
final_fit <- final_wf |>
last_fit(data_split)
collect_metrics(final_fit)
Parallel Processing
library(doParallel)
cl <- makePSOCKcluster(parallel::detectCores() - 1)
registerDoParallel(cl)
tune_results <- workflow |>
tune_grid(
resamples = cv_folds,
grid = 100
)
stopCluster(cl)
Using future
library(future)
plan(multisession, workers = 4)
race_results <- workflow |>
tune_race_anova(
resamples = cv_folds,
grid = 100,
control = control_race(parallel_over = "everything")
)
Tuning XGBoost Example
xgb_spec <- boost_tree(
trees = tune(),
tree_depth = tune(),
min_n = tune(),
loss_reduction = tune(),
sample_size = tune(),
mtry = tune(),
learn_rate = tune()
) |>
set_engine("xgboost") |>
set_mode("classification")
xgb_grid <- grid_latin_hypercube(
trees(range = c(100, 1500)),
tree_depth(range = c(3, 15)),
min_n(range = c(2, 30)),
loss_reduction(),
sample_prop(range = c(0.5, 1)),
finalize(mtry(), train_data),
learn_rate(range = c(-3, -1)),
size = 50
)
xgb_results <- workflow(rec, xgb_spec) |>
tune_race_anova(
resamples = cv_folds,
grid = xgb_grid,
metrics = metric_set(roc_auc)
)
Control Options Summary
| Function | Key Control Options |
|---|
tune_grid | save_pred, verbose, allow_par |
tune_bayes | no_improve, uncertain, objective |
tune_race_* | burn_in, num_ties, alpha |
tune_sim_anneal | cooling_coef, restart |
Best Practices
- Start with grid search to understand parameter space
- Use racing methods for large grids (>50 combinations)
- Use Bayesian optimization for expensive models
- Always set a seed for reproducibility
- Use stratified resampling for imbalanced outcomes
- Consider
select_by_one_std_err for simpler models
- Monitor for overfitting during iterative search