缘由

艺多不压身

碎碎念

我们继续飞行在云层和雾气之间,飞行在一个无光无影的空洞世界中。 ——《风沙星辰》

Ref

13 Grid Search | Tidy Modeling with R

解读

1. 数据拆分(交叉验证)

library(tidymodels)
data(cells)
cells <- cells %>% select(-case)
set.seed(1304)
cell_folds <- vfold_cv(cells)
  • 功能:对数据集 cells 进行 v 折交叉验证,默认 v=10。
  • 作用:将数据分成 10 份,每次 9 份训练,1 份验证,用于评估模型的泛化性能。

2. 数据预处理 recipe与定义模型

 
mlp_spec <- 
  mlp(hidden_units = tune(), penalty = tune(), epochs = tune()) %>% 
  set_engine("nnet", trace = 0) %>% 
  set_mode("classification")
 
mlp_rec <-
  recipe(class ~ ., data = cells) %>%
  step_YeoJohnson(all_numeric_predictors()) %>% 
  step_normalize(all_numeric_predictors()) %>% 
  step_pca(all_numeric_predictors(), num_comp = tune()) %>% 
  step_normalize(all_numeric_predictors())
  • class ~ .:因变量为 class,其余所有列作为自变量。
  • step_YeoJohnson():对数值型变量做 Yeo-Johnson 变换(处理非正态分布,能包含负值)。
  • step_normalize():标准化,使均值为 0,方差为 1。
  • step_pca(num_comp = tune()):PCA 降维,主成分个数作为可调参数。

3. 构建 workflow

mlp_wflow <- 
  workflow() %>% 
  add_model(mlp_spec) %>% 
  add_recipe(mlp_rec)
  • workflow:把模型(mlp_spec)和数据处理(mlp_rec)绑定在一起。

4. 定义参数空间

mlp_param <- 
  mlp_wflow %>% 
  extract_parameter_set_dials() %>% 
  update(
    epochs = epochs(c(50, 200)),
    num_comp = num_comp(c(0, 40))
  )
  • extract_parameter_set_dials():提取所有待调参数。

  • update():设定参数范围:

    • epochs:训练轮数 50–200。
    • num_comp:PCA 主成分个数 0–40。

5. 评估指标

roc_res <- metric_set(roc_auc)
  • 评估指标选择 AUC(曲线下面积)。

6. 规则网格调参

set.seed(1305)
mlp_reg_tune <-
  mlp_wflow %>%
  tune_grid(
    cell_folds,
    grid = mlp_param %>% grid_regular(levels = 3),
    metrics = roc_res
  )
  • grid_regular(levels=3):规则网格,每个参数取 3 个等距值,组合成笛卡尔积。
  • 优点:覆盖均匀,适合低维参数空间。
  • 结果:mlp_reg_tune 保存了交叉验证下的性能指标。

可视化:

autoplot(mlp_reg_tune) +
  scale_color_viridis_d(direction = -1) +
  theme(legend.position = "top")

查看最佳:

show_best(mlp_reg_tune) %>% select(-.estimator)

7. 随机搜索调参

set.seed(1306)
mlp_sfd_tune <-
  mlp_wflow %>%
  tune_grid(
    cell_folds,
    grid = 20,             # 随机采样 20 组参数
    param_info = mlp_param,
    metrics = roc_res
  )
  • grid = 20:表示随机选取 20 组参数组合。
  • 适用场景:参数维度高时比规则网格高效。

结果同样可以可视化、选取最优:

autoplot(mlp_sfd_tune)
show_best(mlp_sfd_tune) %>% select(-.estimator)

8. 选择最佳参数 & 拟合最终模型

select_best(mlp_reg_tune, metric = "roc_auc")
 
logistic_param <- 
  tibble(
    num_comp = 0,
    epochs = 125,
    hidden_units = 1,
    penalty = 1
  )
 
final_mlp_wflow <- 
  mlp_wflow %>% 
  finalize_workflow(logistic_param)
 
final_mlp_fit <- 
  final_mlp_wflow %>% 
  fit(cells)
  • select_best():根据指标选择最优参数。
  • finalize_workflow():把参数定下来。
  • fit():在完整数据上训练最终模型。

9. 其它模型示例

9.1 C5.0 决策树调参

c5_spec <- 
  boost_tree(trees = tune()) %>% 
  set_engine("C5.0") %>% 
  set_mode("classification")
 
set.seed(1307)
c5_spec %>%
  tune_grid(
    class ~ .,
    resamples = cell_folds,
    grid = data.frame(trees = 1:100),
    metrics = roc_res
  )
  • trees = 1:100:网格搜索树的数量,从 1 到 100。