SHAP (SHapley Additive exPlanations) assigns each feature a contribution to each prediction. Based on Shapley values from cooperative game theory, SHAP is the only method with mathematical guarantees: consistency, local accuracy, and missingness.
TreeExplainer for tree models (fast, exact). KernelExplainer for any model (slow, approximate). DeepExplainer for deep learning.- Train your model first — SHAP explains a trained model, it doesn't improve it
- Use
shap.plots.waterfall()to explain individual predictions (e.g. "why was this loan denied?") - Use
shap.plots.beeswarm()for global feature importance — which features matter most overall - Check for feature interactions with
shap.plots.scatter()— colored by another feature - Compare SHAP with permutation importance — if they disagree, you likely have correlated features
SHAP compute cost varies dramatically by explainer type:
- TreeExplainer: O(TLD²) per prediction — fast, handles 100K samples in seconds for XGBoost/LightGBM
- KernelExplainer: O(2^M) where M=features — exponential. With 50 features, use background subsampling (100-200 samples) or wait hours
- Production tip: Pre-compute SHAP for common feature ranges and cache them. Real-time SHAP on every API call is expensive — batch process nightly
- EU AI Act and US lending regulations increasingly require explainability — SHAP is widely used for this
pip install shap xgboost pandas matplotlib
# ────────────────────────────────────────
import shap, xgboost, pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv('your_data.csv')
X_train, X_test, y_train, y_test = train_test_split(df.drop('target',1), df['target'])
model = xgboost.XGBClassifier().fit(X_train, y_train)
explainer = shap.TreeExplainer(model)
sv = explainer(X_test)
shap.plots.beeswarm(sv) # global importance
shap.plots.waterfall(sv[0]) # explain one prediction
For a linear model the SHAP value of each feature is exactly its weight times the distance from the average input. Here the contributions are 2, 0 and −1, the base value is 5, and base plus contributions gives 6 — the prediction, every time. Duplicate the first feature and the model can split its weight; SHAP then gives each copy 1, half the credit.
- Credit is shared among correlated features in ways that depend on the model, not on the world.
- SHAP explains the model, not the outcome; a feature with large SHAP values is not shown to cause anything.
- Different background datasets give different SHAP values for the same prediction.
w, b = np.array([2.0, -1.0, 0.5]), 1.0 # a linear model X = np.array([[1.0, 2.0, 3.0], [3.0, 0.0, 1.0], [2.0, 1.0, 2.0]]) # background data x = np.array([3.0, 1.0, 0.0]) phi = w * (x - X.mean(axis=0)) # exact SHAP values for a linear model base = w @ X.mean(axis=0) + b check = (base + phi.sum(), w @ x + b) # additivity dup = np.array([1.0, 1.0]) * w[0] / 2 * (x[0] - X[:, 0].mean()) # feature 1 copied twice, weight split
Assumes import numpy as np and import pandas as pd (and SciPy where imported). Each snippet simulates or makes up its own data, as the comments say.
The same idea with a library
# Python — SHAP waterfall for a single prediction import shap explainer = shap.TreeExplainer(model) shap_values = explainer(X_test) # Waterfall for one prediction shap.plots.waterfall(shap_values[0]) # Global summary shap.plots.beeswarm(shap_values)
- S. M. Lundberg & S.-I. Lee, “A Unified Approach to Interpreting Model Predictions”, NeurIPS, 2017
- E. Štrumbelj & I. Kononenko, “Explaining Prediction Models and Individual Predictions with Feature Contributions”, Knowledge and Information Systems 41(3), 2014
- K. Aas, M. Jullum & A. Løland, “Explaining Individual Predictions When Features Are Dependent”, Artificial Intelligence 298, 2021
Last reviewed October 2026 · How this site checks its content · Report a mistake