相关链接:
【ai竞赛系列】新冠疫情预测–卷积LSTM未来数值预测
【ai竞赛系列】新冠疫情预测–BiLSTM未来数值预测
【ai竞赛系列】新冠疫情预测–时序数据预测模型
第一次参加竞赛,评测新冠疫情未来预测。
给该地区历史几个月的新冠新增数据,然后预测未来一周的新冠。
官方给的历史数据如下:
本次采用的是堆叠LSTM算法,采用Keras实现的
堆叠LSTM 代码:
import numpy as np
import keras
from keras.layers import *
import matplotlib.pyplot as plt
import openpyxl
n_input = 7 # 输入的数据个数
n_output = 7 # 输出的数据个数
n_features = 1 # 每个数据含有的特征数量
step_lenth = 1 # 步长(时间序列的组合方式:若为1,表示1,2,3的方式组合;若为2,表示1,3,5的方式组合)
epochs_num=500 # 训练的迭代次数
# 堆叠LSTM
def encoder_decoder_LSTM_train(n_input,n_out,n_features,epochs_num,train_data,train_label,vaild_data,vaild_label):
model =keras.Sequential()
model.add(LSTM(3, activation='tanh', return_sequences=True, input_shape=(n_input, n_features)))
model.add(LSTM(3, activation='tanh', return_sequences=True, dropout=0.2, recurrent_dropout=0.2))
model.add(LSTM(3, activation='tanh', dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(n_out))
# 模型编译
model.compile(optimizer='adam',loss='mse')
model.fit(train_data,train_label,epochs=epochs_num,batch_size=None,shuffle=False,validation_data=(vaild_data,vaild_label))
return model
# 根据输入数据个数,输出数据个数,步长,特征数,将原始的时间序列数据制作成为训练数据和标签;
def to_supervised(data, n_input, n_out, n_features,step):
X, y = list(), list()
in_start = 0 # in_start:当前训练数据的首位数据的位置。
for _ in range(len(data)): # 遍历原始数据
in_end = in_start + (n_input-1)*step # inend:当前训练数据的最后一位数据的位置
out_end =in_end + step*n_out # out_end:当前标签的最后一位数据的位置
if (out_end) <= len(data): #若作为标签的最后一位数据在原始数据的范围内,则可以划分一组训练数据和标签
tmp_x = list()
for i in range(n_input):
if n_features == 1: # 当特征数为1,即只有单特征时间序列数据
element_x = list()
element_x.append(data[in_start + i * step]) #根据开始和结束位置存入训练数据(例如:[3,3,2,4,1])
tmp_x.append(element_x) # 再存入容器中,这样与多特征的格式统一(格式变为:[[3,3,2,4,1]])
else:
tmp_x.append(data[in_start+i*step,0:n_features]) # 多特征的时序数据,训练数据也存入多特征(例如3特征的时序数据:[[3,2,1],[4,7,5],[9,5,2]])
X.append(tmp_x) # 再将该组时序数据的容器存入训练数据的容器
y.append(data[in_end:in_end + step*n_out]) # 该组的标签存入标签容器中
in_start += 1 # 更新起始位置
return np.array(X),np.array(y)
# 载入数据集
file_path = '测评四-测试数据_52109.xlsx' # 输入数据路径(存储数据的xlsx文件或者csv文件)
wb = openpyxl.load_workbook(file_path)# 利用openpyxl将文件存入内存
sheet_case = wb['样例数据 1-测试数据']# sheet_case表示xlsx左下角数据所在的分页
colA = sheet_case['A']# 提取‘Sheet1’分页上第A列的数据
colB = sheet_case['B']# 提取‘Sheet1’分页上第B列的数据
# demo说明:案例中的xlsx文件中A列是日期,B列是新增的病例数。因此在预测未来数据的时候实际上只需要用到B列的病例数,并且时间先后有序排列。
org_case_count = [] # 存储原始病例数的容器
day_count = [] # 天数(从1开始累加)
date_record = []
count = 0
for data in colB:
if count == 0:
count += 1
continue
org_case_count.append(data.value) # 病例数
day_count.append(count) # 天数
date_record.append(colA[count].value)
count += 1
# # 归一化
max_val = max(org_case_count) # 取最大值
# print(max_val)
case_count=list() # 存储归一化后病例数的容器
for data in org_case_count:
tmp = data/max_val # 将所有病例数据都控制在0~1之间
case_count.append(tmp) # 添加归一化后病例数
# 制作训练集序列
case_count = np.array(case_count) # 转换为numpy.array格式
# 将数据制作成训练数据和标签
# 举例说明:
# 若n_input=7,n_output=3,则表示利用前7天的数据预测后3天的数据,训练数据是前7天的病例数,标签就是后3天的病例数
# 例如时序数据为:1,2,3,4,5,6,7,8,9,10,11,12,13~~
# 数据格式:
# 训练数据:case_data.shape = (分组的总数,每一组的元素数,特征数)
# 举例:case_data = [[[1],[2],[3],[4],[5],[6],[7]],[[2],[3],[4],[5],[6],[7],[8]] ~~~]
# 标签: case_label.shape = (分组的总数,每一组的元素数)
# 举例:case_label = [[8,9,10],[9,10,11] ~~]
case_data,case_label = to_supervised(case_count,n_input,n_output,n_features,step_lenth)
print(case_data.shape)
print(case_label.shape)
# 划分训练集和验证集。这里表示将后三组的训练数据和标签划为验证集
train_data = case_data[:-3]
train_label = case_label[:-3]
valid_data = case_data[-3:]
valid_label = case_label[-3:]
''' 模型训练 '''
model = encoder_decoder_LSTM_train(n_input, n_output, n_features, epochs_num,train_data, train_label, valid_data, valid_label)
''' 模型保存 '''
#(可选)保存成json格式的文件,只保存模型结构,而不包含其权重或配置信息
# save as JSON
json_string = model.to_json() # json格式的模型结构
open('my_model_architecture.json','w').write(json_string) # 写入到指定路径
#(可选)保存成yam格式的文件,只保存模型结构,而不包含其权重或配置信息
# save as YAML
yaml_string = model.to_yaml()
open('my_model_architectrue.yaml','w').write(yaml_string)
# 保存模型的权重
model.save_weights('my_model_weights.h5')
''' 模型预测 '''
# 取最后的n_input位作为
org_test_data = case_count[-n_input:] #
# print("org_test_data.shape =",org_test_data.shape)
test_data = list()
tmp = list()
for data in org_test_data:
element_x = list()
element_x.append(data)
tmp.append(element_x)
test_data.append(tmp)
test_data = np.array(test_data)
y_hat = model.predict(test_data).reshape((-1))
# print(y_hat.shape)
y_hat *= max_val
print("最终预测结果:",y_hat)
# 图像展示
fig = plt.figure()
plt.plot(y_hat)
plt.show()
最终效果:
代码打包:
提供了单特征时序数据预测和多特征时序数据预测,
并提供对应的样例数据可供参考: