在R中使用開源大規(guī)模預(yù)測工具Prophet
Prophet 是 Facebook 推出的開源大規(guī)模預(yù)測工具,可以在 R 和 Python 中使用以預(yù)測時間序列數(shù)據(jù)。
下面將簡單介紹 Prophet 在 R 中的使用。
一、基礎(chǔ)介紹
下面實例中使用的是佩頓 · 曼寧的維基百科主頁每日訪問量的時間序列數(shù)據(jù)(2007/12/10 – 2016/01/20)。我們使用 R 中的 Wikipediatrend 包獲取該數(shù)據(jù)集。這個數(shù)據(jù)集具有多季節(jié)周期性、不斷變化的增長率和可以擬合特定日期(例如佩頓 · 曼寧的決賽和超級碗)的情況等 Prophet 適用的性質(zhì),因此可以作為一個不錯的例子。( 注: 佩頓 · 曼寧為前美式橄欖球四分衛(wèi))
在 R 中,Prophet 提供了一個 prophet 函數(shù)去擬合模型并且返回一個模型對象,可以對這個模型對象執(zhí)行“預(yù)測”( predict )和“繪圖”( plot )操作。
使用 prophet_plot_components 函數(shù)去展示預(yù)測中的趨勢、周效應(yīng)和年度效應(yīng)。
注: Windows 系統(tǒng)語言設(shè)置為中文的話,會導(dǎo)致 R 輸出成分分析圖時,周效應(yīng)無法正常顯示,可在 R 中使用 Sys.setlocale("LC_ALL","English") 代碼將環(huán)境改為英文。
二、預(yù)測增長
默認情況下, Prophet 使用線性模型進行預(yù)測。當(dāng)預(yù)測增長情況時,通常會存在可到達的***極限值,例如:總市場規(guī)模、總?cè)丝跀?shù)等等。這被稱做承載能力,那么預(yù)測時就應(yīng)當(dāng)在接近該值時趨于飽和。
Prophet 可使用 logistic 增長 趨勢模型進行預(yù)測,同時指定承載能力。下面使用 R 語言的維基百科主頁 訪問量(取對數(shù))的實例來進行說明。
三、趨勢突變點
默認情況下, Prophet 將自動監(jiān)測到突變點,并對趨勢做適當(dāng)?shù)卣{(diào)整。
下面將會介紹幾種使用的方法可以對趨勢的調(diào)整過程做更好地控制。
1. 調(diào)整趨勢的靈活性
如果趨勢的變化被過度擬合(即過于靈活)或者擬合不足(即靈活性不夠),可以利用輸入?yún)?shù) changepoint.prior.scale 來調(diào)整稀疏先驗的程度。默認下,這個參數(shù)被指定為 0.05 。
增加這個值,會導(dǎo)致趨勢擬合得更加靈活。如下代碼和圖所示:
減少這個值,會導(dǎo)致趨勢擬合得靈活性降低。如下代碼和圖所示:
四、節(jié)假日效應(yīng)
1. 對節(jié)假日建模
如果需要專門對節(jié)假日進行建模,你就必須得為此創(chuàng)建一個新的數(shù)據(jù)框,其中包含兩列(節(jié)假日 holiday 和日期戳 ds ),每行分別記錄了每個出現(xiàn)的節(jié)假日。
你可以在這個數(shù)據(jù)框基礎(chǔ)上再新建兩列 lower_window 和 upper_window ,從而將節(jié)假日的時間擴展成一個區(qū)間 [ lower_window , upper_window ] 。舉例來說,如果想將平安夜也加入到 “圣誕節(jié)” 里,就設(shè)置 lower_window = -1 , upper_window = 0 ;如果想將黑色星期五加入到 “感恩節(jié)” 里,就設(shè)置 lower_window = 0 , upper_window = 1 。
下面我們創(chuàng)建一個數(shù)據(jù)框,其中包含了所有佩頓 · 曼寧參加過的決賽日期:
上述代碼中,我們將超級碗的日期既記錄在了決賽的日期數(shù)據(jù)框中,也記錄在了超級碗的日期數(shù)據(jù)框中。這就會造成超級碗日期的效應(yīng)會在決賽日期的作用下疊加兩次。
一旦這個數(shù)據(jù)框創(chuàng)建好了,就可以通過傳入 holidays 參數(shù)使得在預(yù)測時考慮上節(jié)假日效應(yīng)。
可通過 forecast 數(shù)據(jù)框,來展示節(jié)假日效應(yīng):
在成分分析的圖中,如下所示,也可以看到節(jié)假日效應(yīng)。我們可以發(fā)現(xiàn),在決賽日期附近有一個穿透,而在超級碗日期時穿透則更為明顯。
2. 對節(jié)假日和季節(jié)性設(shè)定先驗規(guī)模
如果發(fā)現(xiàn)節(jié)假日效應(yīng)被過度擬合了,通過設(shè)置參數(shù) holidays.prior.scale 可以調(diào)整它們的先驗規(guī)模來使之平滑,默認下該值取 10 。
和之前相比,節(jié)假日效應(yīng)的規(guī)模被減弱了,特別是對觀測值較少的超級碗而言。類似的,還有一個 seasonality.prior.scale 參數(shù)可以用來調(diào)整模型對于季節(jié)性的擬合程度。
五、預(yù)測區(qū)間
在預(yù)測時,不確定性主要來源于三個部分:趨勢中的不確定性、季節(jié)效應(yīng)估計中的不確定性和觀測值的噪聲影響。
1. 趨勢中的不確定性
預(yù)測中,不確定性***的來源就在于未來趨勢改變的不確定性。Prophet 假定 “未來將會和歷史具有相似的趨勢” 。尤其重要的是,我們假定未來趨勢的平均變動頻率和幅度和我們觀測到的歷史值是一樣的,從而預(yù)測趨勢的變化并通過計算,最終得到預(yù)測區(qū)間。
這種衡量不確定性的方法具有以下性質(zhì):變化速率靈活性更大時(通過增大參數(shù)changepoint.prior.scale 的值),預(yù)測的不確定性也會隨之增大。原因在于如果將歷史數(shù)據(jù)中更多的變化速率加入了模型,也就代表我們認為未來也會變化得更多,就會使得預(yù)測區(qū)間成為反映過擬合的標志。
預(yù)測區(qū)間的寬度(默認下,是 80% )可以通過設(shè)置 interval.width 參數(shù)來控制:
2. 季節(jié)效應(yīng)中的不確定性
默認情況下, Prophet 只會返回趨勢中的不確定性和觀測值噪聲的影響。你必須使用貝葉斯取樣的方法來得到季節(jié)效應(yīng)的不確定性,可通過設(shè)置 mcmc.samples 參數(shù)(默認下取 0 )來實現(xiàn)。
上述代碼將***后驗估計( MAP )取代為馬爾科夫蒙特卡洛取樣 ( MCMC ),并且將計算時間從 10 秒延長到 10 分鐘。如果做了全取樣,就能通過繪圖看到季節(jié)效應(yīng)的不確定性了:
六、異常值
下面我們使用之前使用過的 R 語言維基百科主頁對數(shù)訪問量的數(shù)據(jù)來建模預(yù)測,只不過使用存在時間間隔并不完整的數(shù)據(jù):
如上 R 輸出圖所示,趨勢預(yù)測看似合理,預(yù)測區(qū)間的估計卻過于廣泛。
處理異常值***的方法是移除它們,而 Prophet 使能夠處理缺失數(shù)據(jù)的。如果在歷史數(shù)據(jù)中某行的值為空( NA ),但是在待預(yù)測日期數(shù)據(jù)框 future 中仍保留這個日期,那么 Prophet 依舊可以給出該行的預(yù)測值。
上述這個實例雖然影響了不確定性的估計,卻沒有影響到主要的預(yù)測值 yhat 。但是,現(xiàn)實往往并非如此,接下來,在上述數(shù)據(jù)集基礎(chǔ)上加入新的異常值后再建模預(yù)測:
這里 2015年 6 月存在一些異常值破壞了季節(jié)效應(yīng)的估計,因此未來的預(yù)測也會***地受到這個影響。***的解決方法就是移除這些異常值:
七、非日數(shù)據(jù)
Prophet 處理的對象并非必須是日數(shù)據(jù),不過要是試圖通過非日數(shù)據(jù)來預(yù)測每日的情況或擬合季節(jié)性效應(yīng),往往會得到奇奇怪怪的結(jié)果。下面使用美國零售業(yè)銷售量數(shù)據(jù)來預(yù)測未來 10 年的情況:
預(yù)測結(jié)果看起來非常雜亂,原因正是在于這個特殊的數(shù)據(jù)集使用的是月數(shù)據(jù)。當(dāng)我們擬合年度效應(yīng)時,只有每個月***天的數(shù)據(jù),而且對于其他天的周期效應(yīng)是不可測且過擬合的。當(dāng)你使用 Prophet 擬合月度數(shù)據(jù)時,可以通過在 make_future_dataframe 中傳入頻率參數(shù)只做月度的預(yù)測。
