时间序列-N_LSTM
文章目录数据代码多个LSTM-每个LSTM的输入特征时间窗不同,将其输出进行连接,再通过一个Dense层数据数据代码#!usr/bin/env python# -*- coding:utf-8 _*-"""@author: liujie@software: PyCharm@file: Multi-LSTM.py@time: 2020/11/14 11:36"""'''使用LSTM处理回归问题,每个
·
多个LSTM-每个LSTM的输入特征时间窗不同,将其输出进行连接,再通过一个Dense层
数据
代码
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: Multi-LSTM.py
@time: 2020/11/14 11:36
"""
'''
使用LSTM处理回归问题,每个输入特征的时间窗维度不一样,因此可以看作利用了多个LSTM特征提取器
'''
import warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error,mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,optimizers,metrics,losses
from keras.layers.recurrent import LSTM
# 读取数据
def read_data(filepath):
data = pd.read_excel(filepath,header=0)
data = data.iloc[:,1:12] # 数据
label = data.iloc[:,-1]
print('The Data : \n',data)
return data,label
# 归一化
def min_max_scaler(data,label):
label = np.array(label)
data_scaler = MinMaxScaler()
data = data_scaler.fit_transform(data)
label_scaler = MinMaxScaler()
label = label_scaler.fit_transform(label.reshape(-1, 1))
return data,label
# 转换为n_lstm的输入与输出
def n_lstm_data(data,data_length,delay_factor):
x0 = []
x1 = []
x2 = []
x3 = []
x4 = []
x5 = []
x6 = []
y = []
for index in range(max(delay_factor),data_length):
# 每一列数据的滞后参数不同
x0.append(data[index - delay_factor[0] : index + 1,0:1])
x1.append(data[index - delay_factor[1] : index + 1,1:2])
x2.append(data[index - delay_factor[2] : index + 1,2:3])
x3.append(data[index - delay_factor[3] : index + 1,3:4])
x4.append(data[index - delay_factor[4] : index + 1,4:5])
x5.append(data[index - delay_factor[5] : index + 1,5:6])
x6.append(data[index-0 : index +1,6:-1])
y.append(data[index,-1])
x0 = np.array(x0)
x1 = np.array(x1)
x2 = np.array(x2)
x3 = np.array(x3)
x4 = np.array(x4)
x5 = np.array(x5)
x6 = np.array(x6)
y = np.array(y)
print('x0~x6.shape,y.shape\n',x0.shape,x1.shape,x2.shape,x3.shape,x4.shape,x5.shape,x6.shape,y.shape)
return x0,x1,x2,x3,x4,x5,x6,y
# 构造数据,并分割数据集-根据原始数据集构建符合神经网络的数据集
def make_dataset(data,test_num):
feature_num = data.shape[1] - 1
data_length = data.shape[0]
# 转换成模型的输入
x0, x1, x2, x3, x4, x5, x6, y = n_lstm_data(data,data_length,delay_factor)
# 分割数据集
x0_train,x0_test = x0[:-test_num,:],x0[-test_num:,:]
x1_train,x1_test = x1[:-test_num,:],x1[-test_num:,:]
x2_train,x2_test = x2[:-test_num,:],x2[-test_num:,:]
x3_train,x3_test = x3[:-test_num,:],x3[-test_num:,:]
x4_train,x4_test = x4[:-test_num,:],x4[-test_num:,:]
x5_train,x5_test = x5[:-test_num,:],x5[-test_num:,:]
x6_train,x6_test = x6[:-test_num,:],x6[-test_num:,:]
y_train,y_test = y[:-test_num],y[-test_num:]
print('数据集长度:',data_length)
print('测试集长度:',test_num)
return x0_train,x0_test,x1_train,x1_test,x2_train,x2_test,x3_train,x3_test,x4_train,x4_test,x5_train,x5_test,x6_train,x6_test,y_train,y_test
# 建立N_LSTM模型
def n_lstm_model(delay_factor,rnn_units,dropout):
# 输入层
inputs0 = tf.keras.Input(shape=(delay_factor[0]+1,1))
inputs1 = tf.keras.Input(shape=(delay_factor[1]+1,1))
inputs2 = tf.keras.Input(shape=(delay_factor[2]+1,1))
inputs3 = tf.keras.Input(shape=(delay_factor[3]+1,1))
inputs4 = tf.keras.Input(shape=(delay_factor[4]+1,1))
inputs5 = tf.keras.Input(shape=(delay_factor[5]+1,1))
inputs6 = tf.keras.Input(shape=(1,4))
# LSTM层
rnn0 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs0)
rnn1 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs1)
rnn2 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs2)
rnn3 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs3)
rnn4 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs4)
rnn5 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs5)
rnn6 = LSTM(rnn_units,activation='relu',return_sequences=False)(inputs6)
# 将输入张量进行拼接
rnn = layers.Concatenate(axis=1)([rnn0,rnn1,rnn2,rnn3,rnn4,rnn5,rnn6])
# droupout层
dense = layers.Dropout(dropout)(rnn)
# 输出层
outputs = layers.Dense(1,activation='relu')(dense)
# 模型
model = tf.keras.Model(inputs=[inputs0,inputs1,inputs2,inputs3,inputs4,inputs5,inputs6],outputs=outputs)
return model
# 反归一化
def inverse_data(label_,data):
data = np.array(data).reshape(-1,1)
label_ = np.array(label_).reshape(-1,1)
data_scaler = MinMaxScaler()
data_1 = data_scaler.fit(label_)
data = data_scaler.inverse_transform(data)
data = data[:,0]
return data
# 展示
def plotdata(y_test,y_test_pred):
# rmse
rmse = np.sqrt(mean_squared_error(y_test,y_test_pred))
fig = plt.figure(figsize=(10,5))
fig.add_subplot()
plt.plot(y_test,'r--',label = 'test')
plt.plot(y_test_pred,'b-',label = 'predict')
plt.legend(loc = 'upper right')
plt.title('RMSE : %.4f'%rmse)
plt.show()
if __name__ == '__main__':
warnings.filterwarnings(action='ignore')
# 设置美化样式
plt.style.use('ggplot')
# 设置参数
test_num = 200
dropout = 0.1
epoch = 50 # 迭代次数
batch_size = 64 # 批处理数量
validation_split = 0.1 # 验证集比例
delay_factor = [0,11,4,1,0,12] # 滞后参数
# 读取数据
filepath = './data/总的数据集.xlsx'
data,label_ = read_data(filepath)
# 归一化
data,label = min_max_scaler(data,label_)
# 构造数据集
x0_train, x0_test, x1_train, x1_test, x2_train, x2_test, x3_train, x3_test, x4_train, x4_test, x5_train, x5_test, x6_train, x6_test, y_train, y_test = make_dataset(data,test_num)
# parameter
rnn_units = 8 # rnn神经元个数
save_model = 'n_lstm_model.h5'
# Model
model = n_lstm_model(delay_factor,rnn_units,dropout)
# 编译模型
model.compile(optimizer=optimizers.Adam(learning_rate=1e-3),
loss= tf.losses.MSE,
metrics = ['accuracy'])
# 展示模型结构
model.summary()
# 训练模型
# patience含义是:可以接受多少个epoch内monitor没有改善,之后训练将停止
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss',patience=10)
# 保存最好的模型-保存模型或模型权重
cp = keras.callbacks.ModelCheckpoint(filepath = save_model,monitor='val_loss',save_best_only=True)
history = model.fit(x = [x0_train,x1_train,x2_train,x3_train,x4_train,x5_train,x6_train],
y = y_train,
batch_size=batch_size,
epochs = epoch,
verbose=1,callbacks=[early_stop,cp],
validation_split = 0.1)
# 迭代图像
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(len(loss))
plt.plot(epochs_range, loss, label = 'Train Loss')
plt.plot(epochs_range, val_loss, label = 'Val Loss')
plt.legend(loc = 'upper right')
plt.title('Train and Val Loss')
plt.show()
model.load_weights(save_model) #加载最好的训练结果
# 测试集预测结果
y_test_predict = model.predict([x0_test,x1_test,x2_test,x3_test,x4_test,x5_test,x6_test])
# 反归一化
y_test = inverse_data(label_,y_test)
y_test_predict = inverse_data(label_,y_test_predict)
# 保存输出结果
pd.DataFrame(y_test_predict).to_csv('y_test_predict.csv')
# 画图显示
plotdata(y_test,y_test_predict)
更多推荐
所有评论(0)