• 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月每月乘客的数量

lstm预测结果回归 lstm 回归预测_LSTM


从图中可以看出该序列有一定的周期性。

lstm预测结果回归 lstm 回归预测_lstm预测结果回归_02

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维为已知序列,最后一维为预测值。

lstm预测结果回归 lstm 回归预测_LSTM_03

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

lstm预测结果回归 lstm 回归预测_keras_04

6 训练模型

我们在选择前面一些天的数据作为训练集,在训练集上训练模型。

model.fit(X_train, y_train, batch_size=20,epochs=100,validation_split=0.1)

训练过程:

lstm预测结果回归 lstm 回归预测_keras_05

7 预测结果

红色虚线是LSTM在整个序列上的预测结果:

lstm预测结果回归 lstm 回归预测_LSTM_06

放大后观测部分:

lstm预测结果回归 lstm 回归预测_keras_07