您好,登錄后才能下訂單哦!
本文將重點介紹如何使用LSTM神經網絡架構,使用Keras和Tensorflow提供時間序列預測,特別是在股票市場數據集上,以提供股票價格的動量指標。
這個框架的代碼可以在下面的GitHub repo中找到(它假設python版本3.5.x和requirements.txt文件中的需求版本。偏離這些版本可能會導致錯誤):https://github.com/jaungiers/LSTM-Neural-Network-for-Time-Series-Prediction
什么是LSTM神經元?
長期困擾傳統神經網絡架構的基本問題之一是,如何能夠解釋依賴于信息和上下文的輸入序列。該信息可以是句子中的前一個單詞,以方便通過上下文來預測下一個單詞可能是什么,或者它也可以是序列的時序信息。
簡而言之,傳統的神經網絡每次都會采用獨立的數據向量,并且沒有內存概念來幫助他們處理需要內存的任務。
早期嘗試解決這個問題的方法是對網絡中的神經元使用簡單的反饋類型方法,其中輸出被反饋到輸入中,以提供最后看到的輸入的上下文。這些被稱為遞歸神經網絡(RNN)。雖然這些RNN在一定程度上起作用,但它們有一個相當大的缺點,因此它們的一些重要用途都會導致產生消失梯度的問題。我們不會進一步擴展討論它,而是說由于這個問題導致RNN不適合大多數現實問題,因此,我們需要找到別的解決辦法。
這就是長期短期記憶(LSTM)神經網絡起作用的地方。與RNN神經元一樣,LSTM神經元在其管道中可以保持記憶,以允許解決順序和時間問題,而不會出現影響其性能的消失梯度問題。
許多關于它的研究論文和文章都可以在網上找到,它們在數學細節上討論了LSTM細胞的工作原理。然而,在本文中,我們不會討論LSTM的復雜工作原理,因為我們更關心它們的使用。
對于上下文,下面是LSTM神經元的典型內部工作圖。它由若干層和逐點操作組成,這些操作充當數據輸入、輸出的門,為LSTM單元狀態提供信息。這種單元狀態是通過網絡和輸入保持長期記憶和上下文。
一個簡單的正弦波示例
為了演示LSTM神經網絡在預測時間序列中的使用,讓我們從最基本的事情開始,我們可以想到這是一個時間序列:可靠的正弦波。讓我們創建我們需要的數據,以便為LSTM網絡訓練此函數的許多“振蕩模型”。
代碼數據文件夾中提供的數據包含我們創建的sinewave.csv文件,該文件包含5001個正弦波時間段,幅度和頻率為1(角頻率為6.28),時間差值為0.01。繪制時的結果如下所示:
數據集為正弦波
現在我們有了數據,我們實際上想要實現什么?簡單的說,我們只是希望LSTM從我們將提供的數據的設定窗口大小中學習正弦波,并且希望我們可以要求LSTM預測該系列中的第N步驟,并且它將繼續輸出正弦波。
我們將首先把CSV文件中的數據轉換加載到pandas數據幀,然后將其用于輸出,它將為LSTM提供數據的numpy數組。 Keras LSTM層的工作方式是采用3維(N,W,F)的numpy數組,其中N是訓練序列的數量,W是序列長度,F是每個序列的特征數。我們選擇使用50的序列長度(讀取窗口大小)來允許網絡,因此可以在每個序列中看到正弦波的形狀,有希望自己建立基于序列的序列模式。
序列本身是滑動窗口,因此每次移動1,導致與先前窗口不斷重疊。當繪制時,序列長度為50的典型訓練窗口如下所示:
Sinewave數據集訓練窗口
為了加載這些數據,我們在代碼中創建了一個DataLoader類,為數據加載層提供抽象。您會注意到,在初始化DataLoader對象時,會傳入文件名, 并確定用于訓練與測試的數據百分比的拆分變量,且允許選擇一列或多列數據的列變量用于單維或多維分析。
在我們有一個允許我們加載數據的數據對象之后,需要構建深度神經網絡模型。同樣,對于抽象,我們的代碼框架使用的是模型類和config.json文件,在給定存儲在配置文件中的所需體系結構和超參數的情況下,輕松構建模型的實例。構建我們網絡的主要功能是build_model()函數,它接收經過解析的配置文件。
此功能代碼如下所示,可以輕松擴展,以便將來在更復雜的體系架構上使用。
加載數據并建立模型后,我們現在可以繼續使用我們的訓練數據訓練模型。為此,我們創建了一個單獨的運行模塊,它將利用我們的模型和模塊抽象將它們組合起來進行訓練、輸出和可視化。
下面是訓練我們模型的一般運行線程代碼:
對于輸出,我們將運行兩種類型的預測:第一種將以逐點方式進行預測,即我們每次僅預測單個點,將此點繪制為預測,然后沿著下一個窗口進行預測使用完整的測試數據并再次預測下一個點。
我們要做的第二個預測是預測一個完整的序列,我們只用訓練數據的第一部分初始化一次訓練窗口。然后模型預測下一個點,我們就移動窗口,就像逐點方法一樣。不同之處在于我們使用我們在先前預測中預測的數據來進行下一步預測。在第二步中,這意味著只有一個數據點(最后一個點)來自先前的預測。在第三個預測中,最后兩個數據點將來自先前的預測,依此類推。經過50次預測后,我們的模型將隨后根據自己的先前預測進行預測。這使我們可以使用該模型預測未來的許多時間步驟,但由于它是在預測的基礎上進行預測,這反過來可以反過來又可以預測,將增加預測的錯誤率,我們會預測的更遠。
下面我們可以看到逐點預測和完整序列預測的代碼和相應的輸出。
逐點正弦波預測
正弦波全序列預測
作為參考,可以在下面的配置文件中看到用于正弦波示例的網絡架構和超參數。
在真實數據的疊加下我們可以看到,只需1個時期和相當小的訓練數據集,LSTM深度神經網絡就可以很好地預測正弦函數。
您可以看到,隨著我們對未來越來越多的預測,誤差幅度會隨著先前預測中的誤差在用于未來預測時被越來越多地放大并且增加。因此,我們看到在完整序列示例中,預測越遠,我們預測預測的頻率和幅度與真實數據相比就越不準確。然而,由于sin函數是一個非常簡單的零噪聲振蕩函數,它仍然可以在沒有過度擬合的情況下很好地預測它。這很重要,因為我們可以通過增加時期和取出dropout 層來輕松地過度擬合模型。這個訓練數據幾乎完全準確,與測試數據具有相同的模式,但對于其他現實世界的例子,將模型過度擬合到訓練數據上會導致測試精度直線下降,因為模型不會一概而論。
在下一步中,我們將嘗試在此類真實數據上使用該模型來查看效果。
不那么簡單的股票市場
我們在精確的逐點基礎上預測了幾百個正弦波的步長。因此,我們現在可以在股市時間序列中做同樣的事情并立即獲利,對嗎?不幸的是,在現實世界中,這并不是那么簡單。
與正弦波不同,股票市場時間序列不是可以映射的任何特定靜態函數。描述股票市場時間序列運動的最佳屬性是隨機游走。作為隨機過程,真正的隨機游走沒有可預測的模式,因此嘗試對其進行建模將毫無意義。幸運的是,許多方面都在持續爭論說股票市場不是一個純粹的隨機過程,這使我們可以理解時間序列可能有某種隱藏模式。正是這些隱藏的模式,LSTM深度網絡成為預測的主要候選者。
此示例將使用的數據是數據文件夾中的sp500.csv文件。此文件包含2000年1月至2018年9月的標準普爾500股票指數的開盤價、最高價、最低價、收盤價以及每日交易量。
在第一個例子中,我們將僅使用收盤價創建單維模型。調整config.json文件以反映新數據,我們將保持大部分參數相同。然而,需要做出的一個改變是,與只有-1到+1之間的數值范圍的正弦波不同,收盤價是股票市場不斷變化的絕對價格。這意味著如果我們試圖在不對其進行標準化的情況下訓練模型,它就永遠不會收斂。
為了解決這個問題,我們將采用每個n大小的訓練/測試數據窗口,并對每個窗口進行標準化以反映從該窗口開始的百分比變化(因此點i = 0處的數據將始終為0)。我們將使用以下等式進行歸一化,然后在預測過程結束時進行去標準化,以獲得現實世界數量的預測:
n =價格變化的標準化列表[窗口]
p =調整后的每日回報價格的原始清單[窗口]
反規范化:
我們已將normalise_windows()函數添加到DataLoader類以執行此轉換,并且配置文件中包含布爾規范化標志,表示這些窗口的規范化。
隨著窗口的標準化,我們現在可以運行模型,就像我們針對正弦波數據運行模型一樣。但是,我們在運行這些數據時做了一個重要的改變,而不是使用我們框架的model.train()方法,只是使用我們創建的model.train_generator()方法。我們這樣做是因為我們發現在嘗試訓練大型數據集時很容易耗盡內存,因為model.train()函數將完整數據集加載到內存中,然后將規范化應用于內存中的每個窗口,容易導致內存溢出。因此,我們使用了Keras的fit_generator()函數,允許使用python生成器動態訓練數據集來繪制數據,這意味著內存利用率將大大降低。下面的代碼詳細說明了用于運行三種類型預測的新運行線程(逐點,完整序列和多序列)。
如上所述,在單個逐點預測上運行數據可以非常接近匹配返回的內容。但這有點欺騙性。經過仔細檢查,會發現預測線由奇異的預測點組成,這些預測點在它們后面具有整個先前的真實歷史窗口。因此,網絡不需要了解時間序列本身,除了下一個點很可能不會離最后一點太遠。因此,即使它得到錯誤點的預測,下一個預測也將考慮真實的歷史并忽略不正確的預測,然后再次允許產生錯誤。
雖然這對于下一個價格點的精確預測而言最初聽起來并不樂觀,但它確實有一些重要的用途。雖然它不知道確切的下一個價格是多少,但它確實能夠準確地表示下一個價格的范圍。
此信息可用于諸如波動率預測等應用(能夠預測市場中高或低波動的時段對特定交易策略非常有利),或遠離交易這也可用作良好指標用于異常檢測。可以通過預測下一個點,然后將其與真實數據進行比較來實現異常檢測,并且如果真實數據值與預測點顯著不同,則可以針對該數據點標出異常標記。
標準普爾500指數逐點預測
繼續進行完整的序列預測,似乎這被證明是對這種類型的時間序列最不有用的預測(至少使用這些超參數訓練這個模型)。我們可以看到預測開始時的輕微碰撞,其中模型遵循某種類型的動量,但是很快我們可以看到模型確定最佳模式是收斂到時間序列的某個均衡。在這個階段,這可能看起來并沒有提供太多價值,但是均值回歸交易者可能會在那里宣稱,該模型只是找到價格序列在波動率被消除時將恢復的平均值。
標準普爾500指數全序列預測
最后,我們對該模型進行了第三種預測,我將其稱為多序列預測。這是完整序列預測的混合,因為它仍然使用測試數據初始化測試窗口,預測下一個點,然后使用下一個點創建一個新窗口。但是,一旦它到達輸入窗口完全由過去預測組成的點,它就會停止,向前移動一個完整的窗口長度,用真實的測試數據重置窗口,然后再次啟動該過程。實質上,這為測試數據提供了多個趨勢線預測,以便能夠分析模型獲得未來動量趨勢的程度。
標準普爾500指數多序列預測
我們可以從多序列預測中看出,網絡似乎正確地預測了絕大多數時間序列的趨勢(和趨勢幅度)。雖然不完美,但它確實表明了LSTM深度神經網絡在順序和時間序列問題中的有用性。通過仔細的超參數調整,肯定可以實現更高的準確性。
結論
雖然本文的目的是在實踐中給出LSTM深度神經網絡的一個工作實例,但它只是觸及了它們在順序和時間問題中的潛力和應用的表面。
在撰寫本文時,LSTM已成功應用于眾多現實問題中,從此處所述的經典時間序列問題到文本自動糾正、異常檢測和欺詐檢測,以及開發自動駕駛汽車技術的核心。
目前使用上述LSTM存在一些局限性,特別是在使用金融時間序列時,該系列本身具有很難建模的非平穩特性(盡管在使用貝葉斯深度神經網絡方法方面取得了進展)解決時間序列的非平穩性問題。同樣對于一些應用,還發現基于注意力的神經網絡機制的新進展已經超過LSTM(并且LSTM與這些基于注意力的機制相結合也優于其自身)。
然而,截至目前,LSTM在更經典的統計時間序列方法上提供了顯著的進步,能夠非線性地建模關系,并且能夠以非線性方式處理具有多個維度的數據。
我們開發的框架的完整源代碼可以在以下GitHub頁面上的MIT許可證下找到:https: //github.com/jaungiers/LSTM-Neural-Network-for-Time-Series-Prediction
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。