使用SHAP解释XGBoost时出现树层数越界错误的原因排查
问题
使用SHAP解释XGBoost模型时执行以下代码:
explainer = shap.TreeExplainer(model) explainer.shap_values(pd_df) # explainer(xgboost.DMatrix(pd_df, label=label))
运行时抛出错误:
XGBoostError Traceback (most recent call last) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/shap/explainers/_tree.py in shap_values(self, X, y, tree_limit, approximate, check_additivity, from_call) 357 try: --> 358 phi = self.model.original_model.predict( 359 X, iteration_range=(0, tree_limit), pred_contribs=True, /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/core.py in predict(self, data, output_margin, pred_leaf, pred_contribs, approx_contribs, pred_interactions, validate_features, training, iteration_range, strict_shape) 2295 dims = c_bst_ulong() --> 2296 _check_call( 2297 _LIB.XGBoosterPredictFromDMatrix( /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/core.py in _check_call(ret) 280 if ret != 0: --> 281 raise XGBoostError(py_str(_LIB.XGBGetLastError())) 282 XGBoostError: [06:41:59] /workspace/src/gbm/gbtree.h:125: Check failed: end <= model.BoostedRounds() (309 vs. 133) : Out of range for tree layers. Stack trace: [bt] (0) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/lib/libxgboost.so(+0x45a59a) [0x7f315de3b59a] [bt] (1) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/lib/libxgboost.so(+0x47123f) [0x7f315de5223f] [bt] (2) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/lib/libxgboost.so(+0x47166b) [0x7f315de5266b] [bt] (3) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/lib/libxgboost.so(+0x4c463b) [0x7f315dea563b] [bt] (4) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/xgboost/lib/libxgboost.so(XGBoosterPredictFromDMatrix+0x2be) [0x7f315db4de2e] [bt] (5) /lib64/libffi.so.6(ffi_call_unix64+0x4c) [0x7f371af33dec] [bt] (6) /lib64/libffi.so.6(ffi_call+0x1f5) [0x7f371af33715] [bt] (7) /usr/local/lib/python3.9/lib-dynload/_ctypes.cpython-39-x86_64-linux-gnu.so(+0x1286f) [0x7f371b14886f] [bt] (8) /usr/local/lib/python3.9/lib-dynload/_ctypes.cpython-39-x86_64-linux-gnu.so(+0xc2fb) [0x7f371b1422fb] The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) <ipython-input-20-40f7d265c006> in <cell line: 1>() ----> 1 explainer.shap_values(pd_df) /app/dataiku/DSS_DATA_DIR/code-envs/python/env/lib/python3.9/site-packages/shap/explainers/_tree.py in shap_values(self, X, y, tree_limit, approximate, check_additivity, from_call) 365 "See https://github.com/slundberg/shap/issues/580." 366 ) --> 367 raise ValueError(emsg) from e 368 369 if check_additivity and self.model.model_output == "raw": ValueError: This reshape error is often caused by passing a bad data matrix to SHAP. See https://github.com/slundberg/shap/issues/580.
但模型预测功能正常:
(model.predict(pd_df) == label).mean() >> 0.8375209380234506
使用版本:XGBoost 2.0.0,SHAP 0.43.0
原因分析
- 核心问题是SHAP获取的树数量和模型实际训练的树数量不匹配:错误日志里明确提到
309 vs. 133,说明SHAP尝试访问第309棵树,但你的模型实际只有133棵树。 - 可能的触发场景:
- 模型训练时使用了
early_stopping_rounds,最终保存的树数量是最优迭代次数(133),但SHAP读取的是初始设置的n_estimators(比如300+),导致索引越界。 - 模型被后续修改过(比如裁剪过树数量),但SHAP没有正确识别更新后的树数量。
- SHAP与XGBoost版本兼容性问题:XGBoost 2.0.0属于较新的版本,SHAP 0.43.0对其支持可能存在bug,导致树数量读取错误。
- 模型训练时使用了
内容的提问来源于stack exchange,提问作者lenhhoxung
相关产品推荐
相关产品推荐

