使用mlr3tuning空间交叉验证调参时遇task_row_hash错误
问题描述
使用mlr3tuning优化分类模型,尝试通过空间交叉验证(spcv_coords)对2个超参数调优时,执行test$train(task_sp)触发以下错误:
Error in if (!is.null(resamplings[[resampling]]$task_row_hash) && resamplings[[resampling]]$task_row_hash != :
missing value where TRUE/FALSE needed
报错运行日志
> test$train(task_sp) INFO [00:13:46.180] [bbotk] Starting to optimize 2 parameter(s) with '<OptimizerBatchGridSearch>' and '<TerminatorEvals> [n_evals=2, k=0]' INFO [00:13:46.207] [bbotk] Evaluating 9 configuration(s) Error in if (!is.null(resamplings[[resampling]]$task_row_hash) && resamplings[[resampling]]$task_row_hash != : missing value where TRUE/FALSE needed
原始代码
## Import data df <- read.csv("C:/Users/Downloads/test.csv") df[,c("presence")] <- as.factor(df[,c("presence")]) df[,c("habitat")] <- as.factor(df[,c("habitat")]) df[,c("species")] <- as.factor(df[,c("species")]) ## summary(df) ## Create a task task_sp <- mlr3spatial::as_task_classif_st(id = "A", x = df[,c("presence", "x", "y", "habitat")], target = "presence", positive = "1", coordinate_names = c("x", "y"), crs = "EPSG:4326", coords_as_features = FALSE) task_sp$set_col_roles("presence", roles = c("target", "stratum")) ## Perform factor encoding factor_encoding <- mlr3pipelines::po("encodeimpact", affect_columns = selector_cardinality_greater_than(10), id = "highCardinalityFactor") %>% mlr3pipelines::po("encode", method = "one-hot", affect_columns = selector_cardinality_greater_than(2), id = "lowCardinalityFactor") %>% mlr3pipelines::po("encode", method = "treatment", affect_columns = selector_type("factor"), id = "binaryFactor") %>% mlr3pipelines::po("imputeoor", affect_columns = selector_type("factor"), id = "outOfRangeFactor") ## print(po_factor_encoding) ## Perform tuning test <- mlr3tuning::auto_tuner(tuner = mlr3tuning::tnr("grid_search", resolution = 5, batch_size = 10), learner = mlr3::as_learner(factor_encoding %>% mlr3tuningspaces::lts(mlr3::lrn("classif.glmnet", predict_type = "prob", standardize = TRUE))), resampling = mlr3::rsmp("spcv_coords", folds = 2), measure = mlr3::msr("classif.prauc"), terminator = mlr3tuning::trm("evals", n_evals = 2, k = 0)) test$train(task_sp)
解决方案
错误核心原因是空间交叉验证采样器与分层角色设置冲突,同时因子编码管道存在逻辑重叠问题,以下是针对性修正:
1. 移除冗余的分层(stratum)角色设置
spcv_coords是基于空间坐标的交叉验证,不需要通过目标变量presence进行分层。将目标变量同时设为target和stratum会导致内部校验时出现空值判断错误,删除以下代码:
task_sp$set_col_roles("presence", roles = c("target", "stratum"))
2. 调整因子编码管道的逻辑顺序
原管道存在列选择重叠问题(如高基数因子会被后续的selector_type("factor")重复处理),调整顺序并明确各步骤的处理范围:
factor_encoding <- mlr3pipelines::po("imputeoor", affect_columns = selector_type("factor"), id = "outOfRangeFactor") %>% mlr3pipelines::po("encode", method = "treatment", affect_columns = selector_cardinality(2), id = "binaryFactor") %>% mlr3pipelines::po("encode", method = "one-hot", affect_columns = selector_cardinality_between(3,10), id = "lowCardinalityFactor") %>% mlr3pipelines::po("encodeimpact", affect_columns = selector_cardinality_greater_than(10), id = "highCardinalityFactor")
- 优先处理因子的缺失/异常值
- 明确二元因子(仅2个水平)用treatment编码
- 低基数多分类因子(3-10个水平)用one-hot编码
- 高基数因子(>10个水平)用encodeimpact编码
3. 修正调参器的参数匹配
原grid_search的resolution=5会生成25组参数组合,但终止器设为n_evals=2存在逻辑矛盾,建议根据测试需求调整:
- 快速测试:降低
resolution并匹配n_evals - 完整搜索:将终止器改为
trm("none")或对应评估次数
修正后的完整代码
## Import data df <- read.csv("C:/Users/Downloads/test.csv") df$presence <- as.factor(df$presence) df$habitat <- as.factor(df$habitat) df$species <- as.factor(df$species) ## Create a task (移除冗余分层角色) task_sp <- mlr3spatial::as_task_classif_st( id = "A", x = df[,c("presence", "x", "y", "habitat")], target = "presence", positive = "1", coordinate_names = c("x", "y"), crs = "EPSG:4326", coords_as_features = FALSE ) ## 调整后的因子编码管道 factor_encoding <- mlr3pipelines::po("imputeoor", affect_columns = selector_type("factor"), id = "outOfRangeFactor") %>% mlr3pipelines::po("encode", method = "treatment", affect_columns = selector_cardinality(2), id = "binaryFactor") %>% mlr3pipelines::po("encode", method = "one-hot", affect_columns = selector_cardinality_between(3,10), id = "lowCardinalityFactor") %>% mlr3pipelines::po("encodeimpact", affect_columns = selector_cardinality_greater_than(10), id = "highCardinalityFactor") ## 修正调参设置 test <- mlr3tuning::auto_tuner( tuner = mlr3tuning::tnr("grid_search", resolution = 2, batch_size = 5), # 降低分辨率适配测试 learner = mlr3::as_learner(factor_encoding %>% mlr3tuningspaces::lts(mlr3::lrn("classif.glmnet", predict_type = "prob", standardize = TRUE))), resampling = mlr3::rsmp("spcv_coords", folds = 2), measure = mlr3::msr("classif.prauc"), terminator = mlr3tuning::trm("evals", n_evals = 4) # 匹配resolution生成的参数组合数 ) test$train(task_sp)
内容的提问来源于stack exchange,提问作者Sophie Père
相关产品推荐
相关产品推荐

