基于fbprophet的时间序列预测
- 基于fbprophet的时间序列预测
- Prophet模型
- 常用参数说明
- 趋势相关
- 周期相关
- 假日相关
- 简单入门
- 误差评估与调参
- 使用训练出来的参数进行最终的预测
基于fbprophet的时间序列预测
由于业务的需求,需要对未来一段时间做销量预测,这在过去可能有点玄学,而随着数据科学(机器学习)的发展,此类问题被归类为基于时间序列的预测,同时也产生了各种时序预测的算法模型,诸如ARMA/ARIMA、指数平滑法Holt-winters、基于深度学习的LSTM等,还包括fbprophet,这也是本文讨论的主角,与前面的几种算法模型相比,fbprophet更加的简单易用,且效果明显。
时间序列预测属于监督学习,本质上是给计算机输入历史数据集,由计算机根据一定的算法拟合出一条较为贴近(也不是越贴近越好)真实值的曲线(一个数学函数),并依根此函数对未来数据做出预测。
Prophet模型
Prophet是Facebook于2017年开源的一个时间序列预测算法,Facebook宣称默认配置的Prophet模型就可以生成媲美专业数据分析师的预测,即使不是时序分析方面专家,也可以理解该模型的重要参数。Prophet将预测值看成关于时间的函数,其模型如下:
1
2y(t)=g(t)+s(t)+h(t)+εt
其中:
g(t)代表趋势,影响因素如人口(或用户数)的增长,行业发展的最大上限(天花板)等。这一项,prophet提供了两种实现:分段线性(linear)和分段logistic回归(logistic)
s(t)代表周期性,用于拟合数据的周期性变化规率,可以是按年,按季度,按月,按周,按天等等。比如对于线下商店而言,周末客流多会一些,其销量也会高一些。
h(t)代表假日,用于拟合节假日,或促销活动带来影响。
εt是噪声项,代表一些意外因素,用于拟合诸如断电,恶劣天气,自然灾害等影响。
注:上面的每一项,都可以理解为一个复杂的数学函数,这里不做展开,有兴趣的同学可以参看:https://blog.csdn.net/a358463121/article/details/70194279
常用参数说明
常用参数主要分为趁势类,周期类,假日等,等于号后面代表默认。
趋势相关
1
2
3
4
5
6growth='linear',#模型的趋势函数:分段线性:linear,逻辑回归:logistic changepoints=None,#突变点集合 n_changepoints=25,#突变点个数 changepoint_range=0.8,#突变点所在的数据范围,默认为数据集的前80% changepoint_prior_scale=0.05,#自动突变点选择的灵活性,值越大越容易出现changepoint
周期相关
1
2
3
4
5
6yearly_seasonality='auto',#年相关性 weekly_seasonality='auto',#周相关性 daily_seasonality='auto',#日相关性 seasonality_mode='additive',#周期性模型使用的拟合模型,默认使用加法模型,seasonality_mode='multiplicative'表示乘法模型 seasonality_prior_scale=10.0,#周期性相关度,值越大即呈现的周期性规率越明显
假日相关
1
2
3holidays=None,#指定节假日列表 holidays_prior_scale=10.0,#节假日相关度,值越大即表示节假日因素的影响越大
简单入门
以官方文档提供的佩顿 • 曼宁的维基百科主页 每日访问量的时间序列数据(2007/12/10 - 2016/01/20)以例,进行模型拟合与调参。
1
2
3
4
5
6
7
8
9import pandas as pd from fbprophet import Prophet import matplotlib.pyplot as plt from pandas.plotting import register_matplotlib_converters # 读入数据集 whole_df = pd.read_csv('example_wp_log_peyton_manning.csv') whole_df
看下数据是什么样子
1
2
3
4df = whole_df[whole_df['ds']>'2013-01-01']#为显示清晰,只取3年的数据 df.index=df['ds'] df.plot(figsize=(32,8))
进行简单的数据预测
1
2
3
4
5
6
7
8m = Prophet() #创建Prophet对象来拟合模型,这里先采用默认参数 m.fit(df) #代入数据集来拟合模型 fday = 30 #要预测的天数 future = m.make_future_dataframe(periods=fday)#将数据集扩充至未来的天数,同时包含历史数据 forecast = m.predict(future)#执行预测:对每一个日期的历史数据生成一个预测值(称为 yhat ) m.plot(forecast,figsize=(32, 8))#将预测的效果进行绘图
解读:其中离散的圆点是实际值,蓝色线是预测值
直此预测结果已经出来,如果进一步看模型的趋势,以及年度季节性和周季节性,可以采用:
1
2m.plot_components(forecast)
误差评估与调参
上述几行代码就可以实现预测,是不是太简单了?用默认参数构建出来的模型所产生的预测结果可能不是很理想,我们需要将历史数据集拆分成训练集和测试集,然后通过不断调整参数,并且将预测结果与测试集进行对比,计算误差,最后求解出误差最小的参数,并以此参数来对未来数据进行预测。
迭代求解最优参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#寻参:为简化for次数,这里只列出两个参数,实际需要迭代的会更多 def find_params(df,fdays): train_size = len(df) - fdays train_df,test_df=df[0:train_size], df[train_size:len(df)] seasonality_modes = ['additive', 'multiplicative'] seasonality_prior_scales = [0.01,0.03, 0.1, 0.3, 1, 3, 10,30] #holidays_prior_scales = [0.01,0.05, 0.2, 1, 5, 10, 20] #事实上可以加入更多参数,这里略去 min_err = -1 best_params = None for mode in seasonality_modes: for sp_scale in seasonality_prior_scales: params = { "seasonality_mode": mode, "seasonality_prior_scale": sp_scale } avg_err = predict_one(train_df,test_df,fdays,params) if(avg_err < min_err): min_err = avg_err best_params = params print(f'{params}:{avg_err}') print(f'最小平均误差:{min_err},最优参数:{best_params}') #根据参数进行一次预测,并算出预测的误差 def predict_one(train_df,test_df,fdays,params): m = Prophet(**params) m.fit(train_df) future = m.make_future_dataframe(periods=fdays)#将数据集扩充至未来的天数,同时包含历史数据 forecast = m.predict(future).tail(fdays) forecast.index = forecast['ds'].map(lambda x:x.strftime('%Y-%m-%d')) return mean_forecast_err(test_df['y'],forecast['yhat']) #计算平均误差 def mean_forecast_err(y, yhat): return y.sub(yhat).abs().mean()
结果如下:
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 0.01}:0.46835404175700496
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 0.03}:0.47134440199356015
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 0.1}:0.47418518322082714
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 0.3}:0.4748634038391658
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 1}:0.47178295035945506
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 3}:0.47382680395375665
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 10}:0.4750603929631507
{‘seasonality_mode’: ‘additive’, ‘seasonality_prior_scale’: 30}:0.4710919693964274
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 0.01}:0.4699275213869728
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 0.03}:0.46863816555668125
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 0.1}:0.4709381698222656
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 0.3}:0.47118585242058947
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 1}:0.47044784615578944
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 3}:0.46960144311702073
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 10}:0.4688539147158322
{‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 30}:0.4677488199423377
最小平均误差: 0.4677488199423377,最优参数: {‘seasonality_mode’: ‘multiplicative’, ‘seasonality_prior_scale’: 30}
使用训练出来的参数进行最终的预测
这时只需要将参数代入Prophet模型完成预测即可,代码略
参考
[1]: https://blog.csdn.net/anshuai_aw1/article/details/83412058
[2]: https://facebook.github.io/prophet/docs/quick_start.html#python-api
最后
以上就是爱撒娇朋友最近收集整理的关于基于fbprophet的时间序列预测基于fbprophet的时间序列预测的全部内容,更多相关基于fbprophet内容请搜索靠谱客的其他文章。
发表评论 取消回复