LightGBM搭配MultiOutput Regressor时如何传递eval set等拟合参数
问题原因
报错的核心是MultiOutputRegressor本身的fit方法不直接识别LightGBM专属的拟合参数,且你传入的eval_set的y是30维数组,每个基学习器仅负责预测1个维度的输出,无法直接用完整的30维y做验证。
解决方案
有两种常用实现方式:
方法1:加前缀传递参数(scikit-learn 0.23及以上版本支持)
sklearn封装类支持用estimator__前缀传递基学习器的参数,同时需要把验证集的y拆成对应每个输出的一维数组,修改代码如下:
from lightgbm import LGBMRegressor from sklearn.multioutput import MultiOutputRegressor hyper_params = { 'task': 'train', 'boosting_type': 'gbdt', 'objective': 'regression', 'metric': ['l1','l2'], 'learning_rate': 0.01, 'feature_fraction': 0.9, 'bagging_fraction': 0.7, 'bagging_freq': 10, 'verbose': 0, "max_depth": 8, "num_leaves": 128, "max_bin": 512, "num_iterations": 10000 } gbm = LGBMRegressor(**hyper_params) regr_multiglb = MultiOutputRegressor(gbm) fit_params = { 'estimator__early_stopping_rounds': 300, 'estimator__eval_metric': 'l1', # 为每个基学习器传入对应维度的验证集标签 'estimator__eval_set': [(X_test, y_test_array[:, i]) for i in range(30)] } regr_multiglb.fit(X_train, y_train_array, **fit_params)
如果遇到版本兼容问题,可以直接用第二种方案。
方法2:手动循环训练每个输出的模型
手动实现多输出逻辑更清晰,也方便自定义调试,没有额外性能损耗:
from lightgbm import LGBMRegressor import numpy as np hyper_params = { 'task': 'train', 'boosting_type': 'gbdt', 'objective': 'regression', 'metric': ['l1','l2'], 'learning_rate': 0.01, 'feature_fraction': 0.9, 'bagging_fraction': 0.7, 'bagging_freq': 10, 'verbose': 0, "max_depth": 8, "num_leaves": 128, "max_bin": 512, "num_iterations": 10000 } models = [] y_pred = np.zeros_like(y_test_array) # 逐列训练单输出模型 for i in range(30): y_train_i = y_train_array[:, i] y_test_i = y_test_array[:, i] model = LGBMRegressor(**hyper_params) model.fit( X_train, y_train_i, early_stopping_rounds=300, eval_set=[(X_test, y_test_i)], eval_metric='l1', verbose=False ) models.append(model) y_pred[:, i] = model.predict(X_test)
两种方案本质都是训练30个独立的LGBM回归器,每个负责预测1天的数值,计算成本和直接调用MultiOutputRegressor完全一致。
内容的提问来源于stack exchange,提问作者azuber
相关产品推荐
相关产品推荐

