You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

scikit-learn自定义损失函数实现:参数传递问题咨询

关于scikit-learn自定义损失函数的参数与实现问题

首先得明确:scikit-learn对自定义损失/评分函数的参数有硬性约定,你的my_custom_loss_func必须按以下规则定义参数:

  • 第一个参数是真实标签数组(对应你代码里的y_true,也就是你的labm
  • 第二个参数是模型的预测结果数组(对应y_pred,是模型跑出来的预测值)

针对你的具体疑问逐个解答:

  1. 参数传入问题
    你完全不需要手动把labm塞给my_custom_loss_func——当你用make_scorer把它包装成评分器,再传给GridSearchCV后,scikit-learn会在训练/评估过程中自动把真实标签(也就是你fit时传入的labm)和模型实时生成的预测值,按顺序传入这个函数。

    如果要手动模拟计算的话,y_pred就是模型训练后对特征矩阵feam的预测结果,比如clf.fit(feam, labm).predict(feam)

  2. 原代码里的几个坑要修正

    • 你用了Python内置的max()处理数组,这会报错!因为y_truey_pred是numpy数组,得用np.max()(记得先导入numpy)
    • make_scorer里的greater_is_better=False多了个空格,语法错误,要写成greater_is_better=False
    • GridSearchCV的参数不对,必须传param_grid(你要调参的参数网格),不然网格搜索根本不知道要搜什么

修正后的完整可运行代码示例

import numpy as np
from sklearn.metrics import make_scorer
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV

def my_custom_loss_func(y_true, y_pred):
    # 按你的需求:真实值与预测值的绝对差 × 真实值,取最大值
    diff_product = np.abs(y_true - y_pred) * y_true
    return np.max(diff_product)

# 包装成评分器:因为是损失函数,值越小模型越好,所以greater_is_better设为False
custom_scorer = make_scorer(my_custom_loss_func, greater_is_better=False)

# 定义模型和要调的参数网格(示例参数,你可以根据自己的需求修改)
rf_reg = RandomForestRegressor()
param_grid = {'n_estimators': [50, 100], 'max_depth': [3, 5]}

# 初始化网格搜索
grid_search = GridSearchCV(estimator=rf_reg, param_grid=param_grid, scoring=custom_scorer)
# 训练模型
trained_model = grid_search.fit(feam, labm)

额外小提示

  • 自定义函数的参数顺序绝对不能搞反,必须是y_true在前,y_pred在后,这是scikit-learn框架的硬性要求
  • 如果想手动验证损失函数的计算逻辑,可以这么做:
    # 先训练一个基础模型得到预测值
    rf_reg.fit(feam, labm)
    y_pred = rf_reg.predict(feam)
    # 手动调用损失函数
    calculated_loss = my_custom_loss_func(labm, y_pred)
    print(calculated_loss)
    

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

火山引擎 最新活动