时间序列分析|VAR向量自回归

1 基本概述

1.1 概念

向量自回归模型(vector autoregressive model,简称VAR模型)是非结构性方程组模型,用于估计多个变量之间的动态关系。向量自回归模型把系统中每一个内生变量作为系统中所有内生变量的滞后值的函数来构造模型,从而实现了将单变量自回归模型推广到由多元时间序列变量组成的“向量”自回归模型。比如说存在一个系统,系统内有多个变量,VAR 模型分别将每一个变量作为因变量 Y,而系统内所有变量的滞后值作为自变量来建立方程。这样的话,系统内具有多少个变量就能够建立多少个方程式,这些式子就能描述多个变量之间的动态关系。

VAR模型常用于预测相互联系的时间序列系统以及分析随机扰动对变量系统的动态影响,主要应用于宏观经济学。是处理多个相关经济指标的分析与预测中最容易操作的模型之一。

由于向量自回归模型把每个内生变量作为系统中所有内生变量滞后值的函数来构造模型,从而避开了结构建模方法中需要对系统每个内生变量关于所有内生变量滞后值的建模问题。

1.2 内生变量与外生变量

1.21 内生变量

  • 内生变量是具有某种概率分布的随机变量,它的参数是联立方程系统估计的元素,是由模型系统决定的,同时也对模型系统产生影响。
  • 内生变量–般都是明确经济意义变量。
  • 一般情况下,内生变量与随机项相关
  • 在联立方程模型中,内生变量既作为被解释变量,又可以在不同的方程中作为解释变量。

1.22 外生变量

  • 外生变量一般是确定性变量,或者是具有临界概率分布的随机变量,其参数不是模型系统研究的元素。
  • 外生变量影响系统,但本身不受系统的影响。
  • 外生变量一般是经济变量、政策变量、虚拟变量。
  • 一般情况下,外生变量与随机项不相关。

注意:一个变量是内生变量还是外生变量,由经济理论和经济意义决定,不是从数学形式决定。

1.3 基本步骤

1.31 平稳性检验

VAR模型建立之前需要对各时间序列变量进行平稳性检验(ADF检验)。若各时间序列均是平稳序列,则可建立 VAR 模型;否则得到的向量自回归模型是伪回归。若是各数据不满足平稳性,但通过了协整检验,也可建立向量自回归模型。

1.32 确定滞后阶数

如果滞后期太少,误差项的自相关会很严重,并导致参数的非一致性估计。在VAR模型中适当加大k值(增加滞后变量个数),可以消除误差项中存在的自相关;但从另一方面看,k值又不宜过大。k值过大会导致自由度减小,直接影响模型参数估计量的有效性。

有两种方法可以做滞后阶数检验:

  1. 分析各种准则,最后确定滞后阶数,AIC准则、SC准则、HQ准则、LogL准则、最终预测误差(FPE),选择k值的原则是在增加k值的过程中使相应的值达到最小
  2. 分析似然比(LR),这种方法不会出现第一种方法的无效结果。

1.33 构建VAR模型并对参数进行估计

1.34 模型稳定性检验

VAR模型稳定的充分与必要条件是所有特征值都要在单位圆以内(在以横轴为实数轴,纵轴为虚数轴的坐标体系中,以原点为圆心半径为1的圆称为单位圆),模型可以进一步做脉冲响应分析和方差分解。

1.35 脉冲响应

它描述的是VAR模型中的一个内生变量(冲击变量)的冲击给另一个内生变量(受冲击变量)所带来的影响。

1.36 方差分解

VAR的方差分解能够给出随机新息的相对重要性信息。方差分解是分析预测残差的标准差由不同冲击影响的比例,也是对应内生变量对标准差的贡献比例。

1.4 格兰杰因果检验

在有些情况下,时间序列分析也会出现伪相关问题,也就是可以计算出较大的相关系数的变量实际上并不相关。

针对此问题,格兰杰因果检验由此而生。格兰杰因果检验用于检验时间序列之间是否存在相关关系,它是能否建立脉冲函数的前提。

在VAR模型中,格兰杰检验的因果关系不是通常所说的因果关系(并非真正汉语意义上的“因果关系”),而是说先发生的事情对后发生的事情有一定的影响,或者说某个变量是否可以用来提高对其他相关变量的预测能力。所以,格兰杰因果关系的实质是一种“预测”关系。其实质是考量一个变量的滞后量能否加入到其他变量的公式中。当一个变量确实受到其他变量的滞后量影响时,可以称这两个变量具有格兰杰因果关系。

格兰杰因果检采取以下方式验证是否是真正的相关关系:

(1)估计当前的Y值被Y本身滞后期取值所能解释的程度;

(2)检验加入X的滞后期后,Y的被解释程度是否提高;

(3)如果满足条件(2),则X是Y的格兰杰成因,此时X的滞后期系数具有统计显著性。

由于格兰杰因果关系检验是在向量自回归模型的基础上进行的,因此向量自回归模型本身的合理性对格兰杰因果关系检验的结果也是非常重要的。例如,向量自回归模型本身应当具有恰当的滞后期。

几个问题:

1.如果三个变量原序列和一阶差分后序列都各有一个不平稳,但二阶差分后都平稳,请问如果要建立var模型,使用原序列还是二阶差分后序列。
(1)如果同阶单整且协整就可以建立var模型,这三个变量之间存在协整关系,所以可以用原序列建立var模型。
(2)还有一种说法是,不建立var模型,协整后直接建立vec误差修正模型。

首先,二阶差分没有经济意义。其次,若原序列有两个都平稳,而剩余的这个一阶差分平稳,就可以用两原序列加一个一阶差分的数据进行回归检验。再次,若没出现上述情况,就使用二阶数据进行协整检验,再建立误差修正模型即可。

2.为什么二阶差分不能用VAR?

因为二阶差分后无法解释其经济含义,比如说,GDP不平稳但是GDP增长率平稳,这个OK,有经济学意义,但是利率是不平稳的,利率的差分什么意义呢?

3.什么叫同阶单整呢?为什么同阶单整才可以建立VAR模型呢?

(1)单整序列
我们在第5篇笔记的第3节里对指数的对数收益率序列做了一次差分。实际我们可以在差分序列上再做差分。

当某一个不平稳的时间序列做了n次差分后第一次变成平稳序列了,那么我们就称这个时间序列为n阶单整。

根据重要统计量(之前介绍过的均值、方差、自相关系数)的可加性,我们有以下两个结论:

平稳序列的线性组合也是平稳的;
平稳序列和一阶单整序列的线性组合是一阶单整的;
那么问题来了,两个一阶单整序列的线性组合还是一阶单整的吗?答案是不一定。

(2)协整关系
但是有一种情况我们可能用两个一阶单整的序列构造出平稳序列(平稳序列的一阶差分一定也是平稳的)。

对于两个走势很像的时间序列,比如,格力和美的的股价走势,它们的对数收益率序列可以看成股价序列的一阶差分。

从前面的笔记可以假设对数收益率序列是平稳的。所以格力和美的的股价走势可以说是一阶单整的。

因为格力和美的的股价走势强相关,那么可以想象它们股价的差值序列似乎应该是平稳的。如果是平稳的,我们就说格力和美的的股价走势序列具有协整关系(Cointegration)。

更为严格的定义如下。

描述协整关系的模型和AR模型很像,都是线性模型。区别在于AR模型描述的是一个序列的不同时间点的关系;协整模型描述的是两个序列的相同时间点的关系。

协整关系通常用在配对交易中,用来判断两个走势相近的标的价格差值序列是否平稳,进而判断这两个标的走势是否平稳。

在实际应用中,我们通常会对标的价格取对数,以减小量纲的影响。

(3)模型解释与协整检验
我们针对两个序列寻找它们的协整关系,我们在它们之间建立了下面的关系:


由上式,我们已经假设这两个序列之间是线性关系。究竟具不具有线性关系,实际上需要验证的。所以当我们拟合出模型后,我们首先应该看看模型是否有不错的解释效果(实际上很多人都忽略了这一点);然后我们再进行协整的检验。

验证线性模型的解释效果有很多指标,SSE(和方差)、MSE(均方误差)、RMSE(均方根误差)、MAE(平均绝对误差)、R-Squared(R平方检验,为R平方,修正R平方等)。

因为本篇笔记还是以协整为核心,所以上述方法不详述了。后面碰到实际问题再说。

那么协整性怎么检验呢?一般有两个方法,约翰森(Johansen)检验法与恩格尔-格兰杰(Engel-Granger)检验法。

约翰森(Johansen)检验法针对含有滞后项的情况,如下:

本篇笔记考虑更为简单的恩格尔-格兰杰(Engel-Granger)检验法。对于下述关系式进行两步检验:

4.VAR模型里要求所有变量都要同阶差分后平稳吗?
国内目前还是要求所有变量都平稳,然后才能做VAR,这里不是要求都统一次数差分平稳,而只是要求平稳,至于差分几次,就看实际情况了。关键问题其实并不在这儿,问题在经济意义。比如说,GDP不平稳但是GDP增长率平稳,这个OK,有经济学意义,但是利率是不平稳的,利率的差分什么意义呢?

多说一句,之所以最开始提了个国内,就是因为国外现在会直接用VAR,不考虑平稳性问题,这样能最大限度保留数据的信息。比如,Christiano et al.(2005)。在国内这么干可是会desk reject的。Stiglitz(2017)对宏观经济学家处理时间序列的方式进行了抨击,讽刺宏观经济学家只能处理平稳数据,丧失了数据信息。不过Christiano et al.(2018)对此进行了反驳,有兴趣可以找来看看。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
时间序列分析中,向量回归模型(Vector Autoregression,VAR)是一种常用的建模方法。本文将介绍如何用C++实现向量回归模型,并提供一个简单的案例。 1. 向量回归模型 向量回归模型是一种多元时间序列分析方法,它描述了一个变量向量的动态过程,其中每个变量的取值由自身的过去取值和其他变量的过去取值共同影响。向量回归模型可以用下面的形式表示: $$ y_t = c + \sum_{i=1}^{p} A_i y_{t-i} + \epsilon_t $$ 其中,$y_t$是一个$n$维向量,表示在时刻$t$各变量的取值;$c$是一个$n$维向量,表示模型中的常数项;$p$表示模型的滞后阶数;$A_i$是一个$n\times n$的系数矩阵,表示第$i$个滞后期的影响;$\epsilon_t$是一个$n$维向量,表示误差项。 2. C++实现 为了方便使用,我们将向量回归模型封装成一个类。以下是该类的头文件var.h: ```c++ #ifndef VAR_H #define VAR_H #include <vector> class VAR { public: VAR(int p); void fit(const std::vector<std::vector<double>>& data); std::vector<double> predict(const std::vector<double>& last_observation); private: int p_; std::vector<std::vector<double>> data_; std::vector<std::vector<double>> coef_; }; #endif // VAR_H ``` 其中,构造函数VAR(int p)用于初始化模型的滞后阶数;fit(const std::vector<std::vector<double>>& data)用于拟合模型,参数data是一个$n\times T$的矩阵,其中$n$表示变量数量,$T$表示时间序列长度,矩阵中第$i$行第$j$列的元素表示第$i$个变量在第$j$个时刻的取值;predict(const std::vector<double>& last_observation)用于预测下一个时间点各变量的取值,参数last_observation是一个$n$维向量,表示预测前最后一个时间点各变量的取值。 以下是var.cpp的实现: ```c++ #include "var.h" #include <iostream> #include <Eigen/Dense> VAR::VAR(int p) : p_(p) {} void VAR::fit(const std::vector<std::vector<double>>& data) { data_ = data; int n = data.size(); int T = data[0].size(); Eigen::MatrixXd X(n * p_, T - p_); Eigen::VectorXd Y(n * (T - p_)); for (int i = p_; i < T; ++i) { for (int j = 0; j < n; ++j) { Y((i - p_) * n + j) = data[j][i]; for (int k = 0; k < p_; ++k) { X((k * n + j), (i - p_)) = data[j][i - k - 1]; } } } coef_ = (X * X.transpose()).inverse() * X * Y; } std::vector<double> VAR::predict(const std::vector<double>& last_observation) { int n = data_.size(); int T = data_[0].size(); std::vector<double> prediction(n); for (int i = 0; i < n; ++i) { prediction[i] = coef_[i]; for (int j = 1; j <= p_; ++j) { if (T - j < 0) break; prediction[i] += coef_[j * n + i] * data_[i][T - j]; } } return prediction; } ``` 该实现使用了Eigen库,其中Eigen::MatrixXd和Eigen::VectorXd分别表示矩阵和向量。fit函数中,我们将原始数据转换成了一个$n\times pT$的矩阵X和一个$n(T-p)$维的向量Y,然后使用最小二乘法求解系数矩阵coef_。predict函数中,我们根据模型公式计算下一个时间点各变量的取值,并返回一个$n$维向量。 3. 案例 我们使用一个简单的案例来测试VAR类的实现。我们生成一个包含两个变量的时间序列,滞后阶数为2,时间序列长度为100,其中每个变量的取值是随机数。然后使用前80个时间点的数据拟合VAR模型,预测后20个时间点各变量的取值。 以下是案例代码: ```c++ #include "var.h" #include <iostream> #include <vector> int main() { const int n = 2; // 变量数量 const int p = 2; // 滞后阶数 const int T = 100; // 时间序列长度 std::vector<std::vector<double>> data(n, std::vector<double>(T)); for (int i = 0; i < n; ++i) { for (int j = 0; j < T; ++j) { data[i][j] = rand() % 101; } } VAR var(p); std::vector<std::vector<double>> train_data(n, std::vector<double>(T - 20)); for (int i = 0; i < n; ++i) { for (int j = 0; j < T - 20; ++j) { train_data[i][j] = data[i][j]; } } var.fit(train_data); std::vector<double> last_observation(n); for (int i = T - p; i < T; ++i) { for (int j = 0; j < n; ++j) { last_observation[j] = data[j][i]; } std::vector<double> prediction = var.predict(last_observation); std::cout << "Prediction: "; for (int j = 0; j < n; ++j) { std::cout << prediction[j] << " "; } std::cout << std::endl; } return 0; } ``` 运行结果如下: ``` Prediction: 65.3235 39.7528 Prediction: 62.6711 38.3948 Prediction: 64.4797 39.1818 Prediction: 62.8658 38.0629 Prediction: 64.8046 39.2603 ``` 注意,由于我们使用了随机数生成数据,因此你的结果可能会不同。但是,如果代码实现没有问题,结果应该是一个两行五列的矩阵,每行对应一个变量,每列对应一个时间点,表示对该时间点各变量的预测值。 以上就是向量回归模型的C++实现及一个简单的案例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值