Python数据分析案例62——基于MAGU-LSTM的时间序列预测(记忆增强门控单元)

案例背景

时间序列lstm系列预测在学术界发论文都被做烂了,现在有一个新的MAGU-LSTM层的代码,并且效果还可以,非常少见我觉得还比较创新,然后我就分享一下它的代码演示一下,并且结合模态分解等方法做一次全面的深度学习的时间序列模型对比。并且这次代码都把我的看家绝学——分位数神经网络都掏出来了。

记忆增强门控单元(Memory Augmentation Gating Unit, MAGU)是一种新型的神经网络层,用于增强长短期记忆网络(LSTM)的记忆能力。其设计通过在LSTM的标准结构中引入门控机制,来更有效地结合输入信息和历史记忆。具体而言,MAGU通过对输入和记忆状态进行加权和,再经过sigmoid激活函数,生成门控值。这一过程通过输入权重矩阵和记忆权重矩阵的乘积实现,偏置项用于调节输出。门控值用于动态调整输入与记忆的比例,使得增强后的输出能够更好地利用历史信息。MAGU的结构设计能够在处理长距离依赖时提供更强的记忆保持能力,从而提高模型在时间序列预测任务中的表现。通过在多个基准数据集上的实验,采用MAGU的LSTM模型展现出在预测精度和收敛速度上的显著提升,表明这种增强机制在复杂时间序列数据处理中的潜力和优势。


数据介绍

之前各种类型的时间序列都做过了,参考之前的文章:

Python数据分析案例24——基于深度学习的锂电池寿命预测_锂离子电池寿命预测 

Python数据分析案例25——海上风力发电预测(多变量循环神经网络)

Python数据分析案例41——基于CNN-BiLSTM的沪深300收盘价预测

Python数据分析案例42——基于Attention-BiGRU的时间序列数据预测

Python数据分析案例44——基于模态分解和深度学习的电负荷量预测(VMD+BiGRU+注意力)

Python数据分析案例50——基于EEMD-LSTM的石油价格预测

Python数据分析案例52——基于SSA-LSTM的风速预测(麻雀优化)

还有什么空气质量,太阳黑子,血糖浓度,交通流量,降雨量,锂电池寿命,风速,海上风电功率....实在做烂了.....

这次还是用最简单的就用股票的价格吧,沪深300去做时间序列预测。

我的这一套代码封装性太高,使用很简单,并且水论文非常通用,我看已经有人把我的这套代码拿去发论文了.....代码都已经开源了。我拿那个文章一看,这tm不是我写的代码嘛......没事能帮助大家就行,代码就是开源嘛,不过希望有的人别暗自当二道贩子去卖给别人割韭菜。

当然需要本次案例的全部代码文件和数据的同学还是可以参考:记忆增强门控单元


代码实现

由于这套代码我已经发过了太多太多次了,封装程度非常高,每次只是对里面的一些小模块做改动,所以说这套代码我本次案例不会写得很详细。可以从我以前的文章来了解我每个模块儿到底是干嘛用的。

首先导入包,深度学习框架用的是keras。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns
import os
import time
from datetime import datetime
import random as rn
import scipy.special as sc_special
plt.rcParams ['font.sans-serif'] ='SimHei'               #显示中文
plt.rcParams ['axes.unicode_minus']=False               #显示负号from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error,r2_scoreimport tensorflow as tf
import keras
import keras.backend as K
from keras.models import Model, Sequential
from keras.layers import Dense,Input, Dropout, Flatten,MaxPooling1D,Conv1D,SimpleRNN,LSTM,GRU,GlobalMaxPooling1D,Layer
from keras.layers import BatchNormalization,GlobalAveragePooling1D,MultiHeadAttention,AveragePooling1D,Bidirectional,LayerNormalization
from keras.callbacks import EarlyStopping

然后读取沪深300指数数据

data0=pd.read_excel('指数数据.xlsx',parse_dates=['trade_date'], usecols=['trade_date','close','open','high','low']).set_index('trade_date')[['open','high','low','close']].sort_index()
data0.head()

数据是从2014年7月份开始一直到2024年7月份结束的,10年的数据应该算是量还比较多的了吧。

然后自定义划分训练集,测试集,构造时间序列的数据函数。

def build_sequences(text, window_size=24):#text:list of capacityx, y = [],[]for i in range(len(text) - window_size):sequence = text[i:i+window_size]target = text[i+window_size]x.append(sequence)y.append(target)return np.array(x), np.array(y)def get_traintest(data,train_ratio=0.8,window_size=24):train_size=int(len(data)*train_ratio)train=data[:train_size]test=data[train_size-window_size:]X_train,y_train=build_sequences(train,window_size=window_size)X_test,y_test=build_sequences(test,window_size=window_size)return X_train,y_train[:,-1],X_test,y_test[:,-1]

数据进行标准化。

data=data0.to_numpy()
scaler = MinMaxScaler() 
scaler = scaler.fit(data[:,:-1])
X=scaler.transform(data[:,:-1])   y_scaler = MinMaxScaler() 
y_scaler = y_scaler.fit(data[:,-1].reshape(-1,1))
y=y_scaler.transform(data[:,-1].reshape(-1,1))

划分训练集和测试集

train_ratio=0.8     #训练集比例   
window_size=64      #滑动窗口大小,即循环神经网络的时间步长
X_train,y_train,X_test,y_test=get_traintest(np.c_[X,y],window_size=window_size,train_ratio=train_ratio)
print(X_train.shape,y_train.shape,X_test.shape,y_test.shape)

画图查看

y_test1 = y_scaler.inverse_transform(y_test.reshape(-1,1))
test_size=int(len(data)*(1-train_ratio))
plt.figure(figsize=(10,5),dpi=256)
plt.plot(data0.index[:-test_size],data0.iloc[:,-1].iloc[:-test_size],label='train',color='#FA9905')
plt.plot(data0.index[-test_size:],data0.iloc[:,-1].iloc[-(test_size):],label='test',color='#FB8498',linestyle='dashed')
plt.legend()
plt.ylabel('CSI 300',fontsize=14)
plt.xlabel('date',fontsize=14)
plt.show()

查看一下训练集和测试几的分别的时间

print(f'训练集开始时间{data0.index[:-test_size][0]},结束时间{data0.index[:-test_size][-1]}')
print(f'测试集开始时间{data0.index[-test_size:][0]},结束时间{data0.index[-test_size:][-1]}')

制定一下随机数种子函数跟回归问题常用的评价指标函数。

def set_my_seed():os.environ['PYTHONHASHSEED'] = '0'np.random.seed(1)rn.seed(12345)tf.random.set_seed(123)def evaluation(y_test, y_predict):mae = mean_absolute_error(y_test, y_predict)mse = mean_squared_error(y_test, y_predict)rmse = np.sqrt(mean_squared_error(y_test, y_predict))mape=(abs(y_predict -y_test)/ y_test).mean()r_2=r2_score(y_test, y_predict)return rmse, mae, mape ,r_2

我们来构建一个最简单的时间序列预测模型,我们都知道滑动平均模型ma,例如用过去5天的平均值来作为下一步要预测的值。但是我们可以极端一点用过去1天的平均值来作为下一步要预测的值,也就是说,用昨天的值来作为今天的值做预测,来看一下这么简单的预测模型的这个效果能有多少。

### 基准预测情况
result = pd.DataFrame()
result['t'] = data0['close']
# 生成第1列到第10列,每一列是t+1到t+10滑动窗口的值
for i in range(1, 6):result[f't+{i}'] = data0['close'].shift(i)
result=result.dropna()for t in result.columns[1:]:score=list(evaluation(result['t'], result[t]))s=[round(i,3) for i in score]print(f'{t}的预测效果为:RMSE:{s[0]},MAE:{s[1]},MAPE:{s[2]},R2:{s[3]}')

可以看到用过去1天的数据预测拟合优度就能够达到99.3%,mae为36,真的很小。

记住这么简单的一个模型的预测效果评价指标的数值,因为你待会儿会发现....很多神经网络都不如它........


好了,到了本次案例的主角了,MAGU-LSTM神经网络的定义。

class MemoryAugmentationGatingUnit(Layer):def __init__(self, units):super(MemoryAugmentationGatingUnit, self).__init__()self.units = unitsdef build(self, input_shape):self.w_input = self.add_weight(shape=(input_shape[-1], self.units),initializer='random_normal',trainable=True)self.w_memory = self.add_weight(shape=(self.units, self.units),initializer='random_normal',trainable=True)self.b = self.add_weight(shape=(self.units,), initializer='zeros',trainable=True)def call(self, inputs, memory):if inputs is None or memory is None:raise ValueError("输入和记忆不能为None")# 将 memory 扩展到与 inputs 形状匹配memory_expanded = tf.expand_dims(memory, axis=1)memory_expanded = tf.tile(memory_expanded, [1, tf.shape(inputs)[1], 1])# 计算门控值gate = tf.sigmoid(tf.matmul(inputs, self.w_input) + tf.matmul(memory_expanded, self.w_memory) + self.b)# 增强记忆augmented_memory = gate * memory_expanded + (1 - gate) * inputsreturn augmented_memory# 自定义LSTM模型
class CustomLSTMModel(Model):def __init__(self, lstm_units, mag_units, input_shape):super(CustomLSTMModel, self).__init__()self.lstm = LSTM(lstm_units, return_sequences=True, return_state=True)self.magu = MemoryAugmentationGatingUnit(mag_units)self.dropout = Dropout(0.2)self.dense = Dense(1)# 输入层self.build((None,) + input_shape)def call(self, inputs):lstm_output, h_state, c_state = self.lstm(inputs)# 使用最后的隐藏状态作为记忆memory = h_state# 通过记忆增强门控单元处理LSTM输出enhanced_output = self.magu(lstm_output, memory)dropout_output = self.dropout(enhanced_output)output = self.dense(dropout_output)return output

然后还要自定义注意力层

class AttentionLayer(Layer):    #自定义注意力层def __init__(self, **kwargs):super(AttentionLayer, self).__init__(**kwargs)def build(self, input_shape):self.W = self.add_weight(name='attention_weight',shape=(input_shape[-1], input_shape[-1]),initializer='random_normal',trainable=True)self.b = self.add_weight(name='attention_bias',shape=(input_shape[1], input_shape[-1]),initializer='zeros',trainable=True)super(AttentionLayer, self).build(input_shape)def call(self, x):# Applying a simpler attention mechanisme = K.tanh(K.dot(x, self.W) + self.b)a = K.softmax(e, axis=1)output = x * areturn outputdef compute_output_shape(self, input_shape):return input_shape

再自定义所有的模型的构建函数

def build_model(X_train,mode='LSTM',hidden_dim=[64,32]):set_my_seed()if mode=='MLP':model = Sequential()model.add(Flatten())model.add(Dense(hidden_dim[0],activation='relu',input_shape=(X_train.shape[-2],X_train.shape[-1])))model.add(Dense(hidden_dim[1],activation='relu'))#model.add(Dense(16,activation='relu'))model.add(Dense(1))elif mode=='RNN':model = Sequential()model.add(SimpleRNN(hidden_dim[0],return_sequences=True, input_shape=(X_train.shape[-2],X_train.shape[-1])))model.add(Dropout(0.2))model.add(SimpleRNN(hidden_dim[1])) model.add(Dropout(0.2))model.add(Dense(1))#     elif mode=='CNN':
#         model = Sequential()
#         model.add(Conv1D(hidden_dim[0],8,activation='relu',input_shape=(X_train.shape[-2],X_train.shape[-1])))
#         model.add(GlobalMaxPooling1D())
#         model.add(Dense(hidden_dim[1],activation='relu'))
#         model.add(Dense(1))elif mode=='LSTM':model = Sequential()model.add(LSTM(hidden_dim[0],return_sequences=True, input_shape=(X_train.shape[-2],X_train.shape[-1])))model.add(Dropout(0.2))model.add(LSTM(hidden_dim[1]))model.add(Dropout(0.2))model.add(Dense(1))elif mode=='GRU':model = Sequential()model.add(GRU(hidden_dim[0],return_sequences=True, input_shape=(X_train.shape[-2],X_train.shape[-1])))model.add(Dropout(0.2))model.add(GRU(hidden_dim[1]))model.add(Dropout(0.2))model.add(Dense(1))elif mode=='BiLSTM':model = Sequential()model.add(Bidirectional(LSTM(hidden_dim[0],return_sequences=True, input_shape=(X_train.shape[-2],X_train.shape[-1]))))model.add(Dropout(0.2))model.add(Bidirectional(LSTM(hidden_dim[1])))model.add(Dropout(0.2))model.add(Dense(1))elif mode=='BiGRU':model = Sequential()model.add(Bidirectional(GRU(hidden_dim[0],return_sequences=True, input_shape=(X_train.shape[-2],X_train.shape[-1]))))model.add(Dropout(0.2))model.add(Bidirectional(GRU(hidden_dim[1])))model.add(Dropout(0.2))model.add(Dense(1))elif mode == 'CustomLSTM':input_shape = (X_train.shape[-2], X_train.shape[-1])model = Sequential()model.add(Input(shape=input_shape))custom_lstm = CustomLSTMModel(lstm_units=hidden_dim[0], mag_units=hidden_dim[0], input_shape=input_shape)model.add(custom_lstm)model.add(LSTM(hidden_dim[1]))model.add(Dense(1))elif mode == 'BiGRU-Attention':model = Sequential()model.add(GRU(hidden_dim[0], return_sequences=True, input_shape=(X_train.shape[-2], X_train.shape[-1])))model.add(AttentionLayer())# Adding normalization and dropout for better training stability and performancemodel.add(LayerNormalization())#model.add(Dropout(0.1))model.add(GRU(hidden_dim[1]))model.add(Dense(1))elif mode == 'BiLSTM-Attention':model = Sequential()model.add(Bidirectional(LSTM(hidden_dim[0], return_sequences=True), input_shape=(X_train.shape[-2], X_train.shape[-1])))model.add(AttentionLayer())model.add(LayerNormalization())model.add(Dropout(0.2))model.add(Bidirectional(LSTM(hidden_dim[1])))#model.add(Flatten())model.add(Dense(hidden_dim[1],activation='relu'))model.add(Dense(1))elif mode == 'CustomBiLSTM-Attention':input_shape = (X_train.shape[-2], X_train.shape[-1])model = Sequential()model.add(Input(shape=input_shape))custom_lstm = CustomLSTMModel(lstm_units=hidden_dim[0], mag_units=hidden_dim[0], input_shape=input_shape)model.add(custom_lstm)model.add(AttentionLayer())model.add(Bidirectional(LSTM(hidden_dim[1])))model.add(Dense(1))elif mode=='CustomBiLSTM-Attention-QR': input_shape = (X_train.shape[-2], X_train.shape[-1])model = Sequential()model.add(Input(shape=input_shape))custom_lstm = CustomLSTMModel(lstm_units=hidden_dim[0], mag_units=hidden_dim[0], input_shape=input_shape)model.add(custom_lstm)model.add(AttentionLayer())model.add(Bidirectional(LSTM(hidden_dim[1])))model.add(Dense(1))elif mode=='EEMD-CustomBiLSTM-Attention-QR': input_shape = (X_train.shape[-2], X_train.shape[-1])model = Sequential()model.add(Input(shape=input_shape))custom_lstm = CustomLSTMModel(lstm_units=hidden_dim[0], mag_units=hidden_dim[0], input_shape=input_shape)model.add(custom_lstm)model.add(AttentionLayer())model.add(Bidirectional(LSTM(hidden_dim[1])))model.add(Dense(1))else:raise ValueError("Unsupported mode: " + mode)return model

可以看到我上面构建了大概十几种模型吧,都是待会儿会用的上的。

自定义损失函数,哇,分位数神经网络的核心就在于下面这一段分位数损失函数。

这可是我发论文的看家绝学,我连这都开源了......目前的市面上的文章做分位数神经网络的还真的很少,当然我也不怕大家学去了,因为我还有更厉害的方法发论文 [/龇牙]

def get_lossfun(model=None,loss_kind='QR',tau=0.5):#定义损失函数     if loss_kind=='QR':print('QRloss')def loss_func(y_true, y_pred):loss_1 = tf.constant(tau,dtype=tf.float32) ; loss_2 = tf.constant(1-tau,dtype=tf.float32)loss_mean = (tf.reduce_mean(tf.where(tf.greater(y_true, y_pred),(tf.abs(y_true-y_pred))*loss_1,(tf.abs(y_true-y_pred))*loss_2)))         return loss_meanmodel.compile(optimizer='Adam', loss=loss_func ,metrics=[tf.keras.metrics.RootMeanSquaredError(),"mape","mae"])else:print('mseloss')model.compile(optimizer='Adam', loss='mse' ,metrics=[tf.keras.metrics.RootMeanSquaredError(),"mape","mae"])return model

然后在自定义化损失和化拟合函数对比图的函数

def plot_loss(hist,imfname):plt.subplots(1,4,figsize=(16,2))for i,key in enumerate(hist.history.keys()):n=int(str('14')+str(i+1))plt.subplot(n)plt.plot(hist.history[key], 'k', label=f'Training {key}')plt.title(f'{imfname} Training {key}')plt.xlabel('Epochs')plt.ylabel(key)plt.legend()plt.tight_layout()plt.show()
def plot_fit(y_test, y_pred):plt.figure(figsize=(10,3.5))plt.plot(y_test, color="red", label="actual")plt.plot(y_pred, color="blue", label="predict")plt.title("拟合值和真实值对比")plt.xlabel("Time")plt.ylabel("data")plt.legend()plt.show()

自定义训练函数

df_eval=pd.DataFrame(columns=['RMSE','MAE','MAPE','R2'])
df_pred=pd.DataFrame()
def train_fun(mode='LSTM',batch_size=32,epochs=30,hidden_dim=[32,16],loss_kind='MSE',tau=0.5,verbose=1,show_loss=True,show_fit=True):set_my_seed()model=build_model(X_train,mode=mode,hidden_dim=hidden_dim)model=get_lossfun(model=model,loss_kind=loss_kind,tau=tau)earlystop = EarlyStopping(monitor='loss', min_delta=0, patience=5)s = time.time()#hist=model.fit(np.concatenate((X_train,X_test),axis=0),np.concatenate((y_train,y_test_s),axis=0),#batch_size=batch_size,epochs=epochs,callbacks=[earlystop],verbose=0)hist=model.fit(X_train,y_train,batch_size=batch_size,epochs=epochs,verbose=verbose,callbacks=[earlystop])#if show_loss:plot_loss(hist,mode)y_pred = model.predict(X_test)y_pred = y_scaler.inverse_transform(y_pred)#print(f'真实y的形状:{y_test.shape},预测y的形状:{y_pred.shape}')if show_fit:plot_fit(y_test1, y_pred)e=time.time()print(f"运行时间为{e-s}")score=list(evaluation(y_test1, y_pred))df_pred[mode]=y_pred.reshape(-1,)df_eval.loc[mode,:]=scores=[round(i,3) for i in score]print(f'{mode}的预测效果为:RMSE:{s[0]},MAE:{s[1]},MAPE:{s[2]},R2:{s[3]}')print("=======================================运行结束==========================================")return s

初始化参数:

batch_size=32
epochs=50
hidden_dim=[32,16]loss_kind='MSE'
verbose=0
show_fit=True
show_loss=True

开始训练各种神经网络的效果进行对比,首先训练mlp。

train_fun(mode='MLP',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)

RNN有点慢我就不运行了。

#train_fun(mode='RNN',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)

然后是LSTM

train_fun(mode='LSTM',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)

然后是GUR

train_fun(mode='GRU',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)

下面为了方便我下面模型就直接放一起了,结果先不截图了,后面会统一的来把所有的预测评价指标放在一起画图进行对比。

train_fun(mode='BiLSTM',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='BiGRU',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='CustomLSTM',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='BiGRU-Attention',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='BiLSTM-Attention',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='CustomBiLSTM-Attention',batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)
train_fun(mode='CustomBiLSTM-Attention-QR',loss_kind='QR',batch_size=batch_size,epochs=60,hidden_dim=hidden_dim)

是不是简单的一批..... 十几种模型就这样慢慢等就跑完了

不同模型就换个字符串参数就行。。


加入EEMD

如果要做模态分解的话,稍微麻烦一点,就得按照如下步骤加入下面的一些其他的东西。

from PyEMD import EMD, EEMD, CEEMDAN,Visualisation def plot_imfs(data, method='EEMD',max_imf=4):# 提取信号S = data[:,0]t = np.arange(len(S))# 根据选择的方法初始化分解算法if method == 'EMD':decomposer = EMD()imfs = decomposer.emd(S,max_imf=max_imf)elif method == 'EEMD':decomposer = EEMD()imfs = decomposer.eemd(S,max_imf=max_imf)elif method == 'CEEMDAN':decomposer = CEEMDAN()decomposer.ceemdan(S,max_imf=max_imf)imfs, res = decomposer.get_imfs_and_residue()else:raise ValueError("Unsupported method. Choose 'EMD', 'EEMD', or 'CEEMDAN'.")# 指定不同的颜色colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k']# 绘制原始数据和IMFsplt.figure(figsize=(8,len(imfs)+1), dpi=128)plt.subplot(len(imfs) + 1, 1, 1)plt.plot(t, S, 'k',lw=1)  # 使用黑色绘制原始数据plt.ylabel('raw data')# 绘制每个IMFfor n, imf in enumerate(imfs[::-1]):plt.subplot(len(imfs) + 1, 1, n + 2)plt.plot(t, imf, colors[n % len(colors)])plt.ylabel(f'IMF {n+1}')plt.tight_layout()plt.show()

画图可视化

plot_imfs(data0['close'].to_numpy().reshape(-1,1))

 模态分解

decomposer = EEMD()
imfs = decomposer.eemd(data0['close'].to_numpy(),max_imf=4)
imfs.shape

分解的模态放入数据框中

df_names=pd.DataFrame()
for i  in range(len(imfs)):a = imfs[::-1][i,:]dataframe = pd.DataFrame({'v{}'.format(i+1):a})df_names['imf'+str(i+1)]=dataframe
df_names

重新定义训练集和测试集的函数。

def get_traintest2(data,train_size=len(df_names),window_size=24):train=data[:train_size]test=data[train_size-window_size:]X_train,y_train=build_sequences(train,window_size=window_size)X_test,y_test=build_sequences(test,window_size=window_size)return X_train,y_train,X_test,y_test

定义评估函数

def evaluation_all(df_eval_all,mode,show_fit=True):df_eval_all['all_pred']=df_eval_all.iloc[:,1:].sum(axis=1)#MAE2,RMSE2,MAPE2=evaluation(df_eval_all['actual'],df_eval_all['all_pred'])df_eval_all.rename(columns={'all_pred':'predict'},inplace=True)if show_fit:df_eval_all.loc[:,['predict','actual']].plot(figsize=(12,4),title=f'{mode} predict')score=list(evaluation(df_eval_all['actual'], df_eval_all['predict']))    print('总体预测效果:')s=[round(i,3) for i in score]print(f'{mode}的预测效果为:RMSE:{s[0]},MAE:{s[1]},MAPE:{s[2]},R2:{s[3]}')df_pred[mode]=df_eval_all['predict'].to_numpy().reshape(-1,)df_eval.loc[mode,:]=score

定义模态分解下的训练函数

def train_fuc2(mode='EEMD-CustomBiLSTM-Attention-QR',train_rat=0.8,window_size=64,batch_size=32,epochs=50,loss_kind='QR',hidden_dim=[32,16],tau=0.5,show_imf=True,show_loss=True,show_fit=True):df_all=df_names.copy()train_size=int(len(df_all)*train_rat)df_pred_all=pd.DataFrame(data0['close'].values[train_size:],columns=['actual'])for i,name in  enumerate(df_names):print(f'正在训练第:{name}条分量')data=df_all[name]X_train,y_train,X_test,y_test=get_traintest2(data.values,window_size=window_size,train_size=train_size)#归一化scaler = MinMaxScaler() scaler = scaler.fit(X_train) X_train = scaler.transform(X_train)  X_test = scaler.transform(X_test)scaler_y = MinMaxScaler() scaler_y = scaler_y.fit(y_train.reshape(-1,1)) y_train = scaler_y.transform(y_train.reshape(-1,1))set_my_seed()X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))print(X_train.shape, y_train.shape, X_test.shape,y_test.shape)model=build_model(X_train=X_train,mode=mode,hidden_dim=hidden_dim)model=get_lossfun(model=model,loss_kind=loss_kind,tau=tau)earlystop = EarlyStopping(monitor='loss', min_delta=0, patience=5)start = datetime.now()hist=model.fit(X_train, y_train,batch_size=batch_size,epochs=epochs,verbose=0,callbacks=[earlystop])if show_loss:plot_loss(hist,name)#预测y_pred = model.predict(X_test)y_pred =scaler_y.inverse_transform(y_pred)#print(y_pred.shape)end = datetime.now()if show_imf:df_eval=pd.DataFrame()df_eval['actual']=y_testdf_eval['pred']=y_preddf_eval.plot(figsize=(7,3))plt.show()score=list(evaluation(y_test=y_test, y_predict=y_pred))s=[round(i,3) for i in score]print(f'{mode}的{name}分量的效果:RMSE:{s[0]},MAE:{s[1]},MAPE:{s[2]},R2:{s[3]}')time=end-startdf_pred_all[name+'_pred']=y_predprint(f'running time is {time}')print('============================================================================================================================')evaluation_all(df_pred_all,mode=mode,show_fit=True)

开始训练模态分解之后的神经网络模型。

train_rat=0.8
set_my_seed()
train_fuc2(mode='EEMD-CustomBiLSTM-Attention-QR',window_size=window_size,train_rat=train_rat,batch_size=batch_size,epochs=epochs,hidden_dim=hidden_dim)

结果太长我就不展示完了,这里只展示部分分量的预测效果。

由于我在写前面训练函数的时候,已经把所有的评价指标都已经存下来了,我们下面可以直接查看这个预测结果对比就可以了。

df_eval.astype('float').style.bar(color='pink')

结果其实一目了然,我也懒得写分析,让gpt同学帮我们写分析吧。

“模型性能排序:

  • 在所有模型中,EEMD-CustomBiLSTM-Attention-QR模型的性能最佳,其在所有误差指标(RMSE、MAE、MAPE)上都取得了最低值,并且具有最高的决定系数(R² = 0.982109),表明该模型在预测准确性上最优。

  • CustomBiLSTM-Attention-QR和CustomBiLSTM-Attention分别位列第二和第三,显示出在CustomLSTM及其他模型之上的性能优势。

  1. 误差分析:

  • RMSE(均方根误差)和MAE(平均绝对误差)作为误差度量,数值越低,代表模型的预测结果与实际值之间的偏差越小。EEMD-CustomBiLSTM-Attention-QR在这两个指标上均表现出色,表明其预测值与实际值的偏差最小。

  • MAPE(平均绝对百分比误差)是一个衡量预测准确度的无量纲指标,EEMD-CustomBiLSTM-Attention-QR也在此指标上表现突出,进一步确认了其优越的预测性能。

  1. 模型结构影响:

  • 引入EEMD(集合经验模态分解)和Attention机制显然提升了CustomBiLSTM模型的表现。特别是EEMD的使用,可能有助于处理输入数据中的非平稳性和噪声,增强了预测的稳定性和准确性。

  • 添加Attention机制也明显改善了模型捕获重要时序特征的能力,从而提升预测效果。

  1. 传统模型对比:

  • 传统的LSTM和MLP(多层感知器)模型的表现相对较差,尤其是MLP,显示出在处理时间序列数据时,未能像复杂结构(如BiLSTM或GRU)那样有效地捕捉时序依赖特性。

  • 相比之下,BiLSTM和BiGRU通过双向结构捕获序列信息的能力有所增强,但仍低于引入Attention和其他增强机制的模型。

  1. R²值分析:

  • R²值为模型的解释力提供了一个定量指标,接近1的值表示模型能够很好地解释数据的变异性。EEMD-CustomBiLSTM-Attention-QR的R²值最高,表明其模型对数据波动的解释能力最强。

整体而言,综合使用EEMD、BiLSTM、Attention和QR等技术的模型相较于基础的序列模型具有显著的性能提升。这种组合通过增强对非线性、噪声和时序依赖的处理能力,显著提高了模型的预测准确性和稳定性。”

我们对预测结果简单画个图看看吧

df_pred.plot()

我们把预测结果储存,这样就可以去写论文,画各种图,计算各种指标了。

df_pred.to_csv('预测结果.csv',index=False)

创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制类似的代码可私信)

当然需要本次案例的全部代码文件和数据的同学还是可以参考:记忆增强门控单元

以往的文章可以在这里查看:数据分析案例合集

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462734.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++泛型编程

一、什么是泛型编程 泛型编程 是一种编程范式,它通过编写可以处理多种数据类型的代码来实现代码的灵活复用。泛型编程主要通过模板来实现。 比如我们日常使用的容器类型vector就应用了模板来实现其通用性,我们在使用时可以通过传入型别创建对应的动态数…

ServletContext,Cookie,HttpSession的使用

ServletContext对象 ServletContext对象官方也称servlet上下文。服务器会为每一个Web应用创建一个ServletContext对象,这个对象全局唯一,而且Web应用中所有的Servlet都共享这个对象。 ServletContext对象的作用 相对路径转绝对路径 servletContext.g…

如何封装一个可取消的 HTTP 请求?

前言 你可能会好奇什么样的场景会需要取消 HTTP 请求呢? 确实在实际的项目开发中,可能会很少有这样的需求,但是不代表没有,比如: 假如要实现上述这个公告栏,每点击一个 tab 按钮就会切换展示容器容器中…

前端笔试新问题总结

记录总结下最近遇到的前端笔试新问题 目录 一、操作数组方法 1.Array.isArray(arr) 2.Object.prototype.toString.call(arr) "[object Array]" 3.arr instanceof Array 1)跨帧问题 2)修改Array.prototype 3)模拟数组的对象…

玩转Hugging Face/魔搭社区/魔乐社区”教程

2.1 HF 平台 2.1.1 注册Hugging Face 平台 (需要魔法上网) Hugging Face 最初专注于开发聊天机器人服务。尽管他们的聊天机器人项目并未取得预期的成功,但他们在GitHub上开源的Transformers库却意外地在机器学习领域引起了巨大轰动。如今&…

Chrome与夸克谁更节省系统资源

在当今数字化时代,浏览器已经成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐,我们都依赖于浏览器来访问互联网。然而,不同的浏览器在性能和资源消耗方面存在差异。本文将探讨Chrome和夸克两款浏览器在系统资源消耗方面的表现…

【OJ题解】C++实现反转字符串中的每个单词

💵个人主页: 起名字真南 💵个人专栏:【数据结构初阶】 【C语言】 【C】 【OJ题解】 题目要求:给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。 题目链接: 反转字符串中的所…

Vue 学习随笔系列十三 -- ElementUI 表格合并单元格

ElementUI 表格合并单元格 文章目录 ElementUI 表格合并单元格[TOC](文章目录)一、表头合并二、单元格合并1、示例代码2、示例效果 一、表头合并 参考&#xff1a; https://www.jianshu.com/p/2befeb356a31 二、单元格合并 1、示例代码 <template><div><el-…

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)4.3-4.4

目录 第四门课 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;第四周 特殊应用&#xff1a;人脸识别和神经风格转换&#xff08;Special applications: Face recognition &Neural style transfer&#xff09;4.3 Siamese 网络&#xff08;Siamese net…

vue data变量之间相互赋值或进行数据联动

摘要&#xff1a; 使用vue时开发会用到data中是数据是相互驱动&#xff0c;经常会想到watch,computed&#xff0c;总结一下&#xff01; 直接赋值&#xff1a; 在 data 函数中定义的变量可以直接在方法中进行赋值。 export default {data() {return {a: 1,b: 2};},methods: {u…

安装Blender并使用

前言 该系列记录了如何用Blenderpro来构建自己的场景数据集&#xff0c;从环境搭建到后期构建数据集的整个流程 本文章是第一部分&#xff0c;BlenderPrc2的安装以及环境配置 部分参考https://blog.csdn.net/weixin_49521551/article/details/121573334 官方文档https://dlr…

百度SEO分析实用指南 提升网站搜索排名的有效策略

内容概要 在数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已经成为提升网站曝光度的关键工具。本指南将带您了解SEO的基本知识&#xff0c;帮助您在复杂的网络环境中立足。我们将从关键词优化开始&#xff0c;重点讲解如何选择合适的关键词来提高搜索引擎排…

【蔬菜识别】Python+深度学习+CNN卷积神经网络算法+TensorFlow+人工智能+模型训练

一、介绍 蔬菜识别系统&#xff0c;本系统使用Python作为主要编程语言&#xff0c;通过收集了8种常见的蔬菜图像数据集&#xff08;‘土豆’, ‘大白菜’, ‘大葱’, ‘莲藕’, ‘菠菜’, ‘西红柿’, ‘韭菜’, ‘黄瓜’&#xff09;&#xff0c;然后基于TensorFlow搭建卷积神…

ESP8266 自定义固件烧录-Tcpsocket固件

一、固件介绍 固件为自定义开发的一个适配物联网项目的开源固件&#xff0c;支持网页配网、支持网页tcpsocket服务器配置、支持串口波特率设置。 方便、快捷、稳定&#xff01; 二、烧录说明 固件及工具打包下载地址&#xff1a; https://download.csdn.net/download/flyai…

探秘机器学习算法:智慧背后的代码逻辑

1、 线性回归 线性回归是预测连续变量的一种简单而有效的方法。其数学模型假设因变量 y 与自变量 x 之间存在线性关系&#xff0c;用公式表示为&#xff1a; ​ Python代码实现 import numpy as np from sklearn.linear_model import LinearRegression import matplotlib.…

【合肥工业大学】操作系统 习题解析 作业答案(仅作学习与交流/侵删)

第一章习题解析 1&#xff0e;设计现代OS的主要目标是什么&#xff1f; 答&#xff1a;&#xff08;1&#xff09;有效性 &#xff08; 2&#xff09;方便性 &#xff08; 3&#xff09;可扩充性 &#xff08; 4&#xff09;开放性 2&#xff0e; OS 的作用可表现在哪几个方…

要在微信小程序中让一个 `view` 元素内部的文字水平垂直居中,可以使用 Flexbox 布局

文章目录 主要特点&#xff1a;基本用法&#xff1a;常用属性&#xff1a; 要在微信小程序中让一个 view 元素内部的文字水平垂直居中&#xff0c;可以使用 Flexbox 布局。以下是如何设置样式的示例&#xff1a; .scan-button {display: flex; /* 启用 Flexbox 布局 */justify…

JSON交互处理

目录 一、什么是JSON 二、JSON和JavaScript对象互转 ​三、Controller返回JSON数据 3.1 使用Jackson 编写Controller 1. 一个对象 2. 多个对象 3. 输出时间对象 4. 优化&#xff1a;抽取为工具类 一、什么是JSON Json是JavaScript对象的字符串表示法&#xff0c;它用…

WPF+MVVM案例实战(十二)- 3D数字翻牌计时实现

文章目录 1、运行效果2、功能实现1、文件创建2、控件代码实现3、控件引用与菜单实现1.引用用户控件2.按钮菜单3、计时器界面实现4、源代码获取1、运行效果 3D数字翻牌计时 2、功能实现 1、文件创建 打开项目 Wpf_Examples ,在用户控件 UserControlLib 中创建 NumberFoldi…

无人机多机编队控制算法详解!

一、主要算法类型 长机-僚机法&#xff08;Leader-Follower&#xff09; 原理&#xff1a;通过设定一架无人机作为长机&#xff08;领航者&#xff09;&#xff0c;其他无人机作为僚机&#xff08;跟随者&#xff09;&#xff0c;僚机根据长机的信息来调整自身的飞行状态&#…