全文鏈接:http:///?p=8145顧名思義,時間序列數(shù)據(jù)是一種隨時間變化的數(shù)據(jù)類型,。例如,,24小時內(nèi)的溫度,一個月內(nèi)各種產(chǎn)品的價格,,一年中特定公司的股票價格(點擊文末“閱讀原文”獲取完整代碼數(shù)據(jù)),。 諸如長期短期記憶網(wǎng)絡(luò)(LSTM)之類的高級深度學習模型能夠捕獲時間序列數(shù)據(jù)中的模式,因此可用于對數(shù)據(jù)的未來趨勢進行預測,。在本文中,,您將看到如何使用LSTM算法使用時間序列數(shù)據(jù)進行將來的預測。 數(shù)據(jù)集和問題定義 讓我們先導入所需的庫,,然后再導入數(shù)據(jù)集: import matplotlib.pyplot as plt 讓我們將數(shù)據(jù)集加載到我們的程序中
data.head()
輸出: 該數(shù)據(jù)集有三列:year ,,month ,和passengers ,。passengers 列包含指定月份旅行旅客的總數(shù),。讓我們輸出數(shù)據(jù)集的維度: data.shape
輸出: (144, 3)
您可以看到數(shù)據(jù)集中有144行和3列,這意味著數(shù)據(jù)集包含12年的乘客旅行記錄,。 任務(wù)是根據(jù)前132個月來預測最近12個月內(nèi)旅行的乘客人數(shù),。請記住,我們有144個月的記錄,,這意味著前132個月的數(shù)據(jù)將用于訓練我們的LSTM模型,,而模型性能將使用最近12個月的值進行評估。 讓我們繪制每月乘客的出行頻率,。 接下來的腳本繪制了每月乘客人數(shù)的頻率: plt.grid(True) plt.autoscale(axis='x',tight=True) plt.plot(data['passengers'])
輸出: 輸出顯示,,多年來,乘飛機旅行的平均乘客人數(shù)有所增加,。一年內(nèi)旅行的乘客數(shù)量波動,,這是有道理的,因為在暑假或寒假期間,,旅行的乘客數(shù)量與一年中的其他部分相比有所增加,。 數(shù)據(jù)預處理數(shù)據(jù)集中的列類型為object ,如以下代碼所示: data.columns
輸出: Index(['year', 'month', 'passengers'], dtype='object')
第一步是將passengers 列的類型更改為float ,。 all_data = data['passengers'].values.astype(float)
現(xiàn)在,,如果 輸出all_data numpy數(shù)組,,則應(yīng)該看到以下浮點類型值: print(all_data)
前132條記錄將用于訓練模型,后12條記錄將用作測試集,。以下腳本將數(shù)據(jù)分為訓練集和測試集,。 test_data_size = 12 train_data = all_data[:-test_data_size] test_data = all_data[-test_data_size:]
現(xiàn)在讓我們輸出測試和訓練集的長度: 輸出: 132 12
如果現(xiàn)在輸出測試數(shù)據(jù),您將看到它包含all_data numpy數(shù)組中的最后12條記錄:輸出: [417. 391.... 390. 432.]
我們的數(shù)據(jù)集目前尚未歸一化,。最初幾年的乘客總數(shù)遠少于后來幾年的乘客總數(shù),。標準化數(shù)據(jù)以進行時間序列預測非常重要。以在一定范圍內(nèi)的最小值和最大值之間對數(shù)據(jù)進行歸一化,。我們將使用模塊中的MinMaxScaler 類sklearn.preprocessing 來擴展數(shù)據(jù),。 以下代碼 將最大值和最小值分別為-1和1進行歸一化。 MinMaxScaler(feature_range=(-1, 1))
輸出: [[-0.96483516] ...... [0.33186813] [0.13406593] [0.32307692]]
您可以看到數(shù)據(jù)集值現(xiàn)在在-1和1之間,。 在此重要的是要提到數(shù)據(jù)歸一化僅應(yīng)用于訓練數(shù)據(jù),,而不應(yīng)用于測試數(shù)據(jù)。如果對測試數(shù)據(jù)進行歸一化處理,,則某些信息可能會從訓練集中 到測試集中,。 最后的預處理步驟是將我們的訓練數(shù)據(jù)轉(zhuǎn)換為序列和相應(yīng)的標簽。 您可以使用任何序列長度,,這取決于領(lǐng)域知識。但是,,在我們的數(shù)據(jù)集中,,使用12的序列長度很方便,因為我們有月度數(shù)據(jù),,一年中有12個月,。如果我們有每日數(shù)據(jù),則更好的序列長度應(yīng)該是365,,即一年中的天數(shù),。因此,我們將訓練的輸入序列長度設(shè)置為12,。 接下來,,我們將定義一個名為的函數(shù)create_inout_sequences 。該函數(shù)將接受原始輸入數(shù)據(jù),,并將返回一個元組列表,。在每個元組中,第一個元素將包含與12個月內(nèi)旅行的乘客數(shù)量相對應(yīng)的12個項目的列表,,第二個元組元素將包含一個項目,,即在12 + 1個月內(nèi)的乘客數(shù)量。 如果輸出train_inout_seq 列表的長度,,您將看到它包含120個項目,。這是因為盡管訓練集包含132個元素,,但是序列長度為12,這意味著第一個序列由前12個項目組成,,第13個項目是第一個序列的標簽,。同樣,第二個序列從第二個項目開始,,到第13個項目結(jié)束,,而第14個項目是第二個序列的標簽,依此類推,。 現(xiàn)在讓我們輸出train_inout_seq 列表的前5個項目: 輸出: [(tensor([-0.9648, -0.9385, -0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385]), tensor([-0.9516])), (tensor([-0.9385, -0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385, -0.9516]), tensor([-0.9033])), (tensor([-0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385, -0.9516, -0.9033]), tensor([-0.8374])), (tensor([-0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385, -0.9516, -0.9033, -0.8374]), tensor([-0.8637])), (tensor([-0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385, -0.9516, -0.9033, -0.8374, -0.8637]), tensor([-0.9077]))]
您會看到每個項目都是一個元組,,其中第一個元素由序列的12個項目組成,第二個元組元素包含相應(yīng)的標簽,。 創(chuàng)建LSTM模型我們已經(jīng)對數(shù)據(jù)進行了預處理,,現(xiàn)在是時候訓練我們的模型了。我們將定義一個類LSTM ,,該類繼承自nn.Module PyTorch庫的類,。
讓我總結(jié)一下以上代碼。LSTM 該類的構(gòu)造函數(shù)接受三個參數(shù): input_size :對應(yīng)于輸入中的要素數(shù)量,。盡管我們的序列長度為12,,但每個月我們只有1個值,即乘客總數(shù),,因此輸入大小為1,。
hidden_layer_size :指定隱藏層的數(shù)量以及每層中神經(jīng)元的數(shù)量。我們將有一層100個神經(jīng)元,。
output_size :輸出中的項目數(shù),,由于我們要預測未來1個月的乘客人數(shù),因此輸出大小為1,。
接下來,,在構(gòu)造函數(shù)中,我們創(chuàng)建變量hidden_layer_size ,,lstm ,,linear ,和hidden_cell ,。LSTM算法接受三個輸入:先前的隱藏狀態(tài),,先前的單元狀態(tài)和當前輸入。該hidden_cell 變量包含先前的隱藏狀態(tài)和單元狀態(tài),。lstm 和linear 層變量用于創(chuàng)建LSTM和線性層,。 在forward 方法內(nèi)部,將input_seq 作為參數(shù)傳遞,,該參數(shù)首先傳遞給lstm 圖層,。lstm 層的輸出是當前時間步的隱藏狀態(tài)和單元狀態(tài),,以及輸出。lstm 圖層的輸出將傳遞到該linear 圖層,。預計的乘客人數(shù)存儲在predictions 列表的最后一項中,并返回到調(diào)用函數(shù),。下一步是創(chuàng)建LSTM() 類的對象,,定義損失函數(shù)和優(yōu)化器。由于我們在解決分類問題,, class LSTM(nn.Module): def __init__(self, input_size=1, hidden_layer_size=100, output_size=1): super().__init__() self.hidden_layer_size = hidden_layer_size
讓我們輸出模型: 輸出: LSTM( (lstm): LSTM(1, 100) (linear): Linear(in_features=100, out_features=1, bias=True) )
訓練模型我們將訓練模型150個步長,。 epochs = 150 for i in range(epochs): for seq, labels in train_inout_seq: optimizer.zero_grad()
輸出: epoch: 1 loss: 0.00517058 epoch: 26 loss: 0.00390285 epoch: 51 loss: 0.00473305 epoch: 76 loss: 0.00187001 epoch: 101 loss: 0.00000075 epoch: 126 loss: 0.00608046 epoch: 149 loss: 0.0004329932
由于默認情況下權(quán)重是在PyTorch神經(jīng)網(wǎng)絡(luò)中隨機初始化的,因此您可能會獲得不同的值,。 做出預測現(xiàn)在我們的模型已經(jīng)訓練完畢,我們可以開始進行預測了,。 您可以將上述值與train_data_normalized 數(shù)據(jù)列表的最后12個值進行比較。 該test_inputs 項目將包含12個項目,。在for 循環(huán)內(nèi),,這12個項目將用于對測試集中的第一個項目進行預測,,即編號133,。然后將預測值附加到test_inputs 列表中。在第二次迭代中,,最后12個項目將再次用作輸入,并將進行新的預測,,然后將其test_inputs 再次添加到列表中,。for 由于測試集中有12個元素,因此該循環(huán)將執(zhí)行12次,。在循環(huán)末尾,,test_inputs 列表將包含24個項目。最后12個項目將是測試集的預測值,。以下腳本用于進行預測: model.eval() for i in range(fut_pred): seq = torch.FloatTensor(test_inputs[-train_window:])
如果輸出test_inputs 列表的長度,,您將看到它包含24個項目??梢园匆韵路绞捷敵鲎詈?2個預測項目: 需要再次提及的是,,根據(jù)用于訓練LSTM的權(quán)重,您可能會獲得不同的值,。 由于我們對訓練數(shù)據(jù)集進行了歸一化,,因此預測值也進行了歸一化。我們需要將歸一化的預測值轉(zhuǎn)換為實際的預測值,。 print(actual_predictions)
現(xiàn)在讓我們針對實際值繪制預測值,。看下面的代碼: print(x)
在上面的腳本中,,我們創(chuàng)建一個列表,,其中包含最近12個月的數(shù)值。第一個月的索引值為0,,因此最后一個月的索引值為143,。 在下面的腳本中,我們將繪制144個月的乘客總數(shù)以及最近12個月的預計乘客數(shù)量,。 plt.autoscale(axis='x', tight=True) plt.plot(flight_data['passengers']) plt.plot(x,actual_predictions) plt.show()
輸出: 我們的LSTM所做的預測用橙色線表示,。您可以看到我們的算法不太準確,但是它仍然能夠捕獲最近12個月內(nèi)旅行的乘客總數(shù)的上升趨勢以及波動,。您可以嘗試在LSTM層中使用更多的時期和更多的神經(jīng)元,,以查看是否可以獲得更好的性能。 為了更好地查看輸出,,我們可以繪制最近12個月的實際和預測乘客數(shù)量,,如下所示: plt.plot(flight_data['passengers'][-train_window:]) plt.plot(x,actual_predictions) plt.show()
輸出: 預測不是很準確,但是該算法能夠捕獲趨勢,,即未來幾個月的乘客數(shù)量應(yīng)高于前幾個月,,且偶爾會有波動。 結(jié)論LSTM是解決序列問題最廣泛使用的算法之一,。在本文中,,我們看到了如何通過LSTM使用時間序列數(shù)據(jù)進行未來的預測。
|