时间序列预测(二)—— AR模型

时间序列预测(二)—— AR模型

欢迎大家来我的个人博客网站观看原文:https://xkw168.github.io/2019/05/20/时间序列预测-二-AR模型.html

文章链接

(一)数据预处理

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

(三)Xgboost模型

(四)LSTM模型

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


模型原理

  AR(auto-regressive)模型,亦即是自回归模型,是时间序列分析模型中最简单的两个模型其中之一(另一个是MA/Moving Average/滑动平均模型)。其原理是利用观测点前若干时刻的变量的线性组合来描述观测点后若干时刻变量的值,属于线性回归模型。AR§模型认为,任意时刻的观测值 x t x_t xt取决于前面p个时刻的观测值加上一个误差,见下式:
x t = ϕ 0 + ϕ 1 x t − 1 + ϕ 2 x t − 2 + ⋯ + ϕ p x t − p + ε t x_t = \phi_0 + \phi_1x_{t-1} + \phi_2x_{t-2} + \dots + \phi_px_{t-p} + \varepsilon_t xt=ϕ0+ϕ1xt1+ϕ2xt2++ϕpxtp+εt
ε t \varepsilon_t εt是均值为0,方差为 σ 2 \sigma^2 σ2的白噪声序列。


模型安装

pip install tensorflow


模型实现

  这里使用的是TensorFlow里面的Timeseries模块实现AR模型

def now():
    return datetime.now().strftime("%m_%d_%H_%M_%s")


def parse_result_tf(tf_data):
    """
    parse the result of model output in tensorflow
    :param tf_data: the output of tensorflow
    :return: data in DataFrame format
    """
    return pd.DataFrame.from_dict({"ds": tf_data["times"].reshape(-1), "y": tf_data["mean"].reshape(-1)})


def generate_time_series(
        start_date=datetime(2006, 1, 1),
        cnt=4018, delta=timedelta(days=1), timestamp=False
):
    """
    generate a time series/index
    :param start_date: start date
    :param cnt: date count. If =cnt are specified, delta must not be; one is required
    :param delta: time delta, default is one day.
    :param timestamp: output timestamp or format string
    :return: list of time string or timestamp
    """

    def per_delta():
        curr = start_date
        while curr < end_date:
            yield curr
            curr += delta

    end_date = start_date + delta * cnt

    time_series = []
    if timestamp:
        for t in per_delta():
            time_series.append(t.timestamp())
    else:
        for t in per_delta():
            time_series.append(t)
        # print(t.strftime("%Y-%m-%d"))
    return time_series


def AR_predict_tf(train_data, evaluation_data, forecast_cnt=365, freq="D", model_dir=""):
    """
    predict time series with auto-regressive model in tensorflow
    :param train_data: data use to train the model
    :param evaluation_data: data use to evaluate the model
    :param forecast_cnt: how many point needed to be predicted
    :param freq: the interval between time index
    :param model_dir: directory of pre-trained model(checkpoint, params)
    :return:
    """
    model_directory = "./model/AR_%s" % now()
    params = {
        # periodicities of the input data, in the same units as the time feature.
        # Note this can be a single value or a list of values for multiple periodicities.
        "periodicities": 52,
        # Number of past time steps of data to look at when doing the regression
        "input_window_size": 12,
        # Number of future time steps to predict. Note that setting it to > 1 empirically seems to give a better fit
        "output_window_size": 5,
        # The dimensionality of the time series (one for univariate, more than one for multivariate)
        "num_features": 1,
        # how many steps we train the model
        "global_steps": 3000
    }
    # if there is a pre-trained model, use parameters from it
    if model_dir:
        model_directory = model_dir
        params = read_model_param(model_dir + "/params.txt")

    # create time index for model training(use int)
    time_int = range(len(train_data) + len(evaluation_data))

    data_train = {
        tf.contrib.timeseries.TrainEvalFeatures.TIMES: time_int[:len(train_data)],
        tf.contrib.timeseries.TrainEvalFeatures.VALUES: train_data["y"],
    }

    data_eval = {
        tf.contrib.timeseries.TrainEvalFeatures.TIMES: time_int[len(train_data):],
        tf.contrib.timeseries.TrainEvalFeatures.VALUES: evaluation_data["y"],
    }

    reader_train = NumpyReader(data_train)
    reader_eval = NumpyReader(data_eval)

    """
    define in tensorflow/contrib/timeseries/python/timeseries/input_pipeline.py
    Note window_size must equal to input_window_size + output_window_size
    """
    train_input_fn = tf.contrib.timeseries.RandomWindowInputFn(
        reader_train, batch_size=20, window_size=params["input_window_size"] + params["output_window_size"]
    )

    """
    define in tensorflow.contrib.timeseries.python.timeseries.estimators
    periodicities: periodicities of the input data, in the same units as the time feature. 
                   Note this can be a single value or a list of values for multiple periodicities
    num_features: The dimensionality of the time series (one for univariate, more than one for multivariate
    website: https://www.tensorflow.org/api_docs/python/tf/contrib/timeseries/ARRegressor
    """
    estimator_ar = tf.contrib.timeseries.ARRegressor(
        periodicities=params["periodicities"],
        input_window_size=params["input_window_size"],
        output_window_size=params["output_window_size"],
        num_features=params["num_features"],
        model_dir=model_directory,
        loss=tf.contrib.timeseries.ARModel.NORMAL_LIKELIHOOD_LOSS
    )

    # only train the model when there is no pre-trained model
    if not model_dir:
        estimator_ar.train(input_fn=train_input_fn, steps=params["global_steps"])

    evaluation_input_fn = tf.contrib.timeseries.WholeDatasetInputFn(reader_eval)
    evaluation = estimator_ar.evaluate(input_fn=evaluation_input_fn, steps=1)
    # Predict starting after the evaluation
    (predictions,) = tuple(estimator_ar.predict(
        input_fn=tf.contrib.timeseries.predict_continuation_input_fn(
            evaluation, steps=forecast_cnt)))

    save_model_param(model_directory, params)
    if "loss" in evaluation.keys():
        # mean loss per mini-batch
        print("loss:%.5f" % evaluation["loss"])
        f = open(model_directory + "/%s" % evaluation["loss"], "w")
        f.close()
        model_log(
            evaluation["loss"],
            average_loss=-1 if "average_loss" not in evaluation.keys() else evaluation["average_loss"],
            content=model_dir
        )

    evaluation = parse_result_tf(evaluation)
    predictions = parse_result_tf(predictions)
    # here we should add an offset which is related to window size due to the inherent attribute of AR
    first_date = evaluation_data["ds"].tolist()[0] + \
                 delta_dict[freq] * (params["input_window_size"] + params["output_window_size"])
    evaluation["ds"] = generate_time_series(first_date, cnt=len(evaluation), delta=delta_dict[freq])
    latest_date = evaluation["ds"].tolist()[-1]
    predictions["ds"] = generate_time_series(latest_date, cnt=len(predictions), delta=delta_dict[freq])

    return evaluation, predictions

关键参数

  • periodicities:数据的周期性,这个周期可以是一个列表(数据拥有多个周期);
  • input_window_size:输入的窗口大小,亦即是做回归分析的时候一次性观察多少个过去观测值;
  • output_window_size:输出窗口的大小,亦即是一次预测多少个未来数据;
  • num_features:时间序列的维度,亦即是一个时间点对应的观察值数量,同时分析多少个时间序列,这个值就为多少;
  • model_dir:预训练模型保存的位置(可以不指定);
  • loss:损失函数;
  • steps:模型的训练迭代次数,这里设置为3000次。
郑州大学随机信号处理大作业 附程序, Yule-Walker法、Burg法、协方差法进行AR模型的功率谱估计。楼主拿了90+、4.0。 郑州大学随机信号处理大作业 附程序, Yule-Walker法、Burg法、协方差法进行AR模型的功率谱估计。楼主拿了90+、4.0。 1.引 1.引言 功率谱佔计是分析、了解信号所含有用信息的工具,也是信 号内在本质的也一种表现形式,功率谱密度(PSD)两数描述了随 机过程的功率随频礻的分布。其评价指标包括客观度量和统计度 量,谱分辨率特性是客观度量中的重要指标,而统计度量指标则 包括方差、均方误差等。 在频谱分析中主要包含两大类方法:古典谱估计和现代谱估 计。占典谱估计包括周期图估计法和相关法,它们都以傅里叶分 析为理论基础,计算相刈较为简单,但主要存在着分辨率低和性 能不好等问题。现代谱估计采用参数模型化的谱估计方法,通过 构造合适的系统模型,将要分析的随机信号用模型的参数来表示, 将其过程化为某系统在白噪声激劢下的输岀。常用的纯连续谱的 平稳随杋信号模型是有理分式模型,方法主要包括最大熵谱佔计、 AR模型法、MA模型法、ARMA模型法和最大似然法等,其中AR 模型用得较多。在线性估计方法大多是有偏的谱估计方法,谱分 辨率随数据长度的增加而提高。而非线性谱估计方法大多是无偏 的谱估计方法,通常可以获得高的谱分辨率。 本次实验主要利用了经典法中的周期图法和相关法、求解 Yule-Walker方程法、 Levinsη- durbin快速算法以及Bug算法实现 了对信号的功率谱估计。 2.实验原理 2.实验原理 21古典谱估计 相关法谱估计是以相关函数为媒介米计算功率谱,又叫做间接法 它的理论基础是维纳-辛钦定理,其具体实现步骤如下: 第一步,由获得的N点数据构成的有限长序列xn(n)来估计自相关 哟数,即:f(x) N一1 NAn=0AN(nXN(n+ m) 第步,由自相关函数的傅里叶变换求功率谱,即Sx(el" 1=-(M-1) Rx(me/wi 以上两步经历了两次截断第一次是估计RX(m)时仅利用了x(n)的 N个观测值,这相当于对ⅹn)加矩形窗截断。该窗是加在数据上的, 般称为加数据窗另一次是估计Sx(e)时仅利用了从-(M1)到M-1)的 Rx(m这相当于对Rx(m加矩形窗截断将Rx(m)截成(2M1)长,这称为 加延时窗式中RX(m)和分别表示对它们和的估值由于M<N使得上 式的运算量不是很大因此在FFT问世之前,相关法是最常用的谱估计 方法。相关法谱估计的运算框图为: 快速相关 加窗截断 进行FFT 输出 矩形窗截断 除此之外,周期图法也可运用于占典谱估计。 首先,由获得的N点数据构成的有限长序列X(n)直接求傅里叶 变换,求得频谱X(e/w 2.实验原理 然后取频普幅度的平方,并除以N,以此作为对x(n)真实功率谱x(e) 的估计,即Sx(em)=3x(em)2。 用框图表示周期图法的具体实现过程如下 矩形窗截断 相乘 N点FFT (e 事实上,两种经典法的差异主要在于估计相关函数的方法不同 22 Yule-Walker方程矩阵估计 随机信号可以看作是由当前激励白噪声w(n)以及若干次以往信 号ⅹ(nk)的线性组合产生,即所谓自回归模型(AR模型)。系统输出 与系统函数可分别用公式表示为: x()=w(n) auxin k) k=1 H(z 1+∑ 7 k k=1 P阶AR模型有p+1个待定系数a1到ap和系统增益G,由上 式,可得白噪声激劢得到的系统输出 x(n)=-∑2=10kx(n-1)+Gw(n) 该式可以理解为,用n时刻之前的p个值的线性组合来预测n时 刻的值x(n,预测误差为GW(n)。在均方误差最小准则下,组合系数 a1,a2,a3…,ap的选择应使预测误差GWn)的均方值最小经过一系 2.实验原理 列的运算,最终可以得到AR模型的正则方程 r( -k, m= 1, 2 Rx(m) kRx(m -k)+g2, m=0 其中模型参数为 Yule-Walker方程: Rxx(m a kXX k=1 其矩阵形式为: R(0) R(1) R(p-1) R(1) R(1) R R(p-1) 2 R(2) R(p-1)R(p-2) R(0) R(p) 求解Yule硎 Walker方程就可以得到AR模型系数。得到参数az (i=1,23,4.p),就可以根据自相关函数和以求参数求系统增益G。 再由Sye)=Sx(e)*|H(e)2可以得到功率谱。但是这种方法直 接求解线性方程组,运算量较大,同时在用自相关法对数据开窗的辶 程中,人为假定了数据段之外的数据为0,在计算过程中引入了误差。 23 Levinson-durbin快速递推法 Levinson- durbin递推算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值