==部分來自學習總結==
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