时间序列预测(五)—— Prophet模型

文章链接

(一)数据预处理

(二)AR模型(自回归模型)

(三)Xgboost模型

(四)LSTM模型

(五)Prophet模型(自回归模型)


模型原理

  Prophet模型,是Facebook公司开源的一个专门用于大规模时间序列分析的模型,基于加性模型(Additive Model),利用年月日等的周期性再加上假期影响去拟合非线性的趋势。具体内容可以在这里找到。该模型最适合用于拟合那些具有较强周期性并且拥有几个周期的数据,并且对缺失值,趋势偏移和异常值都有着较好的支持。Prophet采用一种独特的策略(如图所示),在保证当需要的时候可以完全自动化整个流程的前提下,允许数据分析学家通过一组关键的模型参数和选项来在预测中加入自己的判断。

probit回归拟合程度 probit回归模型_时间序列

  Prophet原理图Prophet的大致原理如下,它将一个时间序列看成是三部分的组合:趋势,季节和假日。probit回归拟合程度 probit回归模型_Prophet 模型_02probit回归拟合程度 probit回归模型_Prophet 模型_03代表趋势项,用于拟合时间序列里面的非周期项;probit回归拟合程度 probit回归模型_数据_04代表周期性变化(如季节性变化);probit回归拟合程度 probit回归模型_probit回归拟合程度_05代表了假期的影响(通常表现为对某些时间点的特殊影响);误差项probit回归拟合程度 probit回归模型_probit回归拟合程度_06代表了所有未被模型考虑到的误差因素。同时该模型将一个预测类问题,映射为了曲线拟合类问题,这天然的就和那些用于分析数据间有依赖性的模型有所不同。尽管这种策略会使其放弃很多常规模型(如ARIMA)的一些优势,但是这种映射带来了一些其他的优势:

可拓展:曲线拟合问题可以很轻易的引入季节和多周期性的影响,可以应用于多种数据类型;

数据灵活:与ARIMA模型不同,曲线拟合问题不需要数据等步长,所以不需要对数据进行一些特殊操作(如插值);

速度快:相比较于传统的训练模型,曲线拟合的速度更快,有助于数据科学家进行迭代;

变量易解释:模型的大部分变量都有着明确的物理含义,并且拥有一定数据分析经验的人可以很快的将背景知识转换为新的参数引入模型。


模型安装

Prophet模型的安装推荐使用conda

conda install -c conda-forge fbprophet

下载并安装Anaconda,在cmd/powershell里面输入 conda 已验证是否成功安装

如果你对conda不熟悉,下面有一些链接可能会对你有所帮助:

  • 在conda中使用pip
  • conda虚拟环境详解

模型实现

注意:Prophet模型对输入有所限制,接受的是DataFrame格式的输入,并且时间数据列名为ds,观测数据列名为y

def prophet_predict_fb(observed_data, x_name="ds", y_name="y", forecast_cnt=365, frep="D", file_name=""):
    """
    function that predict time series with library fbprophet
    :param observed_data: time series data(DataFrame format)
    (two columns, one is time in YYYY-MM-DD or YYYY-MM-DD HH:MM:SS format and the other is numeric data)
    :param x_name: x column name(time data), usually is DATE
    :param y_name: y column name(numeric data) e.g. HMD, MAX...
    :param forecast_cnt: how many point needed to be predicted
    :param frep: the frequency/period of prediction
    :param file_name:
    :return: None
    """

    def check_parameter_validity():
        if x_name not in observed_data.keys():
            raise KeyError("train_data doesn't have column named %s" % x_name)
        if y_name not in observed_data.keys():
            raise KeyError("train_data doesn't have column named %s" % y_name)

    try:
        check_parameter_validity()
    except KeyError as e:
        print("key error: %s" % str(e))
        return None

    observed_data = observed_data.rename(columns={x_name: "ds", y_name: "y"})

    observed_data["ds"] = pd.to_datetime(observed_data["ds"])
    observed_data["y"] = pd.to_numeric(observed_data["y"], downcast='float', errors='coerce')

    df2_pro = fbprophet.Prophet(changepoint_prior_scale=0.1)
    df2_pro.fit(observed_data)

    future_date = df2_pro.make_future_dataframe(periods=forecast_cnt, freq=frep)
    df2_forecast = df2_pro.predict(future_date)

    # register a datetime converter for matplotlib
    from pandas.plotting import register_matplotlib_converters
    register_matplotlib_converters()

    if file_name:
        fig1 = df2_pro.plot(df2_forecast, xlabel=x_name, ylabel=y_name)
        fig1.show()
        fig1.savefig('./result/%s.png' % file_name)
        fig2 = df2_pro.plot_components(df2_forecast)
        fig2.show()
        fig2.savefig('./result/%s.png' % str(file_name + "1"))

    return df2_forecast

关键参数

该模型封装较好,无需修改较多参数

  • changepoint_prior_scale:数据趋势的变化频率,值越大,数据的趋势项变化越缓慢。

注意该模型比较适合于分析周期性较为明显的数据。