贡献指南

  • [简介](#introduction)

  • [编写有帮助的错误报告](#writing-helpful-bug-reports)

  • [安装最新版本](#installing-the-latest-version)

  • [设置本地开发环境](#setting-up-a-local-development-environment)

    • Fork the repository

    • [创建一个Python环境](#creating-a-python-environment)

    • [从源代码安装](#installing-from-source)

    • [使用precommit进行代码检查](#code-checks-with-precommit)

    • [使用 pytest 进行单元测试](#unit-tests-with-pytest)

  • [拉取请求 (PRs)](#pull-requests-prs)

    • [创建PR的礼仪](#etiquette-for-creating-prs)

    • [发布PR的检查清单](#checklist-for-publishing-prs)

  • [文档](#documentation)

    • [在拉取请求上预览更改](#previewing-changes-on-pull-requests)

    • [在本地构建文档](#building-the-docs-locally)

  • [Jupyter 笔记本风格指南](#jupyter-notebook-style-guide)

    • [Jupyter 通用指南](#general-jupyter-guidelines)

    • [链接 / 交叉引用](#links–cross-references)

    • [笔记本的代码检查和格式化](#notebook-linting-and-formatting)

  • [维护者指南](#maintainer-guide)

    • [问题分类](#issue-triage)

    • [PR 分类](#pr-triage)

    • [版本控制](#versioning)

    • [制作发布版本](#making-releases)

    • [来自PR标签的发布说明](#release-notes-from-pr-labels)

介绍

感谢您为 SHAP 做出贡献。SHAP 是一个开源的集体努力项目,欢迎各种形式的贡献!

你可以通过以下方式贡献:

  • 在 GitHub [issue tracker][issues] 上提交错误报告和功能请求,

  • 通过 [Pull Requests][pulls] 贡献修复和改进,或

  • 在 [讨论论坛][discussions] 中讨论想法和问题。

如果你在寻找一个开始的好地方,可以查看带有 [good first issue][goodfirstissue] 标签的问题。

撰写有帮助的错误报告

在 [issue tracker][issues] 上提交错误报告时,包含一个好的 最小可复现示例 (MRE) 对维护者非常有帮助。

一个MRE应该是:

  • 最小化:使用尽可能少的代码,但仍能产生相同的问题。

  • 自包含: 包括重现问题所需的一切,包括导入和输入数据。

  • 可复现:在提供代码之前,请测试代码以确保它能复现问题。

更多信息,请参阅 [如何撰写最简化的错误报告](https://matthewrocklin.com/minimal-bug-reports)。

安装最新版本

要获取最新版本的 shap,你可以直接从 master 分支通过 pip 安装该库:

pip install git+https://github.com/shap/shap.git@master

这可以用来测试自最近一次发布以来,某个特定的问题或错误是否已被修复。

另外,如果你考虑对代码进行修改,你可以克隆仓库并将本地副本安装,如下所述。

设置本地开发环境

Fork 仓库

点击 [这个链接](https://github.com/shap/shap/fork) 在 GitHub 上将仓库分叉到您的用户区域。

使用项目主页上绿色 <> Code 按钮提供的 URL,将仓库克隆到您的本地环境。

创建一个 Python 环境

为项目创建一个新的隔离环境,例如使用 conda:

conda create -n shap python=3.11
conda activate shap

从源代码安装

要从源代码构建,您需要一个编译器来构建C扩展。

  • 在Linux上,你可以通过以下命令安装gcc:

    sudo apt install build-essential
    
  • 或者在Windows上,获取编译器的一种方法是 [安装mingw64](https://www.mingw-w64.org/downloads/)。

使用 –editable 标志通过 pip 安装项目,这样可以确保你对源代码所做的任何更改都会立即反映在你的环境中。

pip install --editable '.[test,plots,docs]'

各种 pip 额外功能在 [pyproject.toml](pyproject.toml) 中定义:

  • test-core: 运行 pytest 所需的最小依赖集。

  • test: 一套更广泛的第三方包,用于完整的测试套件,例如 tensorflow、pytest、xgboost。

  • plots: 包含 matplotlib。

  • docs: 使用 Sphinx 构建文档的依赖项。

注意:当从源代码安装时,shap 将尝试构建 C 扩展和 CUDA 扩展。如果 CUDA 不可用,shap 将重新尝试构建,但不支持 CUDA。

因此,如果在没有 CUDA 的情况下从源代码构建时,看到诸如 WARNING: Could not compile cuda extensions 的警告是非常正常的。

使用 precommit 进行代码检查

我们使用 [pre-commit hooks](https://pre-commit.com/#install) 来运行代码检查。通过以下命令在你的本地环境中启用 pre-commit

pip install pre-commit
pre-commit install

要运行所有文件的检查,请使用:

pre-commit install
pre-commit run --all-files

[Ruff](https://beta.ruff.rs/docs/) 被用作一个代码检查工具,并且它被启用为预提交钩子。你也可以通过以下命令在本地运行 ruff

pip install ruff
ruff check .

使用 pytest 进行单元测试

单元测试套件可以在本地运行,命令如下:

pytest

拉取请求 (PRs)

创建PR的礼仪

在开始PR之前,请通过 创建一个Issue 提出建议,检查是否有重复的Issue。对于修复拼写错误等简单的PR,这不是必需的。

保持范围小。这使得PR更容易审查。将功能代码更改(如错误修复)与重构更改(如样式改进)分开。PR应包含其中之一,但不能同时包含两者。

尽早打开一个 草稿PR,不要等到功能完全准备好。在一个描述性的分支上工作,例如 fix/lightgbm-warningsdoc/contributing

使用描述性标题,例如:

  • 修复:更新参数以移除 TreeExplainer 中的 DeprecationWarning

  • ENH: 添加对 Python 3.11 的支持

  • DOCS: 修复 ExactExplainer docstring 的格式

发布PR的检查清单

在将您的PR标记为“准备评审”(通过移除“草稿”状态)之前,请确保:

  • 你的特性分支与主分支是最新的,

  • 所有 [pre-commit 钩子](#code-checks-with-precommit) 都通过,并且

  • 已添加单元测试(如果你的PR添加了任何新功能或修复了错误)。

文档

文档托管在 [shap.readthedocs.io](https://shap.readthedocs.io/en/latest/)。如果你修改了文档字符串或笔记本,请检查这些更改在生成的HTML文件中是否正确呈现。

在拉取请求中预览更改

文档在每次拉取请求时都会自动构建,以便于预览您的更改将如何呈现。要查看预览:

  1. 查找“所有检查已通过”,然后点击“显示所有检查”。

  2. 浏览到名为“docs/readthedocs.org”的检查。

  3. 点击 Details 超链接以打开文档的预览。

PR 预览通常托管在以下形式的 URL 上,替换 <pr-number>:

https://shap--<pr-number>.org.readthedocs.build/en/<pr-number>

本地构建文档

要在本地构建文档:

  1. 导航到 docs 目录。

  2. 运行 make html

  3. 在浏览器中打开“_build/html/index.html”以检查文档。

请注意,nbsphinx 目前需要独立的程序 pandoc。如果你遇到错误“未找到 Pandoc”,请按照 [nbsphinx 安装指南](https://nbsphinx.readthedocs.io/en/0.9.2/installation.html#pandoc) 中的描述安装 pandoc

Jupyter 笔记本样式指南

如果您正在为文档中的 Jupyter 笔记本贡献更改,请遵循以下样式指南。

Jupyter 一般指南

在提交你的笔记本之前,

  • 确保你“重启内核并运行所有单元格…”,确保单元格按顺序执行,笔记本可重现且没有任何隐藏状态。

  • 确保笔记本在Sphinx构建日志中不会因为你的更改而引发语法警告。

Notebook 的代码检查和格式化

我们使用 ruff 对我们的笔记本进行代码检查和自动格式化。假设你已经按照 [上述](#code-checks-with-precommit) 描述设置了 pre-commit,这些检查将在你每次提交更改时自动运行。

要手动运行代码质量检查,你可以执行,例如:

pre-commit run --files notebook1.ipynb notebook2.ipynb

notebook1.ipynbnotebook2.ipynb 替换为你修改过的任何笔记本。

维护者指南

问题分类

错误报告和功能请求在 github 问题跟踪器上进行管理。我们使用自动化来帮助优先处理和组织问题。

good first issue 标签应分配给任何可能适合新贡献者的问题。

如果需要作者提供更多信息,例如可复现的示例,应分配 awaiting feedback 标签。

The [stale bot](https://github.com/actions/stale) 将会标记那些长时间没有任何活动的议题和PR,并加上 stale 标签,同时评论以征求我们社区的反馈。如果在进一步的时间内仍然没有活动,该议题将被关闭。

我们非常重视用户的反馈,因此机器人配置了较长的等待时间,才会将问题标记为过期。

标记为 todo 标签的问题永远不会被标记为过时,因此该标签应分配给任何应保持打开状态的问题,例如长期运行的功能请求。

PR 分类

Pull Requests 通常应分配一个类别标签,如 bugenhancementBREAKING。这些标签用于在发布说明中对 PR 进行分类,如 [下文](#release-notes-from-pr-labels) 所述。

所有PR在被合并之前应至少有一个评审。特别是,维护者通常应确保PR有足够的单元测试来覆盖任何修复的错误或新功能。

PRs 通常使用“压缩并合并”来完成,以保持清晰的线性历史记录,并使调试任何问题变得更加容易。

版本控制

shap 使用符合 PEP 440 的版本控制方案 MAJOR.MINOR.PATCH。与 [numpy][numpy_versioning] 类似,shap 使用语义版本控制,并且从未发布过 major 版本。大多数版本会增加 minor,通常每两个月左右发布一次。patch 版本有时会为任何重要的错误修复而发布。

在进行破坏性更改时,考虑到shap是一个非常流行的包,我们会非常谨慎。当进行破坏性更改时,PR应标记为 BREAKING 标签,以确保它在发布说明中被突出显示。我们使用弃用周期来减轻对下游用户的影响。

GitHub 里程碑可以用来跟踪任何需要为特定版本完成的操作,例如与弃用周期相关的操作。

我们使用 setuptools-scm 从 git 历史记录中自动获取版本号。在构建时,版本号由 git 标签决定。

最低支持的依赖项

我们旨在遵循 [SPEC 0](https://scientific-python.org/specs/spec-0000/) 关于最低支持依赖项的约定。

  • Python 版本的支持在其初始发布后的 3 年内被放弃。

  • 核心包依赖的支持在其初始发布后的两年后被取消。

我们可能会支持比这个窗口稍长一些的Python版本,只要它不会增加任何额外的维护负担。

发布版本

我们尝试使用自动化来使发布过程可靠、透明且可重复。这也有助于我们更频繁地发布。

发布是通过发布一个 [GitHub Release](https://github.com/shap/shap/releases) 来完成的,该发布被打上了一个适当递增的版本号标签。

当发布版本时,轮子将通过 build_wheels GitHub 动作自动构建并发布到 PyPI。此工作流程也可以在任何时候手动触发,以进行 cibuildwheel 的试运行。

在发布之前,为发布创建一个GitHub问题,例如[[Meta issue] Release 0.43.0](https://github.com/shap/shap/issues/3289)。这可以用来与其他维护者协调并同意进行发布。

建议的发布检查清单:

- [ ] Dry-run cibuildwheel & test
- [ ] Make GitHub release & tag
- [ ] Confirm PyPI wheels published
- [ ] Conda forge published

conda 包在 [单独的仓库](https://github.com/conda-forge/shap-feedstock) 中管理。conda-forge 机器人将自动向此仓库提交 PR 以更新 conda 包,通常在 PyPSA 包发布后的几小时内完成。

来自PR标签的发布说明

发行说明可以通过Github自动草拟,使用自上次发布以来合并的PR的标题和标签。更多信息请参阅GitHub文档中的[自动生成的发行说明][auto_release_notes]。

生成的笔记将遵循 [.github/release.yml](.github/release.yml) 中定义的模板,按标签将 PR 整理到子标题中,并排除由机器人创建的 PR。有关可用的配置选项,请参阅 [文档][auto_release_notes]。

为每个PR分配诸如 BREAKINGbugenhancementskip-changelog 等标签是有帮助的,这样更改就会在正确部分的注释中显示。同时,这也有助于确保每个PR都有一个描述性的名称。

这些注释可以编辑(发布前和发布后均可),以删除不太可能对用户有高兴趣的信息,例如维护更新。