训练后如何将sklearn API版LGBM模型转为原生API(解决预测不一致)
LGBM sklearn模型转原生Booster的对齐方案
核心问题说明
你使用cb_classifier.booster_.save_model提取原生模型的操作本身是正确的,预测结果不一致是因为sklearn API与原生Booster的默认预测规则、参数配置不统一,不是模型转换出错。
对齐操作步骤
1. 匹配最优迭代轮数(若启用早停)
如果训练时用了early stopping,sklearn API默认调用best_iteration_对应的最优树数量做预测,原生Booster默认会使用全部训练完成的树。调用原生predict时需手动指定最优轮数:
raw_scores = native_lgbm_model.predict( X_test[features], num_iteration=cb_classifier.best_iteration_, raw_score=True )
2. 后处理输出对齐sklearn结果
原生Booster默认返回未经过激活函数处理的原始边际得分,而sklearn API默认输出经过sigmoid/softmax校准的概率或分类标签,需手动转换:
- 二分类场景:
import numpy as np # 等价于sklearn predict_proba输出的正类概率 positive_proba = 1 / (1 + np.exp(-raw_scores)) # 等价于sklearn predict输出的分类标签(自动匹配类别顺序) pred_labels = cb_classifier.classes_[(positive_proba >= 0.5).astype(int)] - 多分类场景:
# softmax计算各类别概率 exp_scores = np.exp(raw_scores) proba = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # 等价于sklearn predict输出的预测类别 pred_labels = cb_classifier.classes_[np.argmax(proba, axis=1)]
3. 特征输入严格对齐
原生Booster不会自动按列名匹配特征,仅按输入的列顺序对应训练时的特征顺序,需注意:
- 传入的X_test特征列顺序必须和训练时使用的
features列表完全一致 - 类别特征的数据类型需和训练时保持统一(如训练时用pandas
category类型,测试集需先做相同转换;整数编码的类别不能混入浮点数或字符串) - 不得传入训练时未使用的额外特征,也不能缺失必要特征
一致性校验方法
可直接用训练时的验证集做对齐测试,确认转换后的结果完全匹配:
# 验证集对比 val_sklearn_proba = cb_classifier.predict_proba(X_validation[features])[:, 1] val_native_raw = native_lgbm_model.predict( X_validation[features], num_iteration=cb_classifier.best_iteration_ ) val_native_proba = 1 / (1 + np.exp(-val_native_raw)) # 输出最大差值,正常应小于1e-10 print(np.max(np.abs(val_sklearn_proba - val_native_proba)))
内容的提问来源于stack exchange,提问作者jartymcfly
相关产品推荐
相关产品推荐

