自定义L1损失函数复现LGBMRegressor官方l1目标结果不符问题
问题原因与解决方案
你的自定义L1损失和官方l1目标结果不一致,核心原因有两个:
1. 初始预测值的差异
LightGBM内置的l1目标会自动将初始预测值设置为训练集标签的中位数(这是L1损失的最优初始值),而自定义目标函数默认的初始预测值是0。训练起点的不同,会导致后续迭代的方向和结果出现偏差。
2. 未固定训练随机性
LightGBM训练过程中包含随机抽样逻辑(如样本采样、特征采样),如果不固定random_state,两次训练的随机种子不同,结果自然会有差异。
修正后的代码
import lightgbm as lgb import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split def l1_loss(y_true, y_pred): grad = np.sign(y_pred - y_true) hess = np.ones_like(y_pred) return grad, hess X, y = datasets.load_iris(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 计算训练集标签的中位数,作为自定义模型的初始预测值 init_score = np.median(y_train) # 固定random_state,确保两次训练的随机逻辑一致 reg1 = lgb.LGBMRegressor(objective="l1", random_state=42).fit(X_train, y_train) yh_test1 = reg1.predict(X_test) # 设置init_score为中位数,同时固定random_state reg2 = lgb.LGBMRegressor(objective=l1_loss, random_state=42).fit( X_train, y_train, init_score=np.full_like(y_train, init_score) ) yh_test2 = reg2.predict(X_test) # 现在差异会非常小 print(np.abs((yh_test1 - yh_test2) / yh_test1).mean())
额外说明
如果你需要完全对齐官方实现,还可以检查以下参数是否一致:
lambda_l1、lambda_l2:正则化参数,默认都是0min_child_samples、min_child_weight:叶子节点的样本数和权重限制,默认一致learning_rate、n_estimators:学习率和迭代次数,默认一致
内容的提问来源于stack exchange,提问作者bernard k
相关产品推荐
相关产品推荐

