- 1 简介
- 2 问题
- 3 数据分析
- 4 数据处理
- 5 lstm模型
- 6 训练模型
- 7 预测结果
详细代码见github: https://github.com/pjgao/lstm_helloworld/
1 简介
针对时间序列预测问题传统方法如ARIMA算法来拟合序列,综合考虑趋势、循环、季节等因素。
随着深度学习的飞速发展,基于RNN的方法在时间序列中的应用越来越广泛。
本文使用air passenger航空公司乘客数据集,来测试LSTM在时间序列中的预测:
2 问题
这里我们使用前n个月的乘客量来预测下一个月的乘客量
3 数据分析
航空公司乘客数据集为1949年1月到1960年12月每月乘客的数量
从图中可以看出该序列有一定的周期性。
4 数据处理
这里一定要注意,需要先对数据进行归一化处理,否则结果惨不忍睹!
这里我们使用sklearn中的MinMaxScaler
对数据进行归一化处理。这里使用过去10个月的数据来推断下一个月的数据,因此infer_seq_length
设置为10
#将数据归一化
scaler_minmax = MinMaxScaler()
data = scaler_minmax.fit_transform(df)
infer_seq_length = 10#用于推断的历史序列长度
d = []
for i in range(data.shape[0]-infer_seq_length):
d.append(data[i:i+infer_seq_length+1].tolist())
d = np.array(d)
d的shape为(134, 11, 1),前10维为已知序列,最后一维为预测值。
5 lstm模型
这里使用了两层lstm来搭建模型,lstm不宜太多。
- 因为有两层,所以第一层lstm的
return_sequences
要设置为True
,否则两层不会连接到一起。 - 因为我们预测的只有乘客数量一个变量,因此第一层lstm的输入shape为1
- lstm完了之后一般会接一个全连接层
Dense
用于输出,这里Dense
的激活函数为Linear
def create_model():
model = Sequential()
#输入数据的shape为(n_samples, timestamps, features)
#隐藏层设置为256, input_shape元组第二个参数1意指features为1
#下面还有个lstm,故return_sequences设置为True
model.add(LSTM(units=256,input_shape=(None,1),return_sequences=True))
model.add(LSTM(units=256))
#后接全连接层,直接输出单个值,故units为1
model.add(Dense(units=1))
model.add(Activation('linear'))
model.compile(loss='mse',optimizer='adam')
return model
6 训练模型
我们在选择前面一些天的数据作为训练集,在训练集上训练模型。
model.fit(X_train, y_train, batch_size=20,epochs=100,validation_split=0.1)
训练过程:
7 预测结果
红色虚线是LSTM在整个序列上的预测结果:
放大后观测部分: