본문 바로가기
2. Data Science Basics/Python

VAR을 이용하여 Kospi 예측해보기

by Mojito 2021. 8. 19.

VAR 이란?

  - VAR은 두개 이상의 시계열 데이터를 사용해 앞으로를 예측하는 알고리즘이다

 

VAR특징

  - 두개 이상의 시계열 데이터를 가지고 있어야 하며, 한 시계열 데이터가 다른 시계열 데이터에게 영향을 줌

  - lags (지연된 시간 값)을 가지고 있으며 데이터는 stationary 해야함. 

  - AR, ARMA, ARIMA 모델과는 다르게 VAR은 양방향성(bi-direction)을 가짐

(예: 금가격은 달러가격에 영향이 있다 / 달러가격은 금가격에 영향이 있다)

 

VAR의 간단한 수식은 아래와 같다 (출저:Wikipedia)

var(1)

수식은 2개의 시계열 데이터가 있을 때 공식을 나타낸것이다. 이러한 모델은 VAR(1) 모델이라 하며 lag order 이 1 인 VAR 모델이다.

 

이번시간에 모델을 만들기 위해 서로 영향이 있는 데이터들을 가져오겠다. 

https://mojitos.tistory.com/28

 

Granger's Causality Test

Granger's Causality란? - 1969년에 처음 발명된 통계기법으로 시계열 데이터 x 가 얼마나 y에 영향을 끼치는지 알아볼 수 있는 Test이다. Null Hypothesis = x does not Granger-cause y P-value가 0.05 보다 낮..

mojitos.tistory.com

저번시간에 Post 했듯이, Granger Test를 이용하여 코스피는 니케이 지수와 granger cause 한다는 것을 발견해 냈다.

일본 니케이지수를 이용하여 코스피를 예측하는 모델을 만들어보겠다.

(주의: 이 포스트는 설명을 돕기위해 1년동안의 주식데이터를 모아서 만든 간단한 모델입니다. 주식시장은 훨신 noise 도 많고 외부적인 영향을 많이 받기때문에 이 모델은 학습용으로만 만들어보시길 바랍니다. 맹신하고 투자하시면 절대 안됩니다!)

KS = Kospi / NK = Nikkei

위와같이 2019년부터 약 3년간의 종가 데이터 프레임을 만들었다.

VAR 모델을 만들기 전에 제일 먼저 해야할 것은 데이터가 stationary 하게 만들어줘야 한다

 

(Difference Method)

nobs = 5
df_train, df_test = df[0:-nobs], df[-nobs:]

df_differenced = df_train.diff().dropna()

Test Train Split 후 데이터를 difference 해주었다. 이제 성공적으로 데이터가 stationary 하게 변경 되었는지 확인 해 보기위해 Dickey-Fuller test 를 진행해보겠다.

 

from statsmodels.tsa.stattools import adfuller

def adf_test(df):
    result = adfuller(df.values)
    print('ADF: %f' % result[0])
    print('p-value: %f' % result[1])
    print('Critical values:')
    for key, value in result[4].items():
        print('\t%s: %.3f' % (key, value))
        
adf_test(df_differenced["KS"])
adf_test(df_differenced["NK"])

 

P-value 가 0.05 보다 작아서 두 데이터는 stationary 하다고 말할수있다.

그 후에, lag order 을 정해야 한다. lag order 은 previous element 를 뜻한다. (예: 오늘이 금요일이면 lag = 1 는 목요일)

from statsmodels.tsa.api import VAR

model = VAR(df_differenced)
for i in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]:
    result = model.fit(i)
    print('Lag Order =', i)
    print('AIC : ', result.aic)
    print('BIC : ', result.bic)
    print('FPE : ', result.fpe)
    print('HQIC: ', result.hqic, '\n')

lag order 은 주로 AIC 나 BIC 가 제일 작은 값을 선택한다. 위의 경우 lag order = 2를 선택해서 모델을 만들어 보겠다.

model = model.fit(2)
model.summary()

fc = model.forecast(y=df_differenced.values[-lag_order:], steps=nobs)
df_forecast = pd.DataFrame(fc, index=df.index[-nobs:], columns=df.columns)
df_forecast
def invert_transformation(df_train, df_forecast):
    df_ = df_forecast.copy()
    columns = df_train.columns
    for col in columns:        
        df_[str(col)+'_forecast'] = df_train[col].iloc[-1] + df_[str(col)].cumsum()
    return df_
    

df_results = invert_transformation(df_train, df_forecast)        
df_results.loc[:, ['KS_forecast','NK_forecast']]

예상
실제

 

반응형

댓글