chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:22:52 +08:00
commit 9d4c7d16ba
528 changed files with 740585 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
---
name: ai-disclosure
description: Track and document Claude's contributions during coding sessions for PR transparency. Use when working on feature branches, PRs, or when the user wants to maintain AI contribution records. Maintains a disclosure file per branch summarizing Claude's involvement.
---
# AI Disclosure Tracking
Track Claude's contributions during coding sessions and maintain a disclosure file for PR transparency.
## Involvement Levels
1. **Autonomous** - Claude wrote the code/solution independently
2. **Assisted** - Claude implemented based on user direction
3. **Advised** - Claude provided guidance that user implemented
## File Location
**Disclosure file:** `.claude/disclosures/<branch-name>.md`
Get branch name with `git branch --show-current`. If not in a git repo, use `session-<date>`.
## Workflow
### 1. Opt-in
When starting work on a feature branch, offer once:
> "Would you like me to track AI contributions for this branch?"
If yes, create the disclosure file and begin tracking.
### 2. Track Silently
**Only track contributions made AFTER the user opts in.** Do not backfill anything from earlier in the conversation, even if it seems relevant to the branch. The disclosure file starts as a clean slate from the moment the user says yes.
After significant actions (writing functions, fixing bugs, refactoring):
1. **Log the contribution** - Append to the appropriate section in the disclosure file
2. **Record what you changed** - Track in the internal section:
- Which files you touched
- Brief summary of what you wrote/changed
- Initial involvement level
Only use the disclosure file to track contributions — do not rely on in-context memory of what happened before opt-in.
No prompts during work—just silently maintain the record.
### 3. Verify and Generate Summary
When user requests summary or creates a PR:
1. **Check your work against current state:**
- Review files you logged as touching
- Compare current file contents against what you originally wrote
- Use `git diff` or read the files to see if user modified them after you
- Also recall from conversation context: did user correct you? Ask for changes? Rewrite parts?
2. **Downgrade if needed:**
- If user significantly modified your code afterward → downgrade to Assisted
- If user corrected your approach multiple times → downgrade to Assisted
- Add note: "co-creation with significant user involvement"
3. **Generate the summary** with accurate involvement levels
## Disclosure File Format
```markdown
# AI Disclosure for branch: <branch-name>
## Summary
[Generated on request]
## Contributions
### Autonomous
- [One-line descriptions of independent work]
### Assisted
- [One-line descriptions of directed work]
### Advised
- [One-line descriptions of guidance provided]
```
## Internal Tracking
Track your changes in an HTML comment (not shown in final summary):
```markdown
<!--
CHANGES:
- src/partition.py: wrote repartitioning logic (autonomous)
- tests/test_partition.py: wrote validation tests (autonomous)
- src/boundaries.py: implemented boundary calc (autonomous)
CORRECTIONS:
- src/boundaries.py: user fixed off-by-one error (count: 2)
-->
```
This record lets you verify at summary time whether files still contain what you wrote, or if the user significantly changed them.
**Downgrade rule:** If user significantly modified your code or corrected your approach repeatedly, downgrade from Autonomous to Assisted and note: "co-creation with significant user involvement".
## Example Output
```markdown
# AI Disclosure for branch: feature/healpix-partitioning
## Summary
Claude assisted with repartitioning logic (co-creation with significant human involvement), autonomously wrote test cases, and advised on spatial indexing approaches.
## Contributions
### Autonomous
- Wrote test cases for HEALPix partition validation
### Assisted
- Implemented repartitioning logic based on user requirements
### Advised
- Suggested using spatial indexing for performance
```
## PR Format
When user creates a PR, offer a copy-paste block:
```markdown
## AI Disclosure
Developed with Claude assistance:
- **Autonomous**: [list]
- **Assisted**: [list]
- **Advised**: [list]
Details: `.claude/disclosures/<branch>.md`
```
@@ -0,0 +1,37 @@
# PR Disclosure Templates
## Standard Format
```markdown
## AI Disclosure
Developed with Claude assistance:
- **Autonomous**: [list]
- **Assisted**: [list]
- **Advised**: [list]
Details: `.claude/disclosures/<branch>.md`
```
## Minimal Format
```markdown
**AI Disclosure:** Developed with Claude assistance. See `.claude/disclosures/<branch>.md`
```
## Detailed Format
```markdown
## AI Disclosure
This PR was developed with assistance from Claude (Anthropic).
**Summary:** [Brief description]
### Contributions
- **Autonomous**: [Claude worked independently]
- **Assisted**: [Claude implemented user requirements]
- **Advised**: [Claude provided guidance]
Full details: `.claude/disclosures/<branch>.md`
```
+13
View File
@@ -0,0 +1,13 @@
# This file helps clean up the git "blame" view, by ignoring repo-wide style & refactoring commits.
# Sorted imports with isort
6be5b996cc7f048bf04875a8dc7775b2233dbeb4
# Removed trailing whitespace
b2a60a31edcc22ed41778cbe3ef93a499d76277f
# Fixed end-of-file line endings
9438e81732d04f9e9c56d98074e6b35615e21a9a
# Renormalised file endings
edb34644a218127437f9e6bb1588bc3246a2c222
# Bulk update of docstrings with pydocstyle
56394f1c208e384ad3302d596e90f6818943c840
# Applied ruff formatter
fc8a60f9b0854279014ff668db3d84a1d11bbc7e
+5
View File
@@ -0,0 +1,5 @@
# Ensure consistent treatment of line endings
* text=auto
# Do not raise merge conflicts for multiple changelog edits
CHANGELOG.md merge=union
+75
View File
@@ -0,0 +1,75 @@
name: Bug Report
description: Report incorrect behavior in the shap library
title: "BUG: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: Thanks for taking the time to fill out this bug report!
- type: textarea
id: problem
attributes:
label: Issue Description
description: Please describe the issue.
validations:
required: true
- type: textarea
id: example
attributes:
label: Minimal Reproducible Example
description: |
Please provide a minimal, self-contained example that reproduces the issue.
placeholder: |
import shap
...
render: python
validations:
required: true
- type: markdown
attributes:
value: |
**Note**: without a working Minimal Reproducible Example, the maintainers will not be able to help you and your issue will be closed!
Your example should be:
1. **Minimal**: Use as little code as possible that still produces the same problem.
2. **Self-contained**: Provide all minimal imports, data and code needed to reproduce the problem.
3. **Verifiable**: Test the example to make sure it reproduces the problem.
See [Matt's guide](https://matthewrocklin.com/minimal-bug-reports) for further information on how to write helpful bug reports.
- type: textarea
id: traceback
attributes:
label: Traceback
description: Copy & paste the traceback of the error (if relevant).
placeholder: |
Traceback (most recent call last):
File "/shap/__init__.py", line 4, in <module>
import foo
NameError: name 'foo' is not defined
render: shell
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
description: Please describe or show a code example of the expected behavior.
- type: checkboxes
id: checks
attributes:
label: Bug report checklist
options:
- label: I have checked that this issue has not already been reported.
required: true
- label: I have confirmed this bug exists on the [latest release](https://github.com/shap/shap/releases) of shap.
required: true
- label: I have confirmed this bug exists on the [master branch](https://github.com/shap/shap/blob/master/CONTRIBUTING.md#installing-from-the-master-branch) of shap.
- label: I'd be interested in making a PR to fix this bug
- type: textarea
id: version
attributes:
label: Installed Versions
description: What version of the shap library are you using?
validations:
required: true
+8
View File
@@ -0,0 +1,8 @@
# For reference, see
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/
blank_issues_enabled: true # In future, may disable to force use of standardised issue forms
contact_links:
- name: Discussions and Q&A
url: https://github.com/shap/shap/discussions
about: Ask general questions about shap and get help from other users
@@ -0,0 +1,40 @@
name: Feature Request
description: Suggest an idea for shap
title: "ENH: "
labels: [enhancement]
body:
- type: markdown
attributes:
value: Thanks for taking the time to fill out this feature request form!
- type: textarea
id: description
attributes:
label: Problem Description
description: >
Please describe what problem the feature would solve (e.g. "I wish I could
use shap to ..."), and how the new feature would be used. Use pseudo-code if relevant.
validations:
required: true
- type: textarea
id: alternative
attributes:
label: Alternative Solutions
description: >
Please describe any alternative solutions (existing functionality, workarounds,
3rd party packages, etc.) that would satisfy the feature request.
- type: textarea
id: context
attributes:
label: Additional Context
description: >
Please provide any relevant GitHub issues, code examples or references
that help describe and support the feature request.
- type: checkboxes
id: checks
attributes:
label: Feature request checklist
options:
- label: I have checked the issue tracker for duplicate issues.
required: true
- label: I'd be interested in making a PR to implement this feature
+12
View File
@@ -0,0 +1,12 @@
## Overview
Closes #XXXX <!--Add issue number here, or delete as appropriate-->
Description of the changes proposed in this pull request:
## Checklist
- [ ] All [pre-commit checks](https://pre-commit.com/#install) pass.
- [ ] Unit tests added (if fixing a bug or adding a new feature)
+13
View File
@@ -0,0 +1,13 @@
codecov:
notify:
after_n_builds: 7
wait_for_ci: yes
coverage:
range: 70..90
comment:
require_changes: true
after_n_builds: 7
ignore:
# Ignore coverage on vendored code
- "shap/plots/colors/_colorconv.py"
- "shap/explainers/other/_maple.py"
+12
View File
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/javascript/"
schedule:
interval: "monthly"
groups:
# Group all minor and patch updates in a single PR
js-minor:
update-types:
- "minor"
- "patch"
+26
View File
@@ -0,0 +1,26 @@
changelog:
exclude:
labels:
- skip-changelog
authors:
- dependabot
- pre-commit-ci
categories:
- title: Breaking changes
labels:
- BREAKING
- title: Added
labels:
- enhancement
- title: Fixed
labels:
- bug
- title: Documentation
labels:
- documentation
- title: Maintenance
labels:
- ci
- title: Other Changes
labels:
- "*"
+51
View File
@@ -0,0 +1,51 @@
# Dummy release workflow to reserve the "shap-gpu" name on PyPI and TestPyPI.
# Each job builds an sdist (no CUDA/C compilation) with the name overridden to
# "shap-gpu" and a placeholder version, then publishes via trusted publishing.
name: release
on:
workflow_dispatch:
jobs:
publish-pypi:
runs-on: ubuntu-latest
# Only publish tagged releases to PyPI
if: startsWith(github.ref, 'refs/tags')
environment: pypi
permissions:
id-token: write # for PyPI trusted publishing
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # setuptools_scm needs full history/tags
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Override package name to shap-gpu
run: sed -i 's/^name = "shap"/name = "shap-gpu"/' pyproject.toml
- name: Build sdist
env:
SETUPTOOLS_SCM_PRETEND_VERSION: "0.0.1.dev0"
run: uv build --sdist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
publish-testpypi:
runs-on: ubuntu-latest
environment: testpypi
permissions:
id-token: write # for TestPyPI trusted publishing
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # setuptools_scm needs full history/tags
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Override package name to shap-gpu
run: sed -i 's/^name = "shap"/name = "shap-gpu"/' pyproject.toml
- name: Build sdist
env:
SETUPTOOLS_SCM_PRETEND_VERSION: "0.0.1.dev0"
run: uv build --sdist
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
+188
View File
@@ -0,0 +1,188 @@
name: Build wheels
on:
release:
types: [published]
# Enable manual run
workflow_dispatch:
jobs:
# we need this test since we run into 403 errors on MacOS, see GH #4179
prepare_data:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies for dataset download
run: |
uv pip install --system . --group download-datasets
- name: Pre-download datasets
run: python tests/datasets_to_cache.py
- name: Create unified cache directory
run: |
mkdir -p /tmp/test_data_cache
cp -r ~/scikit_learn_data /tmp/test_data_cache/ || true
cp -r shap/cached_data /tmp/test_data_cache/ || true
ls -la /tmp/test_data_cache/
- name: Upload cached datasets
uses: actions/upload-artifact@v4
with:
name: test-data-cache
path: /tmp/test_data_cache
retention-days: 1
build_wheels:
name: Build ${{ matrix.os }} wheels
needs: [prepare_data]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-14, macos-15-intel, windows-latest]
runs-on: ${{ matrix.os }}
steps:
# Ensure all git tags are present so version number is extracted.
# https://github.com/actions/checkout/issues/1471
# Careful: the "fetch-tags" option to the checkout action is broken
# when the workflow is triggered by a tag!
# https://github.com/actions/checkout/issues/1467
- name: Check out the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --tags
- name: Download pre-cached datasets
uses: actions/download-artifact@v4
with:
name: test-data-cache
path: ${{ runner.temp }}/test_data_cache
- name: Install libomp (macOS)
if: runner.os == 'macOS'
run: |
brew install libomp
# Set DYLD_LIBRARY_PATH to avoid OpenMP conflicts, see https://github.com/unit8co/darts/pull/3050
_libomp_path=$(brew --prefix libomp 2>/dev/null)/lib
echo "DYLD_LIBRARY_PATH=$_libomp_path:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
unset _libomp_path
- name: "Install uv"
uses: astral-sh/setup-uv@v7
- name: Build wheels
uses: pypa/cibuildwheel@v3.2.1
env:
CIBW_ARCHS_LINUX: ${{ contains(matrix.os, '-arm') && 'aarch64' || 'x86_64' }}
CIBW_ARCHS_MACOS: ${{ matrix.os == 'macos-14' && 'arm64' || 'x86_64' }}
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
CIBW_MUSLLINUX_AARCH64_IMAGE: musllinux_1_2
# Pass the cache location to cibuildwheel tests
CIBW_BEFORE_TEST: |
python -c "import os, shutil; cache_path = os.environ.get('CACHE_PATH', '${{ runner.temp }}/test_data_cache'); home = os.path.expanduser('~'); sklearn_cache = os.path.join(home, 'scikit_learn_data'); os.makedirs(sklearn_cache, exist_ok=True); shutil.copytree(os.path.join(cache_path, 'scikit_learn_data'), sklearn_cache, dirs_exist_ok=True) if os.path.exists(os.path.join(cache_path, 'scikit_learn_data')) else None"
CIBW_TEST_COMMAND_MACOS: |
python -c "import shap, os, shutil; cache_path = '${{ runner.temp }}/test_data_cache'; shap_cache = os.path.join(os.path.dirname(shap.__file__), 'cached_data'); os.makedirs(shap_cache, exist_ok=True); shutil.copytree(os.path.join(cache_path, 'cached_data'), shap_cache, dirs_exist_ok=True) if os.path.exists(os.path.join(cache_path, 'cached_data')) else None" && pytest -v {project}/tests --import-mode=append
CIBW_TEST_COMMAND_LINUX: |
python -c "import shap, os, shutil; cache_path = '${{ runner.temp }}/test_data_cache'; shap_cache = os.path.join(os.path.dirname(shap.__file__), 'cached_data'); os.makedirs(shap_cache, exist_ok=True); shutil.copytree(os.path.join(cache_path, 'cached_data'), shap_cache, dirs_exist_ok=True) if os.path.exists(os.path.join(cache_path, 'cached_data')) else None" && pytest -v {project}/tests --import-mode=append
CIBW_TEST_COMMAND_WINDOWS: |
python -c "import shap, os, shutil; cache_path = r'${{ runner.temp }}\test_data_cache'; shap_cache = os.path.join(os.path.dirname(shap.__file__), 'cached_data'); os.makedirs(shap_cache, exist_ok=True); shutil.copytree(os.path.join(cache_path, 'cached_data'), shap_cache, dirs_exist_ok=True) if os.path.exists(os.path.join(cache_path, 'cached_data')) else None" && pytest -v {project}/tests --import-mode=append
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/*.whl
name: bdist_files_${{ matrix.os }}
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
# Ensure all git tags are present so version number is extracted.
# https://github.com/actions/checkout/issues/1471
# Careful: the "fetch-tags" option to the checkout action is broken
# when the workflow is triggered by a tag!
# https://github.com/actions/checkout/issues/1467
- name: Check out the repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --tags
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build sdist (pep517)
run: |
uv build --sdist
- name: Upload sdist
uses: actions/upload-artifact@v4
with:
name: sdist_files
path: dist/*.tar.gz
publish_test_pypi:
name: Publish wheels to TestPyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/shap
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist
pattern: bdist_files_*
merge-multiple: true
- uses: actions/download-artifact@v4
with:
name: sdist_files
path: dist
- name: Publish package to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
repository-url: https://test.pypi.org/legacy/
publish_pypi:
name: Publish wheels to PyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
# Only publish tagged releases to PyPI
if: startsWith(github.ref, 'refs/tags')
environment:
name: pypi
url: https://pypi.org/p/shap
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist
pattern: bdist_files_*
merge-multiple: true
- uses: actions/download-artifact@v4
with:
name: sdist_files
path: dist
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
+88
View File
@@ -0,0 +1,88 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
paths:
- "shap/**"
- "javascript/**"
- "tests/**"
- "data/**"
- ".github/workflows/codeql-analysis.yml"
- "**.py"
- "**.js"
- "**.cc"
- "**.cu"
- "**.h"
- "**.cpp"
schedule:
- cron: '16 9 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp', 'javascript', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v2
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build python package
run: uv build
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+40
View File
@@ -0,0 +1,40 @@
name: notebooks
on:
push:
branches:
- master
pull_request:
branches:
- master
paths:
- "shap/**"
- "notebooks/**"
- ".github/workflows/run_notebooks.yml"
- "scripts/**"
- "pyproject.toml"
- "CMakeLists.txt"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# Cancel only PR intermediate builds
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs:
run_notebooks:
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
uv pip install --system . --group test --group plots --group nbtest
- name: Run notebooks
run: |
python scripts/run_notebooks_timeouts.py
+210
View File
@@ -0,0 +1,210 @@
name: tests
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
branches:
- master
paths:
- "shap/**"
- "tests/**"
- "data/**"
- "javascript/**" # Include JS changes that affect bundle.js
- ".github/workflows/run_tests.yml"
- "pyproject.toml"
- "CMakeLists.txt"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# Cancel only PR intermediate builds
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs:
# we need this test since we run into 403 errors on MacOS, see GH #4179
prepare_data:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies for dataset download
run: |
uv pip install --system . --group download-datasets
- name: Pre-download datasets
run: python -P tests/datasets_to_cache.py
- name: Create unified cache directory
run: |
mkdir -p /tmp/test_data_cache
cp -r ~/scikit_learn_data /tmp/test_data_cache/ || true
cp -r shap/cached_data /tmp/test_data_cache/ || true
ls -la /tmp/test_data_cache/
- name: Upload cached datasets
uses: actions/upload-artifact@v4
with:
name: test-data-cache
path: /tmp/test_data_cache
retention-days: 1
run_tests:
needs: prepare_data
strategy:
matrix:
os: ["ubuntu-latest"]
# The total number of matrix jobs should match codecov.yml `after_n_builds`.
python-version: ["3.12",
"3.13",
"3.14"
]
extras: ["test"]
include:
# Test on windows/mac, just one job each
- os: windows-latest
python-version: "3.13"
extras: "test"
- os: macos-latest
python-version: "3.13"
extras: "test"
# Run tests with only the core dependencies, to ensure we
# cover the latest version of numpy/pandas. See GH dsgibbons#46
- os: ubuntu-latest
python-version: "3.13"
extras: "test-core"
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
js:
- 'javascript/**'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
# Build JavaScript bundle if JS files have changed
- name: Set up Node.js
if: steps.filter.outputs.js == 'true'
uses: actions/setup-node@v3
with:
node-version: lts/Hydrogen
- name: Build JavaScript bundle conditionally
if: steps.filter.outputs.js == 'true'
shell: bash
run: |
cd javascript
npm ci
npm run build
cp build/bundle.js ../shap/plots/resources/bundle.js
- name: Install libomp (macOS)
if: runner.os == 'macOS'
run: |
brew install libomp
# Set DYLD_LIBRARY_PATH to avoid OpenMP conflicts, see https://github.com/unit8co/darts/pull/3050
_libomp_path=$(brew --prefix libomp 2>/dev/null)/lib
echo "DYLD_LIBRARY_PATH=$_libomp_path:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
unset _libomp_path
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
# Do regular install NOT editable install: see GH #3020
run: |
uv pip install --system . --group ${{matrix.extras}} --group plots
- name: Download pre-cached datasets
uses: actions/download-artifact@v4
with:
name: test-data-cache
path: /tmp/test_data_cache
- name: Restore datasets to correct locations
shell: bash
run: |
# Restore sklearn data
if [ "$RUNNER_OS" == "Windows" ]; then
cp -r /d/tmp/test_data_cache/scikit_learn_data ~/scikit_learn_data || true
else
cp -r /tmp/test_data_cache/scikit_learn_data ~/scikit_learn_data || true
fi
# Restore shap cached data to the installed package location
SHAP_CACHE_DIR=$(python -P -c "import shap, os; print(os.path.join(os.path.dirname(shap.__file__), 'cached_data'))")
mkdir -p "$SHAP_CACHE_DIR"
if [ "$RUNNER_OS" == "Windows" ]; then
cp -r /d/tmp/test_data_cache/cached_data/* "$SHAP_CACHE_DIR/" 2>/dev/null || true
else
cp -r /tmp/test_data_cache/cached_data/* "$SHAP_CACHE_DIR/" 2>/dev/null || true
fi
echo "Sklearn data:"
ls -la ~/scikit_learn_data/ 2>/dev/null || echo "No sklearn data"
echo "Shap cache data:"
ls -la "$SHAP_CACHE_DIR" 2>/dev/null || echo "No shap data"
- name: Test with pytest
# Ensure we avoid adding current working directory to sys.path:
# - Use "pytest" over "python -m pytest"
# - Use "append" import mode rather than default "prepend"
run: >
pytest --durations=20
--cov --cov-report=xml
--mpl-generate-summary=html --mpl-results-path=./mpl-results
--import-mode=append
- name: Upload mpl test report
if: failure()
uses: actions/upload-artifact@v4
with:
name: mpl-results-${{ matrix.python-version }}-${{ runner.os }}-${{ matrix.extras }}
path: mpl-results/
if-no-files-found: ignore
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
test_oldest_supported_numpy:
# Package is built with numpy 2.X
# This job is recommended by https://numpy.org/doc/stable/dev/depending_on_numpy.html#numpy-2-0-specific-advice
# The "oldest supported numpy" is determined by SPEC 0:
# https://scientific-python.org/specs/spec-0000/
name: run tests (oldest supported numpy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
uv pip install --system numpy==2.0 . --group test-core --group plots
- name: Test with pytest
run: pytest --durations=20 --import-mode=append
run_mypy:
# Run mypy on the latest Python version
name: run mypy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.13
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: |
uv pip install --system . --group test-core
- name: Run mypy
run: mypy shap tests
+59
View File
@@ -0,0 +1,59 @@
name: 'Close stale issues and PRs'
# See CONTIBUTING.md : "Issue Triage"
# See also: https://github.com/shap/shap/discussions/3051
on:
schedule:
# Run at 2:30 AM every day
- cron: '30 2 * * *'
# Enable manual run
workflow_dispatch:
permissions:
actions: write # Workaround for https://github.com/actions/stale/issues/1090
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
# See discussion on generous time limits:
# https://github.com/shap/shap/discussions/3051
days-before-stale: 730 # 2 years
days-before-close: 90 # 3 months
stale-issue-message: "This issue has been inactive for two years, so it's
been automatically marked as 'stale'.
\n\n
We value your input! If this issue is still relevant, please leave a
comment below. This will remove the 'stale' label and keep it open.
\n\n
If there's no activity in the next 90 days the issue will be closed."
stale-pr-message: "We appreciate your contribution! This Pull Request has
been inactive for two years, so it's been automatically marked as 'stale'.
\n\n
Please leave a comment if you would still like the PR to remain open, and
the 'stale' label will be removed.
\n\n
Otherwise, if there is no activity in the next 90 days the PR will be
closed."
close-issue-message: "This issue has been automatically closed due to lack of
recent activity.
\n\n
Your input is important to us! Please feel free to open a new issue if the
problem persists or becomes relevant again."
close-pr-message: "This PR has been automatically closed due to a lack of
recent activity.
\n\n
We welcome your contributions! If your patch is still relevant, please
don't hesitate to open a new PR."
stale-issue-label: stale
stale-pr-label: stale
# If an issue or PR is marked with the "todo" label, never mark it as stale.
exempt-issue-labels: todo
exempt-pr-labels: todo
operations-per-run: 500
# Process the oldest issues first:
ascending: true
+47
View File
@@ -0,0 +1,47 @@
# Ensure that the javascript package can be built with webpack
# Runs on any PRs that modify the javascript directory
# Also verifies that the built bundle matches the committed bundle
name: test_js
on:
push:
branches:
- master
pull_request:
branches:
- master
paths:
- "javascript/**"
jobs:
build-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: lts/Hydrogen
- run: npm ci
working-directory: ./javascript
- run: npm run build
working-directory: ./javascript
- run: npm run test
working-directory: ./javascript
# Check if the built bundle matches the committed bundle (ignoring whitespace)
- name: Compare built bundle with committed bundle
run: |
# Normalize whitespace in both files for comparison
# Remove empty lines and all whitespace, then compare
sed '/^[[:space:]]*$/d; s/[[:space:]]//g' javascript/build/bundle.js | tr -d '\n' > /tmp/new_bundle_normalized.js
sed '/^[[:space:]]*$/d; s/[[:space:]]//g' shap/plots/resources/bundle.js | tr -d '\n' > /tmp/committed_bundle_normalized.js
if diff -q /tmp/new_bundle_normalized.js /tmp/committed_bundle_normalized.js > /dev/null; then
echo "✅ Bundle matches the committed version"
else
echo "❌ Built bundle differs from committed version"
echo "The bundle.js file needs to be updated."
echo "Run: cd javascript && npm run build && cp build/bundle.js ../shap/plots/resources/bundle.js"
exit 1
fi
+49
View File
@@ -0,0 +1,49 @@
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# shap/shap
__pycache__
.DS_Store
.eggs
.idea
.ipynb_checkpoints
.ruff_cache
.vscode
.python-version
*.pyc
*.so
**/.coverage*
/build
/data/*
/dist
/docs/_build
/docs/artwork/local
/docs/generated/
/docs/local
/javascript/build/*
/notebooks/deep_explainer/mnist_data
/notebooks/local_scratch
/shap.egg-info
/shap/_cext*
shap/explainers/_kernel_lib.c
/shap/_version.py
/shap/cached_data
/tests/local_scratch.py
/tests/mnist_data
catboost_info
node_modules
mpl-results
# intermediate AI skill files
.claude/disclosures/
# Do not track uv lock
uv.lock
# Auto-generated by nanobind_add_stub
*.pyi
+48
View File
@@ -0,0 +1,48 @@
ci:
autoupdate_schedule: monthly
exclude: '.*tree_shap_paper.*|.*user_studies.*|.*__snapshots__.*'
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.15
hooks:
- id: ruff
types_or: [python, pyi, jupyter]
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
types_or: [python, pyi, jupyter]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: mixed-line-ending
- id: trailing-whitespace
- id: end-of-file-fixer
exclude: tests/gpu_tree_tests.ipynb
- repo: https://github.com/stefsmeets/nbcheckorder/
rev: v0.3.0
hooks:
- id: nbcheckorder
# TODO: get passing on all notebooks
exclude: |
(?x)^(
notebooks/api_examples/plots/decision_plot.ipynb|
notebooks/api_examples/plots/heatmap.ipynb|
notebooks/api_examples/plots/text.ipynb|
notebooks/api_examples/plots/violin.ipynb|
notebooks/image_examples/image_captioning/Image.Captioning.using.Azure.Cognitive.Services.ipynb|
notebooks/image_examples/image_captioning/Image.Captioning.using.Open.Source.ipynb|
notebooks/image_examples/image_classification/Image.Multi.Class.ipynb|
notebooks/tabular_examples/model_agnostic/Census.income.classification.with.scikit-learn.ipynb|
notebooks/tabular_examples/model_agnostic/Squashing.Effect.ipynb|
notebooks/tabular_examples/tree_based_models/Perfomance.Comparison.ipynb|
notebooks/text_examples/sentiment_analysis/Emotion.classification.multiclass.example.ipynb|
notebooks/text_examples/sentiment_analysis/Keras.LSTM.for.IMDB.Sentiment.Classification.ipynb|
)$
+23
View File
@@ -0,0 +1,23 @@
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-24.04
tools:
python: "3.12"
jobs:
# cf. https://docs.readthedocs.io/en/stable/build-customization.html#install-dependencies-with-uv
pre_create_environment:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
create_environment:
- uv venv
- uv sync
install:
- uv pip install -r docs/requirements-docs.txt
build:
html:
- >-
uv run python -m sphinx -T -b html -d docs/_build/doctrees -D language=en
docs $READTHEDOCS_OUTPUT/html
+145
View File
@@ -0,0 +1,145 @@
# Followed https://nanobind.readthedocs.io/en/latest/building.html
cmake_minimum_required(VERSION 3.15...3.27)
project(shap_extensions LANGUAGES CXX)
if (NOT SKBUILD)
message(FATAL_ERROR "\
This CMakeLists.txt is meant to be used with scikit-build.
Please use 'python -m pip install .', not 'cmake'.")
endif()
# Find the Python interpreter and development components.
if (CMAKE_VERSION VERSION_LESS 3.18)
set(DEV_MODULE Development)
else()
set(DEV_MODULE Development.Module)
endif()
find_package(Python 3.12
COMPONENTS Interpreter ${DEV_MODULE} REQUIRED
OPTIONAL_COMPONENTS Development.SABIModule)
# Perform an optimized release build unless otherwise specified
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# ==============================================================================
# Build the nanobind extension module (cutils)
# ==============================================================================
# Detect the installed nanobind package and import it into CMake
find_package(nanobind CONFIG REQUIRED)
# Create the cutils module using nanobind
nanobind_add_module(
_cutils
# This extension is free-threaded
FREE_THREADED
# Target the stable ABI of Python 3.12+, reducing the number of binary wheels
STABLE_ABI
# Build libnanobind as a static library and link it into the module
NB_STATIC
# Sources for the cutils module
shap/cutils/cutils.cpp
)
nanobind_add_stub(
_cutils_stub
MODULE _cutils
OUTPUT _cutils.pyi
PYTHON_PATH $<TARGET_FILE_DIR:_cutils>
MARKER_FILE py.typed
DEPENDS _cutils
)
# Keep generated typing artifacts visible to language servers during local/editable
# development. VS Code/Pylance resolves this workspace package from source.
add_custom_command(
TARGET _cutils_stub POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/_cutils.pyi
${CMAKE_CURRENT_SOURCE_DIR}/shap/_cutils.pyi
)
# Install the module to shap
install(TARGETS _cutils LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME})
# ==============================================================================
# Build the Tree Logic extension module (cext)
# ==============================================================================
# Check if the SABI version is being requested
if(NOT "${SKBUILD_SABI_VERSION}" STREQUAL "")
set(USE_SABI USE_SABI ${SKBUILD_SABI_VERSION})
endif()
python_add_library(
_cext MODULE
# Target the stable ABI of Python 3.12+, reducing the number of binary wheels
${USE_SABI} WITH_SOABI
# Sources for the cext module
shap/cext/_cext.cc
)
# Get the include directory for NumPy and add it to the include path
execute_process(
COMMAND "${PYTHON_EXECUTABLE}"
-c "import numpy; print(numpy.get_include())"
OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_include_directories(_cext PUBLIC ${NUMPY_INCLUDE_DIR})
# Install directive for scikit-build-core
install(TARGETS _cext LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME})
# ==============================================================================
# Optional: Build the GPU Tree SHAP extension module (cext_gpu)
# Enabled via: SHAP_ENABLE_CUDA=1 pip install .
# ==============================================================================
if(ENV{SHAP_ENABLE_CUDA})
message(MESSAGE "SHAP_ENABLE_CUDA is set, attempting to build the GPU extension...")
enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
python_add_library(
_cext_gpu MODULE
${USE_SABI} WITH_SOABI
# The .cu file is compiled by nvcc, the .cc file by the host compiler
shap/cext/_cext_gpu.cu
shap/cext/_cext_gpu.cc
)
target_include_directories(_cext_gpu PUBLIC ${NUMPY_INCLUDE_DIR})
target_link_libraries(_cext_gpu PRIVATE CUDA::cudart)
set_target_properties(_cext_gpu PROPERTIES
CUDA_ARCHITECTURES "60;70;75;80"
CUDA_STANDARD 14
CUDA_EXTENSIONS ON
)
# nvcc flags matching the previous setup.py build
target_compile_options(_cext_gpu PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:
--expt-extended-lambda
--expt-relaxed-constexpr
>
)
install(TARGETS _cext_gpu LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME})
else()
message(MESSAGE "SHAP_ENABLE_CUDA is not set, skipping the GPU extension.")
endif()
+431
View File
@@ -0,0 +1,431 @@
# Contributing guidelines
- [Introduction](#introduction)
- [Writing helpful bug reports](#writing-helpful-bug-reports)
- [Installing the latest version](#installing-the-latest-version)
- [Setting up a local development environment](#setting-up-a-local-development-environment)
- [Fork the repository](#fork-the-repository)
- [Creating a python environment](#creating-a-python-environment)
- [Installing from source](#installing-from-source)
- [Code checks with precommit](#code-checks-with-precommit)
- [Unit tests with pytest](#unit-tests-with-pytest)
- [Pull Requests (PRs)](#pull-requests-prs)
- [Etiquette for creating PRs](#etiquette-for-creating-prs)
- [Checklist for publishing PRs](#checklist-for-publishing-prs)
- [AI Usage Policy](#ai-usage-policy)
- [Documentation](#documentation)
- [Previewing changes on Pull Requests](#previewing-changes-on-pull-requests)
- [Building the docs locally](#building-the-docs-locally)
- [Jupyter notebook style guide](#jupyter-notebook-style-guide)
- [General Jupyter guidelines](#general-jupyter-guidelines)
- [Links / Cross-references](#links--cross-references)
- [Notebook linting and formatting](#notebook-linting-and-formatting)
- [Maintainer guide](#maintainer-guide)
- [Issue triage](#issue-triage)
- [PR triage](#pr-triage)
- [Versioning](#versioning)
- [Minimum supported dependencies](#minimum-supported-dependencies)
- [Making releases](#making-releases)
- [Release notes from PR labels](#release-notes-from-pr-labels)
## Introduction
Thank you for contributing to SHAP. SHAP is an open source collective effort,
and contributions of all forms are welcome!
You can contribute by:
- Submitting bug reports and features requests on the GitHub [issue
tracker][issues],
- Contributing fixes and improvements via [Pull Requests][pulls], or
- Discussing ideas and questions in the [Discussions forum][discussions].
If you are looking for a good place to get started, look for issues with the
[good first issue][goodfirstissue] label.
[issues]: https://github.com/shap/shap/issues
[pulls]: https://github.com/shap/shap/pulls
[discussions]: https://github.com/shap/shap/discussions
[goodfirstissue]:
https://github.com/shap/shap/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
## Writing helpful bug reports
When submitting bug reports on the [issue tracker][issues], it is very helpful
for the maintainers to include a good **Minimal Reproducible Example** (MRE).
An MRE should be:
- **Minimal**: Use as little code as possible that still produces the same
problem.
- **Self-contained**: Include everything needed to reproduce your problem,
including imports and input data.
- **Reproducible**: Test the code you're about to provide to make sure it
reproduces the problem.
For more information, see [How To Craft Minimal Bug
Reports](https://matthewrocklin.com/minimal-bug-reports).
## Installing the latest version
To get the very latest version of shap, you can pip-install the library directly
from the `master` branch:
```bash
pip install git+https://github.com/shap/shap.git@master
```
This can be useful to test if a particular issue or bug has been fixed since the
most recent release.
Alternatively, if you are considering making changes to the code you can clone
the repository and install your local copy as described below.
## Setting up a local development environment
### Fork the repository
Click [this link](https://github.com/shap/shap/fork) to fork the repository on
GitHub to your user area.
Clone the repository to your local environment, using the URL provided by the
green `<> Code` button on your projects home page.
### Creating a python environment
Create a new isolated environment for the project, e.g. with [uv](https://docs.astral.sh/uv/):
```bash
uv venv
```
### Installing from source
To build from source, you need a compiler to build the C extension.
- On linux, you can install gcc with:
```bash
sudo apt install build-essential
```
- Or on Windows, one way of getting a compiler is to [install
mingw64](https://www.mingw-w64.org/downloads/).
Pip-install the project with the `-e` flag, which ensures that any
changes you make to the source code are immediately reflected in your
environment.
```bash
pip install -e . --group test-core --group plots
# or using uv (-e is implied)
uv sync --group test-core --group plots
```
The various dependency groups are defined in [pyproject.toml](pyproject.toml):
- `test-core`: a minimal set of dependencies to run pytest.
- `test`: a wider set of 3rd party packages for the full test suite such as
tensorflow, pytest, xgboost.
- `plots`: includes matplotlib.
- `docs`: dependencies for building the docs with Sphinx.
To use the CUDA extension for ``GPUTreeExplainer``, set the ``SHAP_ENABLE_CUDA`` environment variable to `1` when installing:
```bash
SHAP_ENABLE_CUDA=1 pip install -e . --group test-core --group plots
# or using uv
SHAP_ENABLE_CUDA=1 uv sync --group test-core --group plots
```
### Code checks with precommit
We use [pre-commit hooks](https://pre-commit.com/#install) to run code checks.
Enable `pre-commit` in your local environment with:
```bash
pre-commit install
# or using uv
uv run pre-commit install
```
To run the checks on all files, use:
```bash
pre-commit run --all-files
# or using uv
uv run pre-commit run --all-files
```
[Ruff](https://beta.ruff.rs/docs/) is used as a linter, and it is enabled as a
pre-commit hook. You can also run `ruff` locally with:
```bash
ruff check .
# or using uv
uv run ruff check .
```
### Unit tests with pytest
The unit test suite can be run locally with:
```bash
pytest
# or using uv
uv run pytest
```
For info about matplotlib tests, see `tests/plots/__init__.py`.
## Pull Requests (PRs)
### Etiquette for creating PRs
Before starting on a PR, please make a proposal by **opening an Issue**,
checking for any duplicates. This isn't necessary for trivial PRs such as fixing
a typo.
**Keep the scope small**. This makes PRs a lot easier to review. Separate
functional code changes (such as bug fixes) from refactoring changes (such as
style improvements). PRs should contain one or the other, but not both.
Open a **Draft PR** as early as possible, do not wait until the feature is
ready. Work on a feature branch with a descriptive name such as
`fix/lightgbm-warnings` or `doc/contributing`.
Use a descriptive title, such as:
- `FIX: Update parameters to remove DeprecationWarning in TreeExplainer`
- `ENH: Add support for python 3.11`
- `DOCS: Fix formatting of ExactExplainer docstring`
### Checklist for publishing PRs
Before marking your PR as "ready for review" (by removing the `Draft` status),
please ensure:
- Your feature branch is up-to-date with the master branch,
- All [pre-commit hooks](#code-checks-with-precommit) pass, and
- Unit tests have been added (if your PR adds any new features or fixes a bug).
### AI Usage Policy
This repository accepts PRs written by LLMs in any capacity. When filing a PR, please keep the following in mind:
- Disclose your AI usage. A disclosure skill is available at [.claude/skills/ai-disclosure](.claude/skills/ai-disclosure) — not mandatory, but a good guideline for what we expect. Explain what the agent did, where it acted autonomously, where it assisted, and where it advised.
- Make sure you understand each and every line in your PR as if you've written it yourself. Explain what you understood during working on the issue in the PR description and the rationale behind your changes.
- This repository is maintained by humans, so write your PR documentation in a clean, minimal and human-oriented way without AI bloat.
- Most of the work on a feature happens after the merge, so maintainers need to understand the code thoroughly. As someone filing the PR it is your responsibility to help them so maintainers can confidently own the code.
- LLMs can reproduce copyrighted code. As a contributor, you are responsible for ensuring your submission does not violate copyright.
- PRs can be closed if any of these points are not met.
- This policy is experimental and can change any time.
## Documentation
The documentation is hosted at
[shap.readthedocs.io](https://shap.readthedocs.io/en/latest/). If you have
modified the docstrings or notebooks, please also check that the changes are
are rendered properly in the generated HTML files.
### Previewing changes on Pull Requests
The documentation is built automatically on each Pull Request, to facilitate
previewing how your changes will render. To see the preview:
1. Look for "All checks have passed", and click "Show all checks".
2. Browse to the check called "docs/readthedocs.org".
3. Click the `Details` hyperlink to open a preview of the docs.
The PR previews are typically hosted on a URL of the form below, replacing
`<pr-number>`:
```text
https://shap--<pr-number>.org.readthedocs.build/en/<pr-number>
```
### Building the docs locally
To build the documentation locally:
1. Navigate to the `docs` directory.
2. Run `make html`.
3. Open "\_build/html/index.html" in your browser to inspect the documentation.
Note that `nbsphinx` currently requires the stand-alone program `pandoc`. If you
get an error "Pandoc wasn't found", install `pandoc` as described in
[nbsphinx installation
guide](https://nbsphinx.readthedocs.io/en/0.9.2/installation.html#pandoc).
The documentation dependencies are pinned in `docs/requirements-docs.txt`. These can be
updated by running the `uv` command specified in the top of that file, optionally with
the `--upgrade` flag.
## Jupyter notebook style guide
If you are contributing changes to the Jupyter notebooks in the documentation, please
adhere to the following style guidelines.
### General Jupyter guidelines
Before committing your notebook(s),
- Ensure that you "Restart Kernel and Run All Cells...", making
sure that cells are executed in order, the notebook is reproducible and does not have any hidden states.
- Ensure that the notebook does not raise syntax warnings in the Sphinx build logs as a result of your
changes.
### Links / Cross-references
You are advised to include links in the notebooks as much as possible if it provides the
reader with more background / context on the topic at hand.
Here's an example of how you would accomplish this in a Markdown cell in the notebook:
```markdown
# Force Plot Colors
The [scatter][scatter_doclink] plot create Python matplotlib plots that can be customized at will.
[scatter_doclink]: ../../../generated/shap.plots.scatter.rst#shap.plots.scatter
```
where the link specified is a relative path to the rst file generated by Sphinx.
Prefer relative links over absolute paths.
### Notebook linting and formatting
We use `ruff` to perform code linting and auto-formatting on our notebooks.
Assuming you have set up `pre-commit` as described
[above](#code-checks-with-precommit), these checks will run automatically
whenever you commit any changes.
To run the code-quality checks manually, you can do, e.g.:
```bash
uv run pre-commit run --files notebook1.ipynb notebook2.ipynb
```
replacing `notebook1.ipynb` and `notebook2.ipynb` with any notebook(s) you have modified.
## Maintainer guide
### Issue triage
Bug reports and feature requests are managed on the github issue tracker. We use
automation to help prioritise and organise the issues.
The `good first issue` label should be assigned to any issue that could be
suitable for new contributors.
The `awaiting feedback` label should be assigned if more information is required
from the author, such as a reproducible example.
The [stale bot](https://github.com/actions/stale) will mark issues and PRs that
have not had any activity for a long period of time with the `stale` label, and
comment to solicit feedback from our community. If there is still no activity,
the issue will be closed after a further period of time.
We value feedback from our users very highly, so the bot is configured with long
time periods before marking issues as stale.
Issues marked with the `todo` label will never be marked as stale, so this label
should be assigned to any issues that should be kept open such as long-running
feature requests.
### PR triage
Pull Requests should generally be assigned a category label such as `bug`,
`enhancement` or `BREAKING`. These labels are used to categorise the PR in the
release notes, as described [below](#release-notes-from-pr-labels).
All PRs should have at least one review before being merged. In particular,
maintainers should generally ensure that PRs have sufficient unit tests to cover
any fixed bugs or new features.
PRs are usually completed with "squash and merge" in order to maintain a clear
linear history and make it easier to debug any issues.
### Versioning
shap uses a PEP 440-compliant versioning scheme of `MAJOR.MINOR.PATCH`. Like
[numpy][numpy_versioning], shap does *not* use semantic versioning, and has
never made a `major` release. Most releases increment `minor`, typically made
every month or two. `patch` releases are sometimes made for any important
bugfixes.
[numpy_versioning]: https://numpy.org/doc/stable/dev/depending_on_numpy.html
Breaking changes are done with care, given that shap is a very popular package.
When breaking changes are made, the PR should be tagged with the `BREAKING`
label to ensure it is highlighted in the release notes. Deprecation cycles are
used to mitigate the impact on downstream users.
GitHub milestones can be used to track any actions that need to be completed for
a given release, such as those relating to deprecation cycles.
We use `setuptools-scm` to source the version number from the git history
automatically. At build time, the version number is determined from the git tag.
### Minimum supported dependencies
We aim to follow the [SPEC 0](https://scientific-python.org/specs/spec-0000/) convention
on minimum supported dependencies.
- Support for Python versions are dropped 3 years after their initial release.
- Support for core package dependencies are dropped 2 years after their initial release.
We may support python versions for slightly longer than this window where it does
not add any extra maintenance burden.
### Making releases
We try to use automation to make the release process reliable, transparent and
reproducible. This also helps us make releases more frequently.
A release is made by publishing a [GitHub
Release](https://github.com/shap/shap/releases), tagged with an appropriately
incremented version number.
When a release is published, the wheels will be built and published to PyPI
automatically by the `build_wheels` GitHub action. This workflow can also be
triggered manually at any time to do a dry-run of cibuildwheel.
In the run-up to a release, create a GitHub issue for the release such as [[Meta
issue] Release 0.43.0](https://github.com/shap/shap/issues/3289). This can be
used to co-ordinate with other maintainers and agree to make a release.
Suggested release checklist:
```markdown
- [ ] Dry-run cibuildwheel & test
- [ ] Make GitHub release & tag
- [ ] Confirm PyPI wheels published
- [ ] Conda forge published
```
The conda package is managed in a [separate
repo](https://github.com/conda-forge/shap-feedstock). The conda-forge bot will
automatically make a PR to this repo to update the conda package, typically
within a few hours of the PyPSA package being published.
### Release notes from PR labels
Release notes can be automatically drafted by Github using the titles and labels
of PRs that were merged since the previous release. See the GitHub docs on
[automatically generated release notes][auto_release_notes] for more
information.
The generated notes will follow the template defined in
[.github/release.yml](.github/release.yml), arranging PRs into subheadings by
label and excluding PRs made by bots. See the [docs][auto_release_notes] for the
available configuration options.
[auto_release_notes]:
https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
It's helpful to assign labels such as `BREAKING`, `bug`, `enhancement` or
`skip-changelog` to each PR, so that the change will show up in the notes under
the right section. It also helps to ensure each PR has a descriptive name.
The notes can be edited (both before and after release) to remove information
that is unlikely to be of high interest to users, such as maintenance updates.
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Scott Lundberg
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+357
View File
@@ -0,0 +1,357 @@
<p align="center">
<img src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/shap_header.svg" width="800" />
</p>
---
[![PyPI](https://img.shields.io/pypi/v/shap)](https://pypi.org/project/shap/)
[![Conda](https://img.shields.io/conda/vn/conda-forge/shap)](https://anaconda.org/conda-forge/shap)
![License](https://img.shields.io/github/license/shap/shap)
![Tests](https://github.com/shap/shap/actions/workflows/run_tests.yml/badge.svg)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/shap/shap/master)
[![Documentation Status](https://readthedocs.org/projects/shap/badge/?version=latest)](https://shap.readthedocs.io/en/latest/?badge=latest)
![Downloads](https://img.shields.io/pypi/dm/shap)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/shap)](https://pypi.org/pypi/shap/)
**SHAP (SHapley Additive exPlanations)** is a game theoretic approach to explain the output of any machine learning model. It connects optimal credit allocation with local explanations using the classic Shapley values from game theory and their related extensions (see [papers](#citations) for details and citations).
<!--**SHAP (SHapley Additive exPlanations)** is a unified approach to explain the output of any machine learning model. SHAP connects game theory with local explanations, uniting several previous methods [1-7] and representing the only possible consistent and locally accurate additive feature attribution method based on expectations (see our [papers](#citations) for details and citations).-->
## Install
SHAP can be installed from either [PyPI](https://pypi.org/project/shap) or [conda-forge](https://anaconda.org/conda-forge/shap):
<pre>
pip install shap
<i>or</i>
conda install -c conda-forge shap
</pre>
### GPU support
To enable GPU-accelerated Tree SHAP, install from source with the CUDA toolkit available and the `SHAP_ENABLE_CUDA` environment variable set:
<pre>
SHAP_ENABLE_CUDA=1 pip install .
</pre>
This requires the [CUDA toolkit](https://developer.nvidia.com/cuda-toolkit) to be installed on your system.
## Supported versions
SHAP follows [SPEC 0](https://scientific-python.org/specs/spec-0000/) for minimum supported dependency versions. We test against the versions specified there and may not fix bugs for older versions.
## Contributing
We welcome contributions highly. Feel free to file an issue. Before opening a PR make sure you've read our [CONTRIBUTING.md](CONTRIBUTING.md) guideline.
## Tree ensemble example (XGBoost/LightGBM/CatBoost/scikit-learn/pyspark models)
While SHAP can explain the output of any machine learning model, we have developed a high-speed exact algorithm for tree ensemble methods (see our [Nature MI paper](https://rdcu.be/b0z70)). Fast C++ implementations are supported for *XGBoost*, *LightGBM*, *CatBoost*, *scikit-learn* and *pyspark* tree models:
```python
import xgboost
import shap
# train an XGBoost model
X, y = shap.datasets.california()
model = xgboost.XGBRegressor().fit(X, y)
# explain the model's predictions using SHAP
# (same syntax works for LightGBM, CatBoost, scikit-learn, transformers, Spark, etc.)
explainer = shap.Explainer(model)
shap_values = explainer(X)
# visualize the first prediction's explanation
shap.plots.waterfall(shap_values[0])
```
<p align="center">
<img width="616" src="./docs/artwork/california_waterfall.png" />
</p>
The above explanation shows features each contributing to push the model output from the base value (the average model output over the training dataset we passed) to the model output. Features pushing the prediction higher are shown in red, those pushing the prediction lower are in blue. Another way to visualize the same explanation is to use a force plot (these are introduced in our [Nature BME paper](https://rdcu.be/baVbR)):
```python
# visualize the first prediction's explanation with a force plot
shap.plots.force(shap_values[0])
```
<p align="center">
<img width="811" src="./docs/artwork/california_instance.png" />
</p>
If we take many force plot explanations such as the one shown above, rotate them 90 degrees, and then stack them horizontally, we can see explanations for an entire dataset (in the notebook this plot is interactive):
```python
# visualize all the training set predictions
shap.plots.force(shap_values[:500])
```
<p align="center">
<img width="811" src="./docs/artwork/california_dataset.png" />
</p>
To understand how a single feature effects the output of the model we can plot the SHAP value of that feature vs. the value of the feature for all the examples in a dataset. Since SHAP values represent a feature's responsibility for a change in the model output, the plot below represents the change in predicted house price as the latitude changes. Vertical dispersion at a single value of latitude represents interaction effects with other features. To help reveal these interactions we can color by another feature. If we pass the whole explanation tensor to the `color` argument the scatter plot will pick the best feature to color by. In this case it picks longitude.
```python
# create a dependence scatter plot to show the effect of a single feature across the whole dataset
shap.plots.scatter(shap_values[:, "Latitude"], color=shap_values)
```
<p align="center">
<img width="544" src="./docs/artwork/california_scatter.png" />
</p>
To get an overview of which features are most important for a model we can plot the SHAP values of every feature for every sample. The plot below sorts features by the sum of SHAP value magnitudes over all samples, and uses SHAP values to show the distribution of the impacts each feature has on the model output. The color represents the feature value (red high, blue low). This reveals for example that higher median incomes increases the predicted home price.
```python
# summarize the effects of all the features
shap.plots.beeswarm(shap_values)
```
<p align="center">
<img width="583" src="./docs/artwork/california_beeswarm.png" />
</p>
We can also just take the mean absolute value of the SHAP values for each feature to get a standard bar plot (produces stacked bars for multi-class outputs):
```python
shap.plots.bar(shap_values)
```
<p align="center">
<img width="570" src="./docs/artwork/california_global_bar.png" />
</p>
## Natural language example (transformers)
SHAP has specific support for natural language models like those in the Hugging Face transformers library. By adding coalitional rules to traditional Shapley values we can form games that explain large modern NLP model using very few function evaluations. Using this functionality is as simple as passing a supported transformers pipeline to SHAP:
```python
import transformers
import shap
# load a transformers pipeline model
model = transformers.pipeline('sentiment-analysis', top_k=None)
# explain the model on two sample inputs
explainer = shap.Explainer(model)
shap_values = explainer(["What a great movie! ...if you have no taste."])
# visualize the first prediction's explanation for the POSITIVE output class
shap.plots.text(shap_values[0, :, "POSITIVE"])
```
<p align="center">
<img width="811" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/sentiment_analysis_plot.png" />
</p>
## Deep learning example with DeepExplainer (TensorFlow/Keras models)
Deep SHAP is a high-speed approximation algorithm for SHAP values in deep learning models that builds on a connection with [DeepLIFT](https://arxiv.org/abs/1704.02685) described in the SHAP NIPS paper. The implementation here differs from the original DeepLIFT by using a distribution of background samples instead of a single reference value, and using Shapley equations to linearize components such as max, softmax, products, divisions, etc. Note that some of these enhancements have also been since integrated into DeepLIFT. TensorFlow models and Keras models using the TensorFlow backend are supported (there is also preliminary support for PyTorch):
```python
# ...include code from https://github.com/keras-team/keras/blob/master/examples/demo_mnist_convnet.py
import shap
import numpy as np
# select a set of background examples to take an expectation over
background = x_train[np.random.choice(x_train.shape[0], 100, replace=False)]
# explain predictions of the model on four images
e = shap.DeepExplainer(model, background)
# ...or pass tensors directly
# e = shap.DeepExplainer((model.layers[0].input, model.layers[-1].output), background)
shap_values = e.shap_values(x_test[1:5])
# plot the feature attributions
shap.image_plot(shap_values, -x_test[1:5])
```
<p align="center">
<img width="820" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/mnist_image_plot.png" />
</p>
The plot above explains ten outputs (digits 0-9) for four different images. Red pixels increase the model's output while blue pixels decrease the output. The input images are shown on the left, and as nearly transparent grayscale backings behind each of the explanations. The sum of the SHAP values equals the difference between the expected model output (averaged over the background dataset) and the current model output. Note that for the 'zero' image the blank middle is important, while for the 'four' image the lack of a connection on top makes it a four instead of a nine.
## Deep learning example with GradientExplainer (TensorFlow/Keras/PyTorch models)
Expected gradients combines ideas from [Integrated Gradients](https://arxiv.org/abs/1703.01365), SHAP, and [SmoothGrad](https://arxiv.org/abs/1706.03825) into a single expected value equation. This allows an entire dataset to be used as the background distribution (as opposed to a single reference value) and allows local smoothing. If we approximate the model with a linear function between each background data sample and the current input to be explained, and we assume the input features are independent then expected gradients will compute approximate SHAP values. In the example below we have explained how the 7th intermediate layer of the VGG16 ImageNet model impacts the output probabilities.
```python
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
import keras.backend as K
import numpy as np
import json
import shap
# load pre-trained model and choose two images to explain
model = VGG16(weights='imagenet', include_top=True)
X,y = shap.datasets.imagenet50()
to_explain = X[[39,41]]
# load the ImageNet class names
url = "https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json"
fname = shap.datasets.cache(url)
with open(fname) as f:
class_names = json.load(f)
# explain how the input to the 7th layer of the model explains the top two classes
def map2layer(x, layer):
feed_dict = dict(zip([model.layers[0].input], [preprocess_input(x.copy())]))
return K.get_session().run(model.layers[layer].input, feed_dict)
e = shap.GradientExplainer(
(model.layers[7].input, model.layers[-1].output),
map2layer(X, 7),
local_smoothing=0 # std dev of smoothing noise
)
shap_values,indexes = e.shap_values(map2layer(to_explain, 7), ranked_outputs=2)
# get the names for the classes
index_names = np.vectorize(lambda x: class_names[str(x)][1])(indexes)
# plot the explanations
shap.image_plot(shap_values, to_explain, index_names)
```
<p align="center">
<img width="500" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/gradient_imagenet_plot.png" />
</p>
Predictions for two input images are explained in the plot above. Red pixels represent positive SHAP values that increase the probability of the class, while blue pixels represent negative SHAP values the reduce the probability of the class. By using `ranked_outputs=2` we explain only the two most likely classes for each input (this spares us from explaining all 1,000 classes).
## Model agnostic example with KernelExplainer (explains any function)
Kernel SHAP uses a specially-weighted local linear regression to estimate SHAP values for any model. Below is a simple example for explaining a multi-class SVM on the classic iris dataset.
```python
import sklearn
import shap
from sklearn.model_selection import train_test_split
# print the JS visualization code to the notebook
shap.initjs()
# train a SVM classifier
X_train,X_test,Y_train,Y_test = train_test_split(*shap.datasets.iris(), test_size=0.2, random_state=0)
svm = sklearn.svm.SVC(kernel='rbf', probability=True)
svm.fit(X_train, Y_train)
# use Kernel SHAP to explain test set predictions
explainer = shap.KernelExplainer(svm.predict_proba, X_train, link="logit")
shap_values = explainer.shap_values(X_test, nsamples=100)
# plot the SHAP values for the Setosa output of the first instance
shap.force_plot(explainer.expected_value[0], shap_values[0][0,:], X_test.iloc[0,:], link="logit")
```
<p align="center">
<img width="810" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/iris_instance.png" />
</p>
The above explanation shows four features each contributing to push the model output from the base value (the average model output over the training dataset we passed) towards zero. If there were any features pushing the class label higher they would be shown in red.
If we take many explanations such as the one shown above, rotate them 90 degrees, and then stack them horizontally, we can see explanations for an entire dataset. This is exactly what we do below for all the examples in the iris test set:
```python
# plot the SHAP values for the Setosa output of all instances
shap.force_plot(explainer.expected_value[0], shap_values[0], X_test, link="logit")
```
<p align="center">
<img width="813" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/iris_dataset.png" />
</p>
## SHAP Interaction Values
SHAP interaction values are a generalization of SHAP values to higher order interactions. Fast exact computation of pairwise interactions are implemented for tree models with `shap.TreeExplainer(model).shap_interaction_values(X)`. This returns a matrix for every prediction, where the main effects are on the diagonal and the interaction effects are off-diagonal. These values often reveal interesting hidden relationships, such as how the increased risk of death peaks for men at age 60 (see the NHANES notebook for details):
<p align="center">
<img width="483" src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/nhanes_age_sex_interaction.png" />
</p>
## Sample notebooks
The notebooks below demonstrate different use cases for SHAP. Look inside the notebooks directory of the repository if you want to try playing with the original notebooks yourself.
### TreeExplainer
An implementation of Tree SHAP, a fast and exact algorithm to compute SHAP values for trees and ensembles of trees.
- [**NHANES survival model with XGBoost and SHAP interaction values**](https://shap.github.io/shap/notebooks/NHANES%20I%20Survival%20Model.html) - Using mortality data from 20 years of followup this notebook demonstrates how to use XGBoost and `shap` to uncover complex risk factor relationships.
- [**Census income classification with LightGBM**](https://shap.github.io/shap/notebooks/tree_explainer/Census%20income%20classification%20with%20LightGBM.html) - Using the standard adult census income dataset, this notebook trains a gradient boosting tree model with LightGBM and then explains predictions using `shap`.
- [**League of Legends Win Prediction with XGBoost**](https://shap.github.io/shap/notebooks/League%20of%20Legends%20Win%20Prediction%20with%20XGBoost.html) - Using a Kaggle dataset of 180,000 ranked matches from League of Legends we train and explain a gradient boosting tree model with XGBoost to predict if a player will win their match.
### DeepExplainer
An implementation of Deep SHAP, a faster (but only approximate) algorithm to compute SHAP values for deep learning models that is based on connections between SHAP and the DeepLIFT algorithm.
- [**MNIST Digit classification with Keras**](https://shap.github.io/shap/notebooks/deep_explainer/Front%20Page%20DeepExplainer%20MNIST%20Example.html) - Using the MNIST handwriting recognition dataset, this notebook trains a neural network with Keras and then explains predictions using `shap`.
- [**Keras LSTM for IMDB Sentiment Classification**](https://shap.github.io/shap/notebooks/deep_explainer/Keras%20LSTM%20for%20IMDB%20Sentiment%20Classification.html) - This notebook trains an LSTM with Keras on the IMDB text sentiment analysis dataset and then explains predictions using `shap`.
### GradientExplainer
An implementation of expected gradients to approximate SHAP values for deep learning models. It is based on connections between SHAP and the Integrated Gradients algorithm. GradientExplainer is slower than DeepExplainer and makes different approximation assumptions.
- [**Explain an Intermediate Layer of VGG16 on ImageNet**](https://shap.github.io/shap/notebooks/gradient_explainer/Explain%20an%20Intermediate%20Layer%20of%20VGG16%20on%20ImageNet.html) - This notebook demonstrates how to explain the output of a pre-trained VGG16 ImageNet model using an internal convolutional layer.
### LinearExplainer
For a linear model with independent features we can analytically compute the exact SHAP values. We can also account for feature correlation if we are willing to estimate the feature covariance matrix. LinearExplainer supports both of these options.
- [**Sentiment Analysis with Logistic Regression**](https://shap.github.io/shap/notebooks/linear_explainer/Sentiment%20Analysis%20with%20Logistic%20Regression.html) - This notebook demonstrates how to explain a linear logistic regression sentiment analysis model.
### KernelExplainer
An implementation of Kernel SHAP, a model agnostic method to estimate SHAP values for any model. Because it makes no assumptions about the model type, KernelExplainer is slower than the other model type specific algorithms.
- [**Census income classification with scikit-learn**](https://shap.github.io/shap/notebooks/Census%20income%20classification%20with%20scikit-learn.html) - Using the standard adult census income dataset, this notebook trains a k-nearest neighbors classifier using scikit-learn and then explains predictions using `shap`.
- [**ImageNet VGG16 Model with Keras**](https://shap.github.io/shap/notebooks/ImageNet%20VGG16%20Model%20with%20Keras.html) - Explain the classic VGG16 convolutional neural network's predictions for an image. This works by applying the model agnostic Kernel SHAP method to a super-pixel segmented image.
- [**Iris classification**](https://shap.github.io/shap/notebooks/Iris%20classification%20with%20scikit-learn.html) - A basic demonstration using the popular iris species dataset. It explains predictions from six different models in scikit-learn using `shap`.
## Documentation notebooks
These notebooks comprehensively demonstrate how to use specific functions and objects.
- [`shap.decision_plot` and `shap.multioutput_decision_plot`](https://shap.github.io/shap/notebooks/plots/decision_plot.html)
- [`shap.dependence_plot`](https://shap.github.io/shap/notebooks/plots/dependence_plot.html)
## Methods Unified by SHAP
1. *LIME:* Ribeiro, Marco Tulio, Sameer Singh, and Carlos Guestrin. "Why should i trust you?: Explaining the predictions of any classifier." Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. ACM, 2016.
2. *Shapley sampling values:* Strumbelj, Erik, and Igor Kononenko. "Explaining prediction models and individual predictions with feature contributions." Knowledge and information systems 41.3 (2014): 647-665.
3. *DeepLIFT:* Shrikumar, Avanti, Peyton Greenside, and Anshul Kundaje. "Learning important features through propagating activation differences." arXiv preprint arXiv:1704.02685 (2017).
4. *QII:* Datta, Anupam, Shayak Sen, and Yair Zick. "Algorithmic transparency via quantitative input influence: Theory and experiments with learning systems." Security and Privacy (SP), 2016 IEEE Symposium on. IEEE, 2016.
5. *Layer-wise relevance propagation:* Bach, Sebastian, et al. "On pixel-wise explanations for non-linear classifier decisions by layer-wise relevance propagation." PloS one 10.7 (2015): e0130140.
6. *Shapley regression values:* Lipovetsky, Stan, and Michael Conklin. "Analysis of regression in game theory approach." Applied Stochastic Models in Business and Industry 17.4 (2001): 319-330.
7. *Tree interpreter:* Saabas, Ando. Interpreting random forests. http://blog.datadive.net/interpreting-random-forests/
## Citations
The algorithms and visualizations used in this package came primarily out of research in [Su-In Lee's lab](https://suinlee.cs.washington.edu) at the University of Washington, and Microsoft Research. If you use SHAP in your research we would appreciate a citation to the appropriate paper(s):
- For general use of SHAP you can read/cite our [NeurIPS paper](http://papers.nips.cc/paper/7062-a-unified-approach-to-interpreting-model-predictions) ([bibtex](https://raw.githubusercontent.com/shap/shap/master/docs/references/shap_nips.bib)).
- For TreeExplainer you can read/cite our [Nature Machine Intelligence paper](https://www.nature.com/articles/s42256-019-0138-9) ([bibtex](https://raw.githubusercontent.com/shap/shap/master/docs/references/tree_explainer.bib); [free access](https://rdcu.be/b0z70)).
- For GPUTreeExplainer you can read/cite [this article](https://arxiv.org/abs/2010.13972).
- For `force_plot` visualizations and medical applications you can read/cite our [Nature Biomedical Engineering paper](https://www.nature.com/articles/s41551-018-0304-0) ([bibtex](https://raw.githubusercontent.com/shap/shap/master/docs/references/nature_bme.bib); [free access](https://rdcu.be/baVbR)).
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=189147091855991&ev=PageView&noscript=1" />
+7
View File
@@ -0,0 +1,7 @@
# WeHub 来源说明
- 原始项目:`shap/shap`
- 原始仓库:https://github.com/shap/shap
- 导入方式:上游默认分支的最新快照
- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准
- 本文件仅用于记录来源,不代表 WeHub 是原项目作者
+229
View File
@@ -0,0 +1,229 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"
$PYTHON_PRERELEASE_REGEX = @"
(?x)
(?<major>\d+)
\.
(?<minor>\d+)
\.
(?<micro>\d+)
(?<prerelease>[a-z]{1,2}\d+)
"@
function Download ($filename, $url) {
$webclient = New-Object System.Net.WebClient
$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}
# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for ($i = 0; $i -lt $retry_attempts; $i++) {
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}
function ParsePythonVersion ($python_version) {
if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
$matches.prerelease)
}
$version_obj = [version]$python_version
return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
}
function DownloadPython ($python_version, $platform_suffix) {
$major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
if (($major -le 2 -and $micro -eq 0) `
-or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
) {
$dir = "$major.$minor"
$python_version = "$major.$minor$prerelease"
} else {
$dir = "$major.$minor.$micro"
}
if ($prerelease) {
if (($major -le 2) `
-or ($major -eq 3 -and $minor -eq 1) `
-or ($major -eq 3 -and $minor -eq 2) `
-or ($major -eq 3 -and $minor -eq 3) `
) {
$dir = "$dir/prev"
}
}
if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
$ext = "msi"
if ($platform_suffix) {
$platform_suffix = ".$platform_suffix"
}
} else {
$ext = "exe"
if ($platform_suffix) {
$platform_suffix = "-$platform_suffix"
}
}
$filename = "python-$python_version$platform_suffix.$ext"
$url = "$BASE_URL$dir/$filename"
$filepath = Download $filename $url
return $filepath
}
function InstallPython ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = ""
} else {
$platform_suffix = "amd64"
}
$installer_path = DownloadPython $python_version $platform_suffix
$installer_ext = [System.IO.Path]::GetExtension($installer_path)
Write-Host "Installing $installer_path to $python_home"
$install_log = $python_home + ".log"
if ($installer_ext -eq '.msi') {
InstallPythonMSI $installer_path $python_home $install_log
} else {
InstallPythonEXE $installer_path $python_home $install_log
}
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallPythonEXE ($exepath, $python_home, $install_log) {
$install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
RunCommand $exepath $install_args
}
function InstallPythonMSI ($msipath, $python_home, $install_log) {
$install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
$uninstall_args = "/qn /x $msipath"
RunCommand "msiexec.exe" $install_args
if (-not(Test-Path $python_home)) {
Write-Host "Python seems to be installed else-where, reinstalling."
RunCommand "msiexec.exe" $uninstall_args
RunCommand "msiexec.exe" $install_args
}
}
function RunCommand ($command, $command_args) {
Write-Host $command $command_args
Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
}
function InstallPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$python_path = $python_home + "\python.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
Write-Host "Executing:" $python_path $GET_PIP_PATH
& $python_path $GET_PIP_PATH
} else {
Write-Host "pip already installed."
}
}
function DownloadMiniconda ($python_version, $platform_suffix) {
if ($python_version -eq "3.4") {
$filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
} else {
$filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
}
$url = $MINICONDA_URL + $filename
$filepath = Download $filename $url
return $filepath
}
function InstallMiniconda ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = "x86"
} else {
$platform_suffix = "x86_64"
}
$filepath = DownloadMiniconda $python_version $platform_suffix
Write-Host "Installing" $filepath "to" $python_home
$install_log = $python_home + ".log"
$args = "/S /D=$python_home"
Write-Host $filepath $args
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallMinicondaPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$conda_path = $python_home + "\Scripts\conda.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$args = "install --yes pip"
Write-Host $conda_path $args
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}
function main () {
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
InstallPip $env:PYTHON
}
main
+88
View File
@@ -0,0 +1,88 @@
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
::
:: To build extensions for 64 bit Python 2, we need to configure environment
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
::
:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
:: environment configurations.
::
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
:: cmd interpreter, at least for (SDK v7.0)
::
:: More details at:
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
:: http://stackoverflow.com/a/13751649/163740
::
:: Author: Olivier Grisel
:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
::
:: Notes about batch files for Python people:
::
:: Quotes in values are literally part of the values:
:: SET FOO="bar"
:: FOO is now five characters long: " b a r "
:: If you don't want quotes, don't include them on the right-hand side.
::
:: The CALL lines at the end of this file look redundant, but if you move them
:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
:: case, I don't know why.
@ECHO OFF
SET COMMAND_TO_RUN=%*
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
:: Extract the major and minor versions, and allow for the minor version to be
:: more than 9. This requires the version number to have two dots in it.
SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
IF "%PYTHON_VERSION:~3,1%" == "." (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
) ELSE (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
)
:: Based on the Python version, determine what SDK version to use, and whether
:: to set the SDK for 64-bit.
IF %MAJOR_PYTHON_VERSION% == 2 (
SET WINDOWS_SDK_VERSION="v7.0"
SET SET_SDK_64=Y
) ELSE (
IF %MAJOR_PYTHON_VERSION% == 3 (
SET WINDOWS_SDK_VERSION="v7.1"
IF %MINOR_PYTHON_VERSION% LEQ 4 (
SET SET_SDK_64=Y
) ELSE (
SET SET_SDK_64=N
IF EXIST "%WIN_WDK%" (
:: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
REN "%WIN_WDK%" 0wdf
)
)
) ELSE (
ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
EXIT 1
)
)
IF %PYTHON_ARCH% == 64 (
IF %SET_SDK_64% == Y (
ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
) ELSE (
ECHO Using default MSVC build environment for 64 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)
) ELSE (
ECHO Using default MSVC build environment for 32 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)
+226
View File
@@ -0,0 +1,226 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
rm -rf generated/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SHAP.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SHAP.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/SHAP"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SHAP"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
+57
View File
@@ -0,0 +1,57 @@
.wy-side-nav-search>div.version {
color: black;
}
@media screen and (min-width: 767px) {
.wy-table-responsive table td {
white-space: normal;
}
.wy-table-responsive {
overflow: visible;
}
}
.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo {
max-width: 40%;
}
.wy-side-nav-search>div.version {
color: #d9d9d9;
}
.wy-nav-top {
background: #343131;
}
.highlight {
background: #f7f7f7;
}
.wy-side-nav-search input[type=text] {
border-color: #666666;
}
a {
color: #008bfb;
}
a:hover {
color: #008bfb;
}
a:visited {
color: #008bfb;
}
html.writer-html4 .rst-content dl:not(.docutils)>dt, html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt {
background: #008bfb11;
color: #0086f6;
border-top: 3px solid #008bfbaa;
}
.rst-versions .rst-current-version {
color: #fcfcfc;
}
.wy-menu-vertical a {
color: #d9d9d9;
}
+5
View File
@@ -0,0 +1,5 @@
{# layout.html #}
{# Import the layout of the theme. #}
{% extends "!layout.html" %}
{% set css_files = css_files + ['_static/css/style.css'] %}
+154
View File
@@ -0,0 +1,154 @@
.. currentmodule:: shap
API Reference
=============
This page contains the API reference for public objects and functions in SHAP.
There are also :ref:`example notebooks <api_examples>` available that demonstrate how
to use the API of each object/function.
.. _explanation_api:
Explanation
-----------
.. autosummary::
:toctree: generated/
shap.Explanation
shap.Cohorts
.. _explainers_api:
explainers
----------
*See also:* :ref:`Explainer API Examples <explainers_examples>`.
.. autosummary::
:toctree: generated/
shap.Explainer
shap.TreeExplainer
shap.GPUTreeExplainer
shap.LinearExplainer
shap.PermutationExplainer
shap.PartitionExplainer
shap.SamplingExplainer
shap.AdditiveExplainer
shap.DeepExplainer
shap.KernelExplainer
shap.GradientExplainer
shap.ExactExplainer
shap.explainers.other.Coefficient
shap.explainers.other.Random
shap.explainers.other.LimeTabular
shap.explainers.other.Maple
shap.explainers.other.TreeMaple
shap.explainers.other.TreeGain
.. _plots_api:
plots
-----
*See also:* :ref:`Plot API Examples <plots_examples>`.
.. autosummary::
:toctree: generated/
shap.plots.bar
shap.plots.waterfall
shap.plots.scatter
shap.plots.heatmap
shap.plots.force
shap.plots.text
shap.plots.image
shap.plots.partial_dependence
shap.plots.decision
shap.plots.embedding
shap.plots.initjs
shap.plots.group_difference
shap.plots.image_to_text
shap.plots.monitoring
shap.plots.beeswarm
shap.plots.violin
.. _maskers_api:
maskers
-------
*See also:* :ref:`Masker API Examples <maskers_examples>`.
.. autosummary::
:toctree: generated/
shap.maskers.Masker
shap.maskers.Independent
shap.maskers.Partition
shap.maskers.Impute
shap.maskers.Fixed
shap.maskers.Composite
shap.maskers.FixedComposite
shap.maskers.OutputComposite
shap.maskers.Text
shap.maskers.Image
.. _models_api:
models
------
.. autosummary::
:toctree: generated/
shap.models.Model
shap.models.TeacherForcing
shap.models.TextGeneration
shap.models.TopKLM
shap.models.TransformersPipeline
.. _utils_api:
utils
-----
.. autosummary::
:toctree: generated/
shap.utils.hclust
shap.utils.hclust_ordering
shap.utils.partition_tree
shap.utils.partition_tree_shuffle
shap.utils.delta_minimization_order
shap.utils.approximate_interactions
shap.utils.potential_interactions
shap.utils.sample
shap.utils.shapley_coefficients
shap.utils.convert_name
shap.utils.OpChain
shap.utils.show_progress
shap.utils.MaskedModel
shap.utils.make_masks
.. _datasets_api:
datasets
--------
.. autosummary::
:toctree: generated/
shap.datasets.a1a
shap.datasets.adult
shap.datasets.california
shap.datasets.communitiesandcrime
shap.datasets.corrgroups60
shap.datasets.diabetes
shap.datasets.imagenet50
shap.datasets.imdb
shap.datasets.independentlinear60
shap.datasets.iris
shap.datasets.linnerud
shap.datasets.nhanesi
shap.datasets.rank
+71
View File
@@ -0,0 +1,71 @@
.. currentmodule:: shap
.. _api_examples:
API Examples
----------------
These examples parallel the namespace structure of SHAP. Each object or function in SHAP has a
corresponding example notebook here that demonstrates its API usage. The source notebooks
are `available on GitHub <https://github.com/shap/shap/tree/master/notebooks/api_examples>`_.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/api_examples/migrating-to-new-api.ipynb
.. _explainers_examples:
explainers
==========
*See also:* :ref:`Explainer API Reference <explainers_api>`.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/api_examples/explainers/*
.. _maskers_examples:
maskers
=======
*See also:* :ref:`Masker API Reference <maskers_api>`.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/api_examples/maskers/*
.. _models_examples:
models
======
.. Examples for members of :ref:`shap.models <models_api>`.
Work in progress.
.. TODO: Uncomment this toctree once we have at least one example to share
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/api_examples/models/*
.. _plots_examples:
plots
=====
*See also:* :ref:`Plot API Reference <plots_api>`.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/api_examples/plots/*
Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

+1454
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

+48
View File
@@ -0,0 +1,48 @@
.. currentmodule:: shap
.. benchmarks
Benchmarks
----------
These benchmark notebooks compare different types of explainers across a variety of metrics.
They are all generated from Jupyter notebooks
`available on GitHub <https://github.com/shap/shap/tree/master/notebooks/benchmarks>`_.
Image
=====
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/benchmarks/image/*
Tabular
=======
Benchmarks that compare explainers on tabular datasets.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/benchmarks/tabular/*
Text
====
Benchmarks that compare explainers on text datasets.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/benchmarks/text/*
Others
======
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/benchmarks/others/*
+455
View File
@@ -0,0 +1,455 @@
#!/usr/bin/env python3
#
# SHAP documentation build configuration file, created by
# sphinx-quickstart on Tue May 22 10:44:55 2018.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import shutil
import sys
import requests
print(os.path.abspath("./shap"))
sys.path.insert(0, os.path.abspath(".."))
# make copy of notebooks in docs folder, as they must be here for sphinx to
# pick them up properly.
NOTEBOOKS_DIR = os.path.abspath("example_notebooks")
if os.path.exists(NOTEBOOKS_DIR):
import warnings
warnings.warn("example_notebooks directory exists, replacing...")
shutil.rmtree(NOTEBOOKS_DIR)
shutil.copytree(os.path.abspath("../notebooks"), NOTEBOOKS_DIR)
if os.path.exists(NOTEBOOKS_DIR + "/local_scratch"):
shutil.rmtree(NOTEBOOKS_DIR + "/local_scratch")
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosectionlabel",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"sphinx_rtd_theme",
"numpydoc",
"nbsphinx", # Allows parsing Jupyter notebooks
"myst_parser", # Allows parsing Markdown, such as CONTRIBUTING.md
"sphinx_github_changelog",
]
# --- Extension options
# [autodoc]
autodoc_default_options = {"members": True, "inherited-members": True}
# [autosectionlabel]
# Make sure the autogenerated targets are unique
autosectionlabel_prefix_document = True
# [autosummary]
autosummary_generate = True
# [intersphinx]
intersphinx_mapping = {
# "stdlib": ("https://docs.python.org/3", None),
"mpl": (
"https://matplotlib.org/stable/",
"https://matplotlib.org/stable/objects.inv",
),
"scikit-learn": (
"https://scikit-learn.org/stable/",
"https://scikit-learn.org/stable/objects.inv",
),
"scipy": ("https://docs.scipy.org/doc/scipy", None),
}
# Sphinx defaults to automatically resolve *unresolved* labels using all your Intersphinx mappings.
# This behavior has unintended side-effects, namely that documentations local references can
# suddenly resolve to an external location.
# See also:
# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_disabled_reftypes
intersphinx_disabled_reftypes = ["*"]
# [numpydoc]
numpydoc_show_class_members = False
# ---
# Do not create toctree entries for each class/function
toc_object_entries = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ".rst"
# The encoding of source files.
#
# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = "index"
# General information about the project.
project = "SHAP"
copyright = "2018, Scott Lundberg"
author = "Scott Lundberg"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = "latest"
# The full version, including alpha/beta/rc tags.
release = "latest"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = "en"
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#
# today = ''
#
# Else, today_fmt is used as the format for a strftime call.
#
# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = [
"_build",
"Thumbs.db",
".DS_Store",
"example_notebooks/tabular_examples/tree_based_models/tree_shap_paper",
"user_studies",
"local",
]
# The reST default role (used for this markup: `text`) to use for all
# documents.
#
# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#
# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#
# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Release notes configuration ------------------------------------------
# Make available a URL that points to the latest unreleased changes
def get_latest_tag() -> str:
"""Query GitHub API to get the most recent git tag"""
url = "https://api.github.com/repos/shap/shap/releases/latest"
response = requests.get(url)
response.raise_for_status()
return response.json()["tag_name"]
_latest_tag = get_latest_tag()
_url = f"https://github.com/shap/shap/compare/{_latest_tag}...master"
# Make an RST substitution that inserts the correct hyperlink
rst_epilog = f"""
.. |unreleasedchanges| replace:: {_latest_tag}...master
.. _unreleasedchanges: {_url}
"""
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
#'canonical_url': '',
"logo_only": True,
"display_version": True,
"prev_next_buttons_location": "bottom",
"style_external_links": False,
"style_nav_header_background": "#343131",
# Toc options
"collapse_navigation": True,
"sticky_navigation": True,
"navigation_depth": 4,
"includehidden": True,
"titles_only": False,
}
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "artwork/shap_logo_white.png"
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = 'SHAP v0.16'
# A shorter title for the navigation bar. Default is the same as html_title.
#
# html_short_title = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
html_favicon = "artwork/favicon.ico"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#
# html_extra_path = []
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#
# html_last_updated_fmt = None
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#
# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#
# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#
# html_additional_pages = {}
# If false, no module index is generated.
#
# html_domain_indices = True
# If false, no index is generated.
#
# html_use_index = True
# If true, the index is split into individual pages for each letter.
#
# html_split_index = False
# If true, links to the reST sources are added to the pages.
#
# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#
# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
#
# html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = "SHAPdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, "SHAP.tex", "SHAP Documentation", "Scott Lundberg", "manual"),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#
# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#
# latex_use_parts = False
# If true, show page references after internal links.
#
# latex_show_pagerefs = False
# If true, show URL addresses after external links.
#
# latex_show_urls = False
# Documents to append as an appendix to all manuals.
#
# latex_appendices = []
# It false, will not define \strong, \code, itleref, \crossref ... but only
# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
# packages.
#
# latex_keep_old_macro_names = True
# If false, no module index is generated.
#
# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "shap", "SHAP Documentation", [author], 1)]
# If true, show URL addresses after external links.
#
# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"SHAP",
"SHAP Documentation",
author,
"SHAP",
"One line description of project.",
"Miscellaneous",
),
]
# Documents to append as an appendix to all manuals.
#
# texinfo_appendices = []
# If false, no module index is generated.
#
# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False
def setup(app):
import shap # noqa: F401
app.connect("build-finished", build_finished)
def build_finished(app, exception):
shutil.rmtree(NOTEBOOKS_DIR)
+2
View File
@@ -0,0 +1,2 @@
.. include:: ../CONTRIBUTING.md
:parser: myst_parser.sphinx_
+11
View File
@@ -0,0 +1,11 @@
Genomic examples
----------------
These examples explain machine learning models applied to genomic data. They are all generated from Jupyter
notebooks `available on GitHub <https://github.com/shap/shap/tree/master/notebooks/genomic_examples>`_.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/genomic_examples/*
+27
View File
@@ -0,0 +1,27 @@
Image examples
----------------
These examples explain machine learning models applied to image data. They are all generated from Jupyter
notebooks `available on GitHub <https://github.com/shap/shap/tree/master/notebooks/image_examples>`_.
Image classification
====================
Examples using :class:`shap.explainers.Partition` to explain image classifiers.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/image_examples/image_classification/*
Image captioning
================
Examples using :class:`shap.explainers.Permutation` to produce explanations in a model agnostic manner.
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/image_examples/image_captioning/*
+57
View File
@@ -0,0 +1,57 @@
.. SHAP documentation master file, created by
sphinx-quickstart on Tue May 22 10:44:55 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to the SHAP documentation
---------------------------------
.. image:: artwork/shap_header.png
:width: 600px
:align: center
**SHAP (SHapley Additive exPlanations)** is a game theoretic approach to explain the output of
any machine learning model. It connects optimal credit allocation with local explanations
using the classic Shapley values from game theory and their related extensions (see
`papers <https://github.com/shap/shap#citations>`_ for details and citations).
Install
=======
SHAP can be installed from either `PyPI <https://pypi.org/project/shap>`_ or
`conda-forge <https://anaconda.org/conda-forge/shap>`_::
pip install shap
or
conda install -c conda-forge shap
.. toctree::
:maxdepth: 2
:caption: Introduction
Topical overviews <overviews>
.. toctree::
:maxdepth: 2
:caption: Examples
Tabular examples <tabular_examples>
Text examples <text_examples>
Image examples <image_examples>
Genomic examples <genomic_examples>
.. toctree::
:maxdepth: 2
:caption: Reference
API reference <api>
API examples <api_examples>
Benchmarks <benchmarks>
.. toctree::
:maxdepth: 1
:caption: Development
Release notes <release_notes>
Contributing guide <contributing>
+281
View File
@@ -0,0 +1,281 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
echo. dummy to check syntax errors of document sources
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SHAP.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SHAP.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "epub3" (
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
if "%1" == "dummy" (
%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
if errorlevel 1 exit /b 1
echo.
echo.Build finished. Dummy builder generates no files.
goto end
)
:end
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
+26
View File
@@ -0,0 +1,26 @@
# Create 'crime.pickle'
import pickle
import lightgbm as lgb
from sklearn.model_selection import train_test_split
import shap
random_state = 1203344
# Load data and train model
X, y = shap.datasets.communitiesandcrime()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=random_state)
model = lgb.LGBMRegressor(random_state=random_state)
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
# Calculate and plot SHAP values
explainer = shap.TreeExplainer(model)
idx = 13
shap_values = explainer.shap_values(X_test.iloc[[idx]], y_test[idx])
# Dump to pickle
o = (explainer.expected_value, shap_values, X_test.iloc[0])
with open("./crime.pickle", "wb") as fl:
pickle.dump(o, fl)
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
Topical Overviews
-----------------
These overviews are generated from Jupyter notebooks that are
`available on GitHub <https://github.com/shap/shap/tree/master/notebooks/overviews>`_
.. toctree::
:glob:
:maxdepth: 1
example_notebooks/overviews/*
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
@article{lundberg2018explainable,
title={Explainable machine-learning predictions for the prevention of hypoxaemia during surgery},
author={Lundberg, Scott M and Nair, Bala and Vavilala, Monica S and Horibe, Mayumi and Eisses, Michael J and Adams, Trevor and Liston, David E and Low, Daniel King-Wai and Newman, Shu-Fang and Kim, Jerry and others},
journal={Nature Biomedical Engineering},
volume={2},
number={10},
pages={749},
year={2018},
publisher={Nature Publishing Group}
}
+7
View File
@@ -0,0 +1,7 @@
@incollection{NIPS2017_7062,
title = {A Unified Approach to Interpreting Model Predictions},
author = {Lundberg, Scott M and Lee, Su-In},
year = {2017},
publisher = {Curran Associates, Inc.},
url = {http://papers.nips.cc/paper/7062-a-unified-approach-to-interpreting-model-predictions.pdf}
}
+10
View File
@@ -0,0 +1,10 @@
@article{lundberg2020local2global,
title={From local explanations to global understanding with explainable AI for trees},
author={Lundberg, Scott M. and Erion, Gabriel and Chen, Hugh and DeGrave, Alex and Prutkin, Jordan M. and Nair, Bala and Katz, Ronit and Himmelfarb, Jonathan and Bansal, Nisha and Lee, Su-In},
journal={Nature Machine Intelligence},
volume={2},
number={1},
pages={2522-5839},
year={2020},
publisher={Nature Publishing Group}
}

Some files were not shown because too many files have changed in this diff Show More