時間序列模型 Prophet 參數設置 實例 源碼

==部分來自學習總結==

1、先說適用範圍:

很明顯,Prophet只適用於具有明顯的內在規律(或者說,模式)的商業行爲數據。

雖然官方案例裏通常使用日數據的序列,但對於更短時間頻段,比如小時數據,也是支持的。

但對於不具有明顯趨勢性、週期性的時間序列,使用Prophet進行預測就不適合了。比如前面有同學用Prophet來預測滬深300……先不說有效市場假說(EMH)否定了歷史數據對未來價格擬合的可能性,就算市場存在模式,也不是能夠被一個通用模型簡單的線性分解成趨勢和週期的。

2、入門

提一下安裝,win10 +py3.7 +anaconda ,剛開始裝確實有問題,後來按照這個命令:
 

conda install pystan

conda install -c conda-forge fbprophet


要先裝pystan,

可以裝上了,但是很慢,要升級很多庫,我大概用了1小時。

 

網上很多入門代碼,官網也給了很多demo。上手很快,按照網上的數據,預測的結果很ok,信心滿滿。

總是按照別人的東西做,感覺缺點什麼,自己打算給自己挖個坑。

預測一下sin函數。

3、入坑

創建data:這裏我改爲了txt格式,爲了後面方便嵌入到自己的項目程序中。

運行,一氣呵成,結果如圖:

紅線是預測;黑點是輸入。黑色虛線是設定的上線。

肯定是哪裏錯了,不可能連sin函數都預測不出來。

4、學習

應該是要調整參數,給我感覺就是跟隨性太差。

經過學習,主要參數如下:

Prophet()的主要參數:

#設置跟隨性: changepoint_prior_scale=0.05 值越大,擬合的跟隨性越好,可能會過擬合
#設置置信區間:interval_width=0.8(默認值),值越小,上下線的帶寬越小。
#指定預測類型: growth='linear'或growth = "logistic" ,默認應該是linear。
#馬爾科夫蒙特卡洛取樣(MCMC): mcmc_samples=0,會計算很慢。距離意義不清楚
#設置尋找突變點的比例:changepoint_range=0.9 默認從數據的前90%中尋找異常數據。預測這個正弦曲線,如果不設置changepoint_range=1,預測的結果是不對的,不知道爲什麼。

make_future_dataframe( )的主要參數:

#periods 週期,一般是根據實際意義確定,重點:後續預測的長度是一個週期的長度。
#freq 我見的有‘MS‘、H、M ,預測sin,要設置H ,個人理解數據如果變化很快,要用H

其他的內置參數:

yearly_seasonality 是年規律擬合,Prophet模型會描繪出以一年爲單位的數據規律,後面的部分會有圖示;同理於參數 weekly_seasonality,daily_seasonality。

n_changepoints 是預設轉折點數量

changepoint_range 是設定轉折點可以存在的範圍,.1表示存在於歷史數據的前十分之一,.5表示在歷史數據的前半部分,其餘同理。

changepoint_prior_scale 是設置模型對轉折點擬合的靈敏度,值越高越靈活。

changepoints=[] 是指定轉折點的具體位置

yearly_seasonality 是年的擬合度,值越高越靈活,同時可以選擇True和False來設定是否進行年度的擬合。同理與weekly_seasonality和daily_seasonality。

holidays_prior_scale 是假期的擬合度,同樣值越高越靈活,同時前提是你需要有假期信息的加入。

seasonality_mode=‘multiplicative’ 是模型學習的方式,默認情況下爲加性的,如果如上所示來設置,則是乘性的(multiplicative)。
 

5、再調試

經過參數學習後,主要調整參數如下:

m = Prophet(changepoint_prior_scale=0.9,interval_width=0.9,growth='linear',changepoint_range=1)


。。。

future = m.make_future_dataframe(periods=120, freq='H') #freq=‘MS‘或者H  來設置

運行結果:

自己覺得效果挺好了。

6、小技巧

6.1其他語言程序調用Python

一般是命令行的方法,啓動cmd,傳入參數。如下:

filename = sys.argv[1]  #從cmd讀取數據
filename='data'#從指定文件讀取數據

其他程序首先啓動一個cmd,然後切換到.py文件的目錄,然後執行命令: python   yourfilename.py   變量value

就可以把參數傳入filename 。

6.2、prophet預測的未來的長度是設定的periods的長度。

6.3、爲什麼有的數據要現log處理,在預測,看這個:https://blog.csdn.net/anshuai_aw1/article/details/83866105

6.4、保存panda 中的dataframe的數據到文本,(新手,做筆記)

#forecast.to_csv(savename, sep='\t',index=False)   #保留panda.dataframe 的全部列數據

forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].to_csv(savename, sep='\t',index=False) #保留panda.dataframe 的指定列的數據

6.5、在圖上顯示出突變點:

fig=m.plot(forecast)

...

a = add_changepoints_to_plot(fig.gca(), m, forecast)

6.6、疑惑

prophet只能預測一個Y列嗎,如果有多個Y列怎麼辦?是分多次預測嗎?

 

7、源碼

GitHub地址:https://github.com/DamonDBT/prophet_sin_demo

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 19 11:49:17 2019

@author: dbt
"""
# Python
import pandas as pd
import numpy as np
from fbprophet import Prophet
import sys
import os
import matplotlib.pyplot as plt
from fbprophet.plot import add_changepoints_to_plot

#orig_out = sys.stdout
#sys.stdout = open(os.devnull, 'w')
 

#filename = sys.argv[1]  #從cmd讀取數據
filename='data'#從指定文件讀取數據


df = pd.read_csv(filename+'.txt')
#df['y'] = np.log(df['y'])  #爲什麼要log處理?都要有嗎?

#df['cap'] = 1#log預測才用
#df['floor'] = -1#log預測才用

df.head()


#設置跟隨性: changepoint_prior_scale=0.05 值越大,擬合的跟隨性越好,可能會過擬合
#設置置信區間:interval_width=0.8(默認值),值越小,上下線的帶寬越小。
#指定預測類型: growth='linear'或growth = "logistic" ,默認應該是linear。
#馬爾科夫蒙特卡洛取樣(MCMC): mcmc_samples=0,會計算很慢。距離意義不清楚
#設置尋找突變點的比例:changepoint_range=0.9 默認從數據的前90%中尋找異常數據。預測這個正弦曲線,如果不設置changepoint_range=1,預測的結果是不對的,不知道爲什麼。

m = Prophet(changepoint_prior_scale=0.9,interval_width=0.9,growth='linear',changepoint_range=1)          
m.fit(df);

#periods 週期,一般是根據實際意義確定,重點:後續預測的長度是一個週期的長度。
#freq 我見的有‘MS‘、H、M ,預測sin,要設置H ,個人理解數據如果變化很快,要用H
future = m.make_future_dataframe(periods=120, freq='H') #freq=‘MS‘或者H  來設置

future['cap'] = 1 #log預測才用?linear也可以加上。
future['floor'] = -1#log預測才用?linear也可以加上。

#畫圖
future.tail()

forecast = m.predict(future)
forecast.tail()
fig=m.plot(forecast)
plt.savefig('./out/'+filename+'_1.jpg',dpi=500)
m.plot_components(forecast)
plt.savefig('./out/'+filename+'_2.jpg',dpi=500)
#print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']])  #打印到console
 

savename='./out/'+filename+"_out.txt"
 
 
#forecast.to_csv(savename, sep='\t',index=False)   #保留panda.dataframe 的全部列數據

forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].to_csv(savename, sep='\t',index=False) #保留panda.dataframe 的指定列的數據

x = forecast['ds']
y = forecast['yhat']
y1 = forecast['yhat_lower']
y2 = forecast['yhat_upper']
plt.plot(x,y)
plt.savefig('./out/'+filename+'_3.jpg',dpi=500)
plt.plot(x,y1)
plt.savefig('./out/'+filename+'_4.jpg',dpi=500)
plt.plot(x,y2)
plt.savefig('./out/'+filename+'_5.jpg',dpi=500)
#plt.show()

#把檢測到的突變點,用紅色線表示在圖上。
a = add_changepoints_to_plot(fig.gca(), m, forecast)

8、測試數據

給出一部分吧,畢竟就是一個sin 函數,excel拉一下就有了,(GitHub 的demo有完整的。)https://github.com/DamonDBT/prophet_sin_demo

ds y
2007/12/10 0.841471
2007/12/11 0.891207
2007/12/12 0.932039
2007/12/13 0.963558
2007/12/14 0.98545
2007/12/15 0.997495
2007/12/16 0.999574
2007/12/17 0.991665
2007/12/18 0.973848
2007/12/19 0.9463
2007/12/20 0.909297
2007/12/21 0.863209
2007/12/22 0.808496
2007/12/23 0.745705
2007/12/24 0.675463
2007/12/25 0.598472

 

9、附上一些好的博客

https://blog.csdn.net/anshuai_aw1/article/details/83412058#commentBox

https://blog.csdn.net/u010665216/article/details/79216744

https://www.biaodianfu.com/prophet.html

https://www.cnblogs.com/bonelee/p/9577432.html

官網:https://facebook.github.io/prophet/docs/non-daily_data.html#data-with-regular-gaps

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章