社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

机器学习可解释性Python库,令人讨厌

Ai学习的老章 • 3 天前 • 12 次点击  


大家好,我是Ai学习的老章

偶尔推点老本行相关文章——机器学习系列

作者 Tobias Pitters[1]。Tobias 是 shap 项目维护者,现任可解释人工智能初创公司 CloudExplain[2] 工程师。

机器学习面试准备路线图(2025版)机器学习模型的可解释性算法汇总!

SHAP 是最广泛使用的模型可解释性库之一,这有其充分理由——它让解释复杂模型变得直观甚至美观。我自 2023 年 10 月开始参与 SHAP 开发,并于 2024 年 1 月成为维护者。在此期间,我贡献了许多改进和修复,至今仍热爱其底层数学的强大、易于集成的特性以及惊艳的可视化效果(我认为这正是 SHAP 最初如此受欢迎的重要原因)。

但作为维护者也意味着要直面系统崩溃、运行迟缓或用户遭遇挫折的环节。经过一年半时间,我整理出一份亟待改进的痛点清单——既为了项目健康发展,也为了所有使用者。

1. 解释过程可能变得缓慢

在笔记本环境中处理数千条观测数据时一切正常,你可以自由选择最适合的解释器。但一旦涉及更多特征和更大样本量,速度就会急剧下降。对于具有数十万条观测数据的大型模型,解释过程可能耗时数小时。

这种缓慢部分源于 SHAP 值计算方式的固有特性,但更多是由实现选择导致的,比如有限的并行化和大量纯 Python 循环。最近我们合并了一个将部分循环转移到 Cython 的修复方案,使 KernelExplainer 的速度提升了约 5%(参见这个 PR[3] 或这个 PR[4])。我认为仍有很大改进空间,只是我们尚未将其列为优先事项。

2. DeepExplainer 的困扰

DeepExplainer 原本是解释 TensorFlow 或 PyTorch 模型的自然选择,它采用 DeepLIFT 风格逐层反向传播重要性值。遗憾的是,从 TensorFlow 2.4 版本开始,这一过程变得异常困难。许多神经网络层在内部由乘法、激活函数和加法等基础运算组合而成。过去我们只需重写这些底层运算的反向传播逻辑,就能自动适用于 LSTM 等高层结构,无需额外工作即可为各类层计算 SHAP 值。但随着 TensorFlow 转向即时执行模式并隐藏这些内部实现,这条捷径已然失效。如今我们必须为每个需要支持的层单独实现定制逻辑。

这导致 LayerNorm 等标准化层以及 LSTM、Attention 层等复杂结构不再受 DeepExplainer 支持。

3. TreeExplainer——速度快但难以修改

树模型在表格数据预测任务中仍被广泛使用且表现优异。幸运的是,SHAP 值可以通过解析方法从树模型中计算得出,而我们的实现由于采用 C 语言而具有极高的运行效率。但遗憾的是,目前团队缺乏精通 C 语言的维护者,且这部分代码年代久远难以修改。我们还遇到过内存错误——这种因内存处理不当引发的底层问题,所幸已被社区修复。我怀疑仍存在其他潜在问题,因此希望能通过用 Rust 重写代码或寻找专人接管这部分代码库,使其进入更易维护的状态。在与可解释 AI 专家讨论 Rust 实施方案时,我们一致认为这是可行的改进方向:既能借助 Rust 的内存安全设计避免问题,又能保持与当前版本相近的性能表现。

另外,您知道吗?我们其实有 TreeExplainer 的 GPU 版本[5] 。遗憾的是,目前仅支持通过源码安装(克隆代码库后运行 pip install -e .)且需配备 GPU 设备。我理想中的方案是提供额外安装标记(pip install shap[gpu])或预编译的 GPU 轮包(pip install shap-gpu)。虽然需要升级构建基础设施,但其他软件包的成功案例证明这完全可行。

4. 因上游包导致测试失败和代码损坏

SHAP 支持众多机器学习框架——包括 scikit-learn、TensorFlow、PyTorch、LightGBM、XGBoost、CatBoost、transformers 库中的部分文本模型,甚至 NGBoost 模型。这意味着我们必须与所有框架保持兼容,并通过测试确保这一点。但问题在于,支持如此多软件包的同时还要兼顾多个 Python 版本,导致我们的 CI 流水线(自动化测试与集成工作流)经常失败。

每当这些库中的任何内容发生变化,都可能导致我们的代码失效。粗略估计,我花费在 SHAP 上约 30%的时间都用于修复上游变更。这些问题往往晦涩难懂且难以调试。例如,我们曾遇到测试套件在 Python 3.10 上失败,但在 Python 3.11 及更高版本上却运行正常。失败的测试与 transformers 代码相关。经过数小时调试后发现,我们必须将流水线专门升级到 Python 3.10.12 版本,因为 transformers 开始使用了一个仅在 Python 3.10.12 中向后移植的警告过滤参数(3.10.0-3.10.11 版本均未提供)。这种在补丁版本中添加功能的做法并不常见,让我们措手不及(参见 Python 发布说明[6] )。
针对这种情况的解决方案并不多,我们可以改进日志记录、添加类型提示,但仍会有大量问题无法覆盖。

5. 绘图问题

我喜爱 SHAP 的图表功能,相信这是它成功的重要因素之一。其多样性令人印象深刻,几乎无可挑剔——除了那些缺失但难以添加到遗留绘图代码库中的功能。说到"遗留",我确实是这个意思——有些绘图函数在内部就是如此命名的,比如这里[7] ,或这里[8] ,还有那个 waterfall_legacy 函数[9] (这个函数现在已不建议使用)。

若能清理这些代码并简化通常超过 300 行的单个绘图函数就太好了。此外,部分图表是用 JavaScript 生成的,这本身没问题,但这些代码相当陈旧且难以测试。我也希望能重写这部分代码  但这需要更全面的绘图测试。我们确实已有相关测试,但图表仍是代码库中测试覆盖最薄弱的部分。如果有完善的测试,我们不仅能修复一些错误,还能扩展绘图功能,让用户获得更多控制权,比如调整调色板、间距和高度等参数。

6. 其他问题

一些较小的杂项问题或缺失功能:

  • JAX 是一个用于构建深度学习网络的库,可与 PyTorch 或 TensorFlow 相媲美,只是采用了更函数式的编程方法。它正在快速发展,我很想在 Deep-和 GradientExplainer 中支持它。不过在开发大型新功能之前,我们还有许多更紧迫的问题需要解决,这些新功能本身就会带来各种问题。
  • 作为维护者,我最讨厌 SHAP 的 6 件事之一就是缺乏完善的类型标注——这个功能在其他库中让我受益匪浅。对我们而言这是双重困境:一方面自然是时间不足难以实现,另一方面我们许多函数具有高度多态性,允许接收多种不同类型的输入,这也使得类型提示对用户而言变得难以阅读。
  • 我真的很希望实现夜间构建,并支持科学 Python 社区[10]提出的其他功能,比如按需懒加载代码。

乐观的前景

我不想显得悲观或让你觉得这是听天由命的放弃,我相信并致力于让这个软件包不断完善,许多贡献者也同样如此。诚实地面对并承认当前的不足是第一步,但看到 SHAP 带来的价值,就让人觉得值得持续投入。当出现一个 PR 解决了我们长期存在的问题,甚至是我们未曾意识到的问题,或是为 SHAP 构建了全新功能时,我都感到欣喜。看到这如何将人们凝聚在一起,推动事物向前发展,真是太好了。我也热爱这个软件包帮助解释了黑盒机器学习算法,将可解释 AI 带入主流,推动更广泛的机器学习应用,并支持我们更深入地理解复杂算法的工作原理。它让我深入探索可解释 AI,并接触了以前从未涉足的编码领域。

原文:# 作为维护者,我讨厌 SHAP 的 6 个方面 https://mindfulmodeler.substack.com/p/6-things-i-hate-about-shap-as-a-maintainer?utm_source=post-email-title&publication_id=1078760&post_id=173436591&utm_campaign=email-post-title&isFreemail=true&r=u9e1n&triedRedirect=true&utm_medium=email


参考资料
[1] 

Tobias Pitters: https://github.com/CloseChoice

[2] 

CloudExplain: https://www.cloudexplain.eu/

[3] 

这个 PR: https://github.com/shap/shap/pull/3944

[4] 

这个 PR:  https://github.com/shap/shap/pull/3983

[5] 

TreeExplainer 的 GPU 版本: https://github.com/shap/shap/blob/master/shap/explainers/_gpu_tree.py

[6] 

Python 发布说明: https://www.python.org/downloads/release/python-31012/

[7] 

这里: https://github.com/shap/shap/blob/8bcd29f3f49d1315411892417ab59cb7c1227151/shap/init.py#L49-L50

[8] 

这里:  https://github.com/shap/shap/blob/8bcd29f3f49d1315411892417ab59cb7c1227151/shap/init.py#L61

[9] 

waterfall_legacy 函数: https://github.com/shap/shap/blob/8bcd29f3f49d1315411892417ab59cb7c1227151/shap/plots/_waterfall.py#L376

[10] 

科学 Python 社区: https://scientific-python.org/specs/

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/187431
 
12 次点击