VAR(Vector Autoregressive Models)

2024. 6. 17. 23:34계량경제학

반응형

VAR 모형은 우리가 흔히 알고 있는 단변량 시계열 모형인 AR 모형을 다변량 시계열 모형으로 확장한 것입니다. 우리가 다변량 모형을 활용하는 이유는 변수들 사이의 상호관계를 모델에 반영하기 위함입니다. 따라서 VAR 모형을 이용해서 하나의 변수에 변동이 발생했을 때 다른변수는 어떻게 변화하는지를 확인할 수 있습니다. 이와 같은 특성은 복잡한 시스템의 동적 관계를 이해하는데 활용이 되며 특히 경제학에서 많이 활용되는 모형입니다.

AR모형과 같이  VAR에 활용되는 모든 변수들은 Stationary를 만족해야만이 올바른 모형을 적합시킬 수 있습니다. 따라서 VAR모형에 적합하기전 각 변수들은 차분 등과 같은 방법을 활용하여 Stationary를 만족할 수 있도록 데이터를 변형해야 합니다.

기본적인 VAR(p)의 모형은 아래와 같이 표현됩니다.

여기서 $y_t$는 k x 1 벡터이며, $A_i$는 k x k 벡터입니다. 좀 더 직관적인 이해를 위해서 두 개의 변수로 구성된 VAR(1) 모형의 예시는 아래와 같습니다.

위의 수식에서 확인하실 수 있는 것처럼 $y_1$은 $y_2$와 관련이 있으며, 마찬가지로 $y_2$도 $y_1$에 영향을 받을 수 있습니다.(물론 계수가 0이 아닐경우에)

Python에서는 statsmodels패키지를 활용하여 쉽게 VAR모형을 적합해볼 수 있습니다. 이번 포스팅에서는 통계적으로 맞는 VAR모형을 찾는다기 보다는 쉽게 얻을 수 있는 데이터로 적합을 해보고 impulse response analysis까지 진행해보도록 하겠습니다.

이번 실습에서는 S&P와 코스피 데이터를 활용하여 두 변수간의 VAR모형을 적합해보겠습니다.

import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import os


## Data Loading
df_snp = yf.download("^GSPC", start="2004-01-02", end="2014-06-14", progress=False)
df_kospi= yf.download("^KS11", start="2004-01-02", end="2014-06-14", progress=False)

## Data Transformation
df_snp["log"] = np.log(df_snp["Close"])
df_kospi["log"] = np.log(df_kospi["Close"])

# Stationary
snp_ret = df_snp["log"].diff()
kospi_ret = df_kospi["log"].diff()
df_return = pd.merge(snp_ret, kospi_ret, how = 'inner', left_on = 'Date', right_on ='Date' )

# Null 제거
df_return.columns = ["snp", "kospi"]
df_return = df_return.dropna()


## Monthly 데이터 만들기

# VAR 모델은 일반적으로 low-frequency 데이터로 적용하기 때문
monthly_data= pd.DataFrame() 

# resample('M')은 월간단위로 데이터 추출, 각 월의 수익률을 일별 수익률의 누적곱으로 나타냄
monthly_data["snp"] = df_return['snp'].resample('M').agg(lambda x: (x + 1).prod() - 1) 
monthly_data["kospi"] = df_return['kospi'].resample('M').agg(lambda x: (x + 1)

일반적으로 VAR 모형은 일별, 시간별과 같이 Hige frequency 데이터에 대해서 좋은 성능을 나타내지 못합니다. 하나의 변수 변화가 다른 변수에 미치는 영향까지 고려되어야 하는데 시간이 짧으면 이를 반영하기 어렵기 때문입니다. 물론 짧은시간에도 영향을 미친다면 적합하는데 문제는 없을 것으로 생각됩니다.

## VAR Modeling

import statsmodels.api as sm
from statsmodels.tsa.api import VAR
import statsmodels.tsa.stattools as sts 

# 정상성 검사
# 두번째줄이 p-value p-value가 0.05 이하일때 정상성을 가지고 있다고 봄 
sts.adfuller(monthly_data["snp"]) 
sts.adfuller(monthly_data["kospi"])

정상성 검사에 대해서는 지난 포스팅(https://direction-f.tistory.com/64 )을 참고해보시면 좋을 것 같습니다.

maxlag = 12
VAR_model = VAR(monthly_data) 
lag_order =VAR_model.select_order(maxlag)
print(lag_order.summary())

"""
 VAR Order Selection (* highlights the minimums)  
==================================================
       AIC         BIC         FPE         HQIC   
--------------------------------------------------
0       -12.49     -12.44*   3.768e-06     -12.47*
1      -12.49*      -12.35  3.755e-06*      -12.43
2       -12.45      -12.21   3.934e-06      -12.35
3       -12.47      -12.13   3.841e-06      -12.33
4       -12.43      -12.00   3.989e-06      -12.26
5       -12.39      -11.86   4.179e-06      -12.17
6       -12.36      -11.74   4.296e-06      -12.11
7       -12.30      -11.58   4.551e-06      -12.01
8       -12.29      -11.47   4.614e-06      -11.96
9       -12.25      -11.34   4.816e-06      -11.88
10      -12.26      -11.25   4.766e-06      -11.85
11      -12.26      -11.15   4.808e-06      -11.81
12      -12.20      -11.00   5.083e-06      -11.72
--------------------------------------------------
"""


results = VAR_model.fit(maxlags=maxlag, ic='aic') ## 여기서도 AIC 기준으로 자동으로 선정해줌
results.summary()

"""
Results for equation snp
===========================================================================
              coefficient       std. error           t-stat            prob
---------------------------------------------------------------------------
const            0.002708         0.003873            0.699           0.484
L1.snp           0.213927         0.118520            1.805           0.071
L1.kospi        -0.001712         0.091419           -0.019           0.985
===========================================================================

Results for equation kospi
===========================================================================
              coefficient       std. error           t-stat            prob
---------------------------------------------------------------------------
const            0.006165         0.005095            1.210           0.226
L1.snp           0.223536         0.155901            1.434           0.152
L1.kospi        -0.143041         0.120253           -1.190           0.234
===========================================================================
"""

AIC 기준으로 차수 1로 적합하였으며, 결과에서 보는것과 같이 snp 자기 자신이 가지는 계수만 P-value가 유의하고 나머지는 유의하지 않았씁니다. 특히 kospi는 snp에 전혀 영향력을 가지지 못하는 모습을 보입니다. 

이를 impulse response analysis를 활용하여 표현해보면 아래와 같습니다.

irf = results.irf(10)
irf.plot(orth = False)

10 시점 이후까지 plot을 그려보면 다음과 같이 나타납니다.

모형적합결과와 같이 kospi->snp 그래프를 보면 코스피는 Snp에 전혀 영향을 못미치고 있고, p-value는 유의하지 않긴했지만 그래도 snp가 1단위 증가하면 kospi도 증가하는 모습을 볼 수 있습니다.

누적 차트는 아래와 같은 코드를 활용하여 구할 수 있습니다.

irf.plot_cum_effects(impulse = 'snp', orth=False)

반응형