預測將來永遠是一件讓人興奮而又神奇的事。爲此,人們研究了許多時間序列預測模型。然而,大部分的時間序列模型都由於預測的問題過於複雜而效果不理想。這是由於時間序列預測不光須要大量的統計知識,更重要的是它須要將問題的背景知識融入其中。爲此,Prophet充分的將二者融合了起來,提供了一種更簡單、靈活的預測方式,而且在預測準確率上達到了與專業分析師相媲美的程度。若是你還在爲時間序列預測而苦惱,那就一塊兒走進興奮而又神奇的Prophet世界吧。html
前言
json
時間序列預測一直是預測問題中的難點,人們很難找到一個適用場景豐富的通用模型,這是由於現實中每一個預測問題的背景知識,例如數據的產生過程,每每是不一樣的,即便是同一類問題,影響這些預測值的因素與程度也每每不一樣,再加上預測問題每每須要大量專業的統計知識,這又給分析人員帶來了難度,這些都使得時間序列預測問題變得尤爲複雜。框架
傳統的時間序列預測方法,例如ARIMA(autoregressive integrated moving average)模型,在R與Python中都有實現。雖然這些傳統方法已經用在不少場景中了,但它們一般有以下缺陷:ide
a.適用的時序數據過於侷限
例如最通用的ARIMA模型,其要求時序數據是穩定的,或者經過差分化後是穩定的,且在差分運算時提取的是固定週期的信息。這每每很難符合現實數據的狀況。函數
b.缺失值須要填補
對於數據中存在缺失值的狀況,傳統的方法都須要先進行缺失值填補,這很大程度上損害了數據的可靠性。lua
c.模型缺少靈活性
傳統模型僅在於構建數據中的臨時依賴關係,這種模型過於不夠靈活,很難讓使用者引入問題的背景知識,或者一些有用的假設。spa
d.指導做用較弱
當前,雖然R與Python中實現了這些方法並提供了可視化效果,下降了模型的使用門檻。但因爲模型自己的緣由,這些展示的結果也很難讓使用者更清楚地分析影響預測準確率的潛在緣由。code
總之,傳統的時間序列預測在模型的準確率以及與使用者之間的互動上很難達到理想的融合。orm
近期,facebook發佈了prophet(「先知」)項目,它以更簡單、靈活的預測方式以及可以得到與經驗豐富的分析師相媲美的預測結果引發了人們的普遍關注。下面咱們介紹一下Prophet。htm
Prophet介紹
上圖是prophet的總體框架,整個過程分爲四部分:Modeling、Forecast Evaluation、Surface Problems以及Visually Inspect Forecasts。從總體上看,這是一個循環結構,而這個結構又能夠根據虛線分爲分析師操縱部分與自動化部分,所以,整個過程就是分析師與自動化過程相結合的循環體系,也是一種將問題背景知識與統計分析融合起來的過程,這種結合大大的增長了模型的適用範圍,提升了模型的準確性。按照上述的四個部分,prophet的預測過程爲:
a.Modeling:創建時間序列模型。分析師根據預測問題的背景選擇一個合適的模型。
b.Forecast Evaluation:模型評估。根據模型對歷史數據進行仿真,在模型的參數不肯定的狀況下,咱們能夠進行多種嘗試,並根據對應的仿真效果評估哪一種模型更適合。
c.Surface Problems:呈現問題。若是嘗試了多種參數後,模型的總體表現依然不理想,這個時候能夠將偏差較大的潛在緣由呈現給分析師。
d.Visually Inspect Forecasts:以可視化的方式反饋整個預測結果。當問題反饋給分析師後,分析師考慮是否進一步調整和構建模型。
a.有至少幾個月(最好是一年)的每小時、天天或每週觀察的歷史數據;
b.有多種人類規模級別的較強的季節性趨勢:每週的一些天和每一年的一些時間;
c.有事先知道的以不按期的間隔發生的重要節假日(好比國慶節);
d.缺失的歷史數據或較大的異常數據的數量在合理範圍內;
e.有歷史趨勢的變化(好比由於產品發佈);
f.對於數據中蘊含的非線性增加的趨勢都有一個天然極限或飽和狀態。
模型(1)總體由三部分組成:growth(增加趨勢)、seasonality(季節趨勢)以及holidays(節假日對預測值的影響)。其中g(t)表示增加函數,用來擬合時間序列中預測值的非週期性變化;s(t)用來表示週期性變化,好比說每週,每一年中的季節等;h(t)表示時間序列中那些潛在的具備非固定週期的節假日對預測值形成的影響。最後爲噪聲項,表示模型未預測到的波動,這裏假設
是高斯分佈的。
能夠看出這是一種相似generalized additive model(GAM)的模型,不一樣於以往的時間序列預測模型(例如ARIMA),上述的模型將預測問題視做曲線擬合問題。這樣作具備不少實踐價值:
a.靈活度高,許多具備不一樣週期以及不一樣假設的季節性趨勢能很容易的被引入;
b.時間序列中無需有一個固定的週期,也不須要在擬合前對缺失值進行填補,這是傳統的(例如ARIMA)模型所辦不到的;
c.擬合很是快,容許分析師交互式的探索模型的效果;
d.模型中參數的解釋性很強,可讓分析師根據啓發來加強某部分假設。
下面分別介紹模型中各部分的構建。
1.Non-linear growth
非線性增加的公式採用了邏輯迴歸的模型:
這裏,C是承載量,它限定了所能增加的最大值,k表示增加率,b爲偏移量。
固然,實際的增加模型遠沒有這麼簡單,Prophet主要考慮了兩個現實問題:
(1)C值並不必定是常數;(2)增加率也不必定是一沉不變的。對於(1),將C構建成隨時間變化的函數:C(t) = K 或者 C(t) = Mt + K。下面詳細論述。
(2)的解決:首先模型定義了增加率k發生變化時對應的點,咱們將其稱做changepoints,用表示,這些點對應的斜率調整值用表示,全部的斜率調整值造成一個向量
。此時,每一個changepoint點對應的增加率就變爲
。若是有以下定義:
則t時刻的增加率就能夠表示爲:
當增加率k調整後,每一個changepoint點對應的偏移量b也應該相應調整以鏈接每一個分段的最後一個時間點,表達式以下:
綜上,結合(1)和(2),最終的分段式邏輯迴歸增加模型爲:
2.Linear growth
若是認爲時間序列的總體增加趨勢是線性的,那麼就能夠採用線性模型:
這裏的參數定義與非線性增加同樣,惟一不一樣的是每一個changepoint對應的
結合上述兩種增加模型,咱們能夠看到,對於增加趨勢的預測,最重要的就是對這些changepoint的指定。使用時,既能夠手動指定這些changepoint,也能夠根據公式(3)和(4)自動識別。此時,認爲
其中
控制着模型總體的平滑程度。
因爲時間序列中有可能包含多種週期類型的季節性趨勢,所以,傅里葉級數能夠用來近似表達這個週期屬性,公式以下:
其中,P表示某個固定的週期(例如用」天」作單位統計的數據中,年數據的P = 365.25,週數據的P = 7)。2N表示咱們但願在模型中使用的這種週期的個數,較大的N值能夠擬合出更復雜的季節性函數,然而也會帶來更多的過擬合問題。按照經驗值,年週期的N取10,週週期的N取3。
當將s(t)中的全部季節性時間序列模型組合成一個向量X(t),那麼最終的季節性模型爲:
其中,,以此提升季節性模型的平滑性。
不少實際經驗告訴咱們,節假日或者是一些大事件都會對時間序列形成很大影響,並且這些時間點每每不存在週期性。對這些點的分析是極其必要的,甚至有時候它的重要度遠遠超過了日常點。
鑑於每一個節假日(或者某個已知的大事件)的日期與影響程度存在差別,節假日模型將不一樣節假日在不一樣時間點下的影響視做獨立的模型。同時爲每一個模型設置了時間窗口,這主要是考慮到節假日的影響有窗口期(例如中秋節的前幾天與後幾天),模型將同一個窗口期中的影響設置爲相同的值。例如,i表示節假日表示窗口期中包含的時間t,則節假日模型h(t)可表示爲:
其中,表示窗口期中的節假日對預測值的影響。同季節性趨勢的模型,這裏能夠定義:
那麼
其中
Prophet的使用
下面是這個模塊的參數解釋,使用者可充分利用這些參數調整模型:
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格式的配置文件,例如:
其中」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。
完成以上的配置後,接下來就能夠直接運行模型並得到結果了。
總體預測狀況是咱們衡量模型總體預測效果的一個最直接的方式,它是咱們評估當前模型的預測水平的重要來源。同時可視化的展現能夠幫助咱們有效分析預測結果中各個時間階段的預測效果。
上圖是一個總體的預測結果圖,它包含了從歷史數據的時間起點到指望預測的將來時間終點的結果。圖中的ds座標表示時間,y座標對應預測值。圖中的黑點表示已知的歷史數據,由圖上咱們很容易發現數據中的異常點,藍色曲線表示模型的預測值。仔細查看藍色曲線,咱們能夠發現,曲線輪廓的上下邊界有淺藍色區域,它表示模型預測值的上、下邊界。在評估結果時,咱們將藍色曲線的預測值視做主預測值,上、下邊界的預測值做爲參考。除此以外,淺藍色區域還能夠很好的用於模型評估,例如對於下面這個圖:
在2016年以後的模型預測部分,淺藍色區域就過於寬泛,模型預測的上、下邊界被逐漸放大不少倍。這說明模型的平滑性過大,致使異常點對結果形成了很大影響。所以,該模型不夠合理,須要使用者從新設置參數或者對歷史數據中的異常點進行預處理。
上述圖是growth選擇」linear」時的結果,若是認爲時間序列呈非線性增加趨勢,咱們用以下的圖例來講明:
體上與線性增加的結果表達沒有太大差別,惟一須要注意的是,上圖中的水平虛線表示了非線性增加趨勢的承載量cap,預測結果將在該虛線處達到飽和。
除了上述的總體預測狀況外,Prophet還提供了組成成分分析(簡稱成分分析),所謂成分分析就是指對公式(1)中的三大部分模型單獨進行分析,成分分析有助於咱們考察模型中的各個組件分別對預測結果的影響,經過可視化的展現,咱們能夠準確判斷影響預測效果的具體緣由,從而針對性的解決。成分分析是咱們提升模型準確性的重要來源。例以下圖結果:
上述四個圖從上至下依次是對增加趨勢模型(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.https://research.fb.com/prophet-forecasting-at-scale