LightGBM原生API与Sklearn API训练结果差异问题排查
多分类任务中LightGBM原生API与Sklearn API结果不一致问题
背景
针对8分类任务训练LGBClassifier,先采用LightGBM原生API建模,后改用Sklearn API适配工具,但两者训练结果差异显著,Sklearn API训练过程中出现过拟合。
LightGBM原生API实现
import lightgbm as lgb import numpy as np train_data = lgb.Dataset(X_train, (y_train-1)) test_data = lgb.Dataset(X_test, (y_test-1)) params = {} params['learning_rate'] = 0.3 params['boosting_type'] = 'gbdt' params['objective'] = 'multiclass' params['metric'] = 'softmax' params['max_depth'] = 10 params['num_class'] = 8 params['num_leaves'] = 500 lgb_train = lgb.train(params, train_data, 200) # 训练后预测 y_pred = lgb_train.predict(X_test) y_pred_class = [np.argmax(line) for line in y_pred] y_pred_class = np.asarray(y_pred_class) + 1
原生API训练后混淆矩阵表现较好(可能存在过拟合)。
Sklearn API实现
from lightgbm import LGBMClassifier import numpy as np lgb_clf = LGBMClassifier(objective='multiclass', boosting_type='gbdt', max_depth=10, num_leaves=500, learning_rate=0.3, eval_metric=['accuracy','softmax'], num_class=8, n_jobs=-1, early_stopping_rounds=100, num_iterations=500) # 修正:原代码直接调用实例错误,应使用fit方法 clf_train = lgb_clf.fit(X_train, (y_train-1), verbose=1, eval_set=[(X_train, (y_train-1)), (X_test, (y_test-1))]) # 训练过程中观察到过拟合 y_pred = clf_train.predict(X_test) # 原错误:对predict结果使用np.argmax() y_pred = [np.argmax(line) for line in y_pred] y_pred = np.asarray(y_pred) + 1
Sklearn API训练出现过拟合,混淆矩阵结果与原生API差异明显。
备注
- 类别从1开始,需将
y_train减1以适配LightGBM对类别索引从0开始的要求 - 使用RandomSearch或GridSearch调参时,结果与上述Sklearn API表现一致
- 未找到同类问题的公开解决方案
核心问题
- Sklearn API实现中是否存在遗漏?
- 为何LightGBM原生API能得到较好结果(可能存在过拟合)?
- 如何让两个API得到一致结果?
问题解决更新
经排查,核心问题为预测处理错误:Sklearn API的predict()方法直接输出类别标签(已对应0开始的索引,需加1还原原类别),无需对结果使用np.argmax()。修正后预测代码应为:
y_pred = clf_train.predict(X_test) y_pred = np.asarray(y_pred) + 1
特此记录以帮助遇到同类问题的开发者。
内容的提问来源于stack exchange,提问作者M. Merida-Floriano
相关产品推荐
相关产品推荐

