基於 Prophet 的時間序列預測

前言

時間序列預測一直是預測問題中的難點,人們很難找到一個適用場景豐富的通用模型,這是因為現實中每個預測問題的背景知識,例如數據的產生過程,往往是不同的,即使是同一類問題,影響這些預測值的因素與程度也往往不同,再加上預測問題往往需要大量專業的統計知識,這又給分析人員帶來了難度,這些都使得時間序列預測問題變得尤其複雜。

傳統的時間序列預測方法,例如ARIMA(autoregressive integrated moving average)模型,在R與Python中都有實現。雖然這些傳統方法已經用在很多場景中了,但它們通常有如下缺陷:

a.適用的時序數據過於侷限

例如最通用的ARIMA模型,其要求時序數據是穩定的,或者通過差分化後是穩定的,且在差分運算時提取的是固定週期的信息。這往往很難符合現實數據的情況。

b.缺失值需要填補

對於數據中存在缺失值的情況,傳統的方法都需要先進行缺失值填補,這很大程度上損害了數據的可靠性。

c.模型缺乏靈活性

傳統模型僅在於構建數據中的臨時依賴關係,這種模型過於不夠靈活,很難讓使用者引入問題的背景知識,或者一些有用的假設。

d.指導作用較弱

當前,雖然R與Python中實現了這些方法並提供了可視化效果,降低了模型的使用門檻。但由於模型本身的原因,這些展現的結果也很難讓使用者更清楚地分析影響預測準確率的潛在原因。

總之,傳統的時間序列預測在模型的準確率以及與使用者之間的互動上很難達到理想的融合。

近期,facebook發佈了prophet(“先知”)項目,它以更簡單、靈活的預測方式以及能夠獲得與經驗豐富的分析師相媲美的預測結果引起了人們的廣泛關注。下面我們介紹一下Prophet。

Prophet介紹

2.1整體框架

基於 Prophet 的時間序列預測

上圖是prophet的整體框架,整個過程分為四部分:Modeling、Forecast Evaluation、Surface Problems以及Visually Inspect Forecasts。從整體上看,這是一個循環結構,而這個結構又可以根據虛線分為分析師操縱部分與自動化部分,因此,整個過程就是分析師與自動化過程相結合的循環體系,也是一種將問題背景知識與統計分析融合起來的過程,這種結合大大的增加了模型的適用範圍,提高了模型的準確性。按照上述的四個部分,prophet的預測過程為:

a.Modeling:建立時間序列模型。分析師根據預測問題的背景選擇一個合適的模型。

b.Forecast Evaluation:模型評估。根據模型對歷史數據進行仿真,在模型的參數不確定的情況下,我們可以進行多種嘗試,並根據對應的仿真效果評估哪種模型更適合。

c.Surface Problems:呈現問題。如果嘗試了多種參數後,模型的整體表現依然不理想,這個時候可以將誤差較大的潛在原因呈現給分析師。

d.Visually Inspect Forecasts:以可視化的方式反饋整個預測結果。當問題反饋給分析師後,分析師考慮是否進一步調整和構建模型。

2.2適用場景

前文提到,不同時間序列預測問題的解決方案也各有不用。Prophet適用於有如下特徵的業務問題:

a.有至少幾個月(最好是一年)的每小時、每天或每週觀察的歷史數據;

b.有多種人類規模級別的較強的季節性趨勢:每週的一些天和每年的一些時間;

c.有事先知道的以不定期的間隔發生的重要節假日(比如國慶節);

d.缺失的歷史數據或較大的異常數據的數量在合理範圍內;

e.有歷史趨勢的變化(比如因為產品發佈);

f.對於數據中蘊含的非線性增長的趨勢都有一個自然極限或飽和狀態。

2.3 模型原理

模型的整體構建如下:

基於 Prophet 的時間序列預測

模型(1)整體由三部分組成:growth(增長趨勢)、seasonality(季節趨勢)以及holidays(節假日對預測值的影響)。其中g(t)表示增長函數,用來擬合時間序列中預測值的非週期性變化;s(t)用來表示週期性變化,比如說每週,每年中的季節等;h(t)表示時間序列中那些潛在的具有非固定週期的節假日對預測值造成的影響。最後

基於 Prophet 的時間序列預測

為噪聲項,表示模型未預測到的波動,這裡假設

基於 Prophet 的時間序列預測

是高斯分佈的。

可以看出這是一種類似generalized additive model(GAM)的模型,不同於以往的時間序列預測模型(例如ARIMA),上述的模型將預測問題視作曲線擬合問題。這樣做具有很多實踐價值:

a.靈活度高,許多具有不同週期以及不同假設的季節性趨勢能很容易的被引入;

b.時間序列中無需有一個固定的週期,也不需要在擬合前對缺失值進行填補,這是傳統的(例如ARIMA)模型所辦不到的;

c.擬合非常快,允許分析師交互式的探索模型的效果;

d.模型中參數的解釋性很強,可以讓分析師根據啟發來增強某部分假設。

下面分別介紹模型中各部分的構建。

2.3.1 增長趨勢

增長趨勢是整個模型的核心組件,它表示認為整個時間序列是如何增長的,以及預期未來時間裡是如何增長的。這部分為分析師提供了兩種模型:Non-linear growth(非線性增長)和Linear growth(線性增長)。

1.Non-linear growth

非線性增長的公式採用了邏輯迴歸的模型:

基於 Prophet 的時間序列預測

這裡,C是承載量,它限定了所能增長的最大值,k表示增長率,b為偏移量。

當然,實際的增長模型遠沒有這麼簡單,Prophet主要考慮了兩個現實問題:

(1)C值並不一定是常數;(2)增長率也不一定是一沉不變的。對於(1),將C構建成隨時間變化的函數:C(t) = K 或者 C(t) = Mt + K。下面詳細論述。

(2)的解決:首先模型定義了增長率k發生變化時對應的點,我們將其稱作changepoints,用

基於 Prophet 的時間序列預測

表示,這些點對應的斜率調整值用

基於 Prophet 的時間序列預測

表示,所有的斜率調整值形成一個向量

基於 Prophet 的時間序列預測

。此時,每個changepoint點對應的增長率就變為

基於 Prophet 的時間序列預測

。如果有如下定義:

基於 Prophet 的時間序列預測

則t時刻的增長率就可以表示為:

基於 Prophet 的時間序列預測

當增長率k調整後,每個changepoint點對應的偏移量b也應該相應調整以連接每個分段的最後一個時間點,表達式如下:

基於 Prophet 的時間序列預測

綜上,結合(1)和(2),最終的分段式邏輯迴歸增長模型為:

基於 Prophet 的時間序列預測

2.Linear growth

如果認為時間序列的整體增長趨勢是線性的,那麼就可以採用線性模型:

基於 Prophet 的時間序列預測

這裡的參數定義與非線性增長一樣,唯一不同的是每個changepoint對應的

基於 Prophet 的時間序列預測

=

基於 Prophet 的時間序列預測

結合上述兩種增長模型,我們可以看到,對於增長趨勢的預測,最重要的就是對這些changepoint的指定。使用時,既可以手動指定這些changepoint,也可以根據公式(3)和(4)自動識別。此時,認為

基於 Prophet 的時間序列預測

其中

基於 Prophet 的時間序列預測

控制著模型整體的平滑程度。

2.3.2 季節性趨勢

由於時間序列中有可能包含多種週期類型的季節性趨勢,因此,傅里葉級數可以用來近似表達這個週期屬性,公式如下:

基於 Prophet 的時間序列預測

其中,P表示某個固定的週期(例如用”天”做單位統計的數據中,年數據的P = 365.25,週數據的P = 7)。2N表示我們希望在模型中使用的這種週期的個數,較大的N值可以擬合出更復雜的季節性函數,然而也會帶來更多的過擬合問題。按照經驗值,年週期的N取10,週週期的N取3。

當將s(t)中的所有季節性時間序列模型組合成一個向量X(t),那麼最終的季節性模型為:

基於 Prophet 的時間序列預測

其中,

基於 Prophet 的時間序列預測

,以此提高季節性模型的平滑性。

2.3.3 節假日模型

很多實際經驗告訴我們,節假日或者是一些大事件都會對時間序列造成很大影響,而且這些時間點往往不存在週期性。對這些點的分析是極其必要的,甚至有時候它的重要度遠遠超過了平常點。

鑑於每個節假日(或者某個已知的大事件)的日期與影響程度存在差異,節假日模型將不同節假日在不同時間點下的影響視作獨立的模型。同時為每個模型設置了時間窗口,這主要是考慮到節假日的影響有窗口期(例如中秋節的前幾天與後幾天),模型將同一個窗口期中的影響設置為相同的值。例如,i表示節假日

基於 Prophet 的時間序列預測

表示窗口期中包含的時間t,則節假日模型h(t)可表示為:

基於 Prophet 的時間序列預測

其中,

基於 Prophet 的時間序列預測

表示窗口期中的節假日對預測值的影響。同季節性趨勢的模型,這裡可以定義:

基於 Prophet 的時間序列預測

那麼

基於 Prophet 的時間序列預測

其中

基於 Prophet 的時間序列預測

Prophet的使用

3.1參數使用

下面是這個模塊的參數解釋,使用者可充分利用這些參數調整模型:

a.增長趨勢的模型參數

growth:增長趨勢模型。整個預測模型的核心組件,分為兩種:”linear”與”logistic”,分別代表線性與非線性的增長,默認值:”linear”。

cap:承載量。非線性增長趨勢中限定的最大值,預測值將在該點達到飽和。當選擇非線性增長時,該項值必須給出。

changepoints(growth模型中的):改變點。使用者可以自主填寫已知時刻的標示著增長率發生改變的”改變點”,如果不填則系統自動識別。默認值:“None”。

n_changepoints:用戶指定潛在的”changepoint”的個數,默認值:25。

changepoint_prior_scale(growth模型中的):增長趨勢模型的靈活度。調節”changepoint”選擇的靈活度,值越大,選擇的”changepoint”越多,從而使模型對歷史數據的擬合程度變強,然而也增加了過擬合的風險。默認值:0.05。

b.季節趨勢的模型參數

seasonality_prior_scale(seasonality模型中的):調節季節性組件的強度。值越大,模型將適應更強的季節性波動,值越小,越抑制季節性波動,默認值:10.0。

c.節假日的模型參數

holidays_prior_scale(holidays模型中的):調節節假日模型組件的強度。值越大,該節假日對模型的影響越大,值越小,節假日的影響越小,默認值:10.0。

holidays:節假日的定義,設置節假日的json格式的配置文件,例如:

基於 Prophet 的時間序列預測

其中”holiday”表示某類節假日的名稱,”ds”指定具體的節假日期,”lower_window”表示該節假日包括指定日期之前的多少天,”upper_window”表示該節假日包括指定日期之後的多少天,上述四個參數均需要配置。

d.預測中需要的其他參數

freq:數據中時間的統計單位(頻率),默認為”D”,按天統計,具體可參考這裡。

periods:需要預測的未來時間的個數。例如按天統計的數據,想要預測未來一年時間內的情況,則需填寫365。

mcmc_samples:mcmc採樣,用於獲得預測未來的不確定性。若大於0,將做mcmc樣本的全貝葉斯推理,如果為0,將做最大後驗估計,默認值:0。

interval_width:衡量未來時間內趨勢改變的程度。表示預測未來時使用的趨勢間隔出現的頻率和幅度與歷史數據的相似度,值越大越相似,默認值:0.80。當mcmc_samples = 0時,該參數僅用於增長趨勢模型的改變程度,當mcmc_samples > 0時,該參數也包括了季節性趨勢改變的程度。

uncertainty_samples:用於估計未來時間的增長趨勢間隔的仿真繪製數,默認值:1000。

3.2 結果讀取與分析

完成以上的配置後,接下來就可以直接運行模型並獲得結果了。

3.2.1 可視化結果

整體預測情況是我們衡量模型整體預測效果的一個最直接的方式,它是我們評估當前模型的預測水平的重要來源。同時可視化的展示可以幫助我們有效分析預測結果中各個時間階段的預測效果。

基於 Prophet 的時間序列預測

上圖是一個整體的預測結果圖,它包含了從歷史數據的時間起點到期望預測的未來時間終點的結果。圖中的ds座標表示時間,y座標對應預測值。圖中的黑點表示已知的歷史數據,由圖上我們很容易發現數據中的異常點,藍色曲線表示模型的預測值。仔細查看藍色曲線,我們可以發現,曲線輪廓的上下邊界有淺藍色區域,它表示模型預測值的上、下邊界。在評估結果時,我們將藍色曲線的預測值視作主預測值,上、下邊界的預測值作為參考。除此之外,淺藍色區域還可以很好的用於模型評估,例如對於下面這個圖:

基於 Prophet 的時間序列預測

在2016年之後的模型預測部分,淺藍色區域就過於寬泛,模型預測的上、下邊界被逐漸放大很多倍。這說明模型的平滑性過大,導致異常點對結果造成了很大影響。因此,該模型不夠合理,需要使用者重新設置參數或者對歷史數據中的異常點進行預處理。

上述圖是growth選擇”linear”時的結果,如果認為時間序列呈非線性增長趨勢,我們用如下的圖例來說明:

基於 Prophet 的時間序列預測

體上與線性增長的結果表達沒有太大差異,唯一需要注意的是,上圖中的水平虛線表示了非線性增長趨勢的承載量cap,預測結果將在該虛線處達到飽和。

除了上述的整體預測情況外,Prophet還提供了組成成分分析(簡稱成分分析),所謂成分分析就是指對公式(1)中的三大部分模型單獨進行分析,成分分析有助於我們考察模型中的各個組件分別對預測結果的影響,通過可視化的展示,我們可以準確判斷影響預測效果的具體原因,從而針對性的解決。成分分析是我們提高模型準確性的重要來源。例如下圖結果:

基於 Prophet 的時間序列預測

上述四個圖從上至下依次是對增長趨勢模型(trend)、節假日模型(holidays)以及季節性模型(weekly和yearly)的展示。需要注意的是,如果沒有在holidays參數裡註明具體的節假日信息,模塊也不會自動對這一部分進行分析。如果對於上面的結果你覺得有不合理的地方,那麼可以根據2.1中參數使用說明更改相應的成分影響,這裡應該儘可能的利用你的專業背景知識,以使各部分組成的影響更符合實際。舉個例子,如果在每年趨勢”yearly”中你認為當前的效果過擬合了,那麼就可以調解seasonality_prior_scale這個參數,值越小,這裡的季節性波動就越小。

對於上面的可視化分析,這裡總結幾點建議,方便大家定位預測中的問題:

a.如果預測結果的誤差很大,考慮選取的模型是否準確,嘗試調整增長率模型(growth)的參數,在必要的情況下也需要調整季節性(seasonality)參數。

b.如果在嘗試的大多數方法中,某些日期的預測依然存在很大的誤差,這就說明歷史數據中存在異常值。最好的辦法就是找到這些異常值並剔除掉。使用者無需像其他方法那樣對剔除的數據進行插值擬合,可以僅保留異常值對應的時間, 並將異常值修改為空值(NA),模型在預測時依然可以給出這個時間點對應的預測結果。

c.如果對歷史數據進行仿真預測時發現,從一個截點到下一個截點誤差急劇的增加,這說明在兩個截點期間數據的產生過程發生了較大的變化,此時兩個截點之間應該增加一個”changepoint”,來對這期間的不同階段分別建模。

參考文獻

Sean J. Taylor and Benjamin Letham.Forecasting at Scale.

原文發佈於微信公眾號 - 騰訊技術工程官方號(Tencent_TEG)


分享到:


相關文章: