问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Shap解释LSTM时序预测模型(全套代码分享)

创作时间:
作者:
@小白创作中心

Shap解释LSTM时序预测模型(全套代码分享)

引用
CSDN
1.
https://blog.csdn.net/weixin_43470958/article/details/144950979

用LSTM模型对从网上下载的数据进行预测,用12个时间步预测下个时间步的单个值,每个时间步有7个特征,所以是多步预测单步的模型,最后用shap库的DeepExplainer解释器(适用于深度学习模型,基于模型的梯度计算shap值)解释模型,并绘制自变量重要性汇总图、单变量依赖图等8类图片。

数据说明

源数据在“ETTh2.csv “文件中,如下所示,B列到H列是变量(共7个自变量),滑动窗口为12,序列长度为7,用12×7个数据预测下个时刻的OT(油温)。

源代码使用说明

代码文件是“LSTM-Shap.py“,建议用pycharm打开,运行结束后可以看到所有的图片和变量。建模流程说明如下:

第一步 导入python第三方库

首先保证你安装了下图中的库,如果运行报错,可以查看各个库的版本是否太低,大于等于我用的版本就可以

# 加载数据
import torch
from joblib import dump, load
import torch.utils.data as Data
import torch
import torch.nn as nn
import time
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import shap  

Python版本:3.10.0
Pycharm版本:2024.1
Shap库版本:0.46.0
Torch版本:2.4.1
Pandas版本:2.2.3
Sickit-learn版本:1.5.2
Matplotlib版本:1.9.2
Numpy版本:2.0.2
Joblib版本:1.4.2

第二步 建模过程

定义LSTM模型,输入数据的特征维度是7,输出的维度是1,隐藏层的特征维度为64

# 定义 LSTM模型
class LSTMModel(nn.Module):
    def __init__(self, input_dim, output_dim, hidden_layer_sizes):
        """
        params:
        input_dim          : 输入数据的维度
        output_dim         : 输出维度
        hidden_layer_sizes : lstm 隐层的数目和维度
        """
        super().__init__()
        # 参数
        self.output_dim = output_dim
        # LSTM参数
        self.num_layers = len(hidden_layer_sizes)  # lstm层数
        self.lstm_layers = nn.ModuleList()  # 用于保存LSTM层的列表
        # 定义第一层LSTM
        self.lstm_layers.append(nn.LSTM(input_dim, hidden_layer_sizes[0], batch_first=True))
        # 定义后续的LSTM层
        for i in range(1, self.num_layers):
                self.lstm_layers.append(nn.LSTM(hidden_layer_sizes[i-1], hidden_layer_sizes[i], batch_first=True))
        # 定义线性层
        self.linear  = nn.Linear(hidden_layer_sizes[-1], output_dim)
    def forward(self, input_seq):
        # 送入 LSTM 层
        #改变输入形状,lstm 适应网络输入[batch, seq_length, H_in]
        lstm_out = input_seq
        for lstm in self.lstm_layers:
            lstm_out, _ = lstm(lstm_out)  ## 进行一次LSTM层的前向传播
        predict = self.linear(lstm_out[:, -1, :]) # torch.Size([256, 1]  # 仅使用最后一个时间步的输出
        return predict  

第三步 shap解释

使用shap库中Gradient解释器解释LSTM时序预测模型,这里的model参数就是自己的模型,tensor_data是模型的输入,建模的时候要注意一点,那就是模型的输入变量只能有一个,就算是一定要有多个输入变量,也要将其合并,在模型里面再拆分,否则这里无法进行解释

# 假设 model 是你的 transformer或者其他的模型,tensor_data 是模型的输入数据,这里模型只能接受一个输入,建模的时候要注意一下
explainer = shap.GradientExplainer(model, tensor_data)
# 在解释之前将模型设置为训练模式
model.train()
# 计算 SHAP 值
shap_values = explainer.shap_values(tensor_data, check_additivity=False)
shap_values = np.squeeze(shap_values, 3)  

如果需要替换自己的模型,在226行将model换成自己的时序模型即可,同时也要根据自己设置的时间步、序列长度,修改画图api中切片数值

接下来是绘制各种图,共包括各个分类下自变量重要性汇总图、各个分类下自变量重要性柱状图、各个分类下单个变量的依赖图、各个分类下单个变量的力图、各个分类下单个样本的决策图、多个样本的决策图、热图、单个样本的解释图等。部分结果如下所示。

Pycharm中运行结果如下所示。

右上角是用shap解释transformer绘制的各种图片,
右下角是代码运行产生的各种变量,
左下角是交互命令行,运行结束之后可以继续输入命令,

代码纯手写,shap解释部分替大家踩了很多坑,终于整理出了可用的模板,谢谢理解~






© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号