手把手教你用Prophet快速進行時間序列預測(附Prophet和R代碼)

2021-03-02 數據派THU

作者:ANKIT CHOUDHARY

翻譯:王雨桐

校對:丁楠雅

本文約3000字,建議閱讀12分鐘。

本文將通過拆解Prophet的原理及代碼實例來講解如何運用Prophet進行時間序列預測。

簡介


對於任何業務而言,基於時間進行分析都是至關重要的。庫存量應該保持在多少?你希望商店的客流量是多少?多少人會乘坐飛機旅遊?類似這樣待解決的問題都是重要的時間序列問題。

這就是時間序列預測被看作數據科學家必備技能的原因。從預測天氣到預測產品的銷售情況,時間序列是數據科學體系的一部分,並且是成為一個數據科學家必須要補充的技能。

如果你是菜鳥,時間序列為你提供了一個很好的途徑去實踐項目。你可以非常輕易地應用時間序列,它會帶領你進入更大的機器學習世界。

Prophet是Facebook發布的基於可分解(趨勢+季節+節假日)模型的開源庫。它讓我們可以用簡單直觀的參數進行高精度的時間序列預測,並且支持自定義季節和節假日的影響。

本文中,我們將介紹Prophet如何產生快速可靠的預測,並通過Python進行演示。最終結果將會讓你大吃一驚!

本文目錄

1. Prophet有什麼創新點?

2. Prophet預測模型

3. Prophet實戰(附Python和R代碼)

趨勢參數

季節和節假日參數

通過Prophet預測客運量

Prophet有什麼創新點?


當預測模型沒有按預期運行時,我們希望針對問題來調整模型的參數。調整參數需要對時間序列的工作原理有全面的理解。例如automatedARIMA首先輸入的參數是差分的最大階數,自回歸分量和移動平均分量。普通分析師不知道如何調整順序來避免這種表現,這是一種很難掌握積累的專業知識。

Prophet包提供了直觀易調的參數,即使是對缺乏模型知識的人來說,也可以據此對各種商業問題做出有意義的預測。

Prophet預測模型


時間序列模型可分解為三個主要組成部分:趨勢,季節性和節假日。它們按如下公式組合:

Prophet使用時間為回歸元,嘗試擬合線性和非線性的時間函數項,採取類似霍爾特-溫特斯( Holt-Winters )指數平滑的方法,將季節作為額外的成分來建模。事實上,我們將預測問題類比為擬合曲線模型,而不是精確地去看時間序列中每個時點上的觀測值。

1. 趨勢


趨勢是對時間序列中的非周期部分或趨勢部分擬合分段線性函數,線性擬合會將特殊點和缺失數據的影響降到最小。


這裡要問一個重要問題-我們是否希望目標在整個預測區間內持續增長或下降?通常情況下,一些非線性增長的案例會有最大容量限制,比如以下案例:

假設我們要預測未來12個月某app在某地區的下載量,最大下載量總是受該地區智慧型手機用戶總數的限制。然而,智慧型手機用戶的數量也會隨著時間的推移而增加。

基於這樣的領域知識,分析師可以定義時間序列預測的容量限制為C(t)。


另一個要回答的問題是-時間序列是否會因為其他現象發生潛在變化,例如新產品發布、不可預見的災難等。這種情況下,增長率是會改變的。這些突變點是自動選擇的,然而有需要的時候也可以手動輸入突變點。在下圖中,點線代表給定時間序列中的突變點。

隨著突變點數量的增多,擬合變得更靈活。在研究趨勢成分時,分析師要面臨兩個基本問題:

參數changepoint_prior_scale可以用來調整趨勢的靈活性並解決以上兩個問題。參數的值越大,擬合的時間序列曲線越靈活。

2. 季節性


為了擬合併預測季節的效果,Prophet基於傅立葉級數提出了一個靈活的模型。季節效應S(t)根據以下方程進行估算:

P是周期(年度數據的P是365.25,周數據的P是7)。

對季節性建模時,需要在給定N的情況下,估計參數[a1,b1……aN,bN]。

傅立葉階數N是一個重要的參數,它用來定義模型中是否考慮高頻變化。對時間序列來說,如果分析師認為高頻變化的成分只是噪聲,沒必要在模型中考慮,可以把N設為較低的值。如果不是,N可以被設置為較高的值並用於提升預測精度。

3. 節假日和大事件


節假日和大事件會導致時間序列中出現可預測的波動。例如,印度的排燈節(Diwali)每年的日期都不同,在此期間人們大多會購買大量新商品。

Prophet允許分析師使用過去和未來事件的自定義列表。這些大事件前後的日期將會被單獨考慮,並且通過擬合附加的參數模擬節假日和事件的效果。

Prophet實戰(附Python代碼)


目前Prophet只適用於Python和R,這兩者有同樣的功能。

Python中,使用Prophet()函數來定義Prophet預測模型。讓我們看一下最重要的參數。

1.  趨勢參數


參數

描述

growth

『linear』或『logistic』用來規定線性或邏輯曲線趨勢

changepoints

包括潛在突變點的日期列表(不指明則默認為自動識別)

n_changepoints

若不指定突變點,則需要提供自動識別的突變點數量

changepoint_prior_scale

設定自動突變點選擇的靈活性

2. 季節&假日參數


參數

描述

yearly_seasonality

周期為年的季節性

weekly_seasonality

周期為周的季節性

daily_seasonality

周期為日的季節性

holidays

內置的節假日名稱和日期

seasonality_prior_scale

改變季節模型的強度

holiday_prior_scale

改變假日模型的強度

yearly_seasonality、weekly_seasonality和daily_seasonality取值為True或False,沒有上一節中討論的傅立葉項。若值為True,默認取傅立葉項為10。Priorscales用來定義擬合過程中季節或節假日的權重程度。

3. 通過Prophet預測客運交通


現在我們已經了解了這個神奇工具的細節,接下來讓我們通過實際的數據集來看看它的潛力。這裡我在Python中運用Prophet來解決下面連結(DATAHACK平臺)中的實際問題。

DATAHACK平臺:

https://datahack.analyticsvidhya.com/contest/practice-problem-time-series-2/

該數據集是一個單變量的時間序列,即某新型公共運輸服務的每小時客運量。基於給定的過去25個月的歷史交通流量數據,我們可以嘗試預測未來七個月的交通情況。

基本的探索性數據分析(EDA)可以通過以下課程獲取:

課程連結:

https://trainings.analyticsvidhya.com/courses/course-v1:AnalyticsVidhya+TS_101+TS_term1/about

Python實現如下:

導入所需要的包並讀入數據集

#Importing datasets

importpandas as pd

importnumpy as np

fromfbprophet import Prophet

#Read train and test

train= pd.read_csv('Train_SU63ISt.csv')

test= pd.read_csv('Test_0qrQsBZ.csv')

#Convert to datetime format

train['Datetime']= pd.to_datetime(train.Datetime,format='%d-%m-%Y %H:%M')

test['Datetime']= pd.to_datetime(test.Datetime,format='%d-%m-%Y %H:%M')

train['hour']= train.Datetime.dt.hour

我們可以看到時間序列中有很多噪聲。我們可以對其進行重採樣並匯總,得到一個噪聲更少的新序列,進而更易建模。

#Calculate average hourly fraction

hourly_frac=train.groupby(['hour']).mean()/np.sum(train.groupby(['hour']).mean())

hourly_frac.drop(['ID'],axis = 1, inplace = True)

hourly_frac.columns= ['fraction']

#convert to time series from dataframe

train.index= train.Datetime

train.drop(['ID','hour','Datetime'],axis = 1, inplace = True)

daily_train= train.resample('D').sum()

Prophet要求時間序列中的變量名為:

y -> 目標(Target)

ds -> 時間(Datetime)

因此,下一步是基於上述規範來轉換數據文件:

daily_train['ds']= daily_train.index

daily_train['y']= daily_train.Count

daily_train.drop(['Count'],axis= 1, inplace = True)

擬合Prophet模型:

m= Prophet(yearly_seasonality = True, seasonality_prior_scale=0.1)

m.fit(daily_train)

future= m.make_future_dataframe(periods=213)

forecast= m.predict(future)

我們可以通過以下命令來查看各個成分:

m.plot_components(forecast)

將0到23作為節點均等劃分每小時,接下來我們可以把每日預測轉化為每小時預測。基於每日數據的預測如下。

#Extract hour, day, month and year from both dataframes to merge

fordf in [test, forecast]:

   df['hour']= df.Datetime.dt.hour

   df['day']= df.Datetime.dt.day

   df['month']= df.Datetime.dt.month

   df['year']= df.Datetime.dt.year

#Merge forecasts with given IDs

test= pd.merge(test,forecast, on=['day','month','year'], how='left')

cols= ['ID','hour','yhat']

test_new= test[cols]

#Merging hourly average fraction to the test data

test_new= pd.merge(test_new, hourly_frac, left_on = ['hour'],right_index=True, how = 'left')

#Convert daily aggregate to hourly traffic

test_new['Count']= test_new['yhat'] * test_new['fraction']

test_new.drop(['yhat','fraction','hour'],axis= 1, inplace = True)

test_new.to_csv('prophet_sub.csv',index= False)

我在公共積分榜上得到了206分,並得到了一個穩定的模型。讀者可以繼續調整超參數(季節性或變化性的傅立葉階數)以得到更好的分數。讀者也可以嘗試使用不同的方法將每日轉化為每小時的數據,可能會得到更好的分數。

R代碼實現如下:


應用R解決同樣的問題。

library(prophet)

library(data.table)

library(dplyr)

library(ggplot2)

#read data

train= fread("Train_SU63ISt.csv")

test= fread("Test_0qrQsBZ.csv")

#Extract date from the Datetime variable

train$Date= as.POSIXct(strptime(train$Datetime, "%d-%m-%Y"))

test$Date= as.POSIXct(strptime(test$Datetime, "%d-%m-%Y"))

#Convert 'Datetime' variable from character to date-time format

train$Datetime= as.POSIXct(strptime(train$Datetime, "%d-%m-%Y %H:%M"))

test$Datetime= as.POSIXct(strptime(test$Datetime, "%d-%m-%Y %H:%M"))

#Aggregate train data day-wise

aggr_train= train[,list(Count = sum(Count)), by = Date]

#Visualize the data

ggplot(aggr_train)+ geom_line(aes(Date, Count))

#Change column names

names(aggr_train)= c("ds", "y")

#Model building

m= prophet(aggr_train)

future= make_future_dataframe(m, periods = 213)

forecast= predict(m, future)

#Visualize forecast

plot(m,forecast)

#proportion of mean hourly 'Count' based on train data

mean_hourly_count= train %>%

group_by(hour= hour(train$Datetime)) %>%

summarise(mean_count= mean(Count))

s= sum(mean_hourly_count$mean_count)

mean_hourly_count$count_proportion= mean_hourly_count$mean_count/s

#variable to store hourly Count

test_count= NULL

for(iin 763:nrow(forecast)){

test_count= append(test_count, mean_hourly_count$count_proportion *forecast$yhat[i])

}

test$Count= test_count

尾記


Prophet確實是進行快速準確的時間序列預測的好選擇。對於具備良好領域知識但是缺少預測模型技能的人來說,Prophet可以讓他們直觀地調整參數。讀者可以直接在Prophet中擬合以小時為單位的數據並且在評論中討論是否能得到更好的結果。

原文標題:Generate Quick and Accurate Time Series Forecasts using Facebook’s Prophet (with Python & R codes)

原文連結:https://www.analyticsvidhya.com/blog/ 2018/05/generate-accurate-forecasts-facebook-prophet-python-r/

王雨桐,統計學在讀,數據科學碩士預備,跑步不停,彈琴不止。夢想把數據可視化當作藝術,目前日常是摸著下巴看機器學習。

工作內容:需要一顆細緻的心,將選取好的外文文章翻譯成流暢的中文。如果你是數據科學/統計學/計算機類的留學生,或在海外從事相關工作,或對自己外語水平有信心的朋友歡迎加入翻譯小組。

你能得到:定期的翻譯培訓提高志願者的翻譯水平,提高對於數據科學前沿的認知,海外的朋友可以和國內技術應用發展保持聯繫,THU數據派產學研的背景為志願者帶來好的發展機遇。

其他福利:來自於名企的數據科學工作者,北大清華以及海外等名校學生他們都將成為你在翻譯小組的夥伴。

點擊文末「閱讀原文」加入數據派團隊~

點擊「閱讀原文」擁抱組織

相關焦點

  • Prophet: 時間序列預測庫
    prophet是facebook開源的python預測庫,該庫的api設計與sklearn很像,也是分為fit方法和predict方法。
  • NeuralProphet:基於神經網絡的時間序列建模庫
    NeuralProphet是一個python庫,用於基於神經網絡對時間序列數據進行建模。它建立在PyTorch之上,並受到Facebook Prophet和AR-Net庫的極大啟發。
  • prophet應用——快速入門
    《時間序列預測—prophet算法篇》已經介紹了prophet的算法原理。接下來我們說下如何使用Prophet,本文主要翻譯自官方教程。創建一個 Prophet 類的實例,然後使用了「擬合」 fit 和「預測」 predict 方法。Prophet 的輸入量往往是一個包含兩列的數據集:ds 和 y 。ds (datestamp) 列必須包含日期(YYYY-MM-DD)或時間點(YYYY-MM-DD HH:MM:SS)。y 列必須是數值變量,表示我們希望預測的量。
  • 時間序列預測方法總結
    時間序列基本規則法-周期因子法參考:時間序列規則法快速入門 https://www.jianshu.com/p/31e20f00c26f?spm=5176.12282029.0.0.36241491UUhnZE計算周期因子factors計算base預測=base*factorsb.
  • 使用sktime進行時間序列預測
    進行預測的論文,其中我們更詳細地討論了 forecasting API,並使用它來複製和擴展M4研究。當然你也可以你使用其他的預測範圍。將時間序列切成窗口的方式(如窗口長度) 生成預測的方式(遞歸策略、直接策略、其他混合策略) 遞歸策略是指將時間序列切成窗口的方式。陷阱三:給定一個擬合回歸算法,我們如何生成預測?
  • 手把手教你用Python進行時間序列分解和預測
    STL分解法時間序列預測的基本方法:Python中的簡單移動平均(SMA)為什麼使用簡單移動平均?Python中的加權移動平均(WMA)Python中的指數移動平均(EMA)什麼是時間序列?顧名思義,時間序列是按照固定時間間隔記錄的數據集。
  • 乾貨 :手把手教你用Python進行時間序列分解和預測
    Python進行時間序列分解的不同方法,以及如何在Python中進行時間序列預測的一些基本方法和示例。 預測是一件複雜的事情,在這方面做得好的企業會在同行業中出類拔萃。時間序列預測的需求不僅存在於各類業務場景當中,而且通常需要對未來幾年甚至幾分鐘之後的時間序列進行預測。如果你正要著手進行時間序列預測,那麼本文將帶你快速掌握一些必不可少的概念。什麼是時間序列?如何在Python中繪製時間序列數據?時間序列的要素是什麼?如何分解時間序列?
  • 獨家 | 手把手教你用Python進行時間序列分解和預測
    ,以及如何在Python中進行時間序列預測的一些基本方法和示例。 如果你正要著手進行時間序列預測,那麼本文將帶你快速掌握一些必不可少的概念。什麼是時間序列?如何在Python中繪製時間序列數據?時間序列的要素是什麼?如何分解時間序列?經典分解法如何獲得季節性調整值?
  • 用Python進行時間序列分解和預測
    Python進行時間序列分解的不同方法,以及如何在Python中進行時間序列預測的一些基本方法和示例。 預測是一件複雜的事情,在這方面做得好的企業會在同行業中出類拔萃。時間序列預測的需求不僅存在於各類業務場景當中,而且通常需要對未來幾年甚至幾分鐘之後的時間序列進行預測。如果你正要著手進行時間序列預測,那麼本文將帶你快速掌握一些必不可少的概念。什麼是時間序列?如何在Python中繪製時間序列數據?時間序列的要素是什麼?如何分解時間序列?
  • 手把手教你用Python實現針對時間序列預測的特徵選擇
    要將機器學習算法應用於時間序列數據,需要特徵工程的幫助。例如,單變量的時間序列數據集由一系列觀察結果組成,它們必須被轉換成輸入和輸出特徵,才能用於監督性學習算法。但這裡有一個問題:針對每個時間序列問題,你可以處理的特徵類型和數量,卻並沒有明確的限制。
  • Tensorflow實戰系列:手把手教你使用LSTM進行文本分類(附完整代碼)
    【導讀】專知小組計劃近期推出Tensorflow實戰系列,計劃教大家手把手實戰各項子任務。
  • 使用DeepAR 進行時間序列預測
    圖1 WAIC 中展示的時間序列預測 DEMO在本篇博客中,會簡要介紹時間序列預測的場景、常見的分類及對應算法、DeepAR 算法的優勢以及如何使用 DeepAR 算法進行時間序列預測。而結合上文中的時間序列數據,我們能夠做什麼?最顯而易見的是,我們可以通過過去產生的時間序列數據,來預測未來。我們可以通過遊戲歷史的玩家消費時間序列數據,預測該玩家在接下來一周的付費意願和付費大致金額,從而定製化的推送相關遊戲禮包和活動,這通常和傳統的用戶畫像是互補的。
  • 時間序列預測:I概述
    常用的模型,以下基本可以涵蓋主流思想:企業研究來自工業屆的研究經驗與創新模型,值得一看的文章和模型:Uber:Time-series Extreme Event Forecasting with Neural Networks at UberUber:How Uber Manages Uncertainty in Time-Series
  • 時間序列神器之爭:prophet VS lstm
    , :-1], yd_renamed[:n_train, -1]test_X, test_y = yd_renamed[n_train:, :-1], yd_renamed[n_train:, -1]# 最後,我們需要將數據改變一下形狀,因為 RNN 讀入的數據維度是 (seq, batch, feature),所以要重新改變一下數據的維度,這裡只有一個序列
  • 如何使用XGBoost模型進行時間序列預測
    你可以通過pip安裝,如下一旦安裝完成,你可以通過下面代碼確認下是否成功安裝以及你是否使用了新的版本。運行這些代碼,你可以看到下面或者更高的版本號。我用一個例子來支持這一點。想像一些我們有如下的時間序列:我們可以通過前一個時間的值來預測下一個時間的值,從而將該時間序列數據集重組為一個監督學習問題。
  • Keras 實現 LSTM時間序列預測
    keras 深度學習的框架搭建 LSTM 模型對時間序列做預測。1 項目簡單介紹1.1 背景介紹本項目的目標是建立內部與外部特徵結合的多時序協同預測系統。數據集採用來自業界多組相關時間序列(約40組)與外部特徵時間序列(約5組)。課題通過進行數據探索,特徵工程,傳統時序模型探索,機器學習模型探索,深度學習模型探索(RNN,LSTM等),算法結合,結果分析等步驟來學習時序預測問題的分析方法與實戰流程。
  • 用R語言做時間序列分析(附數據集和源碼)
    時間序列(time series)是一系列有序的數據。通常是等時間間隔的採樣數據。
  • 獨家 | 手把手教你學習R語言(附資源連結)
    學習者不知道從哪開始,如何進行,選擇什麼學習資源。雖然網絡上有許多不錯的免費學習資源,然而它們多過了頭,反而會讓人挑花了眼。為了構建R語言學習方法,我們在Vidhya和DataCamp中選一組綜合資源,幫您從頭學習R語言。這套學習方法對於數據科學或R語言的初學者會很有用;如果讀者是R語言的老用戶,則會由本文了解這門語言的部分最新成果。
  • 如何優雅地用TensorFlow預測時間序列:TFTS庫詳細教程
    前言如何用TensorFlow結合LSTM來做時間序列預測其實是一個很老的話題,然而卻一直沒有得到比較好的解決。如圖:使用AR模型預測時間序列自回歸模型(Autoregressive model,可以簡稱為AR模型)是統計學上處理時間序列模型的基本方法之一。在TFTS中,已經實現了一個自回歸模型。使用AR模型訓練、驗證並進行時間序列預測的示例程序為train_array.py。
  • 如何使用 Python 進行時間序列預測?
    在本教程中,您將了解如何開發持久性預測,以便用Python計算時間序列數據集的性能基準級別。完成本教程後,您將知道:讓我們開始吧。以下代碼片段將加載Shampoo Sales數據集並繪製時間序列。不需要進行模型訓練或再訓練,所以本質上,我們按照時間序列逐步完成測試數據集並得到預測。一旦完成對訓練數據集中的每個時間點進預測,就將其與預期值進行比較,並計算均方差(MSE)。