You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mlr3中实现CV覆盖全流程仅对分类器做网格搜索调参

解决方案

要实现10折CV覆盖整个流水线,且每个fold中先完成预处理(ANOVA过滤+PCA)再对逻辑回归(LR)调参,核心是让预处理在每个CV fold中仅执行一次,避免重复计算;同时将LR的调参限制在预处理后的训练数据上。以下是具体实现步骤:

1. 加载依赖包

library(mlr3)
library(mlr3pipelines)
library(mlr3tuning)

2. 定义固定参数的预处理流水线

将ANOVA过滤和PCA封装为固定参数的预处理管道,后续每个fold仅拟合一次:

# 预处理管道:固定参数,不参与调参
preproc_pipe <- po("filter", filter = flt("anova"), filter.frac = .5) %>>%  
  po("pca", rank.=10)

3. 定义LR学习器与调参参数集

直接针对LR学习器定义参数集,无需添加前缀(因为我们单独对LR调参):

# LR学习器
lr_learner <- lrn('classif.log_reg', predict_type = "prob")

# LR的调参参数集
paramset <- ParamSet$new(list(
  ParamDbl$new("epsilon", lower = 0, upper = 1e-6 ),
  ParamDbl$new("maxit", lower = 5, upper = 40, tag = 'budget' )
))

4. 执行带内层调参的10折CV

遍历每个外层CV fold,先完成预处理,再在预处理后的训练数据上对LR做网格搜索调参,最后用最优参数评估测试集:

# 替换为你的任务,比如 task = tsk("iris")
task <- YOUR_TASK_HERE

# 外层10折CV
resampling_outer <- rsmp("cv", folds = 10)
resampling_outer$instantiate(task)

# 网格搜索调参器(可调整resolution控制网格密度)
tuner <- tnr("grid_search", resolution = 10)
terminator <- trm("none")  # 网格搜索无需终止器

# 存储结果
results <- data.table()

# 遍历每个外层fold
for (i in seq_len(resampling_outer$iters)) {
  # 拆分当前fold的训练/测试集
  train_idx <- resampling_outer$train_set(i)
  test_idx <- resampling_outer$test_set(i)
  task_train <- task$clone()$filter(train_idx)
  task_test <- task$clone()$filter(test_idx)
  
  # 拟合预处理管道,转换训练/测试数据
  preproc_learner <- GraphLearner$new(preproc_pipe)
  preproc_learner$train(task_train)
  task_train_preproc <- preproc_learner$predict(task_train)
  task_test_preproc <- preproc_learner$predict(task_test)
  
  # 内层调参实例:在预处理后的训练集上搜索LR最优参数
  instance_inner <- TuningInstanceSingleCrit$new(
    task = task_train_preproc,
    learner = lr_learner,
    resampling = rsmp("holdout"),  # 内层用holdout加速,也可换为3折CV
    measure = msr("classif.ce"),
    search_space = paramset,
    terminator = terminator
  )
  
  # 执行网格搜索
  tuner$optimize(instance_inner)
  
  # 用最优参数训练LR,评估测试集
  lr_opt <- lr_learner$clone()$set_param_values(instance_inner$result_learner_param_vals)
  lr_opt$train(task_train_preproc)
  pred <- lr_opt$predict(task_test_preproc)
  
  # 记录当前fold的结果
  results <- rbind(results, data.table(
    fold = i,
    test_accuracy = pred$score(msr("classif.acc")),
    best_epsilon = instance_inner$result_learner_param_vals$epsilon,
    best_maxit = instance_inner$result_learner_param_vals$maxit
  ))
}

# 查看10折CV的平均性能
cat("10折CV平均准确率:", mean(results$test_accuracy), "\n")

关键说明

  • 预处理仅执行一次 per fold:每个外层fold中,预处理管道仅在训练集上拟合一次,然后同时转换训练和测试数据,避免了每个调参组合重复执行过滤和PCA,大幅减少耗时。
  • 调参仅针对LR:网格搜索仅在预处理后的训练数据上对LR参数进行,不涉及预处理步骤的参数。
  • 灵活调整内层验证策略:内层可选择holdout(快速)或多折CV(更稳定),根据需求平衡速度与性能可靠性。

内容的提问来源于stack exchange,提问作者Haleh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:04:53