如何在Optuna的objective函数中同时优化多个评估指标
Optuna在objective函数中同时优化多个分类指标的实现方法
Optuna原生支持多目标优化,你只需要修改3处核心代码即可实现同时优化F1、精确率、召回率、准确率、AUC等多个指标:
1. 修改objective函数返回值
不要返回单个指标,直接按你需要的顺序返回所有待优化的指标列表即可,示例代码如下:
def objective(trial): # 定义LGBM超参数搜索空间,可按自身需求补全 param = { "objective": "binary", "metric": "auc", "boosting_type": "gbdt", "num_leaves": trial.suggest_int("num_leaves", 20, 300, step=10), "learning_rate": trial.suggest_float("learning_rate", 0.01, 0.3, log=True), "min_child_samples": trial.suggest_int("min_child_samples", 5, 100) } # 训练模型 gbm = lgb.train(param, dtrain) preds = gbm.predict(X_test) pred_labels = np.rint(preds) # 计算所有需要优化的指标 accuracy = sklearn.metrics.accuracy_score(y_test, pred_labels) # 注意:sklearn分类指标的入参顺序为(真实标签, 预测标签),原代码写反会导致指标计算错误 recall = sklearn.metrics.recall_score(y_test, pred_labels) precision = sklearn.metrics.precision_score(y_test, pred_labels) f1 = sklearn.metrics.f1_score(y_test, pred_labels, pos_label=1) auc = sklearn.metrics.roc_auc_score(y_test, preds) # 按顺序返回所有指标,顺序要和后续优化方向配置对应 return accuracy, recall, precision, f1, auc
2. 创建多目标优化Study
创建Study时通过directions参数指定每个指标的优化方向,示例中所有分类指标都是越高越好,所以全部设为maximize:
import optuna # 5个参数顺序和objective返回的指标顺序一一对应 study = optuna.create_study(directions=["maximize", "maximize", "maximize", "maximize", "maximize"])
如果存在需要最小化的指标(比如训练耗时、交叉熵损失),把对应位置的配置改为"minimize"即可。
3. 执行优化并获取结果
优化调用逻辑和单目标完全一致:
study.optimize(objective, n_trials=100) # 按自身需求设置试验总次数
多目标优化得到的是帕累托最优解集,不存在一个在所有指标上都最优的单一解,你可以按需从解集中选择符合业务需求的结果:
# 获取所有帕累托最优试验 best_trials = study.best_trials # 遍历查看每个最优解的超参数和对应指标 for idx, trial in enumerate(best_trials): print(f"最优解{idx+1}超参数:{trial.params}") acc, recall, prec, f1, auc = trial.values print(f"对应指标:准确率={acc:.4f}, 召回率={recall:.4f}, 精确率={prec:.4f}, F1={f1:.4f}, AUC={auc:.4f}")
补充说明
- 帕累托最优的含义是:对于解集中的任意一个解,不存在另一个解能在所有指标上都超过它,你可以根据业务优先级选择适配的解,比如风控场景优先选召回率最高的解,广告推荐场景优先选精确率最高的解。
- 如果需要给不同指标设置权重,也可以自定义加权分数作为单一优化目标,比如
return 0.5*f1 + 0.3*recall + 0.2*precision,直接沿用单目标优化逻辑即可。
内容的提问来源于stack exchange,提问作者Bex T.
相关产品推荐
相关产品推荐

