๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
๋ค๋ณ๋ ์๊ณ์ด ๋ฐ์ดํฐ 1 (Multivariate Time Series Data) ๋ณธ๋ฌธ
๋ค๋ณ๋ ์๊ณ์ด ๋ฐ์ดํฐ 1 (Multivariate Time Series Data)
์ง์ง์ํ์นด 2022. 9. 28. 10:17220928 ์์ฑ
<๋ณธ ๋ธ๋ก๊ทธ๋ today-1๋์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํด์ ๊ณต๋ถํ๋ฉฐ ์์ฑํ์์ต๋๋ค :-) >
https://today-1.tistory.com/38?category=886697
๋ค๋ณ๋ ์ ํ ํ๋ฅ ๊ณผ์ (VAR/Granger Causality/Cointegration)
๋ค๋ณ๋ ์ ํ ํ๋ฅ ๊ณผ์ (VAR/Granger Causality/Cointegration) : ๋ค๋ณ๋ ์ ํ ํ๋ฅ ๊ณผ์ ์ ๊ณต๋ถํ๊ณ ์ ํจ. : ํด๋น ๋ชจ๋ธ๋ค์ ๊ฒฐ๊ตญ AR ๋ชจํ์ ๋ฒ๊ฐ์ ์ฌ์ฉ, X์ธ์ ์ถ๊ฐ, ์ ๋ถ์ ํ์ฉํ ๋ด์ฉ๋ค๋ก ๊ตฌ์ฑ ๋จ. 1) ๋ฒกํฐ
today-1.tistory.com
1๏ธโฃ ๋ค๋ณ๋ ์๊ณ์ด ๋ฐ์ดํฐ (Multivariate Time Series Data)
: ๊ฐ ์๊ฐ ๋จ์๋ง๋ค ์ฌ๋ฌ ๊ฐ์ ๊ฐ์ ๊ฐ์ง๋ ๋ฐ์ดํฐ
: ๋ค์ค ์๊ฐ ์ข ์ ๋ณ์๋ก ๊ตฌ์ฑ
: ๋ค๋ณ๋ ๋ถ์์์ ์์ธกํ ๋ณ์์ ๊ณผ๊ฑฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณ ๋ คํด์ผํ ๋ฟ๋ง ์๋๋ผ ์ฌ๋ฌ ๋ณ์๋ค ์ฌ์ด์ ์์กด์ฑ์ ๊ณ ๋ ค
2๏ธโฃ ๋ค๋ณ๋ ์๊ณ์ด ๋ชจ๋ธ
๐ ๋ฒกํฐ ์๋ ํ๊ท ๋ถ์ VAR(Vector Auto Regression)
: ์์ธกํ ๋ณ์์ ๊ณผ๊ฑฐ ๊ฐ๋ฟ๋ง ์๋๋ผ ์์ธกํ ๋ณ์์ ์์กด์ฑ์ด ์๋ ๋ณ์๋ค๊น์ง ๊ณ ๋ คํ์ฌ ์ ํ ํจ์๋ก ๋ํ๋ด๋ ํ๋ฅ ์ ๊ณผ์
: ์ข ์ ๋ณ์์ ๋ ๋ฆฝ ๋ณ์๋ ์ํธ ์ํฅ์ ๋ฐ๋ ์กด์ฌ
: ๋ ๋ณ์๋ค ์ค ์ด๋ค ๋ณ์๊ฐ ์ข ์๋ณ์๋ก ์ ํฉํ์ง์ ๋ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ฉ
๐ ๊ทธ๋์ธ์ ์ธ๊ณผ๊ด๊ณ (Granger Causality)
: ์ ์์ฑ ๋ฐ์ดํฐ ์ ๋ ฅ (์ฐจ๋ถ ํ์)
: '๋ญ์ด ๋จผ์ ๋ ๋ฌ๊ฑ์ด ๋จผ์ ๋' ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ ์ฌ์ฉ
- ์ถ๋ก ๋ถ๊ฐํ ๋ฌธ์ : "๋ญ์ด ๋จผ์ ์ธ๊ฐ ๋ฌ๊ฑ์ด ๋จผ์ ์ธ๊ฐ?" (์ธ๊ณผ๊ด๊ณ)
- ์ถ๋ก ๊ฐ๋ฅํ ๋ฌธ์ : "๋ญ๊ณผ ๋ฌ๊ฑ์ ์์ฑ์์ ๋ณ ์๋ก์ ์ํฅ๋ ฅ์ ์ด๋ค๊ฐ?" (Granger ์ธ๊ณผ๊ด๊ณ)
: ์์ธ๊ณผ ์ธ๊ณผ ๊ด๊ณ๋ฅผ ๊ท๋ช ํ๋ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ์๋์ ์ผ๋ก ๋ ์์ธ ์ค ๋จผ์ ์ํฅ์ ๋ฏธ์น๋ ๋ณ์๋ฅผ ์์๋ณด๊ณ ์ ํ ๋ ์ฌ์ฉ
- ๊ท๋ฌด๊ฐ์ค(Null Hypothesis, ๐ป0H0): ํ ๋ณ์๊ฐ ๋ค๋ฅธ ๋ณ์๋ฅผ ์์ธกํ๋๋ฐ ๋์์ด ๋์ง ์๋๋ค
- ๋๋ฆฝ๊ฐ์ค(Alternative Hypothesis, ๐ป1H1): ํ ๋ณ์๊ฐ ๋ค๋ฅธ ๋ณ์๋ฅผ ์์ธกํ๋๋ฐ ๋์์ด ๋๋ค
๐ ๊ณต์ ๋ถ (Cointegration)
: ๋น์ ์์ฑ ๋ฐ์ดํฐ ์ ๋ ฅ
: ๊ณต์ ๋ถ ์ํ = ๋ ๋น์ ์์ฑ ์๊ณ์ด์ ์ ํ์กฐํฉํ์ฌ ์์ฑํ ์๊ณ์ด์ ์ ๋ถ ์ฐจ์๊ฐ ๋ฎ์์ง๊ฑฐ๋ ์ ์์ํ๊ฐ ๋๋ ๊ฒฝ์ฐ
: ๊ณต์ ๋ถ ์๊ณ์ด์ ์๋ก ์๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๋๋ผ๋ ์ฅ๊ธฐ์ ์ผ๋ก ๊ฐ์ ๋ฐฉํฅ์ผ๋ก ์์ง์ด๋ ํน์ฑ์ ์ง๋
: ํ์ด ํธ๋ ์ด๋ฉ ์ ๋ต์ ํ์ฉ
3๏ธโฃ ์ฝ๋ ๊ตฌํ
๐ด Library & data load
- statsmodels : ์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๊ณ ํต๊ณ์ ๋ชจ๋ธ์ ์ถ์ ํ๋ฉฐ ํต๊ณ์ ํ ์คํธ๋ฅผ ์ํํ ์ ์๊ฒ ๋์์ฃผ๋ API
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
from statsmodels.tsa.api import VAR
from statsmodels.tsa.stattools import adfuller
- ์ค์งGDP ์ํ
data = sm.datasets.macrodata.load_pandas().data
data.head()
- year, realgdp, realdpi ์ธ๊ฐ์ง๋ง ์ฌ์ฉ
mydata = data[["realgdp", 'realdpi']]
mydata.index = data["year"]
mydata.head()
mydata.plot(figsize = (8,5))
- Stationary time series
- ๋ฐ์ดํฐ๊ฐ ์ ์์ฑ์ ๊ฐ์ง๋ค๋ ์๋ฏธ๋ ๋ฐ์ดํฐ์ ํ๊ท ๊ณผ ๋ถ์ฐ์ด ์์ ๋์ด ์์ด ๋ถ์ํ๊ธฐ ์ฌ์
- VAR์ ์ ์ฉ์์ผ๋ณด๊ธฐ ์ ์ ๋ ์๊ณ์ด ๋ณ์๊ฐ ๋ชจ๋ stationay ์ํ์ด์ด์ผ ํจ
๐ด AIC ๊ธฐ์ค์ ์ฌ์ฉ
: ๋ฐ์ดํฐ์ stationarity๋ฅผ ์ฐพ๊ธฐ ์ํด ADF(Advanced Dickey-Fuller test)์ ๊ฐ์ ํต๊ณ์ ํ ์คํธ๋ฅผ ์ํ
from statsmodels.tsa.stattools import adfuller
- p-value
- test-statistics
- critical value : ํต๊ณ ๊ฒ์ ์์ ๊ฒ์ ๊ฐ์ ํ๋จ ๊ธฐ์ค์ผ๋ก ์์ฉํ๋ ๊ฐ (ADF Test ๊ฒ์ ๊ฐ์ด ๋ณด๋ค ๋ฎ๊ฒ ๋๋ฉด p-value๊ฐ ๋ฎ์ ๊ท๋ฌด ๊ฐ์ค ๊ธฐ๊ฐ ๊ฐ๋ฅ)
- lag, observation
dftest = adfuller(x, maxlag, regression, autolag)
- x : ์๊ณ์ด ๋ฐ์ดํฐ
- maxlag : ADF Test ์์ p ์ง์ (์ง์ ํ๋ ค๋ฉด autolag๋ฅผ None์ผ๋ก ์ค์ )
- regression
- c : ์ถ์ธ๋ ์๊ณ ์์ํญ ์กด์ฌ
- nc : ์์ํญ๊ณผ ์ถ์ธ๊ฐ ์์
- ct : ์ถ์ธ์ ์์ํญ ๋๋ค ์กด์ฌํ๋ค๊ณ ๊ฐ์
- ctt : ์์ํญ๊ณผ ์ผ์ฐจ, ์ด์ฐจ ์ถ์ธ๊ฐ ๋ชจ๋ ์กด์ฌํ๋ค๊ณ ๊ฐ์
- autolag
- ADF Test ์์ p๋ฅผ ์๋์ผ๋ก ์ง์
- AIC, BIC : ๋์ค ๊ฐ์ฅ ๋ฎ๊ฒ ๋์ค๋ p๋ฅผ ์๋ ์ค์ (์ฌ๊ธฐ์ ์ง์ ํ๋ฉด maxlag ๋ฌด์)
- None : maxlag ์ง์ ๊ฐ ์ค์
- t-stat : maxlag์์ ์ง์ ํ ๊ฐ๋ถํฐ regression์ ์ํํ๋ฉด์ ํต๊ณ ๊ฒ์ p-value๊ฐ 5% ๋ฏธ๋ง ๋ ๋์ ๋๊ทธ p๊ฐ์ผ๋ก ์ค์
- ADF Test ์์ p๋ฅผ ์๋์ผ๋ก ์ง์
adfuller_test = adfuller(mydata['realgdp'], autolag= "AIC")
print("ADF test statistic: {}".format(adfuller_test[0]))
print("p-value: {}".format(adfuller_test[1]))
adfuller_test = adfuller(mydata['realdpi'], autolag= "AIC")
print("ADF test statistic: {}".format(adfuller_test[0]))
print("p-value: {}".format(adfuller_test[1]))
- ๋ ๊ฒฝ์ฐ ๋ชจ๋ p-value๊ฐ ์ถฉ๋ถํ ์ ์๋ฏธํ ๊ฐ์ ๊ฐ์ง์ง ์์ ์๊ณ์ด ๋ฐ์ดํฐ๊ฐ non-stationary
๐ด differencing (์ฐจ๋ถ)
adfuller_test = adfuller(mydata['realgdp'], autolag= "AIC")
print("ADF test statistic: {}".format(adfuller_test[0]))
print("p-value: {}".format(adfuller_test[1]))
adfuller_test = adfuller(mydata_diff['realdpi'], autolag= "AIC")
print("ADF test statistic: {}".format(adfuller_test[0]))
print("p-value: {}".format(adfuller_test[1]))
- realgdp, realdpi ๋ชจ๋ p-value ๊ฐ์ด ์์์ง => sationary
๐ด ๋ชจ๋ธ๋ง
- ๋ง์ง๋ง 10์ผ์ test ๋๋จธ์ง๋ train
train = mydata_diff.iloc[:-10,:]
test = mydata_diff.iloc[-10:,:]
- VAR๋ชจ๋ธ์ ์ต์ ์์
- ์ต์ ์ ๋ชจ๋ธ์ ์ฐพ๊ธฐ ์ํ ๊ธฐ์ค AIC(Akaike's Information Criterion)๋ฅผ ๋ชจ๋ธ ์ ํ ๊ธฐ์ค
- ์ต์์ AIC์ ์๋ฅผ ๋ฐํ์ผ๋ก VAR์ ์์(p)๋ฅผ ์ ํ
- AIC๋ ์ผ๋ฐ์ ์ผ๋ก ๋ชจ๋ธ์ด ๋๋ฌด ๋ณต์กํ๋ค๋ ์ด์ ๋ก ๋ถ์ด์ต์ ์ฃผ๊ณค ํ๋๋ฐ ๋ณต์กํ ๋ชจ๋ธ์ ์ผ๋ถ ๋ค๋ฅธ ๋ชจ๋ธ ์ ํ ๊ธฐ์ค์์ ์ฝ๊ฐ ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ฌ ์ค ์ ์์
- ์์(p) ๊ฒ์ ์ ๋ณ๊ณก์ ์ด ์์๋๋๋ฐ, ์ด๋ ์ผ์ ์์๊ฐ ๋ ๋๊น์ง ์์ p๊ฐ ์ปค์ง๋ฉด AIC์ ์๊ฐ ๊ฐ์ํ๊ณ , ์ดํ ์ ์๊ฐ ๋์์ง๊ธฐ ์์ํ๋ค
- grid-search๋ฅผ ์ํํด์ ์ต์ ์ p
- fit์ผ๋ก VAR ๋ชจ๋ธ์ ํ์ต
- 1๋ถํฐ 10๊น์ง ์ ํฉํ ์์์ ๋ํ AIC ์ ์๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ฐ๋ณต๋ฌธ์ ํตํด grid-search
forecasting_model = VAR(train)
results_aic = []
for p in range(1,10):
results = forecasting_model.fit(p)
results_aic.append(results.aic)
- ๊ฒฐ๊ณผ ๊ทธ๋ํ์์ ๊ฐ์ฅ ๋ฎ์ AIC์ ์๋ 2์ด๊ณ , ๊ทธ ์ดํ p๊ฐ ์ปค์ง์ ๋ฐ๋ผ ์ฆ๊ฐ ์ถ์ธ
- VAR๋ชจ๋ธ์ ์ต์ ์์๋ 2
sns.set()
plt.plot(list(np.arange(1,10,1)), results_aic)
plt.xlabel("Order")
plt.ylabel("AIC")
plt.show()
- ๋ชจํ์ ์์ 2๋ก fit ์ํค๊ณ ์์ฝ ๊ฒฐ๊ณผ
results = forecasting_model.fit(2)
results.summary()
๐ด ์์ธกํ๊ธฐ
- ํ์ต๋ ๋ชจ๋ธ์ 2์ผ ๋์์ ํ๋ จ์ ๋ฃ์ด ํฅํ 10์ผ ๋์์ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ์์ธก
laaged_values = train.values[-2:]
forecast = pd.DataFrame(results.forecast(y= laaged_values, steps=10), index = test.index, columns= ['realgdp_1d', 'realdpi_1d'])
forecast
- ์ธ๊ธํ ์์ธก์ด ์ฐจ๋ถ(diffencing)์ ๋ํ ๋ชจ๋ธ์ ๋ํ ๊ฒ
- ์ฐจ๋ถ์ ๋ํ์ฌ ์ฐ๋ฆฌ๊ฐ ์์ธกํด์ผ ํ ๊ฐ์ผ๋ก ๋ง๋ค๊ธฐ
- ์ผ์ชฝ(_1d)์ ์ฐจ๋ถ์ ๋ํ ์์ธก๊ฐ
- ์ค๋ฅธ์ชฝ (_forcasted)์ ์๋ ์๋ฆฌ์ฆ์ ๋ํ ์์ธก๊ฐ
forecast["realgdp_forecasted"] = mydata["realgdp"].iloc[-10-1] + forecast['realgdp_1d'].cumsum()
forecast["realdpi_forecasted"] = mydata["realdpi"].iloc[-10-1] + forecast['realdpi_1d'].cumsum()
forecast
- ์ค์ test ์
๊ณผ ํฉ์ณ์ ์๊ฐํ
- realdpi์ realdpi_forecasted๋ ๋น์ทํ ํจํด
- realgdp์ realgdp_forecasted๋ ์ ๋ฐ ์ ๋๋ ๋น์ทํ๋ค๊ฐ ๋ค๋ฅธ ํจํด
test = mydata.iloc[-10:,:]
test["realgdp_forecasted"] = forecast["realgdp_forecasted"]
test["realdpi_forecasted"] = forecast["realdpi_forecasted"]
test.plot()
'๐ฉโ๐ป ์ธ๊ณต์ง๋ฅ (ML & DL) > Serial Data' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๊ธฐ ์๊ด(AutoCorrelation)์ด ๊ฐํ ์๊ณ์ด ๋ฐ์ดํฐ ํ์ตํ๊ธฐ (1) | 2022.09.28 |
---|---|
์๊ณ์ด ๋ฐ์ดํฐ ๋ถ์ ์์ (Time Series Analysis Order) (0) | 2022.09.28 |
์๊ณ์ด ๋ฐ์ดํฐ(Serial data) ์ ์ฒ๋ฆฌ ํ๊ธฐ (2) (0) | 2022.09.27 |
์๊ณ์ด ๋ฐ์ดํฐ(Serial data) ์ ์ฒ๋ฆฌ ํ๊ธฐ (1) (0) | 2022.09.27 |
์ด์ ํ์ง์ ์๊ณ ๋ฆฌ์ฆ (Anomaly Detection Algorithm) (0) | 2022.09.27 |