scikit-learn自定义损失函数实现:参数传递问题咨询
关于scikit-learn自定义损失函数的参数与实现问题
首先得明确:scikit-learn对自定义损失/评分函数的参数有硬性约定,你的my_custom_loss_func必须按以下规则定义参数:
- 第一个参数是真实标签数组(对应你代码里的
y_true,也就是你的labm) - 第二个参数是模型的预测结果数组(对应
y_pred,是模型跑出来的预测值)
针对你的具体疑问逐个解答:
参数传入问题:
你完全不需要手动把labm塞给my_custom_loss_func——当你用make_scorer把它包装成评分器,再传给GridSearchCV后,scikit-learn会在训练/评估过程中自动把真实标签(也就是你fit时传入的labm)和模型实时生成的预测值,按顺序传入这个函数。如果要手动模拟计算的话,
y_pred就是模型训练后对特征矩阵feam的预测结果,比如clf.fit(feam, labm).predict(feam)。原代码里的几个坑要修正:
- 你用了Python内置的
max()处理数组,这会报错!因为y_true和y_pred是numpy数组,得用np.max()(记得先导入numpy) make_scorer里的greater_is_better=False多了个空格,语法错误,要写成greater_is_better=FalseGridSearchCV的参数不对,必须传param_grid(你要调参的参数网格),不然网格搜索根本不知道要搜什么
- 你用了Python内置的
修正后的完整可运行代码示例
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




