国际旅行人数预测——使用LSTM

时间序列问题增加了输入变量之间的序列依赖性,这样大大提升了模型的复杂程度。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

 

猜你喜欢

转载自blog.csdn.net/sun___M/article/details/83898522
今日推荐