fb
时间序列预测一直是预测问题中的难点,人们很难找到一个适用场景丰富的通用模型,这是因为现实中每个预测问题的背景知识,例如数据的产生过程,往往是不同的,即使是同一类问题,影响这些预测值的因素与程度也往往不同,再加上预测问题往往需要大量专业的统计知识,这又给分析人员带来了难度,这些都使得时间序列预测问题变得尤其复杂。传统的时间序列预测方法通常有如下缺陷:
- 适用的时序数据过于局限
- 缺失值需要填补
- 模型缺乏灵活性
- 指导作用较弱
2017年2月24号facebook开源了时间序列预测框架prophet,目前支持R语言和Python语言。托管在github上:https://github.com/facebookincuBATor/prophet。prophet是基于可分解(趋势+季节+节假日)模型的开源库,Prophet充分的将业务背景知识和统计知识融合起来,它让我们可以用简单直观的参数进行高精度的时间序列预测,并且支持自定义季节和节假日的影响。官方号称“让普通人也能像数据分析师一样得出专业的结论”。
原理
时间序列模型可分解为三个主要组成部分:趋势,季节性和节假日。它们按如下公式组合:
g(t):用于拟合时间序列中的分段线性增长或逻辑增长等非周期变化。
s(t):周期变化(如:每周/每年的季节性)。
h(t):非规律性的节假日效应(用户造成)。
et:误差项用来反映未在模型中体现的异常变动。
上图是prophet的整体框架,整个过程分为四部分:Modeling、Forecast Evaluation、Surface problems以及Visually Inspect Forecasts。从整体上看,这是一个循环结构,而这个结构又可以根据虚线分为分析师操纵部分与自动化部分,因此,整个过程就是分析师与自动化过程相结合的循环体系,也是一种将问题背景知识与统计分析融合起来的过程,这种结合大大的增加了模型的适用范围,提高了模型的准确性。按照上述的四个部分,prophet的预测过程为:
a.Modeling:建立时间序列模型。分析师根据预测问题的背景选择一个合适的模型。
b.Forecast Evaluation:模型评估。根据模型对历史数据进行仿真,在模型的参数不确定的情况下,我们可以进行多种尝试,并根 据对应的仿真效果评估哪种模型更适合。
c.Surface Problems:呈现问题。如果尝试了多种参数后,模型的整体表现依然不理想,这个时候可以将误差较大的潜在原因呈 现给分析师。
d.Visually Inspect Forecasts:以可视化的方式反馈整个预测结果。当问题反馈给分析师后,分析师考虑是否进一步调整和构建模 型。
参看资料:http://blog.51cto.com/13591395/2066888
Prophet创新点
当预测模型没有按预期运行时,我们希望针对问题来调整模型的参数。调整参数需要对时间序列的工作原理有全面的理解。例如automated ARIMA首先输入的参数是差分的最大阶数,自回归分量和移动平均分量。普通分析师不知道如何调整顺序来避免这种表现,这是一种很难掌握积累的专业知识。Prophet包提供了直观易调的参数,即使是对缺乏模型知识的人来说,也可以据此对各种商业问题做出有意义的预测。
适用条件
并非所有的预测问题都可以通过同一种程序(procedure)解决。Prophet 是为我们在 Facebook 所遇到的业务预测任务而优化的,这些任务通常具有以下特点:
- 有至少几个月(最好是一年)的每小时、每天或每周观察的历史数据;
- 有多种人类规模级别的较强的季节性趋势:每周的一些天和每年的一些时间;
- 有事先知道的以不定期的间隔发生的重要节假日(比如国庆节)。
- 缺失的历史数据或较大的异常数据的数量在合理范围内;
- 有历史趋势的变化;
- 对于数据中蕴含的非线性增长的趋势都有一个自然极限或饱和状态。
安装教程
winds环境
- Python 3.5或更高版本(推荐使用anaconda)
- 更新Microsoft .NET Framework到4.5.1以上版本(C++ 编译器需要)
- 安装C++编译器Visual C++ build Tools2015(在安装 PyStan前需要安装C++编译器)
- 安装 pystan库(pip install pystan)
- 安装fbprophet库(conda install -c conda-forge fbprophet)
linux环境
$ sudo apt-get install fbprophet
参考资料:
https://vectorf.github.io/2017/03/08/20170308-Prophet%20%E4%B9%8B%E5%AE%89%E8%A3%85%E7%AF%87/#二、安装-Prophet-包
参数说明
Prophet()参数说明
growth: String 'linear' or 'logistic' to specify a linear or logistic trend.‘linear‘’或’logistic’用来规定线性或逻辑曲线趋势'.
(默认‘linear’)
changepoints: List of dates at which to include potential changepoints. If not specified, potential changepoints are selected automatically.指定潜在改变点,如果不指定,将会自动选择潜在改变点。例如:changepoints=['2014-01-01']指定2014-01-01这一天是潜在的changepoints。(默认None)
n_changepoints: Number of potential changepoints to include. Not used if input `changepoints` is supplied. If `changepoints` is not supplied,then n_changepoints potential changepoints are selected uniformly from the first `changepoint_range` proportion of the history.表示changepoints的数量大小,如果changepoints指定,该传入参数将不会被使用。如果 changepoints不指定,将会从输入的历史数据前80%中选取25个(个数由n_changepoints传入参数决定)潜在改变点。(默认25)
changepoint_range: Proportion of history in which trend changepoints will be estimated. Defaults to 0.8 for the first 80%. Not used if `changepoints` is specified.Not used if input `changepoints` is supplied.估计趋势变化点的历史比例。如果指定了 `changepoints`,则不使用。(默认0.8)
yearly_seasonality: Fit yearly seasonality.Can be 'auto', True, False, or a number of Fourier terms to generate.指定是否分析数据的 年季节性,如果为True, 默认取傅里叶项为10,最后会输出,yearly_trend,yearly_upper,yearly_lower等数据。(默认auto)
weekly_seasonality: Fit yearly seasonality.Can be 'auto', True, False, or a number of Fourier terms to generate.指定是否分析数据的周季节性,如果为True,默认取傅里叶项10,最后会输出,weekly_trend,weekly_upper,weekly_lower等数据。(默认auto)
daily_seasonality: Fit daily seasonality.Can be 'auto', True, False, or a number of Fourier terms to generate.指定是否分析数据的天季节性,如果为True,默认取傅里叶项为10,最后会输出,daily _trend, daily _upper, daily _lower等数据。(默认auto)
holidays: pd.DataFrame with columns holiday (string) and ds (date type) and optionally columns lower_window and upper_window which specify a range of days around the date to be included as holidays.lower_window=-2 will include 2 days prior to the date as holidays. Also optionally can have a column prior_scale specifying the prior scale for that holiday.传入pd.dataframe 格式的数据。这个数据包含有holiday列 (string)和ds(date类型)和可选列lower_window和upper_window来指定该日期的lower_window或者upper_window范围内都被列为假期。lower_window=-2将包括前2天的日期作为假期。(默认None)
seasonality_mode: 'additive' (default) or 'multiplicative'.季节模型。(默认additive)
seasonality_prior_scale: parameter modulating the strength of the seasonality model. Larger values allow the model to fit larger seasonal fluctuations, smaller values dampen the seasonality. Can be specified for inpidual seasonalities using add_seasonality.调节季节性组件的强度。值越大,模型将适应更强的季节性波动,值越小,越抑制季节性波动。(默认10)
holidays_prior_scale: Parameter modulating the strength of the holiday components model, unless overridden in the holidays input.调节节假日模型组件的强度。值越大,该节假日对模型的影响越大,值越小,节假日的影响越小。(默认10)
changepoint_prior_scale: Parameter modulating the flexibility of the automatic changepoint selection. Large values will allow many changepoints, small values will allow few changepoints.增长趋势模型的灵活度。调节”changepoint”选择的灵活度,值越大选择的”changepoint”越多,使模型对历史数据的拟合程度变强,然而也增加了过拟合的风险。(默认0.05)
mcmc_samples: integer, if greater than 0, will do full Bayesian inference with the specified number of MCMC samples. If 0, will do MAP estimation.mcmc采样,用于获得预测未来的不确定性。若大于0,将做mcmc样本的全贝叶斯推理,如果为0,将做最大后验估计。(默认0)
Interval_width: Float, width of the uncertainty intervals provided for the forecast. If mcmc_samples=0, this will be only the uncertainty in the trend using the MAP estimate of the extrapolated generative model. If mcmc.samples>0, this will be integrated over all model parameters, which will include uncertainty in seasonality.衡量未来时间内趋势改变的程度。表示预测未来时使用的趋势间隔出现的频率和幅度与历史数据的相似度,值越大越相似。当mcmc_samples = 0时,该参数仅用于增长趋势模型的改变程度,当mcmc_samples > 0时,该参数也包括了季节性趋势改变的程度。(默认0.8)
uncertainty_samples: Number of simulated draws used to estimate uncertainty intervals.用于估计不确定性区间的模拟抽取数。(默认1000)
make_future_dataframe()参数说明
def make_future_dataframe(self, periods, freq='D', include_history=True):
periods: Int number of periods to forecast forward.向前预测步数
freq: Any valid frequency for pd.date_range, such as’H’、 'D' or 'M'.预测单位小时为’H’,天为’D’,月为’M’
include_history: Boolean to include the historical dates in the data frame for predictions是否包含历史数据的预测,保持默认就好。
案例
以Peyton Manning 在维基百科页面的(2007年12月10日-2016年1月20日)每日点击数量为建模数据。Peyton Manning 是一名美式橄榄球运动员,通过fbprophet你可以看到他一年、一周重要程度的季节性变化,最后也会看到特定事件(季后赛和超级碗)的影响。数据来源:https://github.com/facebook/prophet/tree/master/examples
python代码
import pandas as pd
import numpy as np
from fbprophet import Prophet
df = pd.read_excel('C:/Users/yangge/Desktop/prophet-master/examples/example_wp_peyton_manning.xlsx')
df['y'] = np.log(df['y'])
playoffs = pd.DataFrame({
'holiday': 'playoff',
'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
'2010-01-24', '2010-02-07', '2011-01-08',
'2013-01-12', '2014-01-12', '2014-01-19',
'2014-02-02', '2015-01-11', '2016-01-17',
'2016-01-24', '2016-02-07']),
'lower_window': 0,
'upper_window': 1,
})
superbowls = pd.DataFrame({
'holiday': 'superbowl',
'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']),
'lower_window': 0,
'upper_window': 1,
})
holidays = pd.concat((playoffs, superbowls))#季后赛和超级碗比赛特别日期
m = Prophet(holidays=holidays)#指定节假日参数,其它参数以默认值进行训练
m.fit(df)#对过去数据进行训练
future = m.make_future_dataframe(freq='D',periods=365)#建立数据预测框架,数据粒度为天,预测步长为一年
forecast =m.predict(future)
m.plot(forecast).show()#绘制预测效果图
m.plot_components(forecast).show()#绘制成分趋势图
结果展现
图中黑点表示实际值,蓝色表示预测值,浅蓝色表示yhat_upper和yhat_lower,置信区间受到interval_width这个参数的影响;当然,从forecasts的keys中可以看到,还有其他的_upper和_lower,同样也会受到这个参数的影响。
除了上述的整体预测情况外,Prophet还提供了组成成分分析(简称成分分析),所谓成分分析就是指对原理公式中的三大部分模型单独进行分析,成分分析有助于我们考察模型中的各个组件分别对预测结果的影响,通过可视化的展示,我们可以准确判断影响预测效果的具体原因,从而针对性的解决。成分分析是我们提高模型准确性的重要来源。例如下图结果:
上述四个图从上至下依次是对增长趋势模型(trend)、节假日模型(holidays)以及季节性模型(weekly和yearly)的展示。需要注意的是,如果没有在holidays参数里注明具体的节假日信息,模块也不会自动对这一部分进行分析。如果对于上面的结果你觉得有不合理的地方,那么可以根据中参数使用说明更改相应的成分影响,这里应该尽可能的利用你的专业背景知识,以使各部分组成的影响更符合实际。举个例子,如果在每年趋势”yearly”中你认为当前的效果过拟合了,那么就可以调解seasonality_prior_scale这个参数,值越小,这里的季节性波动就越小。
fbprophet优点
(1)大规模、细粒度数据
能进行大范围预测,并且给出置信区间;数据时间粒度可以很小,支持小时、天、月数据。
(2)自动处理缺失值数据
遇到有缺失的数据时其它预测方法需要先进行插值填补预处理,而fbprophet可以自己处理缺失值数据。
(3)更灵活,支持季节、节假日调节
有些突变点往往是由特别的节假日期引起的,fbprophet支持输入这些日期以及前后影响的时间窗口,预测的时候自动适这些日期。
(4)趋势预测+趋势分解
拟合的有两种趋势:线性趋势、logistic趋势;趋势分解有很多种:Trend、年、周、天趋势、以及节假日效应。
(5)模型参数易解释
模型参数很好理解,可以让分析师根据业务经验调节参数来增强某部分假设提高准确率,使模型与业务达到理想的融合。
(6)拟合速度快
(7)操作简单
不仅环境搭建简单,而且只要十几行代码即可完成整个预测过程。
调参经验
- 首先我们去除数据中的异常点(outlier),直接赋值为none就可以,因为Prophet的设计中可以通过插值处理缺失值,但是对异常值比较敏感。
- 选择趋势模型,默认使用分段线性的趋势,但是如果认为模型的趋势是按照log函数方式增长的,可设置growth='logistic'从而使用分段log的增长方式
- 设置趋势转折点(changepoint),如果我们知道时间序列的趋势会在某些位置发现转变,可以进行人工设置,比如某一天有新产品上线会影响我们的走势,我们可以将这个时刻设置为转折点。
- 设置周期性,模型默认是带有年和星期以及天的周期性,其他月、小时的周期性需要自己根据数据的特征进行设置,或者设置将年和星期等周期关闭。
- 设置节假日特征,如果我们的数据存在节假日的突增或者突降,我们可以设置holiday参数来进行调节,可以设置不同的holiday,例如五一一种,国庆一种,影响大小不一样,时间段也不一样。
- 此时可以简单的进行作图观察,然后可以根据经验继续调节上述模型参数,同时根据模型是否过拟合以及对什么成分过拟合,我们可以对应调节seasonality_prior_scale、holidays_prior_scale、changepoint_prior_scale参数。
- 如果预测结果的误差很大,考虑选取的模型是否准确,尝试调整增长率模型(growth)的参数,在必要的情况下也需要调整季节性(seasonality)参数。
- 如果在尝试的大多数方法中,某些日期的预测依然存在很大的误差,这就说明历史数据中存在异常值。最好的办法就是找到这些异常值并剔除掉。使用者无需像其他方法那样对剔除的数据进行插值拟合,可以仅保留异常值对应的时间, 并将异常值修改为空值(NA),模型在预测时依然可以给出这个时间点对应的预测结果。
- 如果对历史数据进行仿真预测时发现,从一个截点到下一个截点误差急剧的增加,这说明在两个截点期间数据的产生过程发生了较大的变化,此时两个截点之间应该增加一个”changepoint”,来对这期间的不同阶段分别建模。
参考资料:https://blog.csdn.net/h4565445654/article/details/78398089 fbProphe时序预测----论文总结以及调参思路
http://blog.51cto.com/13591395/2066888 腾讯技术工程 | 基于Prophet的时间序列预测
相关网站
- Prophet官方文档:https://facebook.github.io/prophet/
- Prophet论文:https://peerj.com/preprints/3190/
- Prophet-github:https://github.com/facebook/prophet
备注:承接模型、算法代码实现(支持python、Matlab),有意请联系QQ947943645 ,非诚勿扰!
相关阅读
玩转积分系统,纷纷钟稳日活,促留存。移动互联网领域在产品中搭建积分系统,利用小积分的杠杆作用,可有效提升APP留存率,同时在用户忠诚
对于论坛推广和营销,首先介绍一下我的经历,我在常州化龙巷的论坛做了3年的斑竹,我从08年开始上化龙巷,到今年已经整整4年多。一开始的
结合最近的工作,在本文和大家分享面对越来越多的业务场景,我们是如何改版驴妈妈首页设计,既能体现产品的定位又能将用户的价值最大化
一:UDP打洞的用途 当你编写的程序,需要两个局域网能够进行通信的时候,UDP打洞不失为一种好方法。简而言之,UDP打洞是为了实现两
A5创业网(公众号:iadmin5)12月29日消息:对于Facebook这个世界最大社交网络来说,2018年堪称是“多灾多难”的年份,危机频发