美文网首页Time series Analysis
mac版的fbprophet从安装到使用手册

mac版的fbprophet从安装到使用手册

作者: 不分享的知识毫无意义 | 来源:发表于2020-04-11 11:22 被阅读0次

    这篇是学习和使用笔记,参考内容比较多,没有很多原创,目的是希望大家快速入手这个包。
    fbprophet这个包是facebook开源的时间序列预测包,因为其优良的性能,现在得到了大家的追捧,但是安装过程实在太多坑。

    0.安装

    本人使用mac电脑,因为这个包用到c++的环境,笔者是死活安装不成功,然后百度了好多问题无果,最终的解决方案是下面的安装步骤。

    conda install pystan
    #将安装很多依赖,不要用pip装,一定用conda装,嫌安装慢的,可以配置一个国内的镜像安装源。
    #下载最新的prophet包,然后用
    pip install fbprophet-0.6.tar.gz
    

    期间如果遇到什么问题,欢迎随时私信我,这两步是最重要的。

    1.入门

    fbprophet完全继承了sklearn的模式,用fit,predict就可以进行使用。
    fbprophet的输入是一个df,一般只包含两列第一列是日期,当然也可以是小时级别的,第二列就是具体的数据,这个包的好处显而易见,你不用去对数据特征进行处理了。
    使用流程是:导包—导数据—建立一个prophet实例—fit—predict

    import pandas as pd
    from fbprophet import Prophet
    sj = pd.read_excel('/Users/elliot/Desktop/manning.xlsx')
    #sj.head(10)
    m = Prophet()
    m.fit(sj)#去训练
    future = m.make_future_dataframe(periods=365)#再现有数据的基础上外推365天
    future.tail()
    pout = m.predict(future)#去预测
    m.plot_components(pout)#画出分解图
    

    2.饱和增长模型

    饱和增长是指在资源有限的情况下事物的增长有上限的一种模式,符合大部分事物的发展规律,比如一个港口的吞吐量是不可能无限增长的,因为这个增长特征符合逻辑回归的曲线形式,因此又被成为logsitic模型,业内通常翻译为阻滞增长模型。
    使用饱和增长模型,要在原有df的基础上新增一列cap,还要指定预测模型为logstic。

    #前边导包导数据都一样的
    sj['cap'] = 15.0
    m = Prophet(growth='logistic')
    m.fit(sj)
    future = m.make_future_dataframe(periods=365)
    future['cap'] = 15.0
    future.tail()
    pout = m.predict(future)
    fig = m.plot(pout)
    

    当然可以设置饱和增长的最大值,也可以设置饱和下降的最小值,看你业务需要,去调整变量名就好了。

    3.突变点处理

    当然了,时间序列不可能是完全平稳的,正常数据肯定存在突变点的,关于突变点检测有很多方法,网上基本都是现成的,比如用统计学的方法,用zscore,用孤立森林方法或者用其他方法。fbprophet可以自动识别突变点,这一点做得是比较好的。
    这里我不想说的太复杂,简单说就是:同过changepoint和n_changepoint来指定异常点,如果啥也不给定,模型将从输入数据的前80%中找出25个异常点,怎么找呢,其实就是用了拐点检测的算法,具体不用搞懂。如果指定了就用你指定的日期作为异常点。
    prophet对异常点的处理方法嘛很暴力就是忽略,相当于L1正则化,回想一下L1正则化就是将默写指标的权重设置为0来防止过拟合嘛。

    from fbprophet.plot import add_changepoints_to_plot
    fig = m.plot(pout)
    a = add_changepoints_to_plot(fig.gca(), m, pout)
    

    图如下所示:


    异常点自动检测

    如果你不想从80%数据找异常点咋办,设置changepoint_range这个参数,设置为0.9。
    如果你想调整预测结果的灵活性,你可以设置changepoint_prior_scale这个参数,默认是0.05,放大会使预测结果范围更加宽广。

    m = Prophet(changepoint_prior_scale=0.5)
    m.fit(sj)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    fig = m.plot(forecast)
    
    调整changepoint_prior_scale参数结果

    4.节假日效应

    节假日是影响数据波动的一个重要因素,比如双十一可以显著提高销量,春节期间则能显著降低物流量等。所以需要对节假日进行一个特殊处理。
    要想分析节假日效应的话需要新增加一个dataframe,包含节假期和日期两个字段,预测数据中也要注明节假期。当然如果节假日是一个区间,你可以再dataframe中新增两列,lower_window 和 upper_window,将节假日扩展为一个区间。
    建好节假日的dataframe后,建模的时候传参进去就可以了,没啥好说的。

    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(sj)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    fig = m.plot(forecast)
    forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
            ['ds', 'playoff', 'superbowl']][-10:]
    fig = m.plot_components(forecast)
    from fbprophet.plot import plot_forecast_component
    m.plot_forecast_component(forecast, 'superbowl')
    #单独画出节假日影响的图像
    

    如果发现节假日被过拟合了,你可以设置holidays_prior_scale参数来降低节假日的影响,这个参数默认取10,越大节假日影响越大,越小节假日影响越小。

    5.季节性趋势

    5.1 加法季节性

    季节性使用傅里叶级数的方法进行建模的,这也是为什么fbprophet依赖C++包的原因。
    在fbprophet中通过yearly_seasonality来调整,默认是10,如果季节性变化更明显,可以将这个数值调整的大一些,比如20。
    你也可以通过指定weekly_seasonality和daily_seasonality两个参数来指定是否增加周和日的季节性。当然也可以通过add_seasality添加月、周、日甚至小时级别的季节性,三个参数,period、fourier_order,即傅里叶级数和prior_scale,先验规模,用来判断过拟合的。

    m = Prophet(weekly_seasonality=False)
    m.add_seasonality(name='monthly', period=30.5, fourier_order=5,prior_scale=0.1)
    forecast = m.fit(sj).predict(future)
    fig = m.plot_components(forecast)
    

    同节假日相同,如果发现季节被过拟合了,可以设置 seasonality_prior_scale来调整。

    5.2 乘法季节性

    有些时候采用加法季节性是无效的,比如航空数据,有明显的随年度增加的趋势,但季节变化趋势也随着年份的增加发生了改变,采用传统的加法模型就不可行了。这时候可以尝试采用乘法季节性模型,就是在建模时候增加seasonality_mode='multiplicative'参数。值得注意的是因为设置了乘法模型,所以季节性和节假日都是乘法的关系。

    m = Prophet(seasonality_mode='multiplicative')
    m.fit(df)
    forecast = m.predict(future)
    fig = m.plot(forecast)
    fig = m.plot_components(forecast)
    

    当然了你也可以设置加法或者乘法,比如上述代码设置了季节性为乘法,那么你新增加一个季节性的时候可以指定是乘法或加法,这种做法就比较灵活。

    m = Prophet(seasonality_mode='multiplicative')
    m.add_seasonality('quarterly', period=91.25, fourier_order=8, mode='additive')
    

    6.附加回归量

    附加回归量是说有的因素可能影响预测结果,但是这个影响由没有展现出明显的年/月/日周期性,这时候可以加一个附加的回归量。用add_regressor这个方法,在建立预测模型之后添加,附加回归量取逻辑值。

    def nfl_sunday(ds):
        date = pd.to_datetime(ds)
        if date.weekday() == 6 and (date.month > 8 or date.month < 2):
            return 1
        else:
            return 0
    df['nfl_sunday'] = df['ds'].apply(nfl_sunday)
    m = Prophet()
    m.add_regressor('nfl_sunday')
    m.fit(df)
    future['nfl_sunday'] = future['ds'].apply(nfl_sunday)
    forecast = m.predict(future)
    fig = m.plot_components(forecast)
    

    7.预测区间

    7.1 趋势不确定性

    如果你打印fbprophet的预测结果,你会发现fbprophet是区间预测的。因为预测都是基于历史数据做出的,并且假设了未来数据和历史数据具有相似的变化趋势,这个假设可能会导致预测结果的不准确性。fbprophet提供了一个参数,interval_width,这个参数默认为0.8,越大则说明未来与历史变化趋势更接近。

    m = Prophet(interval_width=0.95).fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    

    7.2 季节不确定性

    季节不确定性通过 mcmc.samples 参数调节,如果大于0做全贝叶斯估计,如果等于0做最大后验估计。谨慎使用啊,非常慢,cpu带不动。

    m = Prophet(mcmc_samples=500).fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    

    8.异常值

    异常值不同于突变点,突变点那是正常波动造成的,异常点是数据有错误,或者统计口径发生了变化导致了数据的激增激降。异常值的存在将使得预测区间编的非常非常大。
    处理异常值的最好办法就是删除这个数据,prophet依旧会根据趋势给出预测值,这感觉还不错,怎么删除呢,df赋值为none就好了,不用多说吧。

    9.非日数据

    有时候我们还需要预估小时级别的数据,这个prophet也是可以处理的,只要你传参是标准的时间戳格式就可以的,唯一要处理的就是外推数据,freq设置为‘H’。
    当然月和年的数据是类似的,就是设置freq的问题,其他方法和天级别的预测相似的。

    10.诊断

    就是交叉验证,sklearn里也有交叉验证,用cross_validation进行。

    from fbprophet.diagnostics import cross_validation
    df_cv = cross_validation(m, initial='730 days', period='180 days', horizon = '365 days')
    #参数意思是730天做阶段,每180天对365天的数据做一个交叉验证,
    df_cv.head()
    

    讲到这就基本讲完了,当然对内部机理的介绍还是比较少,我们只要会用就好了。

    相关文章

      网友评论

        本文标题:mac版的fbprophet从安装到使用手册

        本文链接:https://www.haomeiwen.com/subject/iqpdmhtx.html