使用mlr3实现带样条的Cox glmnet模型调参时遇参数错误求助
问题:mlr3中AutoTuner训练时报错“Parameter 'alpha' not available”
尝试用mlr3复现带样条变换的cv.glmnet(family="cox")模型,训练AutoTuner时抛出错误:
Error in self$assert(xs, sanitize = TRUE) :
Assertion on 'xs' failed: Parameter 'alpha' not available. Did you mean 'spline_V1.applicator' / 'spline_V1.affect_columns' / 'spline_V2.applicator'?.
错误原因
当surv.glmnet学习器被嵌入到管道(GraphLearner)中后,其超参数不再是顶层的alpha和lambda,而是需要加上学习器在管道内的ID前缀。默认情况下,管道中的学习器ID为surv.glmnet,因此超参数的正确名称应为surv.glmnet.alpha和surv.glmnet.lambda。原代码中的搜索空间直接使用alpha和lambda,导致AutoTuner无法定位到这些属于管道子组件的参数。
修复步骤
- 修正超参数搜索空间:为
alpha和lambda添加管道内学习器的ID前缀 - 可选优化:给管道中的学习器设置自定义ID,简化超参数名称
完整修复代码
require(mlr3) require(mlr3proba) require(mlr3learners) require(mlr3tuning) require(mlr3pipelines) require(mlr3verse) require(mlr3viz) require(survival) require(glmnet) require(splines) # 模拟回归数据集 set.seed(123) n <- 100 p <- 3 X <- matrix(rnorm(n * p), nrow = n, ncol = p) time <- rexp(n, rate = 1) status <- sample(0:1, n, replace = TRUE) df <- as.data.frame(X) df$time <- time df$status <- status # 创建生存任务 task <- TaskSurv$new("survival_task", backend = df, time = "time", event ="status") # 执行初始划分 initial_split <- rsmp("holdout") initial_split$instantiate(task) # 划分训练集与测试集 train_task <- task$clone()$filter(initial_split$train_set(1)) test_task <- task$clone()$filter(initial_split$test_set(1)) # 加载glmnet学习器 learner <- lrn("surv.glmnet") # 修复:修改超参数搜索空间,添加学习器ID前缀 search_space <- ps( surv.glmnet.alpha = p_dbl(lower = 0, upper = 1), surv.glmnet.lambda = p_dbl(lower = 0.0001, upper = 0.1, logscale = TRUE) ) # 定义样条变换函数 apply_splines <- function(x) { as.data.table(splines::ns(x, df = 3)) } # 定义样条变换管道图 graph <- gunion(list( po("colapply", id = "spline_V1", applicator = apply_splines, affect_columns = selector_name("V1")), po("colapply", id = "spline_V2", applicator = apply_splines, affect_columns = selector_name("V2")), po("colapply", id = "spline_V3", applicator = apply_splines, affect_columns = selector_name("V3")) )) %>% po("featureunion") %>% learner # 默认分配ID为"surv.glmnet" # 创建管道学习器 pipeline <- GraphLearner$new(graph) # 定义调参重采样策略 resampling <- rsmp("cv", folds = 5) # 定义生存分析性能指标 measure <- msr("surv.cindex") # 创建调参器 tuner <- tnr("grid_search", resolution = 5) # 定义AutoTuner at <- AutoTuner$new( learner = pipeline, resampling = resampling, measure = measure, search_space = search_space, terminator = trm("evals", n_evals = 20), tuner = tuner ) # 在训练集上训练AutoTuner at$train(train_task)
可选优化:自定义学习器ID
若想简化超参数名称,可在管道中为学习器指定自定义ID:
# 修改管道定义,为学习器设置自定义ID graph <- gunion(list( po("colapply", id = "spline_V1", applicator = apply_splines, affect_columns = selector_name("V1")), po("colapply", id = "spline_V2", applicator = apply_splines, affect_columns = selector_name("V2")), po("colapply", id = "spline_V3", applicator = apply_splines, affect_columns = selector_name("V3")) )) %>% po("featureunion") %>% po("learner", learner = learner, id = "glmnet") # 自定义ID # 对应修改搜索空间 search_space <- ps( glmnet.alpha = p_dbl(lower = 0, upper = 1), glmnet.lambda = p_dbl(lower = 0.0001, upper = 0.1, logscale = TRUE) )
内容的提问来源于stack exchange,提问作者atg
相关产品推荐
相关产品推荐

