You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在tidymodels工作流中集成kernelshap与shapviz?

从Tidymodels到KernelSHAP的实现(回归+分类通用)

1. 核心前提:提取Tidymodels封装的XGBoost模型

Tidymodels会把模型封装为Parsnip对象,需要先取出底层的xgb.Booster实例,回归和分类场景步骤一致:

  • 用extract_fit_parsnip()从调优后的工作流/拟合模型中提取Parsnip模型
  • 再用extract_fit_engine()取出底层XGBoost引擎对象

2. KernelSHAP通用代码实现

回归场景(以mtcars预测mpg为例)

# 加载依赖包
library(tidymodels)
library(kernelshap)
library(xgboost)
library(ggplot2)

# 假设你已完成调优,得到工作流tuned_wf
# 提取底层XGBoost模型
xgb_model <- tuned_wf %>% 
  extract_fit_parsnip() %>% 
  extract_fit_engine()

# 准备特征数据集(剔除响应变量mpg)
explain_data <- mtcars %>% select(-mpg)

# 定义预测函数:kernelshap要求输入特征矩阵,输出预测值
predict_fun_reg <- function(model, newdata) {
  predict(model, newdata = xgb.DMatrix(data.matrix(newdata)))
}

# 计算KernelSHAP值(用50个样本做背景提升计算速度)
ks_reg <- kernelshap(
  model = xgb_model,
  X = explain_data,
  predict_function = predict_fun_reg,
  bg_X = explain_data %>% slice_sample(n = 50)
)

# 全局SHAP可视化
plot(ks_reg, type = "beeswarm") # 特征影响分布蜂群图
plot(ks_reg, type = "importance") # 特征重要性排序图

分类场景适配

仅需修改预测函数,返回目标类别的概率(以二分类为例):

# 分类场景预测函数
predict_fun_class <- function(model, newdata) {
  # 返回正类概率,可根据模型分类逻辑调整索引
  predict(model, newdata = xgb.DMatrix(data.matrix(newdata)), type = "prob")[,2]
}

# 后续计算与可视化同回归场景,替换预测函数即可
ks_class <- kernelshap(
  model = xgb_model_class, # 分类任务的XGBoost模型
  X = explain_data_class,
  predict_function = predict_fun_class,
  bg_X = explain_data_class %>% slice_sample(n = 50)
)

plot(ks_class, type = "beeswarm")

3. Treeshap vs KernelSHAP:选型建议

  • Treeshap更适合树模型:
    • 专为树结构设计,计算速度远快于KernelSHAP(大数据/大模型场景优势明显)
    • 基于树结构精确计算SHAP值,无近似误差
    • 原生支持XGBoost、LightGBM、随机森林等树模型
  • KernelSHAP胜在通用性:
    • 支持任何模型(包括非树模型如神经网络)
    • 适合需要统一不同模型解释逻辑的场景

结论:如果你的模型是XGBoost这类树模型,优先选Treeshap;需要兼容非树模型时用KernelSHAP。

4. Treeshap实现对比

基于相同的tidymodels提取模型:

library(treeshap)
library(ggplot2)

# 提取底层XGBoost模型(步骤同前)
xgb_model <- tuned_wf %>% 
  extract_fit_parsnip() %>% 
  extract_fit_engine()

# 转换特征为矩阵格式(treeshap要求输入矩阵)
X_matrix <- data.matrix(explain_data)

# 计算Treeshap值
ts <- treeshap(xgb_model, X = X_matrix)

# 特征重要性可视化
plot_importance(ts)

# 手动实现蜂群图(treeshap无原生蜂群图,用ggplot2自定义)
shap_df <- ts$shaps %>% 
  as.data.frame() %>% 
  mutate(observation = row_number()) %>% 
  pivot_longer(-observation, names_to = "feature", values_to = "shap_value") %>% 
  left_join(
    explain_data %>% mutate(observation = row_number()) %>% pivot_longer(-observation, names_to = "feature", values_to = "feature_value"),
    by = c("observation", "feature")
  )

ggplot(shap_df, aes(x = feature_value, y = shap_value, color = feature)) +
  geom_jitter(alpha = 0.6) +
  facet_wrap(~feature, scales = "free_x") +
  labs(x = "特征值", y = "SHAP值") +
  theme_minimal()

内容的提问来源于stack exchange,提问作者Jacek Kotowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:39:53