You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridSearchCV自定义评分函数问题:预测值全0及make_scorer报错

GridSearchCV结合LightGBM自定义评分函数问题解析与修复

问题1:直接使用自定义评分函数时y_pred全为0

现象与代码问题

用户直接将自定义函数summary_of_threshold作为scoring参数传入GridSearchCV,结果模型输出的y_pred全为0。

核心原因

  1. 错误依赖全局测试集:函数中直接调用全局的X_test,而非GridSearchCV交叉验证过程中自动传入的当前折验证集X。GridSearchCV的评分函数会使用CV划分后的验证数据,而非用户定义的全局测试集,这种误用会导致模型在陌生数据上出现异常预测。
  2. 误用硬分类结果:要计算目标假阳性率对应的阈值,需要模型输出的正类概率,而非predict()返回的0/1硬分类结果。硬分类结果无法调整阈值,自然无法找到对应目标FPR的临界值。
  3. Early Stopping适配问题:GridSearchCV每次CV训练都会重新初始化模型,传入全局X_val作为eval_set会导致所有折共用同一验证集,违背交叉验证的逻辑,也可能干扰模型训练效果。

问题2:使用make_scorer触发参数缺失报错

报错信息

TypeError: summary_of_threshold() missing 1 required positional argument: 'y'

核心原因

make_scorer默认要求评分函数的签名为(y_true, y_pred),但用户定义的函数是(estimator,X,y)格式(该格式是直接传入GridSearchCVscoring参数的要求)。两种模式的参数传递逻辑不兼容,导致参数缺失报错。


修复方案

方案1:正确实现直接传入GridSearchCV的自定义评分函数

调整函数逻辑,使用CV传入的验证集数据,改用概率输出计算阈值:

def summary_of_threshold(estimator, X, y):
    fpr_target = 0.0006
    # 获取正类概率,用于阈值计算
    y_pred_proba = estimator.predict_proba(X)[:, 1]
    # 使用当前折的真实标签y,而非全局测试集标签
    threshold, fpr = find_threshold(y, y_pred_proba, fpr_target)
    print(f"当前折FPR: {fpr}, 对应阈值: {threshold}")
    # 返回需要优化的指标:最小化FPR与目标值的差值
    return abs(fpr - fpr_target)

# 初始化GridSearchCV,直接传入自定义评分函数
gsearch = GridSearchCV(gbm_model, param_grid=grid_parametaers, scoring=summary_of_threshold, cv=3, n_jobs=1)
gsearch.fit(
    X=X_train, 
    y=y_train.label,
    categorical_feature=categorical_features,
    verbose=10,
    callbacks=[early_stopping(early_stopping_rounds)]
)

方案2:正确使用make_scorer创建自定义评分器

调整函数为make_scorer要求的签名格式,同时指定需要概率输出:

# 定义基于真实标签和概率的评分函数
def score_by_fpr_target(y_true, y_score):
    fpr_target = 0.0006
    threshold, fpr = find_threshold(y_true, y_score, fpr_target)
    # 返回需要优化的指标:最小化FPR与目标值的差值
    return abs(fpr - fpr_target)

# 创建自定义评分器,指定需要概率输出,且指标越小越好
customized_scorer = make_scorer(score_by_fpr_target, greater_is_better=False, needs_proba=True)

gsearch = GridSearchCV(gbm_model, param_grid=grid_parametaers, scoring=customized_scorer, cv=3, n_jobs=1)
gsearch.fit(
    X=X_train, 
    y=y_train.label,
    categorical_feature=categorical_features,
    verbose=10,
    callbacks=[early_stopping(early_stopping_rounds)]
)

额外注意事项

  • find_threshold函数校验:确保该函数能通过ROC曲线的FPR和阈值序列,插值找到最接近目标FPR的临界值,这是整个逻辑的核心。
  • 规避全局变量:评分函数中禁止使用全局测试集/验证集,必须依赖GridSearchCV传入的当前折数据,保证交叉验证的客观性。
  • Early Stopping逻辑:GridSearchCV会自动为每个CV折划分训练/验证数据,无需传入外部eval_set,否则会破坏交叉验证的独立性。

内容的提问来源于stack exchange,提问作者Bourne813

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:26:06