R语言mlr3包如何将分类阈值设为学习器超参数参与调优
mlr3二分类任务联合调优决策阈值与模型超参数方案
初始代码报错原因
po("tunethreshold")需要基于未参与模型训练的验证集预测结果计算最优阈值,直接接在全量数据训练的po("learner")后会发生数据泄露,且无独立验证数据支撑阈值优化- 未给
po("tunethreshold")指定优化指标,默认优化目标为分类错误率,和你需要优化的PRAUC目标不匹配
你当前可运行的代码逻辑是先固定模型超参数再优化阈值,无法实现阈值和其他超参数在交叉验证流程中统一随机搜索的需求,可通过以下两种方案实现目标。
方案1:将阈值纳入超参数搜索空间(推荐,完全适配统一随机搜索需求)
无需依赖po("tunethreshold"),直接将分类阈值作为普通超参数加入搜索空间即可。调优过程中每一组超参数组合都会在交叉验证折内直接用指定阈值生成预测、计算PRAUC指标,全程无数据泄露,阈值和模型超参数完全在同一层级做联合搜索。
示例代码:
library(mlr3) library(mlr3learners) library(mlr3pipelines) library(mlr3tuning) # 定义随机森林学习器,必须设置predict_type = "prob"才能输出概率支持阈值调整 RF_lrn <- lrn("classif.rfsrc", id = "rf", predict_type = "prob") RF_lrn$param_set$values = list(na.action = "na.impute", seed = -123) # 定义联合搜索空间:原有模型超参数 + 阈值参数 # 注意阈值参数命名规则为 <学习器id>.threshold,取值范围可根据业务需求调整 rf_search_space <- ps( ntree = p_int(lower = 20, upper = 300), mtry = p_int(lower = 2, upper = 5), nodesize = p_int(lower = 1, upper = 7), rf.threshold = p_dbl(lower = 0.1, upper = 0.9) ) # 套入auto_tuner,和原有调优流程完全兼容 rf_auto_tuner <- auto_tuner( learner = RF_lrn, search_space = rf_search_space, resampling = rsmp("bootstrap", repeats = 2, ratio = 0.8), measure = msr("classif.prauc"), term_evals = 100, method = "random_search" ) # XGBoost实现逻辑完全一致 xgb_lrn <- lrn("classif.xgboost", id = "xgb", predict_type = "prob") xgb_search_space <- ps( # 填入需要调优的XGBoost原生超参数即可 nrounds = p_int(lower = 10, upper = 200), eta = p_dbl(lower = 0.01, upper = 0.3), max_depth = p_int(lower = 2, upper = 10), xgb.threshold = p_dbl(lower = 0.1, upper = 0.9) ) xgb_auto_tuner <- auto_tuner( learner = xgb_lrn, search_space = xgb_search_space, resampling = rsmp("bootstrap", repeats = 2, ratio = 0.8), measure = msr("classif.prauc"), term_evals = 100, method = "random_search" ) # 将训练完成的auto_tuner对象传入benchmark设计,即可直接跑基准对比测试
方案2:基于tunethreshold PipeOp实现自动阈值优化
如果不想手动指定阈值搜索范围,希望PipeOp自动在内层验证集上计算最优阈值,可以先将学习器和tunethreshold封装为GraphLearner,再传入auto_tuner做超参数调优。注意必须使用po("learner_cv")生成内层交叉验证预测供阈值优化,避免数据泄露。
示例代码:
# 封装带自动阈值优化的随机森林图学习器 rf_graph <- po("learner_cv", RF_lrn) %>>% po("tunethreshold", param_vals = list(measure = msr("classif.prauc"))) rf_glrn <- as_learner(rf_graph) # 搜索空间仅需配置模型原生超参数,注意参数名需要加<学习器类型>前缀 rf_auto_tuner <- auto_tuner( learner = rf_glrn, search_space = ps( classif.rfsrc.ntree = p_int(lower = 20, upper = 300), classif.rfsrc.mtry = p_int(lower = 2, upper = 5), classif.rfsrc.nodesize = p_int(lower = 1, upper = 7) ), resampling = rsmp("bootstrap", repeats = 2, ratio = 0.8), measure = msr("classif.prauc"), term_evals = 100, method = "random_search" )
注意:该方案的阈值优化是在auto_tuner的内层交叉验证中独立完成的,不会和外层模型超参数做联合搜索,优化效果略差于方案1,优势是无需手动设置阈值搜索区间。
内容的提问来源于stack exchange,提问作者Remy
相关产品推荐
相关产品推荐

