长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,很好的解决了一般的RNN(循环神经网络)存在的长期依赖问题。具体的原理以及公式推导这里不做讲述,感兴趣的可以自行查阅相关资料,这里主要讲解使用tensorflow去搭建LSTM模型,以及模型的使用。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras import models,layers,losses,metrics,callbacks
#from keras.models import Sequentialquential
#from keras.layers import Dense,LSTM ,Droupt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'`
###数据读取与处理
path = ''
filename = path +'Alabama.csv'
df = pd.read_csv(filename,names =['date','confirmed_num','dead_num','cured_num'],encoding='gbk')
df = df.set_index('date')#设置索引
df.index = pd.DatetimeIndex(df.index)#将索引转换为时间序列
#空缺值处理
df = df.fillna(value=0)
df.head()
train_set = df[:150].iloc[:,0:3] #训练集,获取第一列的数据
test_set = df[150:].iloc[:,0:3].values #训练集,获取第一列的数据
train_set.shape
def lstm_Modle():
tf.keras.backend.clear_session()
x_input = layers.Input(shape=(None, 3), dtype=tf.float32)
x = layers.LSTM(5, return_sequences=True, input_shape=(None, 3))(x_input)
x = layers.LSTM(5, return_sequences=True, input_shape=(None, 3))(x)
x = layers.LSTM(5, return_sequences=True, input_shape=(None, 3))(x)
x = layers.LSTM(5, input_shape=(None, 3))(x)
x = layers.Dense(3)(x)
# 考虑到新增确诊,新增治愈,新增死亡人数数据不可能小于0,设计如下结构
# x = tf.maximum((1+x)*x_input[:,-1,:],0.0)
x = Block()(x_input, x)
model = models.Model(inputs=[x_input], outputs=[x])
model.summary()
return model
#训练模型
def train_modle(model,x_train,y_train):
import datetime
optimizer = tf.keras.optimizers.Adam(learning_rate=0.002)
model.compile(
optimizer=optimizer,
loss='mean_squared_logarithmic_error') # loss=MSPE(name = "MSPE")
logdir = r"D:\疫情Github数据" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tb_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)
# 如果loss在100个epoch后没有提升,学习率减半。
lr_callback = tf.keras.callbacks.ReduceLROnPlateau(monitor="loss", factor=0.5, patience=100)
# 当loss在200个epoch后没有提升,则提前终止训练。
stop_callback = tf.keras.callbacks.EarlyStopping(monitor="loss", patience=200)
callbacks_list = [tb_callback, lr_callback, stop_callback]
history = model.fit(x_train,y_train, epochs=300, callbacks=callbacks_list)
return history
#开始训练
import datetime
model = lstm_Modle()
history = train_modle(model,x_train,y_train)
pre_nums = model.predict(x_test)
pre_nums
#反归一化
stand_pre = sc.inverse_transform(pre_nums)
#print(stand_pre)#预测每日新增确诊人数
stand_prelist = [i[0] for i in stand_pre ]
stand_prelist = stand_prelist[:-1]
print(stand_prelist)
print(sc.inverse_transform(x_test[-1]))
y_test_t = df['confirmed_num'][142:182].values
print(y_test_t)#实际每日新增确诊人数
#绘制测试结果与预测结果
plt.plot(y_test_t,label = "新冠真实确诊人数")
plt.plot(stand_prelist,label = "新冠预测确诊人数")
plt.legend(["true","predict"])
plt.show()
最后的实验结果是经过多次反复的测试,其中包括数据的处理,数据的输入等不断地尝试,最后选择输入数据为三维数据,然后做差最后经过标准化等处理放入模型预测,由于测试版本较多,所以以上代码只是其中关键部分,供大家参考学习使用。