拓端數據tecdat|使用Python中Keras的LSTM遞歸神經網絡進行時間序列預測


原文鏈接 :http://tecdat.cn/?p=19542 

 

時間序列預測問題是預測建模問題中的一種困難類型。

與回歸預測建模不同,時間序列還增加了輸入變量之間序列依賴的復雜性。

用於處理序列依賴性的強大神經網絡稱為 遞歸神經網絡。長短期記憶網絡或LSTM網絡是深度學習中使用的一種遞歸神經網絡,可以成功地訓練非常大的體系結構。

在本文中,您將發現如何使用Keras深度學習庫在Python中開發LSTM網絡,以解決時間序列預測問題。

完成本教程后,您將知道如何針對自己的時間序列預測問題實現和開發LSTM網絡。

  • 關於國際航空公司的旅客時間序列預測問題。
  • 如何基於時間序列預測問題框架開發LSTM網絡。
  • 如何使用LSTM網絡進行開發並做出預測,這些網絡可以在很長的序列中保持狀態(內存)。

在本教程中,我們將為時間序列預測問題開發LSTM。

這些示例將准確地向您展示如何開發結構不同的LSTM網絡,以解決時間序列預測建模問題。

 

問題描述

討論的問題是國際航空公司的乘客預測問題。

任務是預測國際航空旅客的數量。數據范圍為1949年1月至1960年12月,即12年,共進行了144次觀測。

下面是文件前幾行的示例。

  1.  
    "Month","Passengers"
  2.  
     
  3.  
     
  4.  
    "1949-03",132
  5.  
     
  6.  
    "1949-04",129
  7.  
     
  8.  
    "1949-05",121

我們可以使用Pandas庫加載此數據集。下面列出了加載和繪制數據集的代碼。

  1.  
     
  2.  
     
  3.  
     
  4.  
    dataset = pandas.read_csv('airpas.csv', usecols=[1], engine='python')
  5.  
     
  6.  
    plt.plot(dataset)
  7.  
     
  8.  
    plt.show()
  9.  
     
  10.  
     

您可以看到數據集中隨時間的上升趨勢。

您還可以看到數據集中的一些周期性,該周期性可能對應於休假期。

 

通常,最好標准化數據並使它們平穩。

 

長短期記憶網絡

長短期記憶網絡(LSTM)是一種遞歸神經網絡,使用時間反向傳播進行訓練,可以解決梯度消失的問題。

它可用於創建大型循環網絡,進而可用於解決機器學習中的序列問題並獲得最新結果。

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

LSTM 的關鍵就是細胞狀態,LSTM 有通過精心設計的稱作為“門”的結構來去除或者增加信息到細胞狀態的能力。門是一種讓信息選擇式通過的方法,他們包含一個sigmoid神經網絡層和一個按位的乘法操作。Sigmoid 層輸出0到1之間的數值,描述每個部分有多少量可以通過。0代表“不許任何量通過”,1就指“允許任意量通過”!LSTM 擁有三個門,來保護和控制細胞狀態。

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

  • 忘記門:有條件地決定從該塊中丟棄哪些信息。
  • 輸入門:有條件地決定輸入中的哪些值來更新內存狀態。
  • 輸出門:根據輸入的內存,決定輸出什么。

每個單元就像一個微型狀態機,其中單元的門具有在訓練過程中學習到的權重。

LSTM回歸網絡

我們可以將該問題表述為回歸問題。

也就是說,考慮到本月的旅客人數(以千為單位),下個月的旅客人數是多少?

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

在開始之前,讓我們首先導入要使用的所有函數和類。假設安裝了Keras深度學習庫。

在進行任何操作之前,最好先設置隨機數種子,以確保我們的結果可重復。

  1.  
    # 隨機種子以提高可重復性
  2.  
     
  3.  
    numpy.random.seed(7)

我們還可以使用上一部分中的代碼將數據集作為Pandas數據框加載。然后,我們可以從數據幀中提取NumPy數組,並將整數值轉換為浮點值,這更適合使用神經網絡進行建模。

  1.  
    # 加載數據集
  2.  
     
  3.  
     
  4.  
    dataset = dataset.astype('float32')

LSTM對輸入數據的大小敏感,特別是在使用S型(默認)或tanh激活函數時。將數據重新標准化到0到1的范圍(也稱為歸一化)。我們可以使用 scikit-learn庫中的MinMaxScaler預處理類輕松地對數據集進行規范化 。

  1.  
    # 標准化數據集
  2.  
     
  3.  
    scaler = MinMaxScaler(feature_range=(0, 1))
  4.  
     
  5.  
    dataset = scaler.fit_transform(dataset)

在對數據進行建模並在訓練數據集上估計模型之后,我們需要對新的數據測試了解模型的技能。對於正常的分類或回歸問題,我們將使用交叉驗證來完成。

對於時間序列數據,值的順序很重要。我們可以使用的一種簡單方法是將有序數據集拆分為訓練數據集和測試數據集。下面的代碼計算分割點,並使用67%的觀測值將數據分離到訓練數據集中,這些觀測值可用於訓練模型,其余的33%用於測試模型。

  1.  
    # 分為訓練集和測試集
  2.  
     
  3.  
    train_size = int(len(dataset) * 0.67)
  4.  
     
  5.  
    test_size = len(dataset) - train_size
  6.  
     

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

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

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

我們將在下一部分中構造一個形狀不同的數據集。

  1.  
    # 將值數組轉換為數據集矩陣
  2.  
     
  3.  
     
  4.  
     
  5.  
    for i in range(len(dataset)-look_back-1):
  6.  
     
  7.  
    a = dataset[i:(i+look_back), 0]
  8.  
     
  9.  
    return numpy.array(dataX), numpy.array(dataY)

讓我們看一下此函數對數據集第一行的影響。

  1.  
    X Y
  2.  
     
  3.  
    112 118
  4.  
     
  5.  
    118 132
  6.  
     
  7.  
    132 129
  8.  
     
  9.  
    129 121
  10.  
     
  11.  
    121 135

如果將前5行與上一節中列出的原始數據集樣本進行比較,則可以在數字中看到X = t和Y = t + 1模式。

讓我們准備訓練和測試數據集以進行建模。

  1.  
    #整理為X = t和Y = t + 1
  2.  
     
  3.  
    look_back = 1
  4.  
    create_dataset(train, look_back)

LSTM網絡輸入數據(X)具有以下形式的特定數組結構:  [樣本,時間步長,特征]

目前,我們的數據采用以下形式:[樣本,特征],我們將問題定為每個樣本的一步。我們可以使用numpy.reshape()將准備好的訓練和測試輸入數據轉換為預期的結構  ,如下所示:

  1.  
    # 將輸入修改為 [樣本,時間步長,特征]
  2.  
     
  3.  
    numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
  4.  
     

現在,我們准備設計並擬合我們的LSTM網絡以解決此問題。

該網絡具有一個具有1個輸入的可見層,一個具有4個LSTM塊或神經元的隱藏層以及一個進行單個值預測的輸出層。默認的Sigmoid激活功能用於LSTM模塊。該網絡訓練了100個時期。

  1.  
    # 創建並擬合LSTM網絡
  2.  
     
  3.  
     
  4.  
    model.add(LSTM(4, input_shape=(1, look_back)))
  5.  
     
  6.  
    model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2)

一旦模型適合,我們就可以估計模型在訓練和測試數據集上的性能。這將為我們提供新模型的比較點。

請注意,在計算誤差之前,我們先對預測進行了反標准化,以確保以與原始數據相同的單位。

  1.  
    # 作出預測
  2.  
     
  3.  
    trainPredict = model.predict(trainX)
  4.  
     
  5.  
     
  6.  
    # 反向預測
  7.  
     
  8.  
    trainPredict = scaler.inverse_transform(trainPredict)
  9.  
     
  10.  
     
  11.  
    # 計算均方誤差
  12.  
     
  13.  
    trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))

最后,我們可以使用模型為訓練和測試數據集生成預測,以直觀地了解模型的技能。

由於數據集的准備方式,我們必須移動預測,以使它們在x軸上與原始數據集對齊。准備好之后,將數據繪制成圖表,以藍色顯示原始數據集,以綠色顯示訓練數據集的預測,以紅色顯示看不見的測試數據集的預測。

  1.  
    # 預測
  2.  
     
  3.  
     
  4.  
    trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict
  5.  
     
  6.  
    # 繪制測試預測
  7.  
     
  8.  
    testPredictPlot = numpy.empty_like(dataset)
  9.  
     
  10.  
     
  11.  
     
  12.  
    # 繪制基准和預測
  13.  
     
  14.  
     
  15.  
     
  16.  
    plt.plot(testPredictPlot)
  17.  
     
  18.  
    plt.show()

我們可以看到,該模型在擬合訓練和測試數據集方面做得非常出色。

 

LSTM訓練了旅客預測問題的回歸公式

運行示例將產生以下輸出。

  1.  
    ..
  2.  
     
  3.  
     
  4.  
     
  5.  
     
  6.  
    Epoch 100/100
  7.  
     
  8.  
    0s - loss: 0.0020
  9.  
     
  10.  
    Train Score: 22.93 RMSE
  11.  
     
  12.  
    Test Score: 47.53 RMSE

我們可以看到,該模型在訓練數據集上的平均誤差約為23乘客(以千計),在測試數據集上的平均誤差為52乘客(以千計)。

使用窗口方法進行回歸的LSTM

我們還可以使用多個最近的時間步長來預測下一個時間步長。

這稱為窗口,窗口的大小是可以針對每個問題進行調整的參數。

例如,給定當前時間(t),我們要預測序列(t + 1)中下一個時間的值,我們可以使用當前時間(t)以及前兩個時間(t-1)和t-2)作為輸入變量。

當表述為回歸問題時,輸入變量為t-2,t-1,t,輸出變量為t + 1。

 在上一節中創建的 create_dataset()函數使我們可以通過將look_back 參數從1增加到3來創建時間序列問題。

具有此公式的數據集示例如下所示:

  1.  
    X1 X2 X3 Y
  2.  
     
  3.  
    112 118 132 129
  4.  
     
  5.  
    118 132 129 121
  6.  
     
  7.  
    132 129 121 135
  8.  
     
  9.  
    129 121 135 148
  10.  
     
  11.  
    121 135 148 148

我們可以使用較大的窗口大小重新運行上一部分中的示例。

運行示例將提供以下輸出:

  1.  
    ...
  2.  
     
  3.  
     
  4.  
    Epoch 100/100
  5.  
     
  6.  
    0s - loss: 0.0020
  7.  
     
  8.  
    Train Score: 24.19 RMSE
  9.  
     
  10.  
    Test Score: 58.03 RMSE

我們可以看到誤差與上一節相比有所增加。

 

 

LSTM隨時間步長回歸

你可以看到LSTM網絡的數據准備包括時間步長。

某些序列問題每個樣本的時間步長可能不同。

時間步長為表達我們的時間序列問題提供了另一種方法。像上面的窗口示例一樣,我們可以將時間序列中的先前時間作為輸入,以預測下一時間的輸出。

我們可以將它們用作一個輸入函數的時間步長,而不是將過去的觀察結果作為單獨的輸入函數,這確實是問題的更准確框架。

我們可以使用與上一個示例相同的數據表示方式來執行此操作,我們將列設置為時間步長維度,例如:

  1.  
    # 將輸入修改為 [樣本,時間步長,特征]
  2.  
     
  3.  
    numpy.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))
  4.  
     

 

運行示例將提供以下輸出:

  1.  
    ...
  2.  
     
  3.  
    Epoch 95/100
  4.  
     
  5.  
    1s - loss: 0.0021
  6.  
     
  7.  
    Epoch 96/100
  8.  
     
  9.  
    1s - loss: 0.0021
  10.  
     

我們可以看到,結果比之前的示例略好。

 

訓練批次之間具有記憶的LSTM

LSTM網絡具有內存,能夠記憶長序列。

通常,在擬合模型以及每次對model.predict() 或 model.evaluate()的調用后,每次訓練批次后都會重置網絡中的狀態 。

我們可以更好地控制何時在Keras中清除LSTM網絡的內部狀態。這意味着它可以在整個訓練序列中建立狀態,甚至在需要進行預測時也可以保持該狀態。

要求在安裝網絡時,在每次訓練數據之后,還需要通過調用model.reset_states()來重置網絡狀態 。這意味着我們必須創建自己的時期外循環,並在每個時期內調用 model.fit() 和 model.reset_states()。

最后,在構造LSTM層時,  必須將有狀態參數設置為 True  ,我們對批處理中的樣本數量,樣本中的時間步長以及一次中的特征數量進行編碼。通過設置 batch_input_shape 參數。

隨后,在評估模型和進行預測時,必須使用相同的批次大小。

  1.  
    model.predict(trainX, batch_size=batch_size)
  2.  
     

我們可以改編先前的時間步驟示例來使用有狀態LSTM。

運行將提供以下輸出:

  1.  
    ...
  2.  
     
  3.  
     
  4.  
    Epoch 1/1
  5.  
     
  6.  
    1s - loss: 0.0016
  7.  
     
  8.  
    Train Score: 20.74 RMSE
  9.  
     
  10.  
    Test Score: 52.23 RMSE

我們看到結果誤差更大。該模型可能需要更多模塊,並且可能需要針對更多時期進行訓練。

 

 

批次之間具有內存的堆疊式LSTM

最后,我們將看看LSTM的一大優勢:事實上,將LSTM堆疊到深度網絡體系結構中就可以對其進行成功的訓練。

LSTM網絡可以以與其他層類型堆疊相同的方式堆疊在Keras中。所需配置的一個附加函數是,每個后續層之前的LSTM層必須返回序列。這可以通過將return_sequences參數設置 為 True來完成。

我們可以在上一節中將有狀態LSTM擴展為兩層

運行示例將產生以下輸出。

  1.  
    ...
  2.  
     
  3.  
    Epoch 1/1
  4.  
     
  5.  
    1s - loss: 0.0016
  6.  
     
  7.  
    Train Score: 20.49 RMSE
  8.  
     
  9.  
    Test Score: 56.35 RMSE

從對測試數據集的預測誤差來看,模型需要更多的訓練時間。

 

概要

在本文中,您發現了如何使用Keras深度學習網絡開發LSTM遞歸神經網絡,在Python中進行時間序列預測。


 

最受歡迎的見解

1.用於NLP的Python:使用Keras的多標簽文本LSTM神經網絡分類

2.Python中利用長短期記憶模型LSTM進行時間序列預測分析 – 預測電力消耗數據

3.python在Keras中使用LSTM解決序列問題

4.Python中用PyTorch機器學習分類預測銀行客戶流失模型

5.R語言多元Copula GARCH 模型時間序列預測

6.在r語言中使用GAM(廣義相加模型)進行電力負荷時間序列分析

7.R語言中ARMA,ARIMA(Box-Jenkins),SARIMA和ARIMAX模型用於預測時間序列數

8.R語言估計時變VAR模型時間序列的實證研究分析案例

9.用廣義加性模型GAM進行時間序列分析

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM