chore: import upstream snapshot with attribution
@@ -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`
|
||||
```
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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:
|
||||
- "*"
|
||||
@@ -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/
|
||||
@@ -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
|
||||
@@ -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}}"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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|
|
||||
)$
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,357 @@
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/shap/shap/master/docs/artwork/shap_header.svg" width="800" />
|
||||
</p>
|
||||
|
||||
---
|
||||
[](https://pypi.org/project/shap/)
|
||||
[](https://anaconda.org/conda-forge/shap)
|
||||

|
||||

|
||||
[](https://mybinder.org/v2/gh/shap/shap/master)
|
||||
[](https://shap.readthedocs.io/en/latest/?badge=latest)
|
||||

|
||||
[](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" />
|
||||
@@ -0,0 +1,7 @@
|
||||
# WeHub 来源说明
|
||||
|
||||
- 原始项目:`shap/shap`
|
||||
- 原始仓库:https://github.com/shap/shap
|
||||
- 导入方式:上游默认分支的最新快照
|
||||
- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准
|
||||
- 本文件仅用于记录来源,不代表 WeHub 是原项目作者
|
||||
@@ -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
|
||||
@@ -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
|
||||
)
|
||||
@@ -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."
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{# layout.html #}
|
||||
{# Import the layout of the theme. #}
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{% set css_files = css_files + ['_static/css/style.css'] %}
|
||||
@@ -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
|
||||
@@ -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/*
|
||||
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 517 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 502 KiB |
|
After Width: | Height: | Size: 344 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 235 KiB |
@@ -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/*
|
||||
@@ -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)
|
||||
@@ -0,0 +1,2 @@
|
||||
.. include:: ../CONTRIBUTING.md
|
||||
:parser: myst_parser.sphinx_
|
||||
@@ -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/*
|
||||
@@ -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/*
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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/*
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||
@@ -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}
|
||||
}
|
||||