國際旅行人數預測——使用LSTM
阿新 • • 發佈:2018-11-27
時間序列問題增加了輸入變數之間的序列依賴性,這樣大大提升了模型的複雜程度。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