Library / SDK
shap/shap avatar
shap/shap

SHAP: exact Shapley values for tree ensembles, sampling for everything else

A game theoretic approach to explain the output of any machine learning model.

25,761 stars3,751 forksJupyter NotebookMIT

At a glance

What is it?
SHAP implements a game theoretic credit allocation scheme for model predictions, with a fast C++ path for tree models and a model-agnostic fallback. The package is MIT-licensed and installs from PyPI or conda-forge, but the exactness of the tree path does not carry over to neural networks or transformers.
Who is it for?
Adopt SHAP if you are explaining gradient-boosted or scikit-learn tree models and can accept the exact Tree SHAP path, or if you need a single explainer interface across model types. Do not adopt it expecting exact Shapley values from a neural network or a Hugging Face pipeline; the README describes a coalitional approximation there, and the cost scales with the number of function evaluations.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem SHAP addresses: attributing a prediction to its inputs

A trained model returns a number or a class probability. It does not return a reason. For a credit decision, a churn score or a house price estimate, the question that follows is which input features moved that particular prediction, and by how much. SHAP frames this as a cooperative game: the features are players, the model output is the payout, and the Shapley value from game theory assigns each player a share. The README describes the project as connecting optimal credit allocation with local explanations using classic Shapley values and their extensions. The intended audience is anyone who needs per-prediction attribution rather than a global feature ranking, which includes model risk reviewers, data scientists debugging a boosted tree, and researchers working on NLP models where token-level attribution is the point. The package is written primarily in Jupyter Notebook, which reflects its origin as an interactive analysis tool rather than a library-first codebase.

How the Explainer dispatches: one API, two very different algorithms

The README shows the same three lines for XGBoost, LightGBM, CatBoost, scikit-learn, transformers and Spark: construct shap.Explainer(model), call explainer(X), then plot. That uniformity hides a dispatch decision. For tree ensembles, the project states it has developed a high-speed exact algorithm, with fast C++ implementations for XGBoost, LightGBM, CatBoost, scikit-learn and pyspark tree models. Exact here means the Shapley values are computed rather than estimated by sampling. For everything else, the explainer falls back to an estimation procedure. The natural language section is explicit about the compromise: by adding coalitional rules to traditional Shapley values, the project forms games that explain large modern NLP models using very few function evaluations. Few function evaluations is the design goal, and it is also the source of approximation error. The output object is a tensor of SHAP values, one row per sample and one column per feature, plus a base value. The README states that the base value is the average model output over the training dataset passed to the explainer, which is why the waterfall plot can show a prediction moving from that base to the final output.

Reading the plots: waterfall, force, scatter, beeswarm, bar

SHAP ships five plotting entry points in the README example, and they answer different questions. shap.plots.waterfall(shap_values[0]) explains one prediction, with features pushing the output higher in red and lower in blue. shap.plots.force(shap_values[0]) shows the same attribution in a different layout, and shap.plots.force(shap_values[:500]) stacks many of them horizontally to cover a dataset. shap.plots.scatter(shap_values[:, "Latitude"], color=shap_values) plots a single feature's SHAP value against its raw value; the README notes that vertical dispersion at one feature value represents interaction effects with other features, and that passing the whole explanation tensor to color makes the plot pick a feature to color by, in the example longitude. shap.plots.beeswarm(shap_values) sorts features by the sum of SHAP value magnitudes across samples and colors each point by the feature value. shap.plots.bar(shap_values) reduces the same tensor to mean absolute SHAP value per feature, producing stacked bars for multi-class outputs. The distinction matters in practice: beeswarm and bar are global summaries, waterfall and force are local, and scatter is the only one that exposes interaction structure directly.

Installing SHAP and the CUDA build for Tree SHAP

Two install paths are documented. pip install shap from PyPI, or conda install -c conda-forge shap. GPU acceleration is not part of either default package. The README states that to enable GPU-accelerated Tree SHAP you install from source with the CUDA toolkit available and the SHAP_ENABLE_CUDA environment variable set, giving the command SHAP_ENABLE_CUDA=1 pip install . run from a checkout. This requires the CUDA toolkit to be installed on the system, and it applies to Tree SHAP specifically, not to the model-agnostic or transformer paths. On dependency versions, the project follows SPEC 0 for minimum supported versions and states that it tests against the versions specified there and may not fix bugs for older versions. That is a maintenance commitment worth reading literally: if your environment pins an older NumPy or scikit-learn, you are outside the tested matrix by the project's own description. The README also points to a Binder link for running the notebooks without a local install, which is the lowest-commitment way to evaluate the plotting API.

Where SHAP is the wrong tool

The exactness claim is scoped to tree ensembles, and the README does not extend it. For a deep neural network, a Hugging Face sentiment pipeline, or any model reached through the generic path, the values come from a sampling-style estimator whose accuracy depends on how many function evaluations you are willing to pay for. The README's own phrasing for transformers is that the method uses very few function evaluations, which is a statement about cost, not about fidelity. Second, the base value is defined as the average model output over the training dataset passed in. That makes the explanation depend on the background data you chose, so two analysts with different background samples can get different waterfall plots for the same prediction. Third, the package is primarily Jupyter Notebook, so the plotting layer assumes an interactive or notebook-capable environment; shap.plots.force over 500 rows is described in the README as interactive in the notebook, which tells you the intended context. If you need a stable, serializable explanation artifact for a production audit trail, the plots are the wrong output and you want the raw shap_values tensor instead.

Alternatives and the actual difference in approach

The most direct alternative is permutation feature importance, as implemented in scikit-learn. Permutation importance shuffles one column at a time and measures the drop in a scoring metric, producing a single global number per feature. It does not decompose a single prediction, it cannot show direction of effect, and it is subject to the same correlated-feature problem SHAP has, but it is cheap and it does not require choosing a background dataset. SHAP's scatter plot, by contrast, is built to expose per-instance direction and interaction dispersion. A second alternative is the built-in gain-based importance that XGBoost and LightGBM report. Those are computed from training statistics, are essentially free, and describe the model's split structure rather than its behavior on a given input. If the question is which features the model used, gain importance answers it. If the question is why this row got this score, gain importance cannot answer it and SHAP can. The trade is compute and configuration for locality and direction.

Maintenance, versioning and the MIT licence

The repository is not archived, the default branch is main, and the release cadence visible in the material is roughly quarterly: v0.51.0 in March 2026, v0.52.0 in May 2026, and a v0.53.0rc0 pre-release in September 2026. Note that the most recent entry is a release candidate, not a final release, so pinning to v0.53.0rc0 means tracking a pre-release. The 0.x major version means the project has not declared API stability, and the migration cost of a minor bump is not something the README addresses. On licence, SHAP is MIT, which permits commercial and closed-source use and modification provided the copyright notice and permission notice are retained; this is a description of the licence text, not legal advice, and if you redistribute SHAP inside a product you should have counsel confirm the notice requirements. The project follows SPEC 0 for minimum dependency versions, so upgrade cost is tied to whatever that specification currently lists, not to an independent support policy. Contributions go through issues and the CONTRIBUTING.md guideline before a PR.

Who should adopt SHAP, and what to verify first

Adopt SHAP if your model is a tree ensemble from XGBoost, LightGBM, CatBoost, scikit-learn or pyspark, because that is the path where the project claims an exact, high-speed C++ implementation. Adopt it also if you want one Explainer interface across several model types and can tolerate approximation on the non-tree ones. Do not adopt it if you need exact attributions from a neural network or a transformers pipeline, or if you cannot fix a background dataset and treat it as part of the explanation contract. Before you commit, run the README's own snippet against your actual model class and confirm which code path it takes; check that your dependency versions fall inside the SPEC 0 range the project tests against; and decide whether GPU Tree SHAP is required, in which case plan for SHAP_ENABLE_CUDA=1 pip install . with a CUDA toolkit on the build machine rather than a plain pip install shap.

Editorial conclusion

Adopt SHAP if you are explaining gradient-boosted or scikit-learn tree models and can accept the exact Tree SHAP path, or if you need a single explainer interface across model types. Do not adopt it expecting exact Shapley values from a neural network or a Hugging Face pipeline; the README describes a coalitional approximation there, and the cost scales with the number of function evaluations. Before committing, check the supported dependency versions against SPEC 0, confirm whether your model class routes to a tree implementation or to sampling, and decide whether you need the CUDA build, which requires installing from source with SHAP_ENABLE_CUDA=1 and the CUDA toolkit present.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. shap/shap on GitHub
Community notes

Community notes