Code
๐ github.com/hayannn/AIFFEL_MAIN_QUEST/MiniProject4
ํ๋ก์ ํธ ๋ชฉํ
Objective 1
- ARIMA๋ฅผ ํตํ ์๊ณ์ด ์์ธก ์ํ
Objective 2
- ARCH๋ฅผ ํตํ S&P500์ ๋ณ๋์ฑ ๋ชจ๋ธ๋ง ์ํ
์์ ์ ๋ฆฌ
- arch & pmdarima ์ค์น
- ARIMA
- ์ฌ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ import
- ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ & ํํ ํ์ธ
- ๋ถ์ฐ์ ์ผ์ ํ๊ฒ ๋ง๋ค๊ธฐ - log transformation
- ์ฐจ๋ถ ํ ๋ถ์
- ARIMA ์ ์ฉ
- Auto ARIMA ์ ์ฉ
- ๊ฒฐ๊ณผ ๋ถ์
- ์๊ฐํ
- ARCH
- ๋ฐ์ดํฐ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ
- ๋ฐ์ดํฐ ๊ฐ๊ณต ๋ฐ ์๊ฐํ
- ARCH ์ ํฉ
- ๊ฒฐ๊ณผ ๋ถ์
- ์๊ฐํ
- ํ๊ณ
arch & pmdarima ์ค์น
ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
!pip install arch==6.3.0
!pip install pmdarima
ARIMA
์ฌ์ฉํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ import
statsmodels.graphics.tsaplots
์ plot_acf, plot_pacf
statsmodels.tsa.arima_model
์ ARIMA
pmdarima
: Auto ARIMA ๋ชจ๋ธ
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima_model import ARIMA
import pmdarima as pm
๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ & ํํ ํ์ธ
- ๋ฐ์ดํฐ์
:
AirPassengers
ap = pd.read_csv('/content/drive/MyDrive/แแ
ตแแ
จแแ
งแฏ/AirPassengers.csv')
ap
ap.drop('Month', axis = 1, inplace = True)
ap
- ๋ฐ์ดํฐ ํํ ํ์ธ
- ๋ถ์ฐ ์ผ์ ํ์ง ์์
- ์์น ์ถ์ธ
- ๋น์ ์ ๋ฐ์ดํฐ๋ก ๋ถ๋ฅํด์ผ ํจ
plt.plot(ap)
plt.show()
ap_transformed = np.log(ap)
ap_transformed
- ACF plot, PACF plot์ผ๋ก ์๊ฐํํด ํ์ธ
- ๊ธธ์ด๊ฐ ๊ธธ์๋ก ์ ์๋ฏธํจ์ ์๋ฏธ
- ACF plot : ์ ์ฐจ ๊ฐ์ํ๋ ํํ
- PACF plot : lag 2๊น์ง๋ ์ ์๋ฏธํจ์ ๋ฐ๊ฒฌํ ์ ์์
๋ฐ์ดํฐ ์์ฒด๊ฐ ์์ง ์ฆ๊ฐ ์ถ์ธ๋ฅผ ๊ฐ์ง๊ณ ์์
- ACF, PACF ๋ชจ๋ ๋น์ทํ ํํ๋ฅผ ๋๊ณ ์๋ค๊ณ ๋ด๋ ๋ฌด๋ฐฉ
- ๋ ์ ํฉํ๋ ค๋ฉด ์ฐจ๋ถ ์งํ์ด ํ์ํจ
์ฐจ๋ถ ํ ๋ถ์
- ์ฐจ๋ถ์ผ๋ก ์ถ์ธ ์ ๊ฑฐํ๊ธฐ
ap_diff = ap_transformed.diff()
ap_diff = ap_diff.dropna()
- ์๊ฐํ
- lag ๊ฐ์ ๋ ๋ช
ํํ ๋ณด๊ธฐ ์ํด 1 ๋จ์๋ก x์ถ ์กฐ์
- lag 0์ ์๊ธฐ ์์ ์ด๋ ์ ์ธ
- ACF plot
- lag 1, lag 12 ์ ๋๊ฐ ์ ์๋ฏธํ๋ค๊ณ ํ๋จํด๋ณผ ์ ์์
plot_acf(ap_diff)
plt.xticks(range(0, len(ap_diff), 1))
plt.plot();
- PACF plot
- lag 1, lag 8~12 ์ ๋๊ฐ ์ ์๋ฏธ
plot_pacf(ap_diff)
plt.xticks(range(0, len(ap_diff), 1))
plt.plot();
๊ทธ๋ํ๊ฐ ์์ ๊ฒฐ๊ณผ๊ฐ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ์ถ๋ ฅ๋จ
- statsmodels์ ๋ฒ์ ์ฐจ์ด๋ก Default ๊ฐ์ด ๋ฌ๋ผ์ ธ ๋ฐ์ํ ๋ฌธ์
- LMS : 0.13.0
- ์ฝ๋ฉ : 0.14.4
- ํด๊ฒฐ : 0.13.0์์ ์ฌ์ฉํ๋ Default๋ฅผ ๋ช
์ํด์ ๋ค์ ๊ทธ๋ํ ์ถ๋ ฅ
plot_pacf(ap_diff, method='yw', alpha=0.05)
plt.xticks(range(0, len(ap_diff), 1))
plt.plot();
์ด ์์ ์์ ์ ์ ์๋ ๊ฒ์?
- ACF, PACF ๋ชจ๋ 12์์ ๊ฐ์ฅ ์ ์๋ฏธํ ์๊ด ๊ด๊ณ๊ฐ ๋ณด์
- ๊ณ์ ์ฑ ์ฑ๋ถ์ผ๋ก ์ถ์ธก
- Auto ARIMA ์ ์ฉ ์, ์ด๋ฌํ ๊ณ์ ์ฑ ์ฑ๋ถ์ ๊ณ ๋ คํด์ผํ๋, ์ด ๊ฐ ์์ฒด๋ฅผ ์ ์๋ฏธํ๊ฒ ๋ณด์ง ์๋๋ค๋ฉด ๊ทธ ์์ฒด๋ก ์ ์๋ฏธํ์ง ์๊ฒ ๋ ์๋ ์์์ ์ธ์งํ๊ณ ์์ด์ผ ํจ
โ๏ธ ์๋ฌธ์
- ACF์ PACF์ ์ ์๋ฏธํ๋ค๋ ๊ธฐ์ค์ด ๋ชจํธํ ๋ฌธ์
- "์์ ๋ถ๋ถ์ ์ ์๋ฏธํ์ง ์์ ๋ณ์์ธ๊ฑด์ง?"
- ๊ฐ์์์๋ ACF์ ์์ ๋ถ๋ถ์ ๋ฐฐ์ ํ๊ธฐ ๋๋ฌธ์ ๊ถ๊ธํด์ง
- lag 4, 8๋ ์ ์๋ฏธํ๋ค๊ณ ๋ณผ ์ ์๋๊ฒ ์๋๊ฐ?
- PACF์ ๊ฒฝ์ฐ, ์์๊ฐ์ ํฌํจํด ์ ์๋ฏธํ ๊ฒ์ผ๋ก ํ๋ณํด์ ๋ ํผ๋ ๊ฐ์ค
- ํ์ฌ๋ก์์ ๊ฐ์ : D๊ฐ์ 12๋ก ์ง์ ํด์ ์งํํ๊ธฐ ์ํด ์ฆ, ACF์ PACF๊ฐ ํจ๊ป ์ต๋๋ก ์ ์๋ฏธํ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์ก๊ธฐ ์ํด ์์ ์ง์ ํ ๊ฒ์ผ๋ก ํ๋จ
ARIMA ์ ์ฉ
- ๋ก๊ทธ ๋ณํํ
ap_transformed
์ฌ์ฉ
- test ๋ฐ์ดํฐ ๋ถ๋ฆฌ(20% ์ ๋ ์๋ฅด๊ณ , 80%๋ง ์ ํฉ)
train_size = int(len(ap_transformed)*0.8)
ap_transformed_train = ap_transformed[:train_size]
ap_transformed_test = ap_transformed[train_size:]
Auto ARIMA ์ฌ์ฉํ์ฌ ํ๋ จ
seasonal
: False๋ผ๋ฉด -> non-seasonal model๋ก ์ ํ
suppress_warnings
: ์๋ฌ ๋ฌธ๊ตฌ ignore
trace
: True์ผ ๊ฒฝ์ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด -> ๊ทธ ์ผ๋ถ ๋ด์ฉ ์ถ๋ ฅ
max_D
: seasonal ์ต๋๊ฐ ์ค์ ๊ฐ๋ฅ
model = pm.AutoARIMA(seasonal = True, suppress_warnings = True, trace = True, max_D = 12, D = 12)
res = model.fit(ap_transformed_train)
์ ํฉ ํ๋ผ๋ฏธํฐ : ARIMA(5,1,2)
๊ฒฐ๊ณผ ๋ถ์
- (5,1,2)์ AIC : -219.339
- ๋ค๋ฅธ ๊ฒฝ์ฐ๋ณด๋ค, ๊ฐ์ฅ ๋ฎ๊ฒ ์ธก์ ๋จ
- Time : 0.68s
- ์๊ฐ์ด ์ง๋์น๊ฒ ๋ง์ด ์์ or ๋ชจ๋ธ ๋ณต์ก์ฑ์ด ๋์์ง๋ฉด โก๏ธ ๊ณ์ฐ ๋นํจ์จ์ฑ ๋์์ง
- ๊ณผ์ ํฉ ๋ฐฉ์ง๋ฅผ ์ํ ์ ๋นํ ๊ฐ ์ ์ ์ด ํ์ํจ
- confidence interval๊น์ง ๋์ถ
preds, conf_int = res.predict(n_periods=ap_transformed_test.shape[0], return_conf_int=True)
- ๊ฒฐ๊ณผ
preds
: ๋ชจ๋ธ ์์ธก ๊ฐ
- 29 : ์์ธก๊ฐ ๊ฐ์
- pandas์ Series ๊ฐ์ฒด
conf_int
: ์์ธก๊ฐ์ ๋ํ ์ ๋ขฐ ๊ตฌ๊ฐ
print(preds.shape)
print(type(preds))
print('--'*40)
print(preds.shape[0])
print(type(preds.shape[0]))
print('--'*40)
print(preds)
print('--'*40)
print(conf_int)
์๊ฐํ
- ํ๋์ : ๊ธฐ์กด train ๋ฐ์ดํฐ
- ์ ๋ถ๋ถ : ์๋ ๊ฐ์ง๊ณ ์๋ y๊ฐ
- ์ ์ถ์ , ๊ตฌ๊ฐ ์ถ์ ๋ชจ๋ ์ถ๋ ฅ
- ์ฃผํฉ์ : ARIMA 1, 2, 3์ด ์์ธกํ ๋ถ๋ถ โก๏ธ ์ถ์ธ ๋ฐ์์ ์ํ๊ณ ์์!
x_axis = np.arange(ap_transformed_train.shape[0] + ap_transformed_test.shape[0])
plt.plot(x_axis[:ap_transformed_train.shape[0]], ap_transformed_train, alpha=0.75)
plt.plot(x_axis[ap_transformed_train.shape[0]:], preds, alpha=0.75)
plt.scatter(x_axis[ap_transformed_train.shape[0]:], ap_transformed_test, alpha=0.4, marker='o')
plt.fill_between(x_axis[-preds.shape[0]:], conf_int[:, 0], conf_int[:, 1], color='b', alpha=0.1)
plt.title("Log Transformed Air Passengers Forecast")
plt.show()
ARCH
๋ฐ์ดํฐ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ
- datetime : ๋ ์ง ๋ฐ ์๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- arch.data.sp500 : S&P 500 ๋ฐ์ดํฐ์
์ arch์์ ๋ถ๋ฌ์ฌ ์ ์์
import datetime as dt
import arch.data.sp500
๋ฐ์ดํฐ ๊ฐ๊ณต ๋ฐ ์๊ฐํ
- ์์ ๋ ์ง : 2002-01-01
- ๋ ๋ ์ง : 2022-01-01
- ๊ธฐ์ค : ์ข
๊ฐ(Adj Close)
st = dt.datetime(2002, 1, 1)
en = dt.datetime(2022, 1, 1)
data = arch.data.sp500.load()
market = data["Adj Close"]
returns = 100 * market.pct_change().dropna()
- Return(์์ต๋ฅ )์ ๊ทธ๋ํ๋ก ์๊ฐํ
ax = returns.plot()
xlim = ax.set_xlim(returns.index.min(), returns.index.max())
plt.show()
- ์กฐ๊ฑด๋ถ ์ด๋ถ์ฐ์ฑ ๋ฐ๊ฒฌ
- ๋
๋ฆฝ๋ณ์ ์ค์ฐจํญ์ด ์๊ด๊ด๊ณ๊ฐ ์๋ ๊ฒฝ์ฐ
- 2008๋
์ฆ์์ธ ๊ฒ์ผ๋ก ๋ณด์, ๊ธ์ต ์๊ธฐ ๋น์๋ก ์ถ์ธก
- 2007~2008๋
: ๋ฏธ๊ตญ์์์ ๋ถ๋์ฐ ๋ฒ๋ธ ๋ถ๊ดด๋ก ์ธ๊ณ ๊ธ์ต ์๊ธฐ ์ด๋๋์์
ARCH ์ ํฉ
- Return์ ARCH ๋ชจ๋ธ์ ์ ํฉ
- summary ํ์ธ(p-value, AIC, BIC ์ค์ฌ์ผ๋ก ๋ถ์)
from arch import arch_model
am = arch_model(returns)
res = am.fit(update_freq=5)
print(res.summary())
๊ฒฐ๊ณผ ๋ถ์
p-value
- 9.302e-07 โก๏ธ
0.0000009302
๊ฐ๋์ ์์น, ์์ฃผ ์์ ์์น์ ํด๋นํ๊ธฐ ๋๋ฌธ์ ํต๊ณ์ ์ผ๋ก ์ ์๋ฏธ
AIC
13881.4
โก๏ธ ๊ฐ์ด ์์์๋ก ์ข์ ๋ชจ๋ธ ์๋ฏธ, ์์น ์์ฒด๋ง์ผ๋ก ๋ดค์ ๊ฒฝ์ฐ์๋ ๋ค์ ๋์
BIC
13907.5
โก๏ธ ๊ฐ์ด ์์์๋ก ์ข์ ๋ชจ๋ธ ์๋ฏธ, ์์น ์์ฒด๋ง์ผ๋ก ๋ดค์ ๊ฒฝ์ฐ์๋ ๋ค์ ๋์
Volatility Model ํด์
-
omega
- p-value : 1.854e-04(0.0001854)
- ํต๊ณ์ ์ผ๋ก ์ ์๋ฏธ
-
alpha[1]
- arch๋ฅผ ํตํด ์์๋ผ ์ ์๋ ํ๋ผ๋ฏธํฐ ๊ฐ
- p-value : 4.105e-15(0.000000000000004105)
- ํต๊ณ์ ์ผ๋ก ์ ์๋ฏธ
-
beta[1]
- arch๋ฅผ ์ ์ธํ garch์์๋ง ๋ํ๋๋ ํ๋ผ๋ฏธํฐ ๊ฐ
- p-value: 0.000
- ํต๊ณ์ ์ผ๋ก ์์ฃผ ์ ์๋ฏธ
-
์ฆ, alpha[1], Beta[1]๊ฐ GARCH(1,1)์ ์๋ฏธ
-
p-value๋ฅผ ํตํด ์ ๋ขฐ๋ 95%์์ ์ด๋ค์ด ์ ์๋ฏธํ๋ค๊ณ ๊ฒฐ๋ก ๋ด๋ฆด ์ ์์
์๊ฐํ
- ๋ชจ๋ธ ์ ํฉ ํ ๋จ์ ๋๋จธ์ง ์ ์
- ์์ธกํ ์กฐ๊ฑด๋ถ ๋ถ์ฐ ๊ฐ ํ์ธ ๊ฐ๋ฅ
res.plot()
- Standardized Residuals
- ๋๋ ทํ ์กฐ๊ฑด๋ถ ์ด๋ถ์ฐ์ฑ์ ๋ณด์ฌ์ฃผ๋ ๋ถ๋ถ์ด ์ฌ๋ผ์ ธ โก๏ธ ๋ชจ๋ธ ์ ํฉ์ด ์ ๋์์์ ์ ์ ์์
ํ๊ณ
- ์ ์ฒด์ ์ผ๋ก ์ด๋ ค์ด ์์ค์ ์๋์์ผ๋, ACF ๋ฐ PACF์ ์ ์๋ฏธํ๋ค๋ ๊ธฐ์ค ์์ฒด๊ฐ ์ ๋งคํ๊ฒ ๋๊ปด์ ธ์ ํ๋จ์ ์ด๋ ค์์ด ์์์
- ๊ฐ์์์์ ๋ด์ฉ์ด ๋ค์ ์ผ๊ด์ ์ด์ง ๋ชปํ๋ค๋ ์๊ฐ
- ์ ๋ฐ์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ํด์ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์ง ๋ฏธ์ํ๋ค๋ ์๊ฐ์ด ๋ค์์
- ํต๊ณ์ ์ธ ์ด์ ๋ฅผ ์ฐพ์์ผํ๋ ๋ชจ๋ธ์ ํน์ฑ์, ํต๊ณ์ ์ธ ์ง์์ด ์์ฃผ ๋ง์ด ํ์ํ๊ณ ๊ทธ๊ฒ์ ๊ธฐ์ค์ผ๋ก ๋ชจ๋ธ ์ ํฉ์ฑ์ ๋ฐ์ ธ๋ณด๋ ์ฐ์ต์ด ์์ฃผ ๋ง์ด ํ์ํ๋ค๊ณ ๋๋