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

Scikit-Learn中为GridSearchCV自定义损失函数的相关问题

解答:Kaggle房价预测自定义评分函数的两个问题

问题1:自定义损失函数应返回单值还是样本级数组?

在scikit-learn的make_scorer机制里,传入的损失/评分函数必须返回单个标量值(所有样本的总损失或平均得分),而不是每个样本的得分数组。

原因很直接:GridSearchCV这类交叉验证工具需要用单一数值来评估模型在某一折上的表现,进而计算交叉验证的平均得分。如果返回数组,要么会触发报错,要么无法正确完成交叉验证的分数统计。

你的RMSE计算本身就是全局统计量(所有样本的平方差平均后开根号),所以返回单值的方向是对的——只是代码里最后一行多了个没必要的np.sum(np.sqrt(numerator / len(truth))本身就是单值,sum之后结果不变,但可以简化掉)。

问题2:为什么best_score_是负数?

这个问题的核心是make_scorer的greater_is_better参数:

  • 你设置了greater_is_better=False,相当于告诉scikit-learn:你的自定义函数返回的是损失值(越小越好),而非常规的得分值(越大越好)。
  • 但GridSearchCV的逻辑是默认寻找「最高得分」的模型,所以它会自动把你的损失值取反——比如实际RMSE是0.12137,就会被转成-0.12137,这样「最接近0的负数」就对应了最优模型(最小损失)。

所以你看到的负数best_score_,它的绝对值就是你真正需要的RMSE(log(真实值), log(预测值))。

顺便给你修正一下自定义损失函数,让逻辑更清晰准确:

import numpy as np
from sklearn.metrics import make_scorer

def custom_rmse_log(truth, preds):
    # 注意:要确保truth和preds都是正数,避免log(0)报错
    truth_log = np.log(truth)
    preds_log = np.log(preds)
    mse = np.mean(np.square(truth_log - preds_log))
    return np.sqrt(mse)

# 因为RMSE是损失,越小越好,所以greater_is_better=False
custom_scorer = make_scorer(custom_rmse_log, greater_is_better=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:51:05