==部分来自学习总结==
很明显,Prophet只适用于具有明显的内在规律(或者说,模式)的商业行为数据。
虽然官方案例里通常使用日数据的序列,但对于更短时间频段,比如小时数据,也是支持的。
但对于不具有明显趋势性、周期性的时间序列,使用Prophet进行预测就不适合了。比如前面有同学用Prophet来预测沪深300……先不说有效市场假说(EMH)否定了历史数据对未来价格拟合的可能性,就算市场存在模式,也不是能够被一个通用模型简单的线性分解成趋势和周期的。
提一下安装,win10 +py3.7 +anaconda ,刚开始装确实有问题,后来按照这个命令:
conda install pystan
conda install -c conda-forge fbprophet
要先装pystan,
可以装上了,但是很慢,要升级很多库,我大概用了1小时。
网上很多入门代码,官网也给了很多demo。上手很快,按照网上的数据,预测的结果很ok,信心满满。
总是按照别人的东西做,感觉缺点什么,自己打算给自己挖个坑。
预测一下sin函数。
创建data:这里我改为了txt格式,为了后面方便嵌入到自己的项目程序中。
运行,一气呵成,结果如图:
红线是预测;黑点是输入。黑色虚线是设定的上线。
肯定是哪里错了,不可能连sin函数都预测不出来。
应该是要调整参数,给我感觉就是跟随性太差。
经过学习,主要参数如下:
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)。
经过参数学习后,主要调整参数如下:
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.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列怎么办?是分多次预测吗?
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