分类特征的 SHAP

将经过One-Hot 编码转换的分类特征的 SHAP 值相加

可直接在橱窗里购买,或者到文末领取优惠后购买:

img

分类特征需要先进行转换,然后才能用于模型。One-Hot 编码是一种常见的方法:我们最终会得到每个类别的二进制变量。这很好,直到理解使用 SHAP 的模型为止。每个二进制变量都有自己的 SHAP 值。这使得很难理解原始分类特征的整体贡献。

一种简单的方法是将每个二进制变量的 SHAP 值加在一起。这可以解释为原始分类特征的 SHAP 值。我们将向你介绍执行此操作的 Python 代码。我们将看到我们能够使用 SHAP 聚合图。但是,在理解分类特征关系的性质时,这些是有限的。所以,最后我们向你展示如何使用箱线图来可视化 SHAP 值。

如果你不熟悉 SHAP 或 Python 包,我建议你阅读一下之前的这篇文章《[[Python 中的 SHAP 简介]]》。我们将深入探讨如何解释 SHAP 值。我们还探讨了本文中使用的一些聚合。

处理分类变量时还有另一种解决方案。那就是使用 CatBoost 进行建模。关于 CatBoost 如何进行建模,我以后会写一篇相关文章《[[使用 CatBoost 实现分类特征的 SHAP]]》,你可以在其中找到此解决方案。

数据集

为了演示分类特征的问题,我们将使用蘑菇分类数据集。你可以在图 1 中看到此数据集的快照。目标变量是蘑菇的类别。也就是说,蘑菇是有毒 § 还是可食用 (e)。你可以在UCI 的 MLR1中找到此数据集。

图 1:蘑菇数据集快照

对于模型特征,我们有 22 个分类特征。对于每个特征,类别都用一个字母表示。例如,气味有 9 个独特的类别 - almond (a)、anise (l)、creosote ©, fishy (y), foul (f), musty (m), none (n), pungent §, spicy (s)。这就是蘑菇的气味。

建模

我们将向你介绍用于分析此数据集的代码,你可以在GitHub2上找到完整的脚本。首先,我们将使用下面的 Python 包。我们有一些用于处理和可视化数据的常用包(第 1-5 行)。我们使用 OneHotEncoder 来转换分类特征(第 7 行)。我们使用 xgboost 进行建模(第 10 行)。最后,我们使用 shap 来了解我们的模型是如何工作的(第 12 行)。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('default')

from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import accuracy_score,confusion_matrix

import xgboost as xgb

import shap
shap.initjs()

我们导入数据集(第 2 行)。我们需要一个数值目标变量,因此我们通过设置 toxicous = 1 和 edible = 0 来转换它(第 6 行)。我们还获得了分类特征(第 7 行)。我们不使用 X_cat 进行建模,但它以后会派上用场。

# load data 
data = pd.read_csv(dp + "mushrooms.csv")

# get features
y = data['class']
y = y.astype('category').cat.codes
X_cat = data.drop('class', axis=1)

要使用分类特征,我们还需要对其进行转换。我们首先安装一个编码器(第 2-3 行)。然后我们使用它来转换分类特征(第 6 行)。对于每个分类特征,每个类别都有一个二进制特征。我们为每个二进制特征创建特征名称(第 9 至 10 行)。最后,我们将它们放在一起以创建特征矩阵(第 12 行)。

# fit encoder
enc = OneHotEncoder()
enc.fit(X_cat)

# transform categorical features
X_encoded = enc.transform(X_cat).toarray(<
<think> 嗯,用户需要了解多分类问题中如何使用SHAP进行特征解释。根据之前的交互历史,用户可能已经知道SHAP的基本概念,现在需要专门针对多分类场景的解决方案。 用户提供了多个站内引用可以参考。看来引用[1]和[3]特别讨论了分类特征的处理,而引用[4]提到了随机森林分类模型的可解释性分析。这些资料都很有价值,尤其是引用[1]提到了CatBoost处理分类特征的局限性,以及替代方案的选择。 用户真正的需求很明确:多分类问题中SHAP的应用方法。需要从这几个方面组织回答: 第一,基础原理部分要说明SHAP在多分类中的输出特性,比如每个类别都有独立解释器; 第二,重点介绍分类特征的特殊处理方法,特别是引用[3]提到的编码转换技巧; 第三,可视化工具的选择很关键,要区分全局解释和局部解释的不同图表; 第四,集成模型的注意事项需要单独强调,包括XGBoost/LightGBM的参数设置; 最后补充案例代码时会特别注意修改原始示例中的二分类适配问题,改用多分类数据集。 可能遇到的难点是解释多分类SHAP矩阵的三维结构。计划用"样本-特征-类别"的三维张量来比喻,这样用户更容易理解为什么需要切片查看。同时要提醒用户避免常见错误,比如直接使用树模型时的输出维度误解。 用户身份推测是机器学习工程师或数据科学家,正在调试多分类模型的可解释性。深层需求可能是要向业务方解释模型决策依据,所以特别强调可视化方案的选择。回答时需要平衡理论深度和实用技巧,代码示例最好能直接运行验证。 </think> 在**多分类问题**中应用SHAP进行特征解释时,需针对模型输出多个类别的特性调整方法。以下是具体解决方案及操作指南: --- ### **一、核心解决方案** 1. **输出结构处理** SHAP为多分类模型生成**三维张量**(样本 × 特征 × 类别),需按类别单独分析: ```python # 以XGBoost多分类模型为例 import shap explainer = shap.TreeExplainer(model) shap_values = explainer.shap_values(X_test) # 返回维度 [n_classes, n_samples, n_features] # 分析第0类别的特征贡献 shap.summary_plot(shap_values[0], X_test, plot_type="bar") ``` 2. **分类特征的特殊处理** 引用[1][3]指出,若模型不支持原生分类特征(如非CatBoost模型),需进行编码: - **独热编码**:适用于低基数特征,但会增加特征维度 - **目标编码**:需在交叉验证中完成以避免数据泄漏 ```python # 目标编码示例 from category_encoders import TargetEncoder encoder = TargetEncoder() X_train_encoded = encoder.fit_transform(X_train_cat, y_train) X_test_encoded = encoder.transform(X_test_cat) ``` --- ### **二、关键操作步骤** #### **1. 可视化方法选择** | **场景** | **推荐图表** | **代码示例** | |----------------|-----------------------|---------------------------------------| | 全局特征重要性 | 多类别条形图 | `shap.summary_plot(shap_values, X_test, plot_type="bar", class_names=classes)` | | 单样本解释 | 分类别瀑布图 | `shap.plots.waterfall(shap_values[class_idx][sample_idx])` | | 特征交互分析 | 依赖图(按类别着色) | `shap.dependence_plot("feature_A", shap_values[0], X_test)` | #### **2. 集成模型注意事项** - **树模型(XGBoost/LightGBM)**: 直接使用`shap.TreeExplainer`,需确认`model_output`参数: ```python # 输出概率而非原始值 explainer = shap.TreeExplainer(model, data=X_train, model_output="probability") ``` - **神经网络/线性模型**: 改用`KernelExplainer`或`DeepExplainer`: ```python # 适用于Keras模型 explainer = shap.DeepExplainer(model, X_train[:100]) ``` --- ### **三、典型问题解决方案** 1. **维度混淆错误** **问题**:直接对三维`shap_values`使用二分类可视化函数 **解决**:按类别切片后分析: ```python # 正确做法:分析第2类(索引从0开始) shap.plots.beeswarm(shap_values[2]) ``` 2. **分类特征解释模糊** **问题**:编码后特征可解释性下降 **解决**:引用[3]建议使用**SHAP聚合展示类别影响**: ```python # 计算气味特征的全局SHAP均值(针对第1类) odor_shap = shap_values[1][:, "odor"].mean(axis=0) print(f"气味类别贡献度:{odor_shap}") ``` --- ### **四、完整案例流程** ```python # 多分类SHAP分析框架 import shap from sklearn.datasets import load_iris from xgboost import XGBClassifier # 数据加载 & 模型训练 X, y = load_iris(return_X_y=True) model = XGBClassifier().fit(X, y) # SHAP计算 explainer = shap.TreeExplainer(model, model_output="probability") shap_values = explainer.shap_values(X) # 三维数组 (3, 150, 4) # 可视化:三类别的特征重要性对比 shap.summary_plot( shap_values, X, feature_names=["花萼长", "花萼宽", "花瓣长", "花瓣宽"], class_names=["山鸢尾", "变色鸢尾", "维吉尼亚鸢尾"], plot_type="bar" ) ``` 输出效果: ![多分类SHAP条形图](https://via.placeholder.com/400x200?text=三类特征重要性对比) --- ### **
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茶桁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值