keras 时间序列预测
程序员文章站
2022-05-19 08:56:34
...
keras 时间序列预测
num表示自行车数量,weekday表示星期几,hour表示小时。一共45949条数据,这些数据是按一分钟一次的顺序排列的。
用RNN进行预测的话,实际上用num字段就够了,其他两个字段作为额外的参考信息,读者不妨利用这两条信息构建更复杂的模型,提高预测精度。
接下来我们将用多层LSTM 的RNN神经网络去预测这些序列的值,简单来说,我们有9个连续的num,那么如何预测第10个num是多少?(知道前九分钟的num,预测下一分钟的num)
# 加载依赖库
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import time
import csv
from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
np.random.seed(2020)
Using TensorFlow backend.
- matplotlib, numpy, time 分别用于画图、python数组、系统时间。
- csv 模块可以直接从文本里面读取数据,也可以使用 pandas 或者 numpy。
- models 是 Keras 神经网络的核心。这个对象代表这个我们所定义的神经网络:它有层、**函数等等属性和功能。我们进行训练和测试也是基于这个models。 Sequetial 表示我们将使用层堆叠起来的网络,这是Keras中的基本网络结构。
- Dense, Activation, Dropout 这些是神经网络里面的核心层,用于构建整个神经网络。Dense 实际上就是 Fully-connected 层;Activation是**函数,它会通过Relu, Softmax 等函数对上一层产生的结果进行修改;当神经元过多的时候,可能效果并不好,因为容易导致过拟合的现象,Dropout是将上一层神经元进行随机丢弃,有助于解决过拟合的问题。
- LSTM 是经典的RNN神经网络层。LSTM 的内部结构非常复杂,如果想要深入了解的话可以看以下材料: (Chris Olah’s Understanding LSTM Networks )
一、准备数据
data = pd.read_csv('/Users/liming/Downloads/bike_rnn.csv')
print(data.shape)
data.head()
(45949, 3)
num | weekday | hour | |
---|---|---|---|
0 | 0 | 5 | 17 |
1 | 1 | 5 | 17 |
2 | 1 | 5 | 17 |
3 | 2 | 5 | 17 |
4 | 4 | 5 | 17 |
bike = data['num']
sequence_length=20 # 用来预测的时间序列长度
result = []
for index in range(len(bike) - sequence_length):
result.append(bike[index: index + sequence_length])
result = np.array(result)
result
array([[0, 1, 1, ..., 2, 1, 2],
[1, 1, 2, ..., 1, 2, 1],
[1, 2, 4, ..., 2, 1, 1],
...,
[8, 8, 8, ..., 6, 6, 6],
[8, 8, 6, ..., 6, 6, 6],
[8, 6, 5, ..., 6, 6, 6]])
result_mean = result.mean()
result_mean
6.997708419517081
result = result - result_mean
print("Shift : ", result_mean)
print("Data : ", result.shape)
Shift : 6.997708419517081
Data : (45929, 20)
row = int(round(0.9 * result.shape[0]))
train = result[:row, :]
np.random.shuffle(train)
X_train = train[:, :-1]
y_train = train[:, -1]
X_test = result[row:, :-1]
y_test = result[row:, -1]
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
二、创建模型
#建立模型
model = Sequential()
model.add(Embedding(1,30, input_length=maxlen))
model.add(LSTM(40,return_sequences=True))
model.add(Dropout(0.5))
model.add(LSTM(50,return_sequences=False))
model.add(Dense(100))
model.add(Activation("linear"))
model.compile(loss="mse", optimizer="rmsprop",metrics=['accuracy'])
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-9-609329416643> in <module>
1 #建立模型
2 model = Sequential()
----> 3 model.add(Embedding(1,30, input_length=maxlen))
4 model.add(LSTM(40,return_sequences=True))
5 model.add(Dropout(0.5))
NameError: name 'Embedding' is not defined
三、模型训练
batch_size = 128
model.fit(X_train, y_train, batch_size = batch_size, nb_epoch=30)
然后开始训练模型,调用 model 的 fit 方法。这里我们重点关注一下predicted方法。
- 根据我们之前的构造, X_test 是一个个长度为19的时间序列(也可以叫做作19个timesteps),第20个实际上是我们希望预测的值。
- X_test[0] 就是第一个输入序列,包括19个连续的自行车数量。
- predict(X_test[0]) 的意思是通过这个序列预测第20个时刻的自行车数量,它的真实值是 y_test[0] 。实际上根据我们之前的构造, y_test[0] = X_test[1][18] = X_test[2][17] = …
- 所以predict(X_test[1]) 是在预测原始序列的第21个值,它的真实值是 y_test[1] 。
- 所以predict(X_test) 预测出来的是一大串数值,实际上正好和 y_test 整体一一对应。
- predict(X_test) 是一个 list 包含着很多个 list 的numpy数组,我们最终把最里面的 list 内容 reshape 成一个个一维数组。(比如[200, 20] 变成了 [200, 20, 1])
四、模型测试
model.evaluate(X_test, y_test, batch_size = batch_size)
四、总结
- 除了 LSTM 外,可以换成GRU 等其他的RNN模型尝试一下
- 除了 num 字段外,weekday 和 hour 也是有用的,如何利用这两个字段的信息?如何构建更复杂的神经网络模型?希望大家能进一步的探索交流。
- 本文的输出仅仅为1个timestep,实际上可以是连续的多个,感兴趣可以自己动手试试
- 应该如何设定层数,output个数,dropout比例等等是一门艺术。如何优化超参数是也是个比较棘手的问题,参数的设定往往决定着模型的好坏。