使用mlr3堆叠调参时classif.avg报错及子模型预测获取问题
mlr3堆叠模型调优问题解答
问题1:报错原因分析
报错信息:
Error in .__LearnerClassifAvg__prepare_data(self = self, private = private, : Assertion on 'all(fcts) || !any(fcts)' failed: Must be TRUE. This happened in PipeOp classif.avg's $train()
核心原因是**classif.avg学习器的输入数据类型不匹配**:
- 你设置了
lrn_avg$predict_type = "prob",说明该学习器需要输入数值型的概率预测值来计算加权平均概率。 - 但你在每个零级学习器的管道中添加了
po("threshold"),这个PipeOp会将模型输出的概率预测转换为因子型的类别标签(如"0"/"1")。 - 当
featureunion把这些因子型类别标签合并后传给classif.avg时,完全不符合它的输入要求(要么全是因子、要么全是数值概率,当前配置下需要数值概率),触发了断言检查失败。
修复方案
把po("threshold")移到整个堆叠模型的最后,让classif.avg先基于零级学习器的概率输出计算加权平均概率,再对最终的平均概率做阈值调优:
# 修改管道结构:先做堆叠平均,再加threshold调优 graph_1 <- graph_0 %>% lrn_avg %>% po("threshold") lrn_graph_1 <- mlr3::as_learner(graph_1) # 调整调优参数的目标为最终的threshold.thresholds lrn_graph_1$param_set$set_values(threshold.thresholds = to_tune(p_dbl(lower = 0, upper = 1)))
问题2:获取零级学习器的新数据预测
可以通过训练后的auto_tuner对象,提取每个零级学习器的训练实例,再单独调用predict_newdata:
具体步骤
- 训练完成后,提取每个零级学习器的训练实例:
# 提取每个零级学习器的训练后实例 lrn_rpart_trained <- run_auto_tuner$learner$graph$pipeops$po_lrn_rpart_cv$learner$model$learner lrn_kknn_trained <- run_auto_tuner$learner$graph$pipeops$po_lrn_kknn_cv$learner$model$learner lrn_svm_trained <- run_auto_tuner$learner$graph$pipeops$po_lrn_svm_cv$learner$model$learner lrn_xgboost_trained <- run_auto_tuner$learner$graph$pipeops$po_lrn_xgboost_cv$learner$model$learner
- 用每个训练好的零级学习器单独预测新数据:
# 获取单个零级学习器的概率预测 pred_rpart <- lrn_rpart_trained$predict_newdata(newdata = bradypus_data) pred_kknn <- lrn_kknn_trained$predict_newdata(newdata = bradypus_data) # 查看概率值 pred_rpart$prob
补充说明
如果需要在调优过程中保留零级学习器的预测结果,也可以在构建管道时使用po("copy")节点分流数据,但上述方法是训练完成后提取预测的最直接方式。
内容的提问来源于stack exchange,提问作者Marine
相关产品推荐
相关产品推荐

