Optuna集成LightGBM分步调优如何使用自定义指标并解决KeyError问题
Optuna LightGBMTuner自定义评估指标报错解决方案
错误原因
你遇到的KeyError('custom')错误根源是:Optuna的LightGBMTuner会读取参数中metric字段的值,从LightGBM训练返回的best_score中提取对应指标作为调优依据。当你设置metric='custom'但通过feval传入自定义指标时,best_score中存储的是你feval函数返回的自定义指标名(比如你代码里的rce、avg_precision),不存在名为custom的指标,因此触发键值缺失错误。
解决步骤
- 删除
metric='custom'配置,将params中的metric字段值替换为你实际要用来调优的自定义指标名,必须和feval返回的第一个字符串完全一致。如果你传了多个feval,选其中一个作为调优的核心指标即可。 - 明确指定调优方向:自定义指标如果是越大越好(比如你代码里的RCE、平均精度),需要先手动创建Optuna Study并指定
direction="maximize",再传入lgb_sequential.train方法,避免默认的最小化逻辑和你的指标优化方向冲突。 - 确保
feval返回的指标名和params中metric字段完全匹配,大小写、拼写都不能有差异。
修复后可运行代码
from sklearn.metrics import average_precision_score from sklearn.metrics import log_loss import optuna import optuna.integration.lightgbm as lgb_sequential def tune_lightGBM_sequential(X_train, X_val, y_train, y_val): def calculate_ctr(gt): positive = len([x for x in gt if x == 1]) ctr = positive/float(len(gt)) return ctr def compute_rce(preds, train_data): gt = train_data.get_label() cross_entropy = log_loss(gt, preds) data_ctr = calculate_ctr(gt) strawman_cross_entropy = log_loss(gt, [data_ctr for _ in range(len(gt))]) rce = (1.0 - cross_entropy/strawman_cross_entropy)*100.0 return ('rce', rce, True) def compute_avg_precision(preds, train_data): gt = train_data.get_label() avg_precision= average_precision_score(gt, preds) return('avg_precision', avg_precision, True) # 这里metric填你要用来调优的自定义指标名,示例选rce作为调优依据 params = { "objective": "binary", "metric": "rce", "boosting_type": "gbdt", "verbose" : 1 } dtrain = lgb_sequential.Dataset(X_train, label=y_train) dval = lgb_sequential.Dataset(X_val, label=y_val) # 手动创建study,指定优化方向为最大化,匹配rce越高越好的特性 study = optuna.create_study(direction="maximize") print('Starting training lightGBM sequential') model = lgb_sequential.train( params, dtrain, valid_sets=[dval], # 优先用验证集指标调优,避免过拟合训练集 verbose_eval=True, num_boost_round=100, # 原代码设置的2过小会无法收敛,可按需调整 early_stopping_rounds=10, feval=[compute_rce, compute_avg_precision], study=study, # 传入提前创建好的study show_progress_bar=True ) return model.params
额外注意事项
- 如果需要切换调优的指标,只需要把
params中的metric值换成对应的自定义指标名,同时调整study的direction即可 - 不要在
valid_sets里只放训练集,否则调优出来的参数会严重过拟合 - 注意补全
log_loss的导入,原代码漏了该导入也会触发运行错误
内容的提问来源于stack exchange,提问作者Mattia Surricchio
相关产品推荐
相关产品推荐

