在Python中使用LSTM和PyTorch進(jìn)行時(shí)間序列預(yù)測|附代碼數(shù)據(jù)
全文鏈接:http://tecdat.cn/?p=8145
最近我們被客戶要求撰寫關(guān)于LSTM的研究報(bào)告,包括一些圖形和統(tǒng)計(jì)輸出。 顧名思義,時(shí)間序列數(shù)據(jù)是一種隨時(shí)間變化的數(shù)據(jù)類型。例如,24小時(shí)內(nèi)的溫度,一個(gè)月內(nèi)各種產(chǎn)品的價(jià)格,一年中特定公司的股票價(jià)格
諸如長期短期記憶網(wǎng)絡(luò)(LSTM)之類的高級深度學(xué)習(xí)模型能夠捕獲時(shí)間序列數(shù)據(jù)中的模式,因此可用于對數(shù)據(jù)的未來趨勢進(jìn)行預(yù)測。在本文中,您將看到如何使用LSTM算法使用時(shí)間序列數(shù)據(jù)進(jìn)行將來的預(yù)測。
數(shù)據(jù)集和問題定義
?讓我們先導(dǎo)入所需的庫,然后再導(dǎo)入數(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個(gè)月來預(yù)測最近12個(gè)月內(nèi)旅行的乘客人數(shù)。請記住,我們有144個(gè)月的記錄,這意味著前132個(gè)月的數(shù)據(jù)將用于訓(xùn)練我們的LSTM模型,而模型性能將使用最近12個(gè)月的值進(jìn)行評估。
讓我們繪制每月乘客的出行頻率。??接下來的腳本繪制了每月乘客人數(shù)的頻率:
plt.grid(True)plt.autoscale(axis='x',tight=True)plt.plot(data['passengers'])
輸出:

輸出顯示,多年來,乘飛機(jī)旅行的平均乘客人數(shù)有所增加。一年內(nèi)旅行的乘客數(shù)量波動,這是有道理的,因?yàn)樵谑罴倩蚝倨陂g,旅行的乘客數(shù)量與一年中的其他部分相比有所增加。
數(shù)據(jù)預(yù)處理
數(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)該看到以下浮點(diǎn)類型值:
print(all_data)
前132條記錄將用于訓(xùn)練模型,后12條記錄將用作測試集。以下腳本將數(shù)據(jù)分為訓(xùn)練集和測試集。
test_data_size = 12train_data = all_data[:-test_data_size]test_data = all_data[-test_data_size:]
現(xiàn)在讓我們輸出測試和訓(xùn)練集的長度:
輸出:
13212
如果現(xiàn)在輸出測試數(shù)據(jù),您將看到它包含all_data
numpy數(shù)組中的最后12條記錄:輸出:
[417. 391.... 390. 432.]
我們的數(shù)據(jù)集目前尚未歸一化。最初幾年的乘客總數(shù)遠(yuǎn)少于后來幾年的乘客總數(shù)。標(biāo)準(zhǔn)化數(shù)據(jù)以進(jìn)行時(shí)間序列預(yù)測非常重要。以在一定范圍內(nèi)的最小值和最大值之間對數(shù)據(jù)進(jìn)行歸一化。我們將使用模塊中的MinMaxScaler
類sklearn.preprocessing
來擴(kuò)展數(shù)據(jù)。?
以下代碼 將最大值和最小值分別為-1和1進(jìn)行歸一化。
MinMaxScaler(feature_range=(-1, 1))
輸出:
[[-0.96483516]...... [0.33186813] [0.13406593] [0.32307692]]
您可以看到數(shù)據(jù)集值現(xiàn)在在-1和1之間。
在此重要的是要提到數(shù)據(jù)歸一化僅應(yīng)用于訓(xùn)練數(shù)據(jù),而不應(yīng)用于測試數(shù)據(jù)。如果對測試數(shù)據(jù)進(jìn)行歸一化處理,則某些信息可能會從訓(xùn)練集中 到測試集中。
最后的預(yù)處理步驟是將我們的訓(xùn)練數(shù)據(jù)轉(zhuǎn)換為序列和相應(yīng)的標(biāo)簽。
您可以使用任何序列長度,這取決于領(lǐng)域知識。但是,在我們的數(shù)據(jù)集中,使用12的序列長度很方便,因?yàn)槲覀冇性露葦?shù)據(jù),一年中有12個(gè)月。如果我們有每日數(shù)據(jù),則更好的序列長度應(yīng)該是365,即一年中的天數(shù)。因此,我們將訓(xùn)練的輸入序列長度設(shè)置為12。
接下來,我們將定義一個(gè)名為的函數(shù)create_inout_sequences
。該函數(shù)將接受原始輸入數(shù)據(jù),并將返回一個(gè)元組列表。在每個(gè)元組中,第一個(gè)元素將包含與12個(gè)月內(nèi)旅行的乘客數(shù)量相對應(yīng)的12個(gè)項(xiàng)目的列表,第二個(gè)元組元素將包含一個(gè)項(xiàng)目,即在12 + 1個(gè)月內(nèi)的乘客數(shù)量。
如果輸出train_inout_seq
列表的長度,您將看到它包含120個(gè)項(xiàng)目。這是因?yàn)楸M管訓(xùn)練集包含132個(gè)元素,但是序列長度為12,這意味著第一個(gè)序列由前12個(gè)項(xiàng)目組成,第13個(gè)項(xiàng)目是第一個(gè)序列的標(biāo)簽。同樣,第二個(gè)序列從第二個(gè)項(xiàng)目開始,到第13個(gè)項(xiàng)目結(jié)束,而第14個(gè)項(xiàng)目是第二個(gè)序列的標(biāo)簽,依此類推。
現(xiàn)在讓我們輸出train_inout_seq
列表的前5個(gè)項(xiàng)目:
輸出:
[(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]))]
您會看到每個(gè)項(xiàng)目都是一個(gè)元組,其中第一個(gè)元素由序列的12個(gè)項(xiàng)目組成,第二個(gè)元組元素包含相應(yīng)的標(biāo)簽。
創(chuàng)建LSTM模型
我們已經(jīng)對數(shù)據(jù)進(jìn)行了預(yù)處理,現(xiàn)在是時(shí)候訓(xùn)練我們的模型了。我們將定義一個(gè)類LSTM
,該類繼承自nn.Module
PyTorch庫的類。?
讓我總結(jié)一下以上代碼。LSTM
該類的構(gòu)造函數(shù)接受三個(gè)參數(shù):
input_size
:對應(yīng)于輸入中的要素?cái)?shù)量。盡管我們的序列長度為12,但每個(gè)月我們只有1個(gè)值,即乘客總數(shù),因此輸入大小為1。hidden_layer_size
:指定隱藏層的數(shù)量以及每層中神經(jīng)元的數(shù)量。我們將有一層100個(gè)神經(jīng)元。output_size
:輸出中的項(xiàng)目數(shù),由于我們要預(yù)測未來1個(gè)月的乘客人數(shù),因此輸出大小為1。
接下來,在構(gòu)造函數(shù)中,我們創(chuàng)建變量hidden_layer_size
,lstm
,linear
,和hidden_cell
。LSTM算法接受三個(gè)輸入:先前的隱藏狀態(tài),先前的單元狀態(tài)和當(dāng)前輸入。該hidden_cell
變量包含先前的隱藏狀態(tài)和單元狀態(tài)。lstm
和linear
層變量用于創(chuàng)建LSTM和線性層。
在forward
方法內(nèi)部,將input_seq
作為參數(shù)傳遞,該參數(shù)首先傳遞給lstm
圖層。lstm
層的輸出是當(dāng)前時(shí)間步的隱藏狀態(tài)和單元狀態(tài),以及輸出。lstm
圖層的輸出將傳遞到該linear
圖層。預(yù)計(jì)的乘客人數(shù)存儲在predictions
列表的最后一項(xiàng)中,并返回到調(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))
訓(xùn)練模型
我們將訓(xùn)練模型150個(gè)步長。?
epochs = 150for i in range(epochs): ? ?for seq, labels in train_inout_seq: ? ? ? ?optimizer.zero_grad()
輸出:
epoch: ? 1 loss: 0.00517058epoch: ?26 loss: 0.00390285epoch: ?51 loss: 0.00473305epoch: ?76 loss: 0.00187001epoch: 101 loss: 0.00000075epoch: 126 loss: 0.00608046epoch: 149 loss: 0.0004329932
由于默認(rèn)情況下權(quán)重是在PyTorch神經(jīng)網(wǎng)絡(luò)中隨機(jī)初始化的,因此您可能會獲得不同的值。
做出預(yù)測
現(xiàn)在我們的模型已經(jīng)訓(xùn)練完畢,我們可以開始進(jìn)行預(yù)測了。?
您可以將上述值與train_data_normalized
數(shù)據(jù)列表的最后12個(gè)值進(jìn)行比較。
?該test_inputs
項(xiàng)目將包含12個(gè)項(xiàng)目。在for
循環(huán)內(nèi),這12個(gè)項(xiàng)目將用于對測試集中的第一個(gè)項(xiàng)目進(jìn)行預(yù)測,即編號133。然后將預(yù)測值附加到test_inputs
列表中。在第二次迭代中,最后12個(gè)項(xiàng)目將再次用作輸入,并將進(jìn)行新的預(yù)測,然后將其test_inputs
再次添加到列表中。for
由于測試集中有12個(gè)元素,因此該循環(huán)將執(zhí)行12次。在循環(huán)末尾,test_inputs
列表將包含24個(gè)項(xiàng)目。最后12個(gè)項(xiàng)目將是測試集的預(yù)測值。以下腳本用于進(jìn)行預(yù)測:
model.eval()for i in range(fut_pred): ? ?seq = torch.FloatTensor(test_inputs[-train_window:])
如果輸出test_inputs
列表的長度,您將看到它包含24個(gè)項(xiàng)目。可以按以下方式輸出最后12個(gè)預(yù)測項(xiàng)目:
需要再次提及的是,根據(jù)用于訓(xùn)練LSTM的權(quán)重,您可能會獲得不同的值。
由于我們對訓(xùn)練數(shù)據(jù)集進(jìn)行了歸一化,因此預(yù)測值也進(jìn)行了歸一化。我們需要將歸一化的預(yù)測值轉(zhuǎn)換為實(shí)際的預(yù)測值。?
print(actual_predictions)
現(xiàn)在讓我們針對實(shí)際值繪制預(yù)測值。看下面的代碼:
print(x)
在上面的腳本中,我們創(chuàng)建一個(gè)列表,其中包含最近12個(gè)月的數(shù)值。第一個(gè)月的索引值為0,因此最后一個(gè)月的索引值為143。
在下面的腳本中,我們將繪制144個(gè)月的乘客總數(shù)以及最近12個(gè)月的預(yù)計(jì)乘客數(shù)量。
plt.autoscale(axis='x', tight=True)plt.plot(flight_data['passengers'])plt.plot(x,actual_predictions)plt.show()
輸出:

我們的LSTM所做的預(yù)測用橙色線表示。您可以看到我們的算法不太準(zhǔn)確,但是它仍然能夠捕獲最近12個(gè)月內(nèi)旅行的乘客總數(shù)的上升趨勢以及波動。您可以嘗試在LSTM層中使用更多的時(shí)期和更多的神經(jīng)元,以查看是否可以獲得更好的性能。
為了更好地查看輸出,我們可以繪制最近12個(gè)月的實(shí)際和預(yù)測乘客數(shù)量,如下所示:
plt.plot(flight_data['passengers'][-train_window:])plt.plot(x,actual_predictions)plt.show()
輸出:

?預(yù)測不是很準(zhǔn)確,但是該算法能夠捕獲趨勢,即未來幾個(gè)月的乘客數(shù)量應(yīng)高于前幾個(gè)月,且偶爾會有波動。
結(jié)論
LSTM是解決序列問題最廣泛使用的算法之一。在本文中,我們看到了如何通過LSTM使用時(shí)間序列數(shù)據(jù)進(jìn)行未來的預(yù)測。?

點(diǎn)擊文末?“閱讀原文”
獲取全文完整代碼數(shù)據(jù)資料。
本文選自《在Python中使用LSTM和PyTorch進(jìn)行時(shí)間序列預(yù)測》。
點(diǎn)擊標(biāo)題查閱往期內(nèi)容
PYTHON用KERAS的LSTM神經(jīng)網(wǎng)絡(luò)進(jìn)行時(shí)間序列預(yù)測天然氣價(jià)格例子
Python對商店數(shù)據(jù)進(jìn)行l(wèi)stm和xgboost銷售量時(shí)間序列建模預(yù)測分析
Matlab用深度學(xué)習(xí)長短期記憶(LSTM)神經(jīng)網(wǎng)絡(luò)對文本數(shù)據(jù)進(jìn)行分類
RNN循環(huán)神經(jīng)網(wǎng)絡(luò) 、LSTM長短期記憶網(wǎng)絡(luò)實(shí)現(xiàn)時(shí)間序列長期利率預(yù)測
結(jié)合新冠疫情COVID-19股票價(jià)格預(yù)測:ARIMA,KNN和神經(jīng)網(wǎng)絡(luò)時(shí)間序列分析
深度學(xué)習(xí):Keras使用神經(jīng)網(wǎng)絡(luò)進(jìn)行簡單文本分類分析新聞組數(shù)據(jù)
用PyTorch機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)分類預(yù)測銀行客戶流失模型
PYTHON用LSTM長短期記憶神經(jīng)網(wǎng)絡(luò)的參數(shù)優(yōu)化方法預(yù)測時(shí)間序列洗發(fā)水銷售數(shù)據(jù)
Python用Keras神經(jīng)網(wǎng)絡(luò)序列模型回歸擬合預(yù)測、準(zhǔn)確度檢查和結(jié)果可視化
Python用LSTM長短期記憶神經(jīng)網(wǎng)絡(luò)對不穩(wěn)定降雨量時(shí)間序列進(jìn)行預(yù)測分析
R語言中的神經(jīng)網(wǎng)絡(luò)預(yù)測時(shí)間序列:多層感知器(MLP)和極限學(xué)習(xí)機(jī)(ELM)數(shù)據(jù)分析報(bào)告
R語言深度學(xué)習(xí):用keras神經(jīng)網(wǎng)絡(luò)回歸模型預(yù)測時(shí)間序列數(shù)據(jù)
Matlab用深度學(xué)習(xí)長短期記憶(LSTM)神經(jīng)網(wǎng)絡(luò)對文本數(shù)據(jù)進(jìn)行分類
R語言KERAS深度學(xué)習(xí)CNN卷積神經(jīng)網(wǎng)絡(luò)分類識別手寫數(shù)字圖像數(shù)據(jù)(MNIST)
MATLAB中用BP神經(jīng)網(wǎng)絡(luò)預(yù)測人體脂肪百分比數(shù)據(jù)
Python中用PyTorch機(jī)器學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)分類預(yù)測銀行客戶流失模型
R語言實(shí)現(xiàn)CNN(卷積神經(jīng)網(wǎng)絡(luò))模型進(jìn)行回歸數(shù)據(jù)分析
SAS使用鳶尾花(iris)數(shù)據(jù)集訓(xùn)練人工神經(jīng)網(wǎng)絡(luò)(ANN)模型
【視頻】R語言實(shí)現(xiàn)CNN(卷積神經(jīng)網(wǎng)絡(luò))模型進(jìn)行回歸數(shù)據(jù)分析
Python使用神經(jīng)網(wǎng)絡(luò)進(jìn)行簡單文本分類
R語言用神經(jīng)網(wǎng)絡(luò)改進(jìn)Nelson-Siegel模型擬合收益率曲線分析
R語言基于遞歸神經(jīng)網(wǎng)絡(luò)RNN的溫度時(shí)間序列預(yù)測
R語言神經(jīng)網(wǎng)絡(luò)模型預(yù)測車輛數(shù)量時(shí)間序列
R語言中的BP神經(jīng)網(wǎng)絡(luò)模型分析學(xué)生成績
matlab使用長短期記憶(LSTM)神經(jīng)網(wǎng)絡(luò)對序列數(shù)據(jù)進(jìn)行分類
R語言實(shí)現(xiàn)擬合神經(jīng)網(wǎng)絡(luò)預(yù)測和結(jié)果可視化
用R語言實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)預(yù)測股票實(shí)例
使用PYTHON中KERAS的LSTM遞歸神經(jīng)網(wǎng)絡(luò)進(jìn)行時(shí)間序列預(yù)測
python用于NLP的seq2seq模型實(shí)例:用Keras實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)機(jī)器翻譯
用于NLP的Python:使用Keras的多標(biāo)簽文本LSTM神經(jīng)網(wǎng)絡(luò)分類