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

如何为GridSearchCV编写可接收超参数的自定义scorer评分函数

解决方法

核心逻辑:scikit-learn的自定义评分函数默认接收三个参数(estimator, X, y_true),其中第一个参数就是当前待评估的、已经在训练折上拟合完成的模型,直接调用get_params()方法即可获取当前验证组的所有超参数,无需额外传参。

1. 定义自定义评分函数

from sklearn.metrics import mean_absolute_error

def custom_scorer(estimator, X, y_true):
    # 计算预测值
    y_pred = estimator.predict(X)
    # 计算平均绝对误差
    mae = mean_absolute_error(y_true, y_pred)
    # 从当前模型中获取本次验证的max_depth取值
    current_max_depth = estimator.get_params()["max_depth"]
    # 计算目标评分:GridSearchCV默认选择得分最高的参数组,因此如果目标是MAE*max_depth越小越好,需要返回负值
    return -(mae * current_max_depth)

2. 替换GridSearchCV的scoring参数

将原来的scoring='neg_mean_absolute_error'替换为上面定义的自定义评分函数即可:

from sklearn import model_selection, ensemble

params = {'max_depth' : [3, 5, 8, 10],
          'max_features' : [3, 4, 5],
          'min_samples_leaf' : [10, 20, 50]}
model = model_selection.GridSearchCV(ensemble.RandomForestRegressor(n_estimators = 10, random_state = 100),
                                  params,
                                  cv = model_selection.KFold(n_splits = 3, shuffle = True, random_state = 2023),
                                  scoring = custom_scorer)
# 后续fit、取最优参数逻辑和原来完全一致
model.fit(X, y)
print(model.best_params_)

替代方案:后处理验证结果计算评分

如果不想修改评分逻辑,也可以先按原始MAE完成网格搜索,再从结果表中自行计算目标指标选择最优参数:

# 先按原始指标跑网格搜索
model = model_selection.GridSearchCV(ensemble.RandomForestRegressor(n_estimators = 10, random_state = 100),
                                  params,
                                  cv = model_selection.KFold(n_splits = 3, shuffle = True, random_state = 2023),
                                  scoring = 'neg_mean_absolute_error',
                                  return_train_score=False)
model.fit(X, y)

# 转换结果为DataFrame,计算目标指标
import pandas as pd
res_df = pd.DataFrame(model.cv_results_)
# 把负MAE转成正的MAE,乘以对应max_depth得到目标值
res_df["target_metric"] = (-res_df["mean_test_score"]) * res_df["param_max_depth"]
# 选目标值最小的行对应的参数
best_row = res_df.loc[res_df["target_metric"].idxmin()]
print(best_row["params"])

注意事项

  • 若使用Pipeline封装模型,参数名会带步骤前缀,比如随机森林步骤命名为rf,则需要通过estimator.get_params()["rf__max_depth"]获取对应参数
  • 自定义评分的返回值需符合scikit-learn的规则:得分越高代表模型效果越好,如果你的目标指标是越小越好(比如误差类指标),需要返回负值,否则GridSearchCV会选出效果最差的参数组合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:54:01