时间序列问题增加了输入变量之间的序列依赖性,这样大大提升了模型的复杂程度。LSTM是循环神经网络的一种,可以成功地训练架构非常复杂的深度学习模型,用于处理时间序列问题。
LSTM对输入数据的尺度十分敏感,特别是使用sigmoid(这是默认的)或者tanh作为激活函数的时候。
下面代码中使用Scikit-Learn中的MinMaxScaler预处理类对数据集进行归一化处理,将数据缩放到0——1。
LSTM的输入数据具有以下形式的特定阵列结构:[样本,时间步长,特征]。在create_dataset()函数中生成的数据集采用的是如下的形式:[样本,特征]。然后需要使用numpy.reshape()函数对数据集进行结构转换,转换时将每个样本作为一个时间步长。
这里构建一个具有单个神经元的输入层、具有4个LSTM存储单元的隐藏层,以及具有单个值预测的输出层的神经网络。LSTM存储单元采用的是默认的sigmoid激活函数。对网络训练100个epochs,并将batch_size设置为1。
例子来源于魏贞原老师的深度学习书籍。
"""
LSTM时间序列问题预测:国际旅行人数预测
"""
import numpy as np
from matplotlib import pyplot as plt
from pandas import read_csv
import math
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
seed = 7
batch_size = 1
epochs = 100
filename = 'F:/Python/pycharm/keras_deeplearning/datasets/international-airline-passengers.csv'
footer = 3
look_back = 1
def create_dataset(dataset):
#创建数据集
dataX, dataY = [],[]
for i in range(len(dataset) - look_back - 1):
x= dataset[i:i+look_back, 0]
dataX.append(x)
y = dataset[i+look_back, 0]
dataY.append(y)
print('X: %s, Y: %s' % (x,y))
return np.array(dataX), np.array(dataY)
def build_model():
model = Sequential()
model.add(LSTM(units=4, input_shape=(1, look_back)))
model.add(Dense(units=1))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
if __name__ == '__main__':
#设置随机种子
np.random.seed(seed)
#导入数据
data = read_csv(filename, usecols=[1], engine='python', skipfooter=footer)
dataset = data.values.astype('float32')
#标准化数据
scaler = MinMaxScaler()
dataset = scaler.fit_transform(dataset)
train_size = int(len(dataset) * 0.67)
validation_size = len(dataset) - train_size
train, validation = dataset[0:train_size, :], dataset[train_size:len(dataset), :]
#创建dataset,使数据产生相关性
X_train, y_train = create_dataset(train)
X_validation, y_validation = create_dataset(validation)
#将数据转换成[样本,时间步长,特征]的形式
X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
X_validation = np.reshape(X_validation, (X_validation.shape[0], 1, X_validation.shape[1]))
#训练模型
model = build_model()
model.fit(X_train, y_train, epochs=epochs, batch_size=batch_size, verbose=2)
#模型预测数据
predict_train = model.predict(X_train)
predict_validation = model.predict(X_validation)
#反标准化数据,目的是为了保证MSE的准确性
predict_train = scaler.inverse_transform(predict_train)
y_train = scaler.inverse_transform([y_train])
predict_validation = scaler.inverse_transform(predict_validation)
y_validation = scaler.inverse_transform([y_validation])
#评估模型
train_score = math.sqrt(mean_squared_error(y_train[0], predict_train[:, 0]))
print('Train Score: %.2f RMSE' % train_score)
validation_score = math.sqrt(mean_squared_error(y_validation[0], predict_validation[:, 0]))
print('Validation Score : %.2f RMSE' % validation_score)
#构建通过训练数据集进行预测的图表数据
predict_train_plot = np.empty_like(dataset)
predict_train_plot[:, :] = np.nan
predict_train_plot[look_back:len(predict_train) + look_back, :] = predict_train
# 构建通过评估数据集进行预测的图表数据
predict_validation_plot = np.empty_like(dataset)
predict_validation_plot[:, :] = np.nan
predict_validation_plot[len(predict_train) + look_back * 2 + 1 : len(dataset) - 1, :] = predict_validation
#图表显示
dataset = scaler.inverse_transform(dataset)
plt.plot(dataset, color='black')
plt.plot(predict_train_plot, color='green')
plt.plot(predict_validation_plot, color='red')
plt.show()
输出结果为:
Train Score: 22.65 RMSE
Validation Score : 48.57 RMSE