You need to enable JavaScript to run this app. Optuna集成LightGBM分步调优如何使用自定义指标并解决KeyError问题
优惠活动
大模型
产品
解决方案
定价
更多

Optuna集成LightGBM分步调优如何使用自定义指标并解决KeyError问题

Optuna LightGBMTuner自定义评估指标报错解决方案

错误原因

你遇到的KeyError('custom')错误根源是:Optuna的LightGBMTuner会读取参数中metric字段的值,从LightGBM训练返回的best_score中提取对应指标作为调优依据。当你设置metric='custom'但通过feval传入自定义指标时,best_score中存储的是你feval函数返回的自定义指标名(比如你代码里的rce、avg_precision),不存在名为custom的指标,因此触发键值缺失错误。

解决步骤

  1. 删除metric='custom'配置,将params中的metric字段值替换为你实际要用来调优的自定义指标名,必须和feval返回的第一个字符串完全一致。如果你传了多个feval,选其中一个作为调优的核心指标即可。
  2. 明确指定调优方向:自定义指标如果是越大越好(比如你代码里的RCE、平均精度),需要先手动创建Optuna Study并指定direction="maximize",再传入lgb_sequential.train方法,避免默认的最小化逻辑和你的指标优化方向冲突。
  3. 确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 22:06:07