基于fbprophet的时间序列预测

基于fbprophet的时间序列预测

由于业务的需求,需要对未来一段时间做销量预测,这在过去可能有点玄学,而随着数据科学(机器学习)的发展,此类问题被归类为基于时间序列的预测,同时也产生了各种时序预测的算法模型,诸如ARMA/ARIMA、指数平滑法Holt-winters、基于深度学习的LSTM等,还包括fbprophet,这也是本文讨论的主角,与前面的几种算法模型相比,fbprophet更加的简单易用,且效果明显。
时间序列预测属于监督学习,本质上是给计算机输入历史数据集,由计算机根据一定的算法拟合出一条较为贴近(也不是越贴近越好)真实值的曲线(一个数学函数),并依根此函数对未来数据做出预测。

Prophet模型

Prophet是Facebook于2017年开源的一个时间序列预测算法,Facebook宣称默认配置的Prophet模型就可以生成媲美专业数据分析师的预测,即使不是时序分析方面专家,也可以理解该模型的重要参数。Prophet将预测值看成关于时间的函数,其模型如下:

      y(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

常用参数说明

常用参数主要分为趁势类,周期类,假日等,等于号后面代表默认。

趋势相关

growth='linear',#模型的趋势函数:分段线性:linear,逻辑回归:logistic
changepoints=None,#突变点集合
n_changepoints=25,#突变点个数
changepoint_range=0.8,#突变点所在的数据范围,默认为数据集的前80%
changepoint_prior_scale=0.05,#自动突变点选择的灵活性,值越大越容易出现changepoint

周期相关

yearly_seasonality='auto',#年相关性
weekly_seasonality='auto',#周相关性
daily_seasonality='auto',#日相关性
seasonality_mode='additive',#周期性模型使用的拟合模型,默认使用加法模型,seasonality_mode='multiplicative'表示乘法模型
seasonality_prior_scale=10.0,#周期性相关度,值越大即呈现的周期性规率越明显

假日相关

holidays=None,#指定节假日列表
holidays_prior_scale=10.0,#节假日相关度,值越大即表示节假日因素的影响越大

简单入门

以官方文档提供的佩顿 • 曼宁的维基百科主页 每日访问量的时间序列数据(2007/12/10 - 2016/01/20)以例,进行模型拟合与调参。

import 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

在这里插入图片描述
看下数据是什么样子

df = whole_df[whole_df['ds']>'2013-01-01']#为显示清晰,只取3年的数据
df.index=df['ds']
df.plot(figsize=(32,8))

在这里插入图片描述
进行简单的数据预测

m = 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))#将预测的效果进行绘图

在这里插入图片描述
解读:其中离散的圆点是实际值,蓝色线是预测值
直此预测结果已经出来,如果进一步看模型的趋势,以及年度季节性和周季节性,可以采用:

m.plot_components(forecast)

在这里插入图片描述

误差评估与调参

上述几行代码就可以实现预测,是不是太简单了?用默认参数构建出来的模型所产生的预测结果可能不是很理想,我们需要将历史数据集拆分成训练集和测试集,然后通过不断调整参数,并且将预测结果与测试集进行对比,计算误差,最后求解出误差最小的参数,并以此参数来对未来数据进行预测。

在这里插入图片描述
迭代求解最优参数

#寻参:为简化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

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值