前言
- LSTM 航空乘客预测单步预测的两种情况。 简单运用LSTM 模型进行预测分析。
- 加入注意力机制的LSTM 对航空乘客预测采用了目前市面上比较流行的注意力机制,将两者进行结合预测。
- 多层 LSTM 对航空乘客预测 简单运用多层的LSTM 模型进行预测分析。
- 双向LSTM 对航空乘客预测双向LSTM网络对其进行预测。
- MLP多层感知器 对航空乘客预测 使用MLP 对航空乘客预测
- CNN + LSTM 航空乘客预测采用的CNN + LSTM网络对其进行预测。
本文采用ConvLSTM网络对其进行预测。
我喜欢直接代码+ 结果展示 先代码可以跑通,才值得深入研究每个部分之间的关系;进而改造成自己可用的数据。
1 数据集
2 模型
ConvLSTM是为读取二维时空数据而开发的,但可以适用于单变量时间序列预测。 该层期望输入为二维图像序列,因此输入数据的形状必须为: [samples, timesteps, rows, columns, features] 出于我们的目的,我们可以将每个样本分成多个子序列,其中时间步长将成为子序列数或n_seq,列将是每个子序列的时间步数或n_steps。 在处理一维数据时,行数固定为1。
2.1 单步预测 1—》1
import numpy
import matplotlib.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 keras.layers import ConvLSTM2D
from keras.layers import Flatten
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
print("数据集的长度:",len(dataframe))
dataset = dataframe.values
dataset = dataset.astype('float32')
plt.plot(dataset)
plt.show()
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return numpy.array(dataX), numpy.array(dataY)
numpy.random.seed(7)
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
print("原始训练集的长度:",train_size)
print("原始测试集的长度:",test_size)
look_back = 1
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
print("转为监督学习,训练集数据长度:", len(trainX))
print("转为监督学习,测试集数据长度:",len(testX))
trainX = numpy.reshape(trainX, (trainX.shape[0], 1,1,1, trainX.shape[1]))
testX = numpy.reshape(testX, (testX.shape[0],1, 1,1, testX.shape[1]))
print('构造得到模型的输入数据(训练数据已有标签trainY): ',trainX.shape,testX.shape)
model = Sequential()
model.add(ConvLSTM2D(filters=64, kernel_size=(1,1), activation='relu', input_shape=(1,1,1,testX.shape[1])))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.fit(trainX, trainY, epochs=50)
model.summary()
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
plt.plot(scaler.inverse_transform(dataset))
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()
原始训练集的长度: 96
原始测试集的长度: 48
转为监督学习,训练集数据长度: 94
转为监督学习,测试集数据长度: 46
构造得到模型的输入数据(训练数据已有标签trainY): (94, 1, 1, 1, 1) (46, 1, 1, 1, 1)
Epoch 1/50
3/3 [==============================] - 3s 3ms/step - loss: 0.0624
Epoch 2/50
3/3 [==============================] - 0s 5ms/step - loss: 0.0586
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param
=================================================================
conv_lst_m2d (ConvLSTM2D) (None, 1, 1, 64) 16896
_________________________________________________________________
flatten (Flatten) (None, 64) 0
_________________________________________________________________
dense (Dense) (None, 1) 65
=================================================================
Total params: 16,961
Trainable params: 16,961
Non-trainable params: 0
_________________________________________________________________
Train Score: 51.49 RMSE
Test Score: 147.12 RMSE
2.1 单步预测 3—》1
import numpy
import matplotlib.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 keras.layers import ConvLSTM2D
from keras.layers import Flatten
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
print("数据集的长度:",len(dataframe))
dataset = dataframe.values
dataset = dataset.astype('float32')
plt.plot(dataset)
plt.show()
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return numpy.array(dataX), numpy.array(dataY)
numpy.random.seed(7)
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
print("原始训练集的长度:",train_size)
print("原始测试集的长度:",test_size)
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
print("转为监督学习,训练集数据长度:", len(trainX))
print("转为监督学习,测试集数据长度:",len(testX))
trainX = numpy.reshape(trainX, (trainX.shape[0], 3,1,1, 1))
testX = numpy.reshape(testX, (testX.shape[0],3, 1,1, 1))
print('构造得到模型的输入数据(训练数据已有标签trainY): ',trainX.shape,testX.shape)
model = Sequential()
model.add(ConvLSTM2D(filters=64, kernel_size=(1,1), activation='relu', input_shape=(3, 1,1, 1)))
model.add(Flatten())
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')
model.fit(trainX, trainY, epochs=50)
model.summary()
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
plt.plot(scaler.inverse_transform(dataset))
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()
Train Score: 33.29 RMSE
Test Score: 79.17 RMSE
3 总结
- LSTM在时序数据的处理上能力非常强,但是如果时序数据是图像,则在LSTM的基础上加上卷积操作,对于图像的特征提取会更加有效。
- ConvLSTM是在《Convolutional LSTM Network: A Machine Learning Approach for Precipitation Nowcasting》中提出的,一作是Xingjian Shi。后面他针对雷达图的天气预测又提出了TrajGRU,基于运行轨迹对图像做更精准的捕捉
- Conv LSTM属于LSTM的一种变体
- ConvLSTM,其不仅具有LSTM的时序建模能力,而且还能像CNN一样刻画局部特征,可以说是时空特性具备。
|