精华内容
下载资源
问答
  • 文章目录prophet 安装数据集下载prophet 实战导入包pandas 读取 csv 数据画个图拆分数据集从日期中拆分特征使用 prophet 训练和预测prophet 学到了什么放大图 prophet 安装 prophet 是facebook 开源的一款时间序列...
  • PROPheT本体填充器 描述 PROPheT(PeRicles本体填充工具)是一种新颖的应用程序,它使用用户友好的图形用户界面(GUI),可以从链接数据中进行实例提取和本体填充。 在PROPheT中,可以定位,过滤和插入用户自己的域...
  • Prophet 安装过程

    2019-04-22 01:24:04
    NULL 博文链接:https://liubin2010.iteye.com/blog/1211700
  • 在这里,我们利用Facebook的时间序列预测算法Prophet,使用多变量,单步预测策略,实时预测美国公司的股票市场价格。 入门 从github下载或克隆项目 $ git clone https://github.com/nityansuman/wa
  • facebook prophet 介绍

    2018-06-15 18:59:09
    facebook prophet的介绍,,包括总体函数组成,以及gam模型的子模块,趋势函数介绍、时间周期函数介绍、节假日介绍等。
  • Prophet Designed and Implemented by Yury Puzis Prophet is a tool that estimates the relevance of each axiom in a set, to (proving) a given conjecture. This relevance measure is based on the intuitive ...
  • facebook prophet 使用教程.docx . 详细的介绍了时间序列模型的使用方法和原理,该模型是来自Facebook的prophet模型,有很好的时间序列预测功能。
  • Prophet的案例数据

    2017-02-26 18:09:00
    R的Prophet包的数据集
  • 脸书预言家开源项目,prophet python模块 fbprophet和pystan。现在网上的教程基本都不能成功安装。本人侥幸安装成功。把pip包中的两个模块上传。大家下载后可以直接导入python安装目录下的模块目录site-packages下...
  • 请注意,该项目仍处于测试阶段。 请报告您遇到的任何问题或建议。 我们将尽力Swift解决它们。 也欢迎捐款! 神经先知 基于PyTorch的和启发的基于神经网络的时间序列模型。 文献资料 我们目前正在改进。...
  • Auto_TS:Auto_TimeSeries 使用单行代码自动构建多个时间序列模型。 现在已用Dask更新。 Auto_timeseries是用于时间序列数据的复杂模型构建实用程序。 由于它可以自动执行复杂任务中的许多任务,因此它假定了许多...
  • P3PROPHET-源码

    2021-03-30 13:24:07
    P3先知 这是Mortensens先生Period 3 Data Structures类中的“ PROPHETS”团队的存储库。 链接 项目计划: : 项目委员会: : 运行时链接: 贡献者(+个人想法) Rohan-希望建立图表系统来跟踪趋势并表示数据 ...
  • prophet是一个可以通过 Python 和 R 语言使用的预测工具 Prophet。并非所有的预测问题都可以通过同一种程序(procedure)解决。Prophet 是为我们在 Facebook 所遇到的业务预测任务而优化的,这些任务通常具有以下...
  • 处理您的Demandware / Salesforce云代码 VS Code扩展,可与沙盒上的Demandware / Salesforce Cloud代码一起使用,支持脚本调试器API(SDAPI)2.0 支持的功能 上载墨盒并观看更改 isml和ds文件的语法高亮 ...
  • duck_prophet 春江水暖“鸭先知”,“鸭先知”是一个利用新闻文本做舆情分析的系统。 1. 软硬件环境说明 a) Python2.7及其相关python依赖包,缺啥补啥 i. tornado ii. requests iii. pymysql iv. urllib2 v. ...
  • Prophet调参

    2021-03-05 13:28:34
    本篇主要讲解实际运用中Prophet调参的主要步骤以及一些本人实际经验。 一 参数理解篇 class Prophet(object): def __init__( self, growth='linear', changepoints=None, n_changepoints=25, changepoint_...

    本篇主要讲解实际运用中Prophet调参的主要步骤以及一些本人实际经验。

    一 参数理解篇

    class Prophet(object):
        def __init__(
                self,
                growth='linear',
                changepoints=None,
                n_changepoints=25,
                changepoint_range=0.8,
                yearly_seasonality='auto',
                weekly_seasonality='auto',
                daily_seasonality='auto',
                holidays=None,
                seasonality_mode='additive',
                seasonality_prior_scale=10.0,
                holidays_prior_scale=10.0,
                changepoint_prior_scale=0.05,
                mcmc_samples=0,
                interval_width=0.80,
                uncertainty_samples=1000,
                stan_backend=None
        ):
    

    1.1 趋势参数

    参数描述
    growthgrowth是指模型的趋势函数,目前取值有2种,linear和logistic
    changepointsChangepoint是指一个特殊的日期,在这个日期,模型的趋势将发生改变。而changepoints是指潜在changepoint的所有日期,如果不指明则模型将自动识别。
    n_changepoints最大的Changepoint的数量。如果changepoints不为None,则本参数不生效。
    changepoint_range是指changepoint在历史数据中出现的时间范围,与n_changeponits配合使用,changepoint_range决定了changepoint能出现在离当前时间最近的时间点,changepont_range越大,changepoint可以出现的距离现在越近。当指定changepoints时,本参数不生效
    changepoint_prior_scale设定自动突变点选择的灵活性,值越大越容易出现changepoint

    1.1.1 growth

    growth是指模型的趋势函数,目前取值有2种,linear和logistic,分别如图1-1图1-2所示。趋势会在changepoint处出现突变点。

    图1-1 linear趋势
    图1-2 logistic趋势

    细心的同学可能会问,可不可能出现同一个模型既有linear趋势,又有logistic趋势,就像下面这样:

    图1-3

    在这里福布湿要给大家纠正下这个错觉,请大家记住Prophet的趋势模型要么是linear要么是logistic。而上图之所以像是两种的叠加,是因为prophet的设计师为了让趋势函数可微(连续,就理解成连续吧)做了平滑处理,

    上面这货就是论文中做平滑处理的公式。

    1.1.2 Changepoints

    Changeponits形状如[‘2013-01-01’,’2013-09-01’,’2017-02-5’],是changepoint的列表。

    Changepoints是一个非常重要的参数,但用户在决定设置此值时必须要注意,这个参数设置之后模型将不会自动寻找changepoints(同时n_changepoints和changepoint_range均不会生效),这就意味着手动设置的changeponits必须准确且完整,否则福布湿不建议大家设置此项。

    1.1.3 n_changeponits、changepoint_range

    这2个参数是模型自动识别changepoint时需要的,n_changepoints限制了changepoint的最大数量,changepoint_range限制了changepoint在历史数据中出现的时间范围。例如图1-1中changepoint_range福布湿设置的是0.5,而图1-3中福布湿设置的是0.8,如果福布湿把图1-3中的changepoint_range设置为0.2,那么所有的changpoint均只能出现在2020-01-01至2020-02-01的范围内。

    1.2 周期性性参数

    参数描述
    yearly_seasonality年周期性,True为启用,false为关闭,如果设置为自然数n,则n代表傅里叶级数的项数,项数越多,模型将拟合的越好,但是也越容易过拟合,因此论文中推荐年周期性的项数取10,而周的(weekly_seasonality)取3。 一般来讲当历史数据大于1年时模型默认为True(项数默认为10),否则默认为False
    weekly_seasonality周周期性,True为启用,false为关闭,如果设置为自然数n,则n代表傅里叶级数的项数,项数越多,模型将拟合的越好,但是也越容易过拟合,因此论文中推荐取3。 一般来讲当历史数据大于1周时模型默认为True(项数默认为3),否则默认为False
    daily_seasonality天周期性,当时间序列为小时级别序列时才会开启。
    seasonality_mode季节模型方式,'additive'(加法模型) (默认) 或者 'multiplicative'(乘法模型)
    seasonality_prior_scale改变周期性影响因素的强度,值越大,周期性因素在预测值中占比越大

    周期性参数设置相对较为固化,除了seasonality_mode和seasonality_prior_scale可能需要手动调整外其余各项一般情况下保持为默认值即可(当然具体问题具体分析,傅里叶项数在某些特殊情况下也可能需要调整)。

    傅里叶级数跟泰勒展开式一样,都是用特定的级数形式拟合某个函数,傅里叶级数是专门为周期性函数设计的,也就是说只要某个函数是周期函数就能使用傅里叶级数拟合。有兴趣的同学可以看下知乎上的这个文章:

    https://zhuanlan.zhihu.com/p/41455378?from_voters_page=true

    seasonality_mode的季节模型类型如果大家不深究按字面意思理解即可。

    1.3 节假日参数

    参数描述
    holidays节假日或特殊日期,商业活动中活动日期是这类日期的典型代表
    holiday_prior_scale改变假日模型的强度

    1.3.1 holidays

    Holidays参数是一个pd.DataFrame:

    holidaydsupper_windowlower_window
    元旦2019/1/11-1
    元旦2018/1/11-1

    holiday是特殊日期的时间,ds是时间(pd.Timestamp类型),upper_window和lower_window分别指特殊日期的影响上下限。

    在Prophet中,认为holiday服从正态分布,正态分布的轴为ds。因此,prophet在预测节假日时会以正态分布作为来估计预测值,但这个过程只是一个先验估计的过程,如果模型后面发现这个holiday期间内不服从正态分布,那么模型将生硬的拟合该节假日。如图1-4中所示,大家可以自行体会。

    图1-4

    holidays这个参数非常重要,对整个模型的影响极大,因此大家在构建这个参数时一定要给予相当的重视。

    holidays在模型中是一个广义的概念,不仅指节假日,也指活动日期,特殊事件日期等,因此大家在设置holidays时一定要确保完整,同时对于upper_window和lower_window的设置也应符合实际情况。

    值得注意的是holidays的数量应尽量少,过多的holidays会对模型的过拟合现象加重,如果holidays的数量超过了整体数据的30%,工程师就应该考虑是否去掉一些影响较小的节假日。

    1.4 其他参数

    参数描述
    mcmc_samples概率估计方式。如果为0将会采用最大后验概率估计(MAP),如果为n(n>0)将会以n个马尔科夫采样样本做全贝叶斯推断。 估计有同学有疑问,这些个概率估计的东西跟本模型有毛关系?大家仔细看下图1-4中的蓝色曲线和淡蓝色区域,这其实就是预测结果,而采样估计就是用来给出淡蓝色区域的(uncertainty intervals),大家可以理解为置信区间或者是预测结果的上下限(虽然外国佬叫它‘不确定区间’)。 当mcmc_samples=0的时候,只有趋势因素会存在这种估计,当mcmc_samples>0时,周期性因素才会存在这种估计。
    interval_widthuncertainty intervals 的宽度,是一个浮点数,越大允许的uncertainty intervals范围越大
    uncertainty_samples用来估计uncertainty intervals的采样次数,如果设置为0或者False,就不会进行uncertainty intervals的估计,从而加快模型的训练速度。
    stan_backendCMDSTANPY或者PYSTAN。一般PYSTAN在linux上使用,cmdstanpy在微软操作系统上使用。提示下在微软操作系统上使用的同学,最好不要开启马尔科夫采样(就是不要把mcmc_samples设成大于0),因为微软操作系统上马尔科夫采样非常慢。

    二 参数调优实战

    目前实际生产中,时序模型的训练往往是数量惊人,因此如果依靠以往的指标和经验调参以不大可行,所以只能采用机器寻参的方式。福布湿在这里给大家介绍下常用的网格寻参。

    在调参之前,最重要的是要确定好模型的评价指标。Prophet中内置的评价指标有传统的mse、rmse、mae、mape、coverage。但这些不一定满足在座各位的胃口,比如福布湿在部分模型中就使用了相对误差的0.8分位数作为评价指标。

    废话不多说,直接上代码。

    class ProphetTrain(ABC):
        def __init__(self, name=None):
            self.name = name
            self.data: pd.DataFrame = None
            self.params = {'holidays': holidays}
            self.mape = np.inf
            self.model = None
            self.grid_search_params_path = None
            self.predict_freq_num = 7
            self.freq = 'd'
        @abstractmethod
        def _load_data(self):
            """
            加载训练及测试数据
            :param rule: DataFrame.resample 中的rule
            :return: 训练及测试数据集,类型是pd.DataFrame
            """
            pass
        @property
        def data_size(self):
            if self.data is None:
                self.data = self._load_data()
            return self.data.shape[0] if self.data is not None else 0
        def _cv_run(self):
            if self.data_size < 14:
                raise Exception("数据量不足,请保证数据航速大于14条")
            self.model = Prophet(**self.params)
            self.model.fit(self.data)
            cv_result = cross_validation(self.model, f'{self.predict_freq_num}{self.freq}',
                                         f'{self.predict_freq_num}{self.freq}')
            return performance_metrics(cv_result, metrics=['mape'])['mape'][0]
        def run(self, show: int = 0, retrain=False):
            """
            根据当前参数生成模型
            :param retrain: 是否根据当前参数重新生成模型
            :param show:
            0:  不保存图片及预测结果 也 不展示图片
            1: 展示图片
            2: 保存图片及预测结果
            3: 保存图片及预测结果 也 展示图片
            :return:
            """
            if self.data_size < 14:
                raise Exception("数据量不足,请保证数据航速大于14条")
            if retrain or self.model is None:
                self.model = Prophet(**self.params)
                self.model.fit(self.data)
            future = self.model.make_future_dataframe(freq=self.freq,
                                                      periods=self.predict_freq_num)  # 建立数据预测框架,数据粒度为天,预测步长为一年
            forecast = self.model.predict(future)
            if show & 0b01:
                self.model.plot(forecast).show()  # 绘制预测效果图
                self.model.plot_components(forecast).show()  # 绘制成分趋势图
            if show & 0b10:
                y = forecast[['ds', 'yhat_lower', 'yhat_upper', 'yhat']].iloc[-self.predict_freq_num:]
                y.to_csv(f'csv/{self.name}.csv', index=False)
                self.model.plot(forecast).savefig(f"img/{self.name}-scatter.png")  # 绘制预测效果图
                self.model.plot_components(forecast).savefig(f"img/{self.name}-trend.png")  # 绘制成分趋势图
            mape_score = np.abs(1 - forecast['yhat'].iloc[:self.data.shape[0]] / self.data['y'].values)
            return np.quantile(mape_score, 0.8)
        @property
        def get_predict_df(self):
            future = self.model.make_future_dataframe(freq=self.freq,
                                                      periods=self.predict_freq_num)  # 建立数据预测框架,数据粒度为天,预测步长为一年
            forecast = self.model.predict(future)
            return forecast
        def grid_search(self, use_cv=True, save_result=True):
            """
            结合cv进行网格寻参,cv方式网格寻参很慢,一般建议先使用非网格方式,待参数调整完毕再使用cv验证。
            :param save_result:
            :return:
            """
            changepoint_range = [i / 10 for i in range(3, 10)]
            seasonality_mode = ['additive', 'multiplicative']
            seasonality_prior_scale = [0.05, 0.1, 0.5, 1, 5, 10, 15]
            holidays_prior_scale = [0.05, 0.1, 0.5, 1, 5, 10, 15]
            for sm in seasonality_mode:
                for cp in changepoint_range:
                    for sp in seasonality_prior_scale:
                        for hp in holidays_prior_scale:
                            params = {
                                "seasonality_mode": sm,
                                "changepoint_range": cp,
                                "seasonality_prior_scale": sp,
                                "holidays_prior_scale": hp,
                                "holidays": holidays
                            }
                            score = self._cv_run() if use_cv else self.run()
                            if self.mape > score:
                                self.mape = score
                                self.params = params
            if save_result:
                future = self.model.make_future_dataframe(freq=self.freq,periods=self.predict_freq_num)  
                forecast = self.model.predict(future)
                forecast[['ds', 'yhat_lower', 'yhat_upper', 'yhat']].iloc[-self.predict_freq_num:].to_csv(
                    f'csv/{self.name}.csv', index=False)
                self.model.plot(forecast).savefig(f"img/{self.name}-scatter.png")  # 绘制预测效果图
                self.model.plot_components(forecast).savefig(f"img/{self.name}-trend.png")  # 绘制成分趋势图
                self.save_model()
            print(f'score:{self.mape}\nparams:{self.params}')
            return self
        def save_model(self):
            with open(f'model/{self.name}.pkl', 'wb') as fp:
                pickle.dump(self, fp)
        @staticmethod
        def load_model(name):
            with open(f'model/{name}.pkl', 'rb') as fp:
                return pickle.load(fp)
    

    在这里主要给大家介绍2点:

    1. 网格寻参很耗CPU,对于CPU性能不好的同学福布湿只能给你一个大大的拥抱。(当然如果使用2分法一组组参数调,麻烦是麻烦了点,但是速度肯定快不少)。

    2. 网格寻参的参数可以是所有的参数,不仅仅是福布湿给出的这几个

    changepoint_range = [i / 10 for i in range(3, 10)]
    seasonality_mode = ['additive', 'multiplicative']
    seasonality_prior_scale = [0.05, 0.1, 0.5, 1, 5, 10, 15]
    holidays_prior_scale = [0.05, 0.1, 0.5, 1, 5, 10, 15]

    而这些参数的取值范围则需要同学们根据每个参数固有的取值范围和时间序列的特点自己研究决定。

    1. Prophet自带的交叉验证(cross_validation)函数

    def cross_validation(model, horizon, period=None, initial=None):

    model: model是已经训练的Prophet模型

    horizon: horizon是每次预测所使用的数据的时间长度,比如‘30d’(30天)

    period:period是触发预测动作的时间周期。如果设置为‘7d’,01-07、01-14、01-21等等,而这些预测的数据为前面定义的horizon。这个值的默认值为horizon*0.5

    Initial:整个交叉验证的数据范围,结束点是昨天的点,开始点是(昨天-initial),initial的默认值是3*horizon。当然同学们也可根据实际情况手动设置,比如“110d”。

    语言总是苍白的,那么福布湿就直接上图了。

    图1-5

    图中的horizon为‘30d’,其他的均为默认值(period=‘15d’,initial=‘90d’)。

    三 结尾

    任何一种算法不可能适合所有情况,所有大家要做的是理解算法原理,针对实际情况优化算法。比如福布湿在研究双十一这个节假日的时候发现实际的分布并不是对称的,而正态分布是一个对称的分布,明显不符合实际情况,因此福布湿将这个先验分布改为了F分布,就这一个小小的改动就让模型的准确率上升了大约5%左右。因此如果想训练出一个好的模型,数据和调参很重要,但更重要的对算法原理的充分理解并根据实际情况改进算法,从而让模型效果达到一个新的台阶。

    参考文献:

    【1】Prophet官方文档:https://facebook.github.io/prophet/

    【2】Prophet论文:https://peerj.com/preprints/3190/

    【3】Prophet-github:https://github.com/facebook/prophet

    展开全文
  • Forecasting_net_prophet-
  • Facebook 时间序列预测算法 Prophet 的研究 Prophet 简介 Facebook 去年开源了一个时间序列预测的算法,叫做 fbprophet,它的官方网址与基本介绍来自于以下几个网站: Github:https://github.com/facebook/prophet ...

    先展示效果:
    在这里插入图片描述
    在这里插入图片描述

    Facebook 时间序列预测算法 Prophet 的研究
    Prophet 简介
    Facebook 去年开源了一个时间序列预测的算法,叫做 fbprophet,它的官方网址与基本介绍来自于以下几个网站:

    Github:https://github.com/facebook/prophet
    官方网址:https://facebook.github.io/prophet/
    论文名字与网址:Forecasting at scale,https://peerj.com/preprints/3190/
    从官网的介绍来看,Facebook 所提供的 prophet 算法不仅可以处理时间序列存在一些异常值的情况,也可以处理部分缺失值的情形,还能够几乎全自动地预测时间序列未来的走势。从论文上的描述来看,这个 prophet 算法是基于时间序列分解和机器学习的拟合来做的,其中在拟合模型的时候使用了 pyStan 这个开源工具,因此能够在较快的时间内得到需要预测的结果。除此之外,为了方便统计学家,机器学习从业者等人群的使用,prophet 同时提供了 R 语言和 Python 语言的接口。从整体的介绍来看,如果是一般的商业分析或者数据分析的需求,都可以尝试使用这个开源算法来预测未来时间序列的走势。

    Prophet 的算法原理
    Prophet 数据的输入和输出

    首先让我们来看一个常见的时间序列场景,黑色表示原始的时间序列离散点,深蓝色的线表示使用时间序列来拟合所得到的取值,而浅蓝色的线表示时间序列的一个置信区间,也就是所谓的合理的上界和下界。prophet 所做的事情就是:

    1、输入已知的时间序列的时间戳和相应的值;
    2、输入需要预测的时间序列的长度;
    3、输出未来的时间序列走势。
    4、输出结果可以提供必要的统计指标,包括拟合曲线,上界和下界等。
    就一般情况而言,时间序列的离线存储格式为时间戳和值这种格式,更多的话可以提供时间序列的 ID,标签等内容。因此,离线存储的时间序列通常都是以下的形式。其中 date 指的是具体的时间戳,category 指的是某条特定的时间序列 id,value 指的是在 date 下这个 category 时间序列的取值,label 指的是人工标记的标签(‘0’ 表示异常,'1‘ 表示正常,‘unknown’ 表示没有标记或者人工判断不清)。
    在这里插入图片描述
    在这里插入图片描述
    而 fbprophet 所需要的时间序列也是这种格式的,根据官网的描述,只要用 csv 文件存储两列即可,第一列的名字是 ‘ds’, 第二列的名称是 ‘y’。第一列表示时间序列的时间戳,第二列表示时间序列的取值。通过 prophet 的计算,可以计算出 yhat,yhat_lower,yhat_upper,分别表示时间序列的预测值,预测值的下界,预测值的上界。两份表格如下面的两幅图表示。

    Prophet 的算法实现
    在这里插入图片描述

    趋势项模型 [公式]
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在 Prophet 里面,是需要设置变点的位置的,而每一段的趋势和走势也是会根据变点的情况而改变的。在程序里面有两种方法,一种是通过人工指定的方式指定变点的位置;另外一种是通过算法来自动选择。在默认的函数里面,Prophet 会选择 n_changepoints = 25 个变点,然后设置变点的范围是前 80%(changepoint_range),也就是在时间序列的前 80% 的区间内会设置变点。通过 forecaster.py 里面的 set_changepoints 函数可以知道,首先要看一些边界条件是否合理,例如时间序列的点数是否少于 n_changepoints 等内容;其次如果边界条件符合,那变点的位置就是均匀分布的,这一点可以通过 np.linspace 这个函数看出来。

    m = Prophet(growth='logistic') 
    df['cap'] = 6 
    m.fit(df) 
    future = m.make_future_dataframe(periods=prediction_length, freq='min') 
    future['cap'] = 6
    

    变点的选择(Changepoint Selection)
    在这里插入图片描述
    对未来的预估(Trend Forecast Uncertainty)

    从历史上长度为 [公式] 的数据中,我们可以选择出 [公式] 个变点,它们所对应的增长率的变化量是 [公式] 。此时我们需要预测未来,因此也需要设置相应的变点的位置,从代码中看,在 forecaster.py 的 sample_predictive_trend 函数中,通过 Poisson 分布等概率分布方法找到新增的 changepoint_ts_new 的位置,然后与 changepoint_t 拼接在一起就得到了整段序列的 changepoint_ts。

    changepoint_ts_new = 1 + np.random.rand(n_changes) * (T - 1)
    changepoint_ts = np.concatenate((self.changepoints_t, changepoint_ts_new))
    


    季节性趋势
    在这里插入图片描述
    在这里插入图片描述

    节假日效应(holidays and events)
    在现实环境中,除了周末,同样有很多节假日,而且不同的国家有着不同的假期。在 Prophet 里面,通过维基百科里面对各个国家的节假日的描述,hdays.py 收集了各个国家的特殊节假日。除了节假日之外,用户还可以根据自身的情况来设置必要的假期,例如 The Super Bowl,双十一等。
    在这里插入图片描述
    由于每个节假日对时间序列的影响程度不一样,例如春节,国庆节则是七天的假期,对于劳动节等假期来说则假日较短。因此,不同的节假日可以看成相互独立的模型,并且可以为不同的节假日设置不同的前后窗口值,表示该节假日会影响前后一段时间的时间序列。用数学语言来说,对与第 [公式] 个节假日来说, [公式] 表示该节假日的前后一段时间。为了表示节假日效应,我们需要一个相应的指示函数(indicator function),同时需要一个参数 [公式] 来表示节假日的影响范围。假设我们有 [公式] 个节假日,那么

    模型拟合(Model Fitting)
    在这里插入图片描述
    Prophet 中可以设置的参数
    在这里插入图片描述
    Prophet 的实际使用

    Prophet 的简单使用
    因为 Prophet 所需要的两列名称是 ‘ds’ 和 ‘y’,其中,‘ds’ 表示时间戳,‘y’ 表示时间序列的值,因此通常来说都需要修改 pd.dataframe 的列名字。如果原来的两列名字是 ‘timestamp’ 和 ‘value’ 的话,只需要这样写:

    df = df.rename(columns={'timestamp':'ds', 'value':'y'})
    

    如果 ‘timestamp’ 是使用 unixtime 来记录的,需要修改成 YYYY-MM-DD hh:mm:ss 的形式:

    df['ds'] = pd.to_datetime(df['ds'],unit='s')
    

    在一般情况下,时间序列需要进行归一化的操作,而 pd.dataframe 的归一化操作也十分简单:

    df['y'] = (df['y'] - df['y'].mean()) / (df['y'].std())
    

    然后就可以初始化模型,然后拟合模型,并且进行时间序列的预测了。

    初始化模型:m = Prophet()
    拟合模型:m.fit(df)
    计算预测值:periods 表示需要预测的点数,freq 表示时间序列的频率。
    future = m.make_future_dataframe(periods=30, freq='min')
    future.tail()
    forecast = m.predict(future)
    

    而 freq 指的是 pd.dataframe 里面的一个指标,‘min’ 表示按分钟来收集的时间序列。具体参见文档:http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
    在这里插入图片描述

    在进行了预测操作之后,通常都希望把时间序列的预测趋势画出来:

    画出预测图:
    m.plot(forecast)
    画出时间序列的分量:
    m.plot_components(forecast)
    

    在这里插入图片描述
    在这里插入图片描述

    如果要画出更详细的指标,例如中间线,上下界,那么可以这样写:

    x1 = forecast[‘ds’]
    y1 = forecast[‘yhat’]
    y2 = forecast[‘yhat_lower’]
    y3 = forecast[‘yhat_upper’]
    plt.plot(x1,y1)
    plt.plot(x1,y2)
    plt.plot(x1,y3)
    plt.show()

    其实 Prophet 预测的结果都放在了变量 forecast 里面,打印结果的话可以这样写:第一行是打印所有时间戳的预测结果,第二行是打印最后五个时间戳的预测结果。
    在这里插入图片描述

    print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']])
    print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
    

    Prophet 的参数设置
    Prophet 的默认参数可以在 forecaster.py 中看到:

    def __init__(
        self,
        growth='linear',
        changepoints=None,
        n_changepoints=25, 
        changepoint_range=0.8,
        yearly_seasonality='auto',
        weekly_seasonality='auto',
        daily_seasonality='auto',
        holidays=None,
        seasonality_mode='additive',
        seasonality_prior_scale=10.0,
        holidays_prior_scale=10.0,
        changepoint_prior_scale=0.05,
        mcmc_samples=0,
        interval_width=0.80,
        uncertainty_samples=1000,
    ):
    

    增长函数的设置
    在 Prophet 里面,有两个增长函数,分别是分段线性函数(linear)和逻辑回归函数(logistic)。而 m = Prophet() 默认使用的是分段线性函数(linear),并且如果要是用逻辑回归函数的时候,需要设置 capacity 的值,i.e. df[‘cap’] = 100,否则会出错。

    m = Prophet()
    m = Prophet(growth='linear')
    m = Prophet(growth='logistic')
    

    变点的设置
    在 Prophet 里面,变点默认的选择方法是前 80% 的点中等距选择 25 个点作为变点,也可以通过以下方法来自行设置变点,甚至可以人为设置某些点。

    m = Prophet(n_changepoints=25)
    m = Prophet(changepoint_range=0.8)
    m = Prophet(changepoint_prior_scale=0.05)
    m = Prophet(changepoints=['2014-01-01'])
    

    而变点的作图可以使用:

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

    在这里插入图片描述

    周期性的设置
    通常来说,可以在 Prophet 里面设置周期性,无论是按月还是周其实都是可以设置的,例如:

    m = Prophet(weekly_seasonality=False)
    m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
    m = Prophet(weekly_seasonality=True)
    m.add_seasonality(name='weekly', period=7, fourier_order=3, prior_scale=0.1)
    

    在这里插入图片描述

    节假日的设置
    有的时候,由于双十一或者一些特殊节假日,我们可以设置某些天数是节假日,并且设置它的前后影响范围,也就是 lower_window 和 upper_window。

    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, holidays_prior_scale=10.0)
    

    结束语
    对于商业分析等领域的时间序列,Prophet 可以进行很好的拟合和预测,但是对于一些周期性或者趋势性不是很强的时间序列,用 Prophet 可能就不合适了。但是,Prophet 提供了一种时序预测的方法,在用户不是很懂时间序列的前提下都可以使用这个工具得到一个能接受的结果。具体是否用 Prophet 则需要根据具体的时间序列来确定。

    参考文献:
    1、https://otexts.org/fpp2/components.html
    2、https://en.wikipedia.org/wiki/Decomposition_of_time_series
    3、A review of change point detection methods, CTruong, L. Oudre, N.Vayatis
    4、https://github.com/facebook/prophet
    5、https://facebook.github.io/prop

    内容是从知乎学术人生copy来的,内容很丰富,所以copy。如有侵权请联系我

    展开全文
  • 网上很多入门代码,官网也给了很多demo。上手很快,按照网上的数据,预测的结果很ok,信心满满。 总是按照别人的东西做,感觉缺点什么,自己打算给自己挖个坑。 预测一下sin函数。
  • (陆续更新)重新整理过的基于机器学习的股票价格预测算法,里面包含了基本的回测系统以及各种不同的机器学习算法的股票价格预测,包含:LSTM算法、Prophet算法、AutoARIMA、朴素贝叶斯、SVM等 强烈推荐大家去看看...
  • Prophet 初学笔记

    2020-12-24 11:08:01
    本文介绍 Prophet 模型的简单调用。

    本文介绍 Prophet 模型的简单调用。

     

    (一)日志设置为不输出

    import os
    
    class SuppressStdoutStderr(object):
        """
        A context manager for doing a "deep suppression" of stdout and stderr in
        Python, i.e. will suppress all print, even if the print originates in a
        compiled C/Fortran sub-function.
    
        This will not suppress raised exceptions, since exceptions are printed
        to stderr just before a script exits, and after the context manager has
        exited (at least, I think that is why it lets exceptions through).
        """
    
        def __init__(self):
            # open a pair of null files
            self.null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
    
            # save the actual stdout (1) and stderr (2) file descriptors
            self.save_fds = (os.dup(1), os.dup(2))
    
        def __enter__(self):
            # assign the null pointers to stdout and stderr
            os.dup2(self.null_fds[0], 1)
            os.dup2(self.null_fds[1], 2)
    
        def __exit__(self, *_):
            # reassign the real stdout/stderr back to (1) and (2)
            os.dup2(self.save_fds[0], 1)
            os.dup2(self.save_fds[1], 2)
    
            # close the null files
            os.close(self.null_fds[0])
            os.close(self.null_fds[1])
            os.close(self.save_fds[0])
            os.close(self.save_fds[1])

     

    (二)Prophet 预测模型 class,与官方 Prophet 结构相似,但不继承

    1. 初始化

    from datetime import datetime, timedelta
    from typing import Tuple
    import numpy as np
    import pandas as pd
    
    from fbprophet import Prophet
    from fbprophet.diagnostics import cross_validation
    
    STD_D_STR = "%Y-%m-%d"  # '%m': 月份,'%M': 分钟
    
    class ProphetPredictor(object):
        def __init__(self, x_train: pd.DataFrame,
                     trg_st_dt: datetime, tm_step: int, his_st_dt: datetime, his_en_dt: datetime,
                     cv_horizon: str, cv_period: str, cv_initial: str,
                     n_changepoints=None, changepoint_range=0.7,
                     yearly_seasonality=False, weekly_seasonality=True, daily_seasonality=False,
                     holidays=None, seasonality_mode='multiplicative',
                     seasonality_prior_scale=10, holidays_prior_scale=0, changepoint_prior_scale=0.05):
            """
            initialisation
    
            :param x_train:  数据集, ['ds', 'y']
            :param trg_st_dt:  预测开始日期
            :param tm_step:  预测时间间隔
            :param his_st_dt:  训练集开始日期
            :param his_en_dt:  训练集结束日期  todo: 允许使用的训练集结束日期必须严格小于预测开始日期
            :param cv_horizon:  交叉验证 horizon 参数, '3 days' 格式
            :param cv_period:  交叉验证 period 参数, '3 days' 格式
            :param cv_initial:  交叉验证 initial 参数, '3 days' 格式
            :param n_changepoints:  Changepoint 最大数量
            :param changepoint_range:  Changepoint 在历史数据中出现的时间范围
            :param yearly_seasonality:  年周期性
            :param weekly_seasonality:  周周期性
            :param daily_seasonality:  日周期性
            :param holidays:  节假日或特殊日期
            :param seasonality_mode:  季节模型方式, {'additive', 'multiplicative'}
            :param seasonality_prior_scale:  改变周期性影响因素的强度
            :param holidays_prior_scale:  改变假日模型的强度
            :param changepoint_prior_scale:  设定自动突变点选择的灵活性,值越大越容易出现 Changepoint
            """
    
            # Prophet 模型参数
            self.params = {
                "n_changepoints": n_changepoints,
                "changepoint_range": changepoint_range,
                "yearly_seasonality": yearly_seasonality,
                "weekly_seasonality": weekly_seasonality,
                "daily_seasonality": daily_seasonality,
                "holidays": holidays,
                "seasonality_mode": seasonality_mode,
                "seasonality_prior_scale": seasonality_prior_scale,
                "holidays_prior_scale": holidays_prior_scale,
                "changepoint_prior_scale": changepoint_prior_scale
            }
    
            self.trg_st_dt = datetime.strptime(trg_st_dt, STD_D_STR) if isinstance(trg_st_dt, str) else trg_st_dt
            self.tm_step = tm_step
            self.trg_en_dt = self.trg_st_dt + timedelta(days=tm_step - 1)
            self.his_st_dt = datetime.strptime(his_st_dt, STD_D_STR) if isinstance(his_st_dt, str) else his_st_dt
            self.his_en_dt = datetime.strptime(his_en_dt, STD_D_STR) if isinstance(his_en_dt, str) else his_en_dt
    
            # 提前期 = 预测开始日期 - 历史数据最晚日期 - 1 (认为次日预测提前期为0)
            self.ahead = (self.trg_st_dt - self.his_en_dt).days - 1
    
            self.x_train = x_train[['ds', 'y']].copy()
            self.model = None
            self.cv_horizon = cv_horizon
            self.cv_period = cv_period
            self.cv_initial = cv_initial
            self.map_err = 100

    2. 模型训练

        def fit(self):
            """
            模型训练
            :return: 无
            """
    
            self.x_train = self.x_train[
                (datetime.strftime(self.his_st_dt, STD_D_STR) <= self.x_train['ds'])
                & (self.x_train['ds'] <= datetime.strftime(self.his_en_dt, STD_D_STR))].reset_index(drop=True)
    
            self.model = Prophet(**self.params)
            with SuppressStdoutStderr():
                self.model.fit(df=self.x_train)

    3. 交叉验证

        def cv(self, params=None) -> float:
            """
            交叉验证
            :param params:  模型参数,网格寻参时不为 None
            :return: map_err:  平均绝对百分比误差(MAPE)
            """
    
            params_ = params if params else self.params
            self.model = Prophet(**params_)
            with SuppressStdoutStderr():
                self.model.fit(self.x_train)
                cv_result = cross_validation(self.model,
                                             horizon=self.cv_horizon, period=self.cv_period, initial=self.cv_initial)
    
            # 平均绝对百分比误差(MAPE)
            map_err = np.mean(np.abs(cv_result['yhat'] - cv_result['y']) / cv_result['y']) * 100
    
            return map_err

    4. 网格寻参

        def grid_search(self) -> pd.DataFrame:
            """
            网格寻参
            :return: df_search:  寻参记录
            """
    
            list_n_changepoints = [i for i in range(2, 7)]
            list_changepoint_range = [i / 10 for i in range(5, 10)]
            list_seasonality_mode = ["additive", "multiplicative"]
            list_seasonality_prior_scale = [0.1, 0.5, 1, 5, 10]
            list_changepoint_prior_scale = [0.1, 0.5, 1, 5, 10]
    
            list_search = []
            for nc in list_n_changepoints:
                for cr in list_changepoint_range:
                    for sm in list_seasonality_mode:
                        for sps in list_seasonality_prior_scale:
                            for cps in list_changepoint_prior_scale:
                                params = {
                                    "n_changepoints": nc,
                                    "changepoint_range": cr,
                                    "yearly_seasonality": False,
                                    "weekly_seasonality": True,
                                    "daily_seasonality": False,
                                    "holidays": None,
                                    "seasonality_mode": sm,
                                    "seasonality_prior_scale": sps,
                                    "holidays_prior_scale": 0,
                                    "changepoint_prior_scale": cps
                                }
                                score = self.cv(params=params)
                                list_search.append([nc, cr, sm, sps, cps, score])
    
                                if score < self.map_err:
                                    self.map_err, self.params = score, params
                                    print("current best mse:  {0};  current params:  {1}".format(round(self.map_err, 4),
                                                                                                 params))
    
            df_search = pd.DataFrame(data=list_search,
                                     columns=['n_changepoints', 'changepoint_range', 'seasonality_mode',
                                              'seasonality_prior_scale', 'changepoint_prior_scale', 'mse'])
    
            return df_search

    5. 预测

        def predict(self) -> Tuple[pd.DataFrame, pd.DataFrame]:
            """
            预测
            :return: df_predict_y:  预测数据
            :return: df_history_y:  历史数据
            """
    
            df_future = self.model.make_future_dataframe(periods=self.ahead + self.tm_step,
                                                         include_history=True).dropna().reset_index(drop=True)
            df_predict = self.model.predict(df=df_future)
            df_predict['ds'] = df_predict['ds'].apply(lambda x: str(x.date()))
    
            df_predict_y = df_predict[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(self.tm_step)
            df_history_y = df_predict[['ds', 'yhat']][: - (self.tm_step + self.ahead)]
    
            return df_predict_y, df_history_y

     

    (三)其他尝试

    添加季节性组件:

    self.model.add_seasonality(name='sin', period=2 * np.pi / 7, fourier_order=1)

     

    (四)模型调用示例

    1. 网格寻参

    # 初始化
    prophet_predictor = ProphetPredictor(x_train=df_input,
                                         trg_st_dt=trg_st_dt, tm_step=3, his_st_dt=his_st_dt, his_en_dt=his_en_dt,
                                         cv_horizon='3 days', cv_period='3 days', cv_initial='135 days')
    
    # 网格寻参
    dts_search = datetime.now()
    df_search = prophet_predictor.grid_search()
    print("df_search:\n", df_search, '\n')
    dte_search = datetime.now()
    tm_search = round((dte_search - dts_search).seconds + (dte_search - dts_search).microseconds / (10 ** 6), 3)
    print("grid search time:  {} s".format(tm_search), '\n')
    
    # 训练
    dts_train = datetime.now()
    prophet_predictor.fit()
    dte_train = datetime.now()
    tm_train = round((dte_train - dts_train).seconds + (dte_train - dts_train).microseconds / (10 ** 6), 3)
    print("train time:  {} s".format(tm_train), '\n')
    
    # 预测
    df_predict_y, df_history_y = prophet_predictor.predict()
    print("df_predict_y:\n", df_predict_y, '\n')
    print("df_history_y:\n", df_history_y, '\n')

    2. 给定参数

    # 参数设定
    params = {
        "n_changepoints": 2,
        "changepoint_range": 0.7,
        "seasonality_mode": 'additive',
        "seasonality_prior_scale": 0.5,
        "changepoint_prior_scale": 10,
        "yearly_seasonality": False,
        "weekly_seasonality": True,
        "daily_seasonality": False
    }
    
    # 初始化
    prophet_predictor = ProphetPredictor(x_train=df_input,
                                         trg_st_dt=trg_st_dt, tm_step=3, his_st_dt=his_st_dt, his_en_dt=his_en_dt,
                                         cv_horizon='3 days', cv_period='3 days', cv_initial='135 days',
                                         **params)
    
    # 训练
    dts_train = datetime.now()
    prophet_predictor.fit()
    dte_train = datetime.now()
    tm_train = round((dte_train - dts_train).seconds + (dte_train - dts_train).microseconds / (10 ** 6), 3)
    print("train time:  {} s".format(tm_train), '\n')
    
    # 预测
    df_predict_y, df_history_y = prophet_predictor.predict()
    print("df_predict_y:\n", df_predict_y, '\n')
    print("df_history_y:\n", df_history_y, '\n')

     

     

    参考资料:

    https://www.cnblogs.com/fulu/p/13329656.html

    https://www.cnblogs.com/zhazhaacmer/p/13786940.html

    展开全文
  • R 基本的R项目,包括Prophet预测,Caret分类模型和Quantmod项目。
  • 时间序列模型Prophet使用详细讲解

    万次阅读 多人点赞 2018-10-26 20:39:34
    之前我们已经讲过了如何在Windows系统下安装Python版本的Prophet。详细见这里。 接下来的几个部分,我们说下如何使用Prophet,以此来体验下Prophet的丰富内容。内容会比较多,主要翻译自官方文档。教程中使用的数据...

    之前我们已经讲过了如何在Windows系统下安装Python版本的Prophet。详细见这里

    接下来的几个部分,我们说下如何使用Prophet,以此来体验下Prophet的丰富内容。内容会比较多,主要翻译自官方文档。教程中使用的数据集可在 Prophet 的 github 主页 中的 examples 文件夹 内下载得到。

    目录

    一、简易入门

    二、饱和预测

    2.1 预测饱和增长

    2.2 预测饱和减少

     三、趋势突变点 

    3.1 Prophet 中的自动监测突变点

    3.2 调整趋势的灵活性

    3.3 指定突变点的位置

    四、季节性,假期效果和回归量 

    4.1 对假期和特征事件建模

    4.2 季节性的傅里叶级数

    4.3 自定义季节性因素

    4.4 对节假日和季节性设定先验规模

    4.5 附加的回归量

    五、乘法季节性 

    六、预测区间

    6.1 趋势的不确定性

    6.2 季节的不确定性

    七、异常值

    八、非日数据

    8.1 子日数据

    8.2 有规则间隔的数据

    8.3 月数据

    九、诊断

    十、与机器学习算法的对比


    一、简易入门

    Prophet 遵循 sklearn 库建模的应用程序接口。我们创建了一个 Prophet 类的实例,其中使用了“拟合模型” fit 和“预测” predict 方法。

    Prophet 的输入量往往是一个包含两列的数据框:ds 和 y 。ds 列必须包含日期(YYYY-MM-DD)或者是具体的时间点(YYYY-MM-DD HH:MM:SS)。 y 列必须是数值变量,表示我们希望去预测的量。

    下面实例中使用的是 佩顿 · 曼宁的维基百科主页 每日访问量的时间序列数据(2007/12/10 - 2016/01/20)。我们使用 R 中的 Wikipediatrend 包获取该数据集。这个数据集具有多季节周期性、不断变化的增长率和可以拟合特定日期(例如佩顿 · 曼宁的决赛和超级碗)的情况等 Prophet 适用的性质,因此可以作为一个不错的例子。(注:佩顿 · 曼宁为前美式橄榄球四分卫)

    首先,我们导入数据,该数据已经做过了log处理(即,做过df['y'] = np.log(df['y'])操作)。

    # Python
    import pandas as pd
    from fbprophet import Prophet
    # 读入数据集
    df = pd.read_csv('examples/example_wp_log_peyton_manning.csv')
    df.head()

    1_1

    通过对一个 Prophet 对象进行实例化来拟合模型,任何影响预测过程的设置都将在构造模型时被指定。接下来,就可以使用 fit 方法代入历史数据集来拟合模型,拟合过程应当花费 1 - 5 秒。

    # 拟合模型
    m = Prophet()
    m.fit(df)

    预测过程则需要建立在包含日期 ds 列的数据框基础上。通过使用辅助的方法 Prophet.make_future_dataframe 来将未来的日期扩展指定的天数,得到一个合规的数据框。默认情况下,这样做会自动包含历史数据的日期,因此我们也可以用来查看模型对于历史数据的拟合效果。

    # 构建待预测日期数据框,periods = 365 代表除历史数据的日期外再往后推 365 天
    future = m.make_future_dataframe(periods=365)
    future.tail()

    predict 方法将会对每一行未来 future 日期得到一个预测值(称为 yhat )。如果你传入了历史数据的日期,它将会提供样本的模型拟合值。预测 forecast 创建的对象应当是一个新的数据框,其中包含一列预测值 yhat ,以及成分的分析和置信区间。

    # 预测数据集
    forecast = m.predict(future)
    forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

    通过 Prophet.plot 方法传入预测得到的数据框,可以对预测的效果进行绘图。

    # 展示预测结果
    m.plot(forecast);

     如果想查看预测的成分分析,可以使用 Prophet.plot_components 方法。默认情况下,将展示趋势、时间序列的年度季节性和周季节性。如果之前包含了节假日,也会展示出来。

    # 预测的成分分析绘图,展示预测中的趋势、周效应和年度效应
    m.plot_components(forecast);

    注: 一个很核心的问题是我们应该怎么样理解上图的3个子图。通过对forecast这个Dataframe分析我们就可以得到结论。

    我们先看下forecast都有哪些列。

    print(forecast.columns)
    Index(['ds', 'trend', 'trend_lower', 'trend_upper', 'yhat_lower', 'yhat_upper',
           'additive_terms', 'additive_terms_lower', 'additive_terms_upper',
           'multiplicative_terms', 'multiplicative_terms_lower',
           'multiplicative_terms_upper', 'weekly', 'weekly_lower', 'weekly_upper',
           'yearly', 'yearly_lower', 'yearly_upper', 'yhat'],
          dtype='object')

    通过对数据的分析,我们就可以知道:

    ①图1是根据trend画出来的,图2是根据weekly画出来的,图3是根据yearly画出来的。

    ②因为是加法模型,有:forecast['additive_terms'] = forecast['weekly'] + forecast['yearly'];有:forecast['yhat']  = forecast['trend'] +  forecast['additive_terms'] 。因此:forecast['yhat']  = forecast['trend'] +forecast['weekly'] + forecast['yearly']

    如果有节假日因素,那么就会有forecast['yhat']  = forecast['trend'] +forecast['weekly'] + forecast['yearly'] + forecast['holidays']。

    在第四部分,我们会讲到节假日因素,对于那些是节假日的天数,forecast['holidays']才会有值,不是节假日的天数,forecast['holidays']为0。

    ③因为是加法模型,'multiplicative_terms', 'multiplicative_terms_lower', 'multiplicative_terms_upper'这3列为空。

    因此,基于上面的分析,weekly中的Monday为0.3的意思就是,在trend的基础上,加0.3;Saturday为-0.3的意思就是,在trend的基础上,减0.3。因此,这条线的高低也在一定程度上反应了“销量的趋势“。

    注:许多方法的细节可以通过help(Prophet) 或者 help(Prophet.fit) 来获得。


    二、饱和预测

    2.1 预测饱和增长

    默认情况下, Prophet 使用线性模型进行预测。当预测增长情况时,通常会存在可到达的最大极限值,例如:总市场规模、总人口数等等。这被称做承载能力(carrying capacity),那么预测时就应当在接近该值时趋于饱和。

    Prophet 可使用 logistic 增长 趋势模型进行预测,同时指定承载能力。下面使用 R 语言的维基百科主页 访问量(取对数)的实例来进行说明。

    首先,我们导入数据,该数据已经做过了log处理(即,做过df['y'] = np.log(df['y'])操作)。

    import pandas as pd
    from fbprophet import Prophet
    df = pd.read_csv('examples/example_wp_log_R.csv')

    新建一列 cap 来指定承载能力的大小。本实例中假设取某个特定的值,通常情况下这个值应当通过市场规模的数据或专业知识来决定。

    df['cap'] = 8.5

    值得注意的是数据框的每行都必须指定 cap 的值,但并非需要是恒定值。如果市场规模在不断地增长,那么 cap 也可以是不断增长的序列。

    如之前教程所述来拟合模型,并且通过一个新增的参数来指定采用 logistic 增长:

    m = Prophet(growth='logistic')
    m.fit(df)

    如前所述,我们可以创建一个数据框来预测未来值,不过这里要指定未来的承载能力。我们将未来的承载能力设定得和历史数据一样,并且预测未来 3 年的数据。

    future = m.make_future_dataframe(periods=1826)
    future['cap'] = 8.5
    fcst = m.predict(future)
    fig = m.plot(fcst)

    预测结果如下图所示:

    2.2 预测饱和减少

    logistic增长模型还可以处理饱和最小值,方法与指定最大值的列的方式相同:

    # Python
    df['y'] = 10 - df['y']
    df['cap'] = 6
    df['floor'] = 1.5
    future['cap'] = 6
    future['floor'] = 1.5
    m = Prophet(growth='logistic')
    m.fit(df)
    fcst = m.predict(future)
    fig = m.plot(fcst)

    结果如下图:


     三、趋势突变点 

    在之前的部分,我们可以发现真实的时间序列数据往往在趋势中存在一些突变点。默认情况下, Prophet 将自动监测到这些点,并对趋势做适当地调整。不过,要是对趋势建模时发生了一些问题,例如:Prophet 不小心忽略了一个趋势速率的变化或者对历史数据趋势变化存在过拟合现象。如果我们希望对趋势的调整过程做更好地控制的话,那么下面将会介绍几种可以使用的方法。

    3.1 Prophet 中的自动监测突变点

    Prophet 首先是通过在大量潜在的突变点(变化速率突变)中进行识别来监测突变点的。之后对趋势变化的幅度做稀疏先验(等同于 L1 正则化)——实际上 Prophet 在建模时会存在很多变化速率突变的点,但只会尽可能少地使用它们。以 第一部分中佩顿 · 曼宁的数据为例,默认下, Prophet 会识别出 25 个潜在的突变点(均匀分布在在前 80% 的时间序列数据中)。下图中的竖线指出这些潜在的突变点所在的位置。

    虽然存在很多变化速率可能会突变的点,但由于做了稀疏先验,绝大多数突变点并不会包含在建模过程中。如下图所示,通过观察对每个突变点绘制的速率变化值图,可以发现这一点。

     潜在突变点的数量可以通过设置 n_changepoints 参数来指定,但最好还是利用调整正则化过程来修正。

    显著的突变点的位置可以通过以下代码获得:

    # Python
    from fbprophet.plot import add_changepoints_to_plot
    fig = m.plot(forecast)
    a = add_changepoints_to_plot(fig.gca(), m, forecast)

    默认情况下,只有在时间序列的前80%才会推断出突变点,以便有足够的长度来预测未来的趋势,并避免在时间序列的末尾出现过度拟合的波动。这个默认值可以在很多情况下工作,但不是所有情况下都可以,可以使用changepoint_range参数进行更改。例如,Python中的m = Prophet(changepoint_range=0.9)。这意味着将在时间序列的前90%处寻找潜在的变化点。 

    3.2 调整趋势的灵活性

    如果趋势的变化被过度拟合(即过于灵活)或者拟合不足(即灵活性不够),可以利用输入参数 changepoint_prior_scale 来调整稀疏先验的程度。默认下,这个参数被指定为 0.05 。

    增加这个值,会导致趋势拟合得更加灵活。代码和图如下所示:

    df = pd.read_csv('examples/example_wp_log_peyton_manning.csv')
    
    # 拟合模型
    m = Prophet(changepoint_prior_scale=0.5)
    m.fit(df)
    
    future = m.make_future_dataframe(periods=365)
    
    forecast = m.predict(future)
    fig = m.plot(forecast)

     

    减少这个值,会导致趋势拟合得灵活性降低。代码和图如下所示: 

    m = Prophet(changepoint_prior_scale=0.001)
    m.fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    m.plot(forecast);

     

    3.3 指定突变点的位置

    如果你希望手动指定潜在突变点的位置而不是利用自动的突变点监测,可以使用 changepoints 参数。

    代码和图如下所示:

    m = Prophet(changepoints=['2014-01-01'])
    m.fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    m.plot(forecast);


    四、季节性,假期效果和回归量 

    4.1 对假期和特征事件建模

    如果需要专门对节假日或者其它的事件进行建模,你就必须得为此创建一个新的dataframe,其中包含两列(节假日 holiday 和日期戳 ds ),每行分别记录了每个出现的节假日。这个数据框必须包含所有出现的节假日,不仅是历史数据集中还是待预测的时期中的。如果这些节假日并没有在待预测的时期中被注明, Prophet 也会利用历史数据对它们建模,但预测未来时却不会使用这些模型来预测。

    注:也就是说,在待预测的日期里,我们也必须指定所有出现的节假日。

    你可以在这个数据框基础上再新建两列 lower_window 和 upper_window ,从而将节假日的时间扩展成一个区间 lower_window , upper_window ] 。举例来说,如果想将平安夜也加入到 “圣诞节” 里,就设置 lower_window = -1 , upper_window = 0 ;如果想将黑色星期五加入到 “感恩节” 里,就设置 lower_window = 0 , upper_window = 1 。

    下面我们创建一个数据框,其中包含了所有佩顿 · 曼宁参加过的决赛日期:

    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))

    上述代码中,我们将超级碗的日期既记录在了决赛的日期数据框中,也记录在了超级碗的日期数据框中。这就会造成超级碗日期的效应会在决赛日期的作用下叠加两次。

    一旦这个数据框创建好了,就可以通过传入 holidays 参数使得在预测时考虑上节假日效应。这里我们仍以第一部分中佩顿 · 曼宁的数据为例:

    df = pd.read_csv('examples/example_wp_log_peyton_manning.csv')
    
    m = Prophet(holidays=holidays)
    m.fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)

    可通过 forecast 数据框,来展示节假日效应:

    # 看一下假期的最后10行数据
    forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
            ['ds', 'playoff', 'superbowl']][-10:]

    在成分分析的图中,如下所示,也可以看到节假日效应。我们可以发现,在决赛日期附近有一个穿透,而在超级碗日期时穿透则更为明显。 

    fig = m.plot_components(forecast)

     

    可以使用 plot_forecast_component(从fbprophet.plot导入)来画出独立的节假日的成分。类似如下代码:

    from fbprophet.plot import plot_forecast_component
    m.plot_forecast_component(forecast, 'superbowl')

     

     

    4.2 季节性的傅里叶级数

    季节性是用部分傅里叶和估计的。有关完整的细节,请参阅论文,以及维基百科上的这个图,以说明部分傅里叶和如何近似于一个线性周期信号。部分和(order)中的项数是一个参数,它决定了季节性的变化有多快。为了说明这一点, 我们仍似乎用第一部分中佩顿 · 曼宁的数据。每年季节性的默认傅立叶级数是10,这就产生了这样的拟合:

    # Python
    from fbprophet.plot import plot_yearly
    m = Prophet().fit(df)
    a = plot_yearly(m)

     

    默认值10通常是合适的,但是当季节性需要适应更高频率的变化时,它们可以增加,并且通常不那么平滑。在实例化模型时,可以为每个内置季节性指定傅立叶级数,这里增加到20: 

    from fbprophet.plot import plot_yearly
    m = Prophet(yearly_seasonality=20).fit(df)
    a = plot_yearly(m)

     

    可以看到,曲线更加的多变了。增加傅立叶项的数量可以使季节性适应更快的变化周期,但也可能导致过度拟合:N个傅立叶项对应于用于建模周期的2N个变量。

    4.3 自定义季节性因素

    如果时间序列超过两个周期,Prophet将默认适合每周每年的季节性。对于子日(sub-daily )时间序列,它也将适合每日的季节性。在Python中,可以使用add_seasality方法添加其它季节性(如每月、每季、每小时)。

    这个函数的输入是一个名字,季节性的周期,以及季节性的傅里叶order。作为参考,默认情况下,Prophet为周季节性设定的傅立叶order为3,为年季节性设定的为10。add_seasality的一个可选输入是该季节性组件的先验规模。

    作为一个例子,我们仍使用佩顿 · 曼宁的数据,但是用每月的季节性替换每周的季节性。每月的季节性将出现在组件图中:

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

     

    4.4 对节假日和季节性设定先验规模

    如果发现节假日效应被过度拟合了,通过设置参数 holidays_prior_scale 可以调整它们的先验规模来使之平滑,默认下该值取 10 。

    减少这个参数会降低假期效果:

    m = Prophet(holidays=holidays, holidays_prior_scale=0.05).fit(df)
    forecast = m.predict(future)
    forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
        ['ds', 'playoff', 'superbowl']][-10:]

    代码输出结果如下所示:

    和之前相比,节假日效应的规模被减弱了,特别是对观测值较少的超级碗而言。类似的,还有一个 seasonality_prior_scale 参数可以用来调整模型对于季节性的拟合程度。 

    可以通过在节假日的dataframe中包含一个列prior_scale来单独设置先验规模。独立的季节性的先验规模可以作为add_seasonality的参数传递。例如,可以使用以下方法设置每周季节性的先验规模:

    m = Prophet()
    m.add_seasonality(
        name='weekly', period=7, fourier_order=3, prior_scale=0.1)

    4.5 附加的回归量

     可以使用add_regressor方法将附加的回归量添加到模型的线性部分。包含回归值的列需要同时出现在拟合数据格式(fit)和预测数据格式(predict)中。例如,我们可以在NFL赛季的周日添加附加的效果。在成分图上,这种效果会出现在“extra_regre_”图中:

    # 判断是否是NFL赛季的周日
    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)

    NFL周日也可以使用之前描述的“节假日”的接口,通过创建一个过去和未来NFL周日的list。add_regressor函数为定义附加的线性回归函数提供了一个更通用的接口,特别是它不要求回归函数是二进制指示器。

    add_regressor函数具有可选的参数,用于指定先验规模(默认情况下使用节假日先验规模),和指定是否标准化回归量。help(Prophet.add_regressor)可以查看相关参数。

    附加的回归量必须要知道历史和未来的日期。因此,它要么是已知未来值(比如nfl_sunday),要么是其他地方已经单独预测出的结果。如果回归量在整个历史中都是不变的,则Prophet会引发一个错误,因为没有任何东西可以fit它。

    附加的回归量被放在模型的线性分量中,所以依赖于附加的回归量时间序列作为底层模型的加法或乘法因子。


    五、乘法季节性 

    默认情况下,Prophet能够满足附加的季节性,这意味着季节性的影响是加到趋势中得到了最后的预报(yhat)。航空旅客数量的时间序列是一个附加的季节性不起作用的例子:

    df = pd.read_csv('../examples/example_air_passengers.csv')
    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(50, freq='MS')
    forecast = m.predict(future)
    fig = m.plot(forecast)

    这个时间序列有一个明显的年度周期,但预测中的季节性在时间序列开始时太大,在结束时又太小。在这个时间序列中,季节性并不是Prophet所假定的是一个恒定的加性因子,而是随着趋势在增长。这就是乘法季节性(multiplicative seasonality)。 

    Prophet可以通过设置seasonality_mode='multiplicative'来建模乘法季节性:

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

    看一下乘法的成分图:

    fig = m.plot_components(forecast)

    与第一部分对成分图分析类似,我们这里对乘法模型的成分图进行一个分析:

    ①图1是根据trend画出来的,图2是根据yearly画出来的。

    ②因为是乘法模型,有:forecast['multiplicative_terms'] = forecast['yearly'];因此:forecast['yhat']  = forecast['trend'] * (1+forecast['multiplicative_terms'])

    使用seasonality_mode='multiplicative',节假日也将被建模为乘法效果。

    ③因为是乘法模型,'additive_terms', 'additive_terms_lower', 'additive_terms_upper'这3列为0。

     

    默认情况下,任何添加的季节性或额外的回归量都可以使用seasality_mode设置为加法或者是乘法。但假如在添加季节性或回归量时,可以通过指定mode=' addiative 'mode=' ative'作为参数来覆盖之前的设定。 

    例如,这个模块将内置的季节性设置为乘法,但使用一个附加的季度季节性来覆盖原本的乘法,这时候季度季节性就是加法了。

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

    额外的加法的季度季节性将出现在成分图的单独的面板上。 

     这个时候是时间序列的混合模型forecast['yhat'] = forecast['trend']  * (1+forecast['multiplicative_terms']) + forecast['additive_terms']。


    六、预测区间

    默认情况下, Prophet 的返回结果中会包括预测值 yhat 的预测区间。当然,预测区间的估计需建立在一些重要的假设前提下。

    在预测时,不确定性主要来源于三个部分:趋势中的不确定性、季节效应估计中的不确定性和观测值的噪声影响

    6.1 趋势的不确定性

    预测中,不确定性最大的来源就在于未来趋势改变的不确定性。在之前的时间序列实例中,我们可以发现历史数据具有明显的趋势性。 Prophet 能够监测并去拟合它,但是我们期望得到的趋势改变究竟会如何走向呢?或许这是无解的,因此我们尽可能地做出最合理的推断,假定 “未来将会和历史具有相似的趋势” 。尤其重要的是,我们假定未来趋势的平均变动频率和幅度和我们观测到的历史值是一样的,从而预测趋势的变化并通过计算,最终得到预测区间。

    这种衡量不确定性的方法具有以下性质:变化速率灵活性更大时(通过增大参数 changepoint_prior_scale 的值),预测的不确定性也会随之增大。原因在于如果将历史数据中更多的变化速率加入了模型,也就代表我们认为未来也会变化得更多,就会使得预测区间成为反映过拟合的标志。

    预测区间的宽度(默认下,是 80% )可以通过设置 interval_width 参数来控制:

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

    由于预测区间估计时假定未来将会和过去保持一样的变化频率和幅度,而这个假定可能并不正确,所以预测区间的估计不可能完全准确。 

    6.2 季节的不确定性

    默认情况下, Prophet 只会返回趋势中的不确定性和观测值噪声的影响。你必须使用贝叶斯取样的方法来得到季节效应的不确定性,可通过设置 mcmc.samples 参数(默认下取 0 )来实现。下面使用佩顿 · 曼宁的数据为例:

    m = Prophet(mcmc_samples=500).fit(df)
    future = m.make_future_dataframe(periods=365)
    forecast = m.predict(future)
    # 报错:UnboundLocalError: local variable 'pool' referenced before assignment

    上述代码将最大后验估计( MAP )取代为马尔科夫蒙特卡洛取样 ( MCMC ),并且将计算时间从 10 秒延长到 10 分钟

    如果做了全取样,就能通过绘图看到季节效应的不确定性了:

    m.plot_components(forecast);

    可以使用m.predictive_samples(future)方法在Python中访问原始的后验预测样本。

    在PyStan有一些针对Windows的上游问题,这使得MCMC采样非常缓慢。在Windows中,MCMC采样的最佳选择是在Linux VM中使用R或Python。

    因此,我的上述代码会出错,季节的不确定性在我windows的python中跑不动,暂时忽略,了解即可。


    七、异常值

    异常值主要通过两种方式影响 Prophet 预测结果。下面我们使用之前使用过的 R 语言维基百科主页对数访问量的数据来建模预测,只不过使用存在时间间隔并不完整的数据:

    
    df = pd.read_csv('examples/example_wp_log_R_outliers1.csv')
    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(periods=1096)
    forecast = m.predict(future)
    m.plot(forecast);

    如上输出图所示,趋势预测看似合理,预测区间的估计却过于广泛。 Prophet 虽能够处理历史数据中的异常值,但仅仅是将它们与趋势的变化拟合在一起,认为未来也会有类似的趋势变化。

    处理异常值最好的方法是移除它们,而 Prophet 是能够处理缺失数据的。如果在历史数据中某行的值为空( NA ),但是在待预测日期数据框 future 中仍保留这个日期,那么 Prophet 依旧可以给出该行的预测值。

    # 将2010年一年的数据设为缺失
    df.loc[(df['ds'] > '2010-01-01') & (df['ds'] < '2011-01-01'), 'y'] = None
    model = Prophet().fit(df)
    model.plot(model.predict(future));

     

    上述这个实例虽然影响了不确定性的估计,却没有影响到主要的预测值 yhat 。但是,现实往往并非如此,接下来,在上述数据集基础上加入新的异常值后再建模预测: 

    df = pd.read_csv('examples/example_wp_log_R_outliers2.csv')
    m = Prophet()
    m.fit(df)
    future = m.make_future_dataframe(periods=1096)
    forecast = m.predict(future)
    m.plot(forecast);

    这里 2015年 6 月存在一些异常值破坏了季节效应的估计,因此未来的预测也会永久地受到这个影响。最好的解决方法就是移除这些异常值: 

    # 将2015年前半年的数据设为缺失
    df.loc[(df['ds'] > '2015-06-01') & (df['ds'] < '2015-06-30'), 'y'] = None
    m = Prophet().fit(df)
    m.plot(m.predict(future));

     


    八、非日数据

    8.1 子日数据

    Prophet可以通过在ds列中传递一个带有时间戳的dataframe来对时间序列进行子日(Sub-daily)观测。时间戳的格式应该是YYYY-MM-DD - HH:MM:SS。当使用子日数据时,日季节性将自动匹配。在这里,我们用5分钟的分辨率数据集(约塞米蒂的每日温度)对Prophet进行数据匹配:

    df = pd.read_csv('examples/example_yosemite_temps.csv')
    m = Prophet(changepoint_prior_scale=0.01).fit(df)
    future = m.make_future_dataframe(periods=300, freq='H')
    fcst = m.predict(future)
    fig = m.plot(fcst)

    成分图中的日季节性: 

    fig = m.plot_components(fcst)

     

    8.2 有规则间隔的数据

    假设上面的数据集只有每天早上6点之前的观测值:

    df2 = df.copy()
    df2['ds'] = pd.to_datetime(df2['ds'])
    # 只保留每天早上6点之前的数据
    df2 = df2[df2['ds'].dt.hour < 6]
    m = Prophet().fit(df2)
    future = m.make_future_dataframe(periods=300, freq='H')
    fcst = m.predict(future)
    fig = m.plot(fcst)

    这个预测看起来很差,未来的波动比历史上看到的要大得多。这里的问题是,我们将每天的循环安排在一个时间序列中,这个时间序列中只有一天的一部分数据(12a到6a)。因此,每天的季节性在一天剩下的时间里是不受约束的,估计也不准确。解决方案是只对有历史数据的时间窗进行预测。这里,这意味着限制未来dataframe的时间(从12a到6a):

    future2 = future.copy()
    future2 = future2[future2['ds'].dt.hour < 6]
    fcst = m.predict(future2)
    fig = m.plot(fcst)

    同样的原理也适用于数据中有规则间隔的其他数据集。例如,如果历史只包含工作日,那么应该只对工作日进行预测,因为不会很好地估计每周的季节性。

    8.3 月数据

    可以使用Prophet来匹配每月的数据。然而,Prophet 的基本模型是连续时间的,这意味着如果将模型与每月的数据相匹配,然后要求每天的预测,我们会得到奇怪的结果。

    下面使用美国零售业销售量数据来预测未来 10 年的情况:

    df = pd.read_csv('examples/example_retail_sales.csv')
    m = Prophet().fit(df)
    future = m.make_future_dataframe(periods=3652)
    fcst = m.predict(future)
    m.plot(fcst);

    预测结果看起来非常杂乱,原因正是在于这个特殊的数据集使用的是月数据。当我们拟合年度效应时,只有每个月第一天的数据,而且对于其他天的周期效应是不可测且过拟合的。当你使用 Prophet 拟合月度数据时,可以通过在 make_future_dataframe 中传入频率参数只做月度的预测。 

    future = m.make_future_dataframe(periods=120, freq='M')
    fcst = m.predict(future)
    m.plot(fcst);


    九、诊断

    Prophet包含时间序列交叉验证功能,以测量使用历史数据的预测误差。这是通过在历史记录中选择截止点来完成的,对于每一个都只使用该截止点之前的数据来拟合模型。然后,我们可以将预测值与实际值进行比较。这张图展示了对Peyton Manning数据集的模拟历史预测,该模型适用于5年的初始历史,并在1年的时间范围内进行了预测。

    源论文中进一步描述了模拟的历史预测。

    这个交叉验证过程可以使用cross_validation函数自动完成一系列历史截断。我们指定预测水平(horizon),然后选择初始训练期(initial)的大小和截断之间的间隔(period)。默认情况下,初始训练期设置为horizon的三倍,每半个horizon就有一个截断。

    注:这里需要解释下horizon,initial和period的意义:initial代表了一开始的时间是多少,period代表每隔多长时间设置一个cutoff,horizon代表每次从cutoff往后预测多少天。

    cross_validation的输出是一个dataframe,在每个模拟预测日期和每个截断日期都有真实值y和样本预测值yhat。特别地,对在cutoffcutoff + horizon之间的每一个观测点都进行了预测。然后,这个dataframe可以用来度量yhaty的错误。

    在这里,我们做交叉验证来评估预测horizon在365天的性能,从第一次截止时730天的训练数据开始,然后每180天进行一次预测。在这个8年的时间序列中,这相当于11个总预测。

    注:Peyton Manning数据一共大约8年多(2007/12/10 - 2016/01/20)的数据。

    根据上面对horizon,initial和period的解释:容易得到为什么是11个总预测。因为最后一个也要预测365天,所有最后一个cutoff在2015-01-20,从2007-12-19数730天是2010-02-15,则在2010-02-15到2015-01-20共有1800天,对应着10个cutoff,最后1个cutoff在2015-01-20,因此共11个cutoff。

    from fbprophet.diagnostics import cross_validation
    df_cv = cross_validation(m, initial='730 days', period='180 days', horizon = '365 days')
    df_cv.head()

    performance_metrics作为离截止点(预测的未来距离)的函数,可用于计算关于预测性能的一些有用统计数据(如与y相比时yhat、yhat_loweryhat_upper)。计算得到的统计信息包括均方误差(mean squared error, MSE)、均方根误差(root mean squared error, RMSE)、平均绝对误差(mean absolute error, MAE)、平均绝对误差(mean absolute percent error, MAPE)以及yhat_lower和yhat_upper估计的覆盖率。这些都是在df_cv中通过horizon (ds - cutoff)排序后预测的滚动窗口中计算出来的。默认情况下,每个窗口都会包含10%的预测,但是可以通过rolling_window参数来更改。 

    from fbprophet.diagnostics import performance_metrics
    df_p = performance_metrics(df_cv)
    df_p.head()

    交叉验证性能指标可以用plot_cross_validation_metric可视化,这里显示的是MAPE。点表示df_cv中每个预测的绝对误差百分比。蓝线显示的是MAPE,均值被取到滚动窗口的圆点。我们可以看到,对于一个月后的预测,误差在5%左右,而对于一年之后的预测,误差会增加到11%左右。 

    # Python
    from fbprophet.plot import plot_cross_validation_metric
    fig = plot_cross_validation_metric(df_cv, metric='mape')

    图中滚动窗口的大小可以通过可选参数rolling_window更改,该参数指定在每个滚动窗口中使用的预测比例。默认值为0.1,即每个窗口中包含的df_cv的10%行;增大值得话将导致图中平均曲线更平滑。

    初始周期应该足够长,以捕获模型的所有特性,特别是季节性和额外的回归变量:对年的季节性至少保证一年,对周的季节性至少保证一周,等等。


    十、与机器学习算法的对比

    与先进的机器学习算法如LGBM相比,Prophet作为一个时间序列的工具,优点就是不需要特征工程就可以得到趋势,季节因素和节假日因素,但是这同时也是它的缺点之一,它无法利用更多的信息,如在预测商品的销量时,无法利用商品的信息,门店的信息,促销的信息等。

    因此,寻找一种融合的方法是一个迫切的需求。

    展开全文
  • Prophet 简介 Facebook 去年开源了一个时间序列预测的算法,叫做fbprophet,它的官方网址与基本介绍来自于以下几个网站: Github:https://github.com/facebook/prophet 官方网址:...
  • 先知是一种用于基于附加模型预测时间序列数据的过程,其中非线性趋势与每年,每周和每天的季节性以及假期效应相吻合。 它最适合具有强烈季节性影响和多个季节历史数据的时间序列。 先知对于丢失数据和趋势变化具有较...
  • prophet模型预测时间序列

    千次阅读 2021-11-04 16:49:59
    prophet模型预测时间序列 prophet:facebook开源的的一个时间序列预测算法。 原理:基于时间序列分解和机器学习的拟合来做的。 把时间序列 分成不同时间间隔 和 整体趋势的组合。 间隔: 年 季度 月 周 日 介绍一个...
  • PySpark-prophet预测

    千次阅读 2020-05-16 12:01:50
    Prophet是facebook开源时间序列预测工具,使用时间序列分解与机器学习拟合的方法进行建模预测 。关于prophet模型优点我不打算说,网络上的文章非常多,各种可视化,和参数的解释与demo演示。 但是在正在用到工业上大...
  • 初识Prophet模型(一)-- 理论篇

    千次阅读 2021-01-01 18:57:09
    1、Prophet 简介 2、Prophet 适用场景 3、Prophet 算法的输入输出 4、Prophet 算法原理 5、Prophet 使用时可设置的参数 6、Prophet 学习资料参考 7、Prophet 模型应用 7.0 背景描述 7.1 导入数据 7.2 拟合模型 7.3 ...
  • df2 = df.copy() df2['ds'] = pd.to_datetime(df2['ds']) # 只保留每天早上6点之前的数据 df2 = df2[df2['ds'].dt.hour ] m = Prophet().fit(df2) future = m.make_future_dataframe(periods=300, freq='H') fcst = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,019
精华内容 1,207
关键字:

Prophet