本文采用ConvLSTM网络对其进行预测。
我喜欢直接代码+ 结果展示
先代码可以跑通,才值得深入研究每个部分之间的关系;进而改造成自己可用的数据。
ConvLSTM是为读取二维时空数据而开发的,但可以适用于单变量时间序列预测。
该层期望输入为二维图像序列,因此输入数据的形状必须为:
[samples, timesteps, rows, columns, features]
出于我们的目的,我们可以将每个样本分成多个子序列,其中时间步长将成为子序列数或n_seq,列将是每个子序列的时间步数或n_steps。 在处理一维数据时,行数固定为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
#matplotlib inline
# load the dataset
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
# print(dataframe)
print("数据集的长度:",len(dataframe))
dataset = dataframe.values
# 将整型变为float
dataset = dataset.astype('float32')
plt.plot(dataset)
plt.show()
# X是给定时间(t)的乘客人数,Y是下一次(t + 1)的乘客人数。
# 将值数组转换为数据集矩阵,look_back是步长。
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]
# X按照顺序取值
dataX.append(a)
# Y向后移动一位取值
dataY.append(dataset[i + look_back, 0])
return numpy.array(dataX), numpy.array(dataY)
# fix random seed for reproducibility
numpy.random.seed(7)
# 数据缩放
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
# 将数据拆分成训练和测试,2/3作为训练数据
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(trainX,trainY)
print("转为监督学习,测试集数据长度:",len(testX))
# print(testX, testY )
# 数据重构为5D [samples, timesteps, rows, columns, features]
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)
# create and fit the LSTM network
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))
# shift train predictions for plotting
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# shift test predictions for plotting
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
# plot baseline and predictions
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
#单变量,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
#matplotlib inline
# load the dataset
dataframe = read_csv('airline-passengers.csv', usecols=[1], engine='python')
# print(dataframe)
print("数据集的长度:",len(dataframe))
dataset = dataframe.values
# 将整型变为float
dataset = dataset.astype('float32')
plt.plot(dataset)
plt.show()
# X是给定时间(t)的乘客人数,Y是下一次(t + 1)的乘客人数。
# 将值数组转换为数据集矩阵,look_back是步长。
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]
# X按照顺序取值
dataX.append(a)
# Y向后移动一位取值
dataY.append(dataset[i + look_back, 0])
return numpy.array(dataX), numpy.array(dataY)
# fix random seed for reproducibility
numpy.random.seed(7)
# 数据缩放
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
# 将数据拆分成训练和测试,2/3作为训练数据
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(trainX,trainY)
print("转为监督学习,测试集数据长度:",len(testX))
# print(testX, testY )
# 数据重构为5D [samples, timesteps, rows, columns, features]
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)
# create and fit the LSTM network
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))
# shift train predictions for plotting
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
# shift test predictions for plotting
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, :] = testPredict
# plot baseline and predictions
plt.plot(scaler.inverse_transform(dataset))
plt.plot(trainPredictPlot)
plt.plot(testPredictPlot)
plt.show()
Train Score: 33.29 RMSE
Test Score: 79.17 RMSE