基於LSTM對時間序列進行預測

本文的案例來自https://machinelearningmastery.com/time-series-prediction-lstm-recurrent-neural-networks-python-keras/

注:以下內容在該案例中進行了刪改。

我們要在這篇文章中看到的問題是國際航空乘客預測問題。

這是一個問題,在一年一個月的時間裏,任務是預測1000個國際航空公司的乘客數量。數據範圍從1949年1月到1960年12月,或12年,有144個觀察。

該數據集可從DataMarket網頁免費下載CSV文件名爲 “ international-airline-passengers.csv”。

我們可以使用Pandas庫輕鬆加載這個數據集。我們對這個日期不感興趣,因爲每個觀測值都是以相同的時間間隔分開的。因此,當我們加載數據集時,我們可以排除第一列。

下載的數據集也有頁腳信息,我們可以用skipfooter參數將pandas.read_csv()設置爲3 來排除3頁腳行。一旦加載,我們可以輕鬆繪製整個數據集。下面列出了加載和繪製數據集的代碼。

import pandas
import matplotlib.pyplot as plt
dataset = pandas.read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3)
plt.plot(dataset)
plt.show()

長期的短期記憶網絡

長期短期記憶網絡(即LSTM網絡)是使用反向傳播時間訓練並克服消失梯度問題的遞歸神經網絡。

因此,它可以用來創建大型循環網絡,反過來又可以用來解決機器學習中的難題序列問題,並獲得最新的結果。

LSTM網絡不是神經元,而是通過層連接的內存塊。

一個塊具有使其比傳統神經元和最近序列的記憶更爲智能的組件。一個塊包含管理塊的狀態和輸出的門。一個程序塊按照一個輸入序列進行操作,一個程序塊內的每個門使用sigmoid激活單元來控制它們是否被觸發,從而使狀態的改變和信息的添加通過該塊有條件地流動。

一個單元內有三種類型的門:

  • 忘記門:有條件地決定從塊中扔掉什麼信息。
  • 輸入門:有條件地決定從輸入中更新內存狀態的值。
  • 輸出門:根據輸入和塊的內存有條件地決定輸出什麼。

每個單位就像一個迷你國家機器,其中單位的大門有訓練過程中學習的權重。

您可以看到如何從一層LSTM中獲得複雜的學習和記憶,不難想象高階抽象如何與多個這樣的層進行分層。

用於迴歸的LSTM網絡

我們可以把這個問題稱爲迴歸問題。

也就是說,考慮到本月乘客人數(以千人計),下個月的乘客人數是多少?

我們可以寫一個簡單的函數來將我們的單列數據轉換成兩列數據集:第一列包含本月的(t)乘客計數,第二列包含下個月的(t + 1)乘客計數。

在我們開始之前,讓我們先導入所有我們打算使用的函數和類。這假定安裝了Keras深度學習庫的工作SciPy環境。

import numpy
import matplotlib.pyplot as plt
import pandas
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
在我們做任何事情之前,確定隨機數種子是一個好主意,以確保我們的結果是可重複的。
numpy.random.seed(7)
我們也可以使用前一節中的代碼來將數據集加載爲Pandas數據框。然後,我們可以從數據框中提取NumPy數組,並將整數值轉換爲浮點值,這更適合用神經網絡進行建模。

# load the dataset
dataframe = pandas.read_csv('international-airline-passengers.csv', usecols=[1], engine='python', skipfooter=3)#原有兩列,一列是時間,一列是乘客數量,這裏利用usecols=[1],只取了乘客數量一列
dataset = dataframe.values #通過.values得到dataframe的值,返回shape是(144, 1)的數組形式
dataset = dataset.astype('float32') #把dataset裏的所有數據從整型變爲浮點型

dataframe的導出結果:


最後dataset的輸出結果爲:


LSTM對輸入數據的規模很敏感,特別是當使用sigmoid(默認)或tanh激活功能時。將數據重新調整到0到1的範圍(也稱爲標準化)可能是一個很好的做法。我們可以使用scikit-learn庫中MinMaxScaler預處理類輕鬆地規範數據集

scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
歸一化後的輸出:



在對數據進行建模並在訓練數據集上估計我們模型的技能之後,我們需要了解模型對於新的不可見數據的技巧。對於正常的分類或迴歸問題,我們會使用交叉驗證來做到這一點。

對於時間序列數據,值的順序很重要。我們可以使用的一個簡單的方法是將有序數據集分解爲訓練和測試數據集。下面的代碼計算分割點的索引,並將排在前面的67%的觀測值數據作爲訓練數據集,我們可以使用這些觀測值來訓練我們的模型,後面剩下的33%用於測試模型。

# split into train and test sets
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(len(train), len(test))
     print結果:96 48 (數據集長度爲144)

現在我們可以定義一個函數來創建一個新的數據集,如上所述。

該函數有兩個參數:數據集(我們想要轉換爲數據集的NumPy數組)和look_back,這是以前的時間步數用作輸入變量來預測下一個時間段,以前的時間步數默認爲1。

這個默認值將創建一個數據集,其中X是給定時間(t)的乘客數量,Y是下一次(t + 1)的乘客數量。

它可以進行配置,我們將在下一節中構建一個不同形狀的數據集。

# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
	dataX, dataY = [], []
	for i in range(len(dataset)-look_back-1):#此處是否要去掉-1呢?待定中
		a = dataset[i:(i+look_back), 0]  #i:i+look_back代表用預測的時間點前的look_back點來作爲輸入,此處用                            #前1個點作爲輸入
		dataX.append(a)
		dataY.append(dataset[i + look_back, 0])
	return numpy.array(dataX), numpy.array(dataY)


附錄:

使用低頻.csv進行預測時出現bug:

1、版本出錯:
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\preprocessing\data.py:377: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
  warnings.warn(DEPRECATION_MSG_1D, DeprecationWarning)
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\preprocessing\data.py:377: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
  warnings.warn(DEPRECATION_MSG_1D, DeprecationWarning)

改進:講一維數組變爲二維數組


加一個[],使原先爲一維數組的trainPredict變爲二維數組即可






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章