Add interpretability SHAP C API#12224
Open
RAMitchell wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a dedicated interpretability-focused C API entry point for computing SHAP values, and updates the Python interpretability API to use it. The goal is to provide a stable C-level interface with separate output buffers for feature attributions and the bias term, while reserving a background DMatrixHandle for future interventional SHAP support.
Changes:
- Added new C API function
XGBoosterInterpretShapValueswith JSON configuration and split outputs (values,bias). - Implemented the C API by reusing the existing contribution prediction path and separating the last “bias” column into its own output buffer.
- Updated Python
xgboost.interpret.shap_valuesand added C++/Python tests to validate behavior and expected error handling for unsupported interventional SHAP.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| include/xgboost/c_api.h | Declares and documents the new public C API function for SHAP values. |
| src/c_api/c_api.cc | Implements XGBoosterInterpretShapValues by splitting contribution predictions into values + bias. |
| src/common/api_entry.h | Extends thread-local return buffers to support multiple float/shape outputs. |
| python-package/xgboost/interpret.py | Routes Python shap_values through the new C API and returns split outputs. |
| tests/cpp/c_api/test_c_api.cc | Adds a C++ C-API test validating shapes/contents vs contribution prediction and unsupported paths. |
| tests/python/test_interpret.py | Updates expected exception type/message when passing background data (now errors from C API). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a dedicated C API entry point for SHAP values:
XGBoosterInterpretShapValuesDMatrixHandlereserved for interventional SHAPxgboost.interpret.shap_valuesnow routes through the new C APIThe initial implementation supports the existing tree-path-dependent SHAP behavior by reusing the current contribution prediction path and splitting the final bias column into a separate output. Interventional SHAP is not implemented yet, but the C API shape now includes the background handle needed for it.
Testing
pre-commit run --files include/xgboost/c_api.h src/c_api/c_api.cc src/common/api_entry.h tests/cpp/c_api/test_c_api.cc python-package/xgboost/interpret.py tests/python/test_interpret.pybuild-cpu/testxgboost --gtest_filter=CAPI.InterpretShapValuesPYTHONPATH=/home/nfs/rorym/xgboost-wt/interpret-capi/python-package LD_LIBRARY_PATH=/home/nfs/rorym/xgboost-wt/interpret-capi/lib conda run -n xgboost python -m pytest tests/python/test_interpret.py