如何用LSTM自編碼器進行極端事件預測?(含Python實現)
- 2019 年 10 月 7 日
- 筆記
原標題 | Extreme Event Forecasting with LSTM Autoencoders
作 者 | Marco Cerliani
翻 譯 | 黃闖、Dooria、ybNero、肖書忠、鄴調
審 校 | 唐里、鳶尾、skura

Photo by Nur Afni Setiyaningrum on Unsplash
對於每個數據科學家來說,進行極端事件預測是一個經常會遇到的噩夢。尋尋覓覓,我終於發現了處理這個問題非常有趣的資源。就我個人而言,我確實愛上了Uber研究人員發布的方法。在他們的論文(https://eng.uber.com/neural-networks/ 和 https://arxiv.org/pdf/1709.01907.pdf,有兩個版本)中,他們開發了一個基於機器學習的解決方案,用於預測每日乘客需求。他們的方法以其簡潔易懂的解釋和易於實施的特點而引起了我的注意。所以我的目的是用python重現他們的發現。我對這個挑戰非常滿意,並且最終我還提高了自己對回歸預測的認識。
這篇文章最重要的收穫可以概括為:
1.開發一種穩定的方法來評估和比較keras模型(同時避免權重種子生成器的問題);
2.實現了一個簡單而智慧的LSTM自編碼器,用於新特徵的創建;
3.通過簡單的技巧提高時間序列的預測性能(參見上面的步驟);
4.處理嵌套數據集,即我們觀察到的屬於不同實體的問題(例如,不同商店/引擎/人員的時間序列等)。從這個意義上說,我們只為所有人開發一個高性能的模型!
保持鎮定,讓我們一步一步開始吧。
問題概述
對於Uber來講,對出行(特別是特殊日期里)的準確預測有許多重要的好處:更有效的駕駛員分配,以減少司機的等待時間,預算和其他相關任務。
為了更準確地預測駕駛員對共享車輛的需求,Uber的研究人員開發了一種用於時間序列預測的高性能模型。他們能夠將一個模型與來自不同位置(城市)的不同時間序列相匹配,該過程允許提取相關的時間模式。最後,他們能夠針對不同的位置(城市)預測需求,優於傳統的預測方法。
對於這個問題,uber使用了他們的內部數據,即不同城市的出行數據,其包含了一些額外特徵:天氣資訊、城市等級資訊。他們的目標是以固定窗口數據(即過去一天)預測第二天的需求。
不幸的是,我們並沒有這種優質的數據,不過幸好我們可愛的kaggle粉絲給我挑選了一個優質的數據集:Avocado Prices Dataset (https://www.kaggle.com/neuromusic/avocado-prices)。這個數據展示了兩種不同品種的鱷梨的歷史價格,和其在美國多個商場的銷量。
我們選擇這個數據主要是因為我們需要具有時間依賴性的嵌套數據集:我們擁有一共54個商場的鱷梨銷售記錄,也就是我們所說的時間序列數據,如果算上不同種類(常規和有機),我們就有108個時間序列。uber的科研人員強調這種數據結構非常重要,因為它可以讓我們的模型發現其中重要的隱藏關係。在我們使用LSTM Autoencoder做特徵提取的時候,序列間的關係也會為我們模型的效果帶來提升。
我們使用了從開始到2017年末為止的售價數據搭建模型,而18年最開始兩月的數據我們拿來做測試數據。我們分析時,應該考慮到所有數據的回歸曲線,圖中顯示的頻率較弱,所以我們決定:給定一個固定的窗口,即過去四周數據作為訓練集,預測即將到來的價格。

訓練數據(藍色)測試數據(橘色),囊括所有數據
由於缺乏指數增長和交易行為,我們不需要擴展我們的價格序列。
模型
為了解決我們的預測任務,我們複製了Uber的一個新結構模型,它時一個但模型卻為我們提供了複雜的預測功能。如下圖所示,我們訓練LSTM Autoencoder作為我們模型的第一部分:自動特徵提取,這對於大量捕獲複雜的動態時間序列是很重要的。特徵向量通過拼接後作為新的輸入傳到LSTM Forecaster模組中做預測(autoencoder模組輸入的是多個時間序列,這裡是拼接好的單一向量)
我們的forecaster模組的工作流程十分好理解:我們有一個初始的窗口,代表著不同商場的若干周售價數據。我們首先使用這些數據去訓練我們LSTM Autoencoder, 之後刪除encoder模組,並利用它製作特徵生成器,最後再去訓練我們forecaster模組中的LSTM 模型做預測任務。基於真實/存在的回歸值和人造向量我們可以獲得的下周的鱷梨預測價格。

圖片來自於Time-series ExtremeEvent Forecasting with Neural Networks at Uber
我們可以很容易的在keras實現這個邏輯。
我們的LSTMAutoencoders模組由簡單的LSTM encoder層組成,其餘則由LSTM decoder組成,最後還有一層TImeDistribute層,切莫忘了。你將知道在模型驗證時添加dropout的好處,相信我,不會害你的。
input_ae= Input(shape = (sequence_length, 1)) encode_ae = LSTM(128, return_sequences = True, dropout = 0.3)(input_ae, training = True) decode_ae = LSTM(32, return_sequences = True, dropout = 0.3)(encode_ae, training = True) out_ae = TimeDistributed(Dense(1))(decode_ae) sequence_autoencoder = Model(input_ae, out_ae) sequence_autoencoder.compile(optimizer='adam', loss='mse', metrics=['mse']) sequence_autoencoder.fit(X, y, batch_size = 16, epochs = 100, verbose = 2, shuffle=True)
我們會將特徵提取部分計算出來並拼接作為其他變數。關於這點我和uber的解決方案有點偏差:他們建議使用整合技術(例如平均)將特徵向量聚合,作為我們特徵向量的提取操作。我決定讓它們保持原樣,因為在我的實驗中這樣可以給我帶來更好的結果。
encoder = Model(input_ae, encode_ae) XX = encoder.predict(X) XXF = np.concatenate([XX, F], axis = 2)
最後,預測模型是另一個基於簡單LSTM的神經網路。
inputs1 = Input(X_train1.shapw[1], X_train1.shape[2]) lstm1 = LSMT(128, return_sequence=True, dropout = 0.3)(inputs1, training = True) lstm1 = LSTM(32, return_sequence=True, dropout = 0.3)(lstm1, training = True) dense1 = Dense(50)(lstm1) out1 = Dense(1)(dense1) model1 = Model(inputs, out1) model1.compile(loss='mse', optimizer='adam', metrics=['mse']) model.fit(X_train1, y_train1, epochs=30, batch_size=128, verbose=2, sh
評估
最後,我們已經準備好看一些結果和做預測。最後一步所要做的是,為了進行結果對比,我們需要創建一個對抗模型,製造出一些具有健壯性預測方法的結果。
個人來看,評估兩個不同程式的最好方法是儘可能多的重複自身,為了能夠讓它們能夠聚焦在真正需要關注的點上。在這次實踐中,我想展示一些LSTM自編碼能夠作為一個有力的工具,產出對時序數據預測有利的相關特徵的證據。在這種層面上去評估我們方法的好處,我決定去開發一個新的預測價格的模型,用之前預測NN同樣的結構。

模型1 和模型2 之間不同點在於,它們接收到的特徵不一樣:
模型1接收編碼器輸出加上回歸結果;
模型2接收歷史原始數據加上回歸結果。
不確定性估計
在自然中對於事關利益的極端事件時序預測是非常重要的。另外,如果你嘗試創建一個基於神經網路的模型,你的結果也將會受制於神經網路初始權重初始化,為了克服這個缺點,有一些現存的方法來應對不確定性估計:從貝葉斯到基於bootstrap理論。
在uber研究員的工作中,他們融合來bootstrap和貝葉斯方法來創建一個簡單、健壯、有確定便捷的、並且易收斂的模型。
這項技術是非常簡單並且實用,我們已經部署上來。如下圖所示,在神經網路前饋過程中,dropout應用在每一層中,包括編碼層和預測網路。結果,編碼層隨機dropout能夠在嵌入空間更聰明的輸入,讓模型泛化能力增強,而且傳播更遠通過預測網路。

很python的說,在神經網路中我們簡單增加一些可訓練的dropout層,在預測中我們激活它們(keras預測中去除來dropout),下邊是我用過的一些簡單功能,簡化為:dropout 激活,特徵串聯,預測所有的數據。

為了最後的評估,我們必須迭代調用上邊的函數,存儲它們的結果。我也可以計算出在每一次迭代中的預測分值(我選擇的是均絕對值誤差)。
scores1 = [] for i in tqdm.tqdm(range(0,100)): scores1.append(mean_absolute_error(stoc_drop1(0.5), y_test1)) print(np.mean(scores1), np.std(scores1))
我們必須設置超參數,就是迭代次數,dropout比率。存儲每一次預測分值之後,我們可以計算均值,標準差,以及相關均方絕對值誤差。
預測和結果
我們對我們的「競爭模型」複製了同樣的過程,只使用lstm預測網路。在平均得分和計算不確定度後,最終結果為:LSTM自動編碼器+LSTM預報員0.118 Mae(0.0012 Mae不確定度),單個LSTM預報員0.124 Mae(0.0015 Mae不確定度)。在不確定性程度相同的情況下,我們的預測精度最終提高了5%。我們可以斷言,我們的lstm自動編碼器是一個從時間序列中提取重要的未知特徵的好武器。下面我還報告了有機鱷梨和傳統鱷梨在單一市場上的得分表現。

測試數據的性能(mae)比較
在訓練期間,我也保留排除整個市場(奧爾巴尼地區)的權利。這是因為我想測試我們的網路在沒有訓練過的數據上的效果。我們在有機市場和傳統市場的表現都有所改善。

看不見時間序列的性能比較
總結
在本文中,我複製了uber為特殊事件預測開發的端到端神經網路架構。我想強調的是:lstm自動編碼器在特徵提取中的作用;該方案的可擴展性,能夠很好地推廣,避免了為每個時間序列訓練多個模型;能夠為神經網路的評價提供一種穩定而有益的方法。
我還注意到,當你有足夠數量的時間序列共享共同的行為時,這種解決方案非常適合……這些行為不是顯而易見的重要,而是自動編碼器為我們製造的。
參考文獻
[1] Deep and Confident Prediction for Time Series atUber: Lingxue Zhu, Nikolay Laptev
[2] Time-series ExtremeEvent Forecasting with Neural Networks at Uber: Nikolay Laptev, Jason Yosinski,Li Erran Li, Slawek Smyl
via https://towardsdatascience.com/extreme-event-forecasting-with-lstm-autoencoders-297492485037