✨ 欢迎关注 ✨
本节介绍: 通过TOPSIS赋权优化多模型融合的SHAP解释提升模型透明性 ,作者根据个人对机器学习的理解进行代码实现与图表输出,仅供参考。 完整 数据和代码将在稍后上传至交流群,成员可在交流群中获取下载。需要的朋友可关注公众文末提供的获取方式。 获取 前请咨询,避免不必要的问题
✨ 文献信息 ✨
文献中的热图展示了在预测脓毒性休克患者28天死亡风险时,最优GBDT子模型的SHAP特征重要性。SHAP值通过从红色(高重要性)到蓝色(低重要性)的渐变色表示,提供了哪些临床特征对预测结果影响最大的见解。特征如NOR(复苏次数)、DOMV(机械通气时间)、LOC-ICU(ICU住院天数)等在预测死亡风险中发挥了重要作用。这一可视化帮助理解模型的决策过程,突出显示了对死亡预测有显著影响的关键特征,强调的是SHAP是针对最优模型做的
由于融合模型本身不具有特征贡献排名,在使用SHAP解释最优模型之后,对各个子模型(基于树的模型)的特征重要性贡献排名进行汇总。表格中列出了多个特征(如DOMV、NOR、LOS-ICU等),并对每个特征在不同模型(如决策树(DT)、随机森林(RF)、XGBoost(XGB)、LightGBM(LGBM)、GBDT)的贡献进行了排序,帮助理解每个特征在多模型融合中的相对贡献,可以发现的是该方法得到的贡献排名是和SHAP针对最优模型得到的排名是相差不大的
✨ 基础代码 ✨
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
import warnings
# 忽略所有警告
warnings.filterwarnings("ignore")
path = r"2025-8-9公众号Python机器学习AI.xlsx"
df = pd.read_excel(path)
from sklearn.model_selection import train_test_split
# 划分特征和目标变量
X = df.drop(['Electrical_cardioversion'], axis=1)
y = df['Electrical_cardioversion']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.3,
random_state=250807,
stratify=df['Electrical_cardioversion']
)
读取存储在Excel文件中的数据,并将其划分为特征(X)和目标变量(y)。然后,使用train_test_split将数据按照70%的训练集和30%的测试集进行划分,并设置随机种子,确保每次运行时数据划分的结果一致,保证模型训练的可复现性。需要注意的是,这里并没有重新训练模型,而是直接调用前面已经训练好的模型进行预测或评估
import joblib
# 逐个加载每个模型
BernoulliNB = joblib.load('BernoulliNB.pkl')
DecisionTree = joblib.load('DecisionTree.pkl')
GradientBoosting = joblib.load('GradientBoosting.pkl')
LightGBM = joblib.load('LightGBM.pkl')
RandomForest = joblib.load('RandomForest.pkl')
SVM = joblib.load('SVM.pkl')
XGBoost = joblib.load('XGBoost.pkl')
ensemble_model = joblib.load('ensemble_model.pkl')
通过joblib.load加载之前训练好的多个子模型(如BernoulliNB、DecisionTree等)以及融合模型(ensemble_model),以便在后续的步骤中进行预测或评估,具体模型训练可以参考往期文章——顶刊复现:基于TOPSIS赋权的多模型融合方法及其优化应用提升模型预测性能
from sklearn.metrics import roc_auc_score
# 定义计算AUC的函数
def calculate_auc(model, X_test, y_test):
y_pred_proba = model.predict_proba(X_test)[:, 1] # 获取类别1的预测概率
return roc_auc_score(y_test, y_pred_proba)
# 计算每个模型的AUC值
roc_auc_BernoulliNB = calculate_auc(BernoulliNB, X_test, y_test)
roc_auc_DecisionTree = calculate_auc(DecisionTree, X_test, y_test)
roc_auc_GradientBoosting = calculate_auc(GradientBoosting, X_test, y_test)
roc_auc_LightGBM = calculate_auc(LightGBM, X_test, y_test)
roc_auc_RandomForest = calculate_auc(RandomForest, X_test, y_test)
roc_auc_SVM = calculate_auc(SVM, X_test, y_test)
roc_auc_XGBoost = calculate_auc(XGBoost, X_test, y_test)
roc_auc_ensemble_model = calculate_auc(ensemble_model, X_test, y_test)
# 输出每个模型的ROC AUC值
print(f"BernoulliNB ROC AUC: {roc_auc_BernoulliNB}")
print(f"DecisionTree ROC AUC: {roc_auc_DecisionTree}")
print(f"GradientBoosting ROC AUC: {roc_auc_GradientBoosting}")
print(f"LightGBM ROC AUC: {roc_auc_LightGBM}")
print(f"RandomForest ROC AUC: {roc_auc_RandomForest}")
print(f"SVM ROC AUC: {roc_auc_SVM}")
print(f"XGBoost ROC AUC: {roc_auc_XGBoost}")
print(f"ensemble_model ROC AUC: {roc_auc_ensemble_model}")
定义一个函数来计算每个模型的ROC AUC值,并依次计算并输出每个子模型和融合模型在测试集上的AUC性能指标,当然在前面文章模型构建部分给出了更多的模型详细评价指标,这里只是为了再次确定最优子模型,进行SHAP解释
BernoulliNB ROC AUC: 0.8096153846153846
DecisionTree ROC AUC: 0.6626923076923077
GradientBoosting ROC AUC: 0.8538461538461538
LightGBM ROC AUC: 0.856153846153846
RandomForest ROC AUC: 0.8730769230769231
SVM ROC AUC: 0.7884615384615385
XGBoost ROC AUC: 0.86
ensemble_model ROC AUC: 0.8861538461538462
从输出的ROC AUC值可以看出,RandomForest 模型的AUC值为0.8731,在所有单个子模型中表现最优。因此,RandomForest是最优的子模型。此外,ensemble_model(融合模型)的 AUC 值为0.8862,稍微高于单个子模型,说明融合模型在整体上表现最佳
import shap
explainer = shap.TreeExplainer(RandomForest)
shap_values = explainer.shap_values(X_test)
# 创建 shap.Explanation 对象
shap_explanation = shap.Explanation(shap_values[:,:,1], # 绘制类别1
base_values=explainer.expected_value,
data=X_test, feature_names=X_test.columns)
# 绘制热图
shap.plots.heatmap(shap_explanation)
对最优子模型进行SHAP解释,从热图中可以观察到每个特征对模型输出的影响。热图的颜色从红色到蓝色变化,表示每个特征在各个样本上的SHAP值大小:
红色:表示该特征对预测结果有较大的正向影响,即该特征的增加会增加预测值。蓝色:表示该特征对预测结果有较大的负向影响,即该特征的增加会减少预测值。横轴:代表不同的样本(实例),每列是一个不同的测试样本。纵轴:代表模型中的不同特征,显示了每个特征在不同样本上的贡献,最右侧的柱状是表示该特征的整体贡献度,顶部折线为预测值变化
from sklearn.preprocessing import MinMaxScaler
feature_names = X_test.columns
# 存储每个模型的特征重要性分数
model_importances = {}
# 定义模型
models = {
"DecisionTree": DecisionTree,
"GradientBoosting": GradientBoosting,
"LightGBM": LightGBM,
"RandomForest": RandomForest,
"XGBoost": XGBoost
}
# 提取每个模型的特征重要性分数
for model_name, model in models.items():
if hasattr(model, 'feature_importances_'):
model_importances[model_name] = model.feature_importances_
# 将字典转换为 DataFrame,按特征名和模型名排列
importance_df = pd.DataFrame(model_importances, index=feature_names)
# 为了避免出现0或1,可以对每个特征的值加上一个小的常量
importance_df += 1e-6 # 添加一个小的常量,避免归一化结果为0
# 使用 MinMaxScaler 归一化特征重要性分数
scaler = MinMaxScaler()
normalized_importance_df = pd.DataFrame(scaler.fit_transform(importance_df),
columns=importance_df.columns,
index=importance_df.index)
# 计算每一行的特征重要性之和,作为 SUM 列
normalized_importance_df['SUM'] = normalized_importance_df.sum(axis=1)
# 根据 SUM 列的值进行排名,使用 sort_values 按照 SUM 排序,并且加上 Rank 列
normalized_importance_df['Rank'] = normalized_importance_df['SUM'].rank(ascending=False, method='min')
# 根据 Rank 列进行排序
normalized_importance_df = normalized_importance_df.sort_values(by='Rank', ascending=True)
normalized_importance_df.head(10)
计算了多个子模型(树模型)的特征重要性,使用MinMaxScaler归一化后,添加特征重要性之和(SUM)和排名(Rank)列,并根据排名对特征进行排序,以确定每个特征在不同模型中的综合重要性
进行归一化处理的主要原因是LightGBM的feature_importances_ 计算方式与其他树模型(如DecisionTree、GradientBoosting、RandomForest、XGBoost)的计算方式不同,导致它们的特征重要性分数具有不同的量纲。这种差异可能会影响不同模型之间特征重要性分数的直接比较,尤其是在进行加权求和(SUM)时,可能会引入偏差
树模型的特征重要性汇总排名为 NtproBNP、LeftAtrialDiam、BMI、Cr、SystolicBP等,通过SHAP方法进行最优子模型解释时的排名为 NtproBNP、LeftAtrialDiam、AtrialFibrillationType、BMI、Hb等
可以发现通过树模型获取的特征排名与通过SHAP解释的排名可能存在差异,但是对于排名靠前的特征还是一致的,说明这种方法有一定的参考价值,当然文献在这里的模型解释就到此结束,并没有对融合模型进行一个整体的解释,下一期文章将对其进行扩展如何在融合模型整体上进行解释
该文献完整复现流程参考这几期文章——digital medicine复现:缺失值过滤、方差过滤、缺失值插补、相关系数与逐步特征选择、顶刊复现:基于TOPSIS赋权的多模型融合方法及其优化应用提升模型预测性能
当然,公众号中还有更多机器学习期刊实战技巧,您可以通过历史文章进行检索和阅读,关注公众号,点击“发信息”>“历史文章”即可搜索公众号所有文章信息
✨ 该文章案例 ✨
在上传至交流群的文件中,像往期文章一样,将对案例进行逐步分析,确保读者能够达到最佳的学习效果。内容都经过详细解读,帮助读者深入理解模型的实现过程和数据分析步骤,从而最大化学习成果。
同时,结合提供的免费AI聚合网站进行学习,能够让读者在理论与实践之间实现融会贯通,更加全面地掌握核心概念。
✨ 介绍 ✨
本节介绍到此结束,有需要学习数据分析和Python机器学习相关的朋友欢迎到淘宝店铺:Python机器学习AI,下方提供淘宝店铺二维码获取作者的公众号合集。截至目前为止,合集已包含近300多篇文章,购买合集的同时,还将提供免费稳定的AI大模型使用。
更新的内容包含数据、代码、注释和参考资料。 作者仅分享案例项目,不提供额外的答疑服务。项目中将提供详细的代码注释和丰富的解读,帮助您理解每个步骤 。 获取 前请咨询,避免不必要的问题。
✨ 群友反馈 ✨
✨ 淘宝店铺 ✨
请大家打开淘宝扫描上方的二维码,进入店铺,获取更多Python机器学习和AI相关的内容 ,希望能为您的学习之路提供帮助!
往期推荐
期刊复现:连续数据与分类数据共存的SHAP可视化散点图与箱形图组合形式
期刊复现:多分类任务如何拆分为二分类任务并进行堆叠预测提高模型预测性能
期刊配图:SHAP值分析模型可解释性在柱状图与蜂窝图中的进阶组合展示
期刊配图:通过堆叠Mean|SHAP|展示不同区间对模型贡献度的可视化分析
期刊复现:利用UMAP降维算法可视化深度学习随着训练次数的增加模型区分能力的变化
期刊配图:PCA、t-SNE与UMAP三种降维方法简化高维数据的展示应用对比
Science期刊复现:分类、回归与Shap分析多角度揭示同一数据集变量对目标的影响
多模型SHAP+PDP解读Stacking集成模型:从基学习器到元学习器的可解释性与模型调参实现
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
个人观点,仅供参考