[๋จธ์ ๋ฌ๋][์๊ณ์ด] AR, MA, ARMA, ARIMA์ ๋ชจ๋ ๊ฒ - ์ค์ตํธ
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/๋จธ์ ๋ฌ๋์๊ณ์ด-AR-MA-ARMA-ARIMA์-๋ชจ๋ -๊ฒ-์ค์ตํธ
๋ณธ ํฌ์คํ ์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์๊ณ์ด ๋ถ์์ ์ ๋ฐ์ ์ธ ํ๋ก์ธ์ค ๊ณผ์ ์ ๋ด๊ณ ์์ต๋๋ค. ๋ถ์ ํ์ด๋ ํผ๋๋ฐฑ์ ์ธ์ ๋ ํ์์ ๋๋ค!! ๐โโ๏ธ
๋ถ์์ ์์๋ ์๋์ ๊ฐ์ต๋๋ค. ํด๋น ๋ถ์์ ์์์ ๋ค๋ฃฌ ์๊ณ์ด ๊ฐ๋ ์ ๊ธฐ๋ฐ์ผ๋ก ๋ถ์์ ์ํํ ๊ฒ์ด๋ฏ๋ก ๊ฐ๋ ์ ์ฐพ์๋ณด๊ณ ์ถ๋ค๋ฉด ์ ์ด์ ํฌ์คํธ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
- ์ฐธ๊ณ
- ๋ฐ์ดํฐ ์ ์ ๋ฐ ์ ์ฒ๋ฆฌ
- ๋ฐ์ดํฐ์ ์ ์์ฑ(๋น์ ์) ํ๋ก์ธ์ค ํ๋ณ
- ์ฐจ๋ถ ์ํ ๋ฐ ์ ์์ฑ(๋น์ ์) ํ๋ก์ธ์ค ํ๋ณ
- ARIMA ๋ชจ๋ธ ์๋ณ ๋ฐ ์ถ์ ์ํ
- ๋ชจ๋ธ ํ๊ฐ
์ฐธ๊ณ (๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ๊ฐ์งํ)
๋ผ์ด๋ธ๋ฌ๋ฆฌ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
import statsmodels.api as sm
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima_model import ARIMA
from statsmodels.tsa.statespace.sarimax import SARIMAX
from pmdarima.arima import auto_arima
import math
import itertools
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use('seaborn-whitegrid')
ํ๊ฐ์งํ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from sklearn import metrics
def mae(y_true, y_pred):
return metrics.mean_absolute_error(y_true,y_pred) #MAE
def mse(y_true, y_pred):
return metrics.mean_squared_error(y_true,y_pred) # MSE
def rmse(y_true, y_pred):
return np.sqrt(metrics.mean_squared_error(y_true,y_pred)) # RMSE
def r2(y_true, y_pred):
return metrics.r2_score(y_true,y_pred) # R2
def mape(y_true, y_pred):
return np.mean(np.abs((y_pred - y_true) / y_true)) * 100 # MAPE
def get_score(model, y_true, y_pred):
model = model
mae_val = mae(y_true, y_pred)
mse_val = mse(y_true, y_pred)
rmse_val = rmse(y_true, y_pred)
r2_val = r2(y_true, y_pred)
mape_val = mape(y_true, y_pred)
score_dict = {"model": model,
"mae" : mae_val,
"mse" : mse_val,
"rmse" : rmse_val,
"r2": r2_val,
"mape" : mape_val
}
return score_dict
-
๋ฐ์ดํฐ ์ ์ ๋ฐ ์ ์ฒ๋ฆฌ
ํ๊ตญ๊ณตํญ๊ณต์ฌ, https://www.airport.co.kr/www/extra/stats/timeSeriesStats/layOut.do?menuId=399
์ด๋ฒ ๋ถ์์ ์ฌ์ฉ๋ ๋ฐ์ดํฐ๋ ํ๊ตญ๊ณตํญ๊ณต์ฌ์์ ์ ๊ณตํ๋ ๊ณตํญ๋ณ ์ด์ฉ๊ฐ ์ ์๊ณ์ด ๋ฐ์ดํฐ๋ก, 2002๋ 1์1์ผ๋ถํฐ 2020๋ 9์1์ผ๊น์ง ๋งค์ ์์ง๋ ์ด ์ฌ๊ฐ๊ธฐ ์ฌ์ฉ ๊ณ ๊ฐ์ ์์ ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ํ์ธํด๋ณธ ๊ฒฐ๊ณผ ์ฌ๊ฐ๊ธฐ๋ฅผ ์ด์ฉํ ๋ฐ์ดํฐ์ด๋ค ๋ณด๋ ์ต๊ทผ 2020๋ 2์๋ถํฐ ์ฌ๊ฐํด์ง ์ฝ๋ก๋ ์ฌํ๋ก ์ธํ์ฌ ๋ฐ์ดํฐ๊ฐ ์ฌ๊ฐํ๊ฒ ์๋์น๋ ๊ฒ์ ํ์ธํ์๊ณ , ์ธ๋ถ ์์ธ ์์ด ๋จ์ ARIMA ๋ชจ๋ธ๋ก๋ ์ฝ๋ก๋๋ผ๋ ์์ธ์ ๋ํ ์ ๋ณด๋ฅผ ํ์ตํ๊ธฐ ์ด๋ ค์ธ ๊ฒ ๊ฐ์ ๋ถ์ ๋ฐ์ดํฐ์ ๊ธฐ๊ฐ์ ์กฐ๊ธ ์กฐ์ ํ์ฌ ์ฝ๋ก๋ ์ฌํ๊ฐ ํฐ์ง๊ธฐ ์ด์ ์ธ 2020๋ 1์๊น์ง์ ๋ฐ์ดํฐ๋ง์ ์ฌ์ฉํ์ฌ ๋ถ์์ ์ํํ๋๋ก ์ ์ฒ๋ฆฌ๋ฅผ ์ํํด์ฃผ์์ต๋๋ค.
๋ํ ๋ชจ๋ธ ๊ตฌ์ถ ํ ์์ธก์ ๋ํ ํ๊ฐ๋ฅผ ์ํํ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ Train, Test Split์ ๋น์จ์ 8:2๋ก ๋์ด Train Dataset๊ณผ Test Dataset์ ๊ตฌ์ถํ์์ต๋๋ค.
-
๋ฐ์ดํฐ์ ์ ์์ฑ(๋น์ ์) ํ๋ก์ธ์ค ํ๋ณ
์๊ฐํ๋ฅผ ํตํ ํ๋จ
๋จผ์ , ๋ฐ์ดํฐ์ ์๋ฌด๋ฐ ๋ณํ๋ฅผ ์ฃผ์ง ์๊ณ , ์ด๋ฅผ ํ์ด์ฌ stats-models ๋ชจ๋์ time series analysis์ ๋ด์ฅ๋์ด ์๋ seasonal decomposition ํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ์์ ์ถ์ธ(Trend), ๊ณ์ (Seasonal), ์์ธก์ค์ฐจ(Residual)๋ฅผ ๋ถ๋ฆฌํด ๋ด์ด ์๊ฐํ๋ฅผ ์ํํ์์ต๋๋ค. ์ ๊ทธ๋ฆผ์ ์ข์ธก์ ๋ณด๋ฉด, ์์๋๋ก ๋ณธ๋ ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ๊ทธ๋ํ, ์ถ์ธ ๊ทธ๋ํ, ๊ณ์ ๊ทธ๋ํ, ์์ธก์ค์ฐจ ๊ทธ๋ํ๋ฅผ ์๋ฏธํฉ๋๋ค. ์ถ์ธ ๊ทธ๋ํ๋ฅผ ํตํด ๋ฐ์ดํฐ๊ฐ ์ฆ๊ฐํ๊ณ ์๊ณ , ๊ณ์ ๊ทธ๋ํ๋ฅผ ํตํด ๋ฐ์ดํฐ๊ฐ ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , ์์ธก์ค์ฐจ ๊ทธ๋ํ๋ฅผ ํตํด ํ๊ท ์ด 0์ด๊ณ ๋ถ์ฐ์ด ์ผ์ ํ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ทธ๋ํ๋ค์ ํตํด ํด๋น ๋ฐ์ดํฐ๊ฐ stationaryํ์ง ์๋ค๋ ๊ฒ์ ์๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
1
2
3
4
decompostion = sm.tsa.seasonal_decompose(data['customer'], model='additive')
fig = decompostion.plot()
fig.set_size_inches(10,10)
plt.show()
์ข ๋ ์์ธํ ๋ถ์์ ์ํ์ฌ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ , ACF, PACF๋ฅผ ๊ทธ๋ ค๋ณด์์ต๋๋ค. ACF์ PACF์ ๋ถํฌ๋ฅผ ํตํด stationary๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ํด๋น ๋ฐ์ดํฐ์ ACF positive autocorrelation์ ๊ฐ์ง๋ฉฐ ์์ํ ๊ฐ์ํ๋ ์์์ ๋๋ ๊ฒ์ผ๋ก ๋ณด์ non-stationaryํจ์ ์ถ์ ํ ์ ์์ต๋๋ค.
1
2
3
4
fig, ax = plt.subplots(1,2,figsize=(10,5))
fig.suptitle('Raw Data')
sm.graphics.tsa.plot_acf(train_data.values.squeeze(), lags=30, ax=ax[0])
sm.graphics.tsa.plot_pacf(train_data.values.squeeze(), lags=30, ax=ax[1]);
ํต๊ณ์ ๊ฒ์ ์ ํตํ ํ๋จ
์์ฅ์์๋ ๋ฐ์ดํฐ์ ๋น์ ์์ฑ์ ์๊ฐํ๋ฅผ ํตํด ํ์ธํด๋ณด๋ ์์ ์ ์ํํด๋ณด์์ต๋๋ค. ์ด๋ฒ ๋จ์์๋ ๋ฐ์ดํฐ์ ๋น์ ์์ฑ์ ํต๊ณ์ ์ผ๋ก ๊ฒ์ฆํด๋ณด๊ธฐ ์ํด Durbin Watson Test์ Dickey Fuller Test๋ฅผ ์ํํด๋ณด์์ต๋๋ค.
Durbin Watson Test
Durbin-Watson Test๋ฅผ ์ฌ์ฉํ์ฌ ํ๊ท ๋ชจํ์ ์ค์ฐจ์ ์๊ธฐ ์๊ด์ด ์๋์ง ๊ฒ์ ํ ์ ์์ต๋๋ค. ์๊ธฐ ์๊ด์ ์ธ์ ๊ด์ธก์น์ ์ค์ฐจ๊ฐ ์๊ด๋์ด ์์์ ์๋ฏธํฉ๋๋ค. Durbin-Watson Test์ ๊ท๋ฌด๊ฐ์ค(H0)์ โthe error terms are not autocorrelatedโ์ด๊ณ , ๋๋ฆฝ๊ฐ์ค(H1)์ โthe error terms are positively autocorrelatedโ์ ๋๋ค. ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ Durbin-Watson Test ๋ฅผ ์ํํ ๊ฒฐ๊ณผ ฯ๋ 1.10697๋ก 0๋ณด๋ค ํฌ๋ฏ๋ก ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ํด๋น ๋ฐ์ดํฐ๋ autocorrelation์ ๊ฐ์ง๊ณ ์๋ค๊ณ ํ ์ ์์ต๋๋ค.
Dickey Fuller Test
Dickey Fuller Test๋ฅผ ์ฌ์ฉํ์ฌ ์๊ณ์ด ๋ฐ์ดํฐ๊ฐ ์ ์์ฑ์ ๊ฐ์ง๋์ง ๊ฐ์ง์ง ์๋์ง๋ฅผ ํ์ธํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. Dickey Fuller Test ์ ๊ท๋ฌด๊ฐ์ค(H0)์ โํด๋น ๋ฐ์ดํฐ๋ ์ ์์ฑ์ ๊ฐ์ง์ง ์๋๋คโ์ด๊ณ , ๋๋ฆฝ๊ฐ์ค(H1)์ โํด๋น ๋ฐ์ดํฐ๋ ์ ์์ฑ์ ๊ฐ๋๋คโ์ ๋๋ค. Dickey Fuller Test ๋ฅผ ์ํํด๋ณด๋ฉด p-value๊ฐ 0.9884๋ก ์์ฃผ ๋๊ฒ ๋ํ๋ฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ์ง ๋ชปํ์ผ๋ฏ๋ก ๋ฐ์ดํฐ๋ ์ ์์ฑ์ ๊ฐ๋๋ค๊ณ ํ ์ ์์ต๋๋ค.
-
์ฐจ๋ถ ์ํ ๋ฐ ์ ์/๋น์ ์ ํ๋ณ
AR, MA, ARMA ๋ชจ๋ธ์ ์ ์ฉํ๊ธฐ ์ํด์๋ ๋ฐ์ดํฐ๊ฐ stationaryํด์ผ ํฉ๋๋ค. ์์์ ๋ดค๋ฏ์ด ์ค๋ฆฌ์ง๋ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๊ฐ stationaryํ์ง ์๊ธฐ์ ์ฐจ๋ถ(differencing) ์์ ์ด ํ์ํฉ๋๋ค. ๋ณธ ๋ถ์์์๋ 1์ฐจ ์ฐจ๋ถ(d=1)๊ณผ 2์ฐจ ์ฐจ๋ถ(d=2)์ ์ํํ์ฌ ์ ๊ทธ๋ํ๋ก ๋ํ๋์ต๋๋ค. ์ฐจ๋ถ ์์ ์ ํตํด ๊ธฐ์กด์ non-stationaryํ๋ ๋ฐ์ดํฐ๊ฐ stationaryํ๊ฒ ๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. ๊ฐ๊ฐ 1์ฐจ ์ฐจ๋ถ, 2์ฐจ ์ฐจ๋ถ์ ๋ํ์ฌ Dickey Fuller Test๋ฅผ ์ํํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋ ๋ค p-value๊ฐ์ด 0.05๋ณด๋ค ์์ผ๋ฏ๋ก ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ์ฌ ์ฐจ๋ถ๋ ๋ฐ์ดํฐ๋ stationaryํ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
1์ฐจ ์ฐจ๋ถ
1
2
3
4
diff_train_data = diff_train_data['customer'].diff()
print(diff_train_data.head())
diff_train_data = diff_train_data.dropna() #๊ฒฐ์ธก์น ์ ๊ฑฐ ์ฝ๋(๋ง์ง๋ง ๋ถ๋ถ ์ ๊ฑฐ)
print(diff_train_data.head())
2์ฐจ ์ฐจ๋ถ
1
2
3
4
5
diff2_train_data = diff_train_data.copy()
diff2_train_data = diff_train_data.diff()
print(diff2_train_data.head())
diff2_train_data = diff2_train_data.dropna() #๊ฒฐ์ธก์น ์ ๊ฑฐ ์ฝ๋(๋ง์ง๋ง ๋ถ๋ถ ์ ๊ฑฐ)
print(diff2_train_data.head())
-
ARIMA ๋ชจ๋ธ ์๋ณ ๋ฐ ์ถ์ ์ํ
ARIMA๋ โ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ โ โก ์๋ฒ์ ์ผ๋ก ํ์ธํด๋ณผ ๋ชจ๋ธ ๊ตฌ์ถ โ โข ํ๋ผ๋ฏธํฐ์ ์ถ์ (ํ์) โ โฃ ํ๋น์ฑ ํ์ธ โ โค ์ต์ข ๋ชจ๋ธ์ ์ ์ ํ๋ฆ์ผ๋ก ๋ถ์์ด ์งํ๋ฉ๋๋ค. ์์์ 1์ฐจ ์ฐจ๋ถ, 2์ฐจ ์ฐจ๋ถ ๋ ๋ค p-value๊ฐ 0.05๋ณด๋ค ์์ ๊ท๋ฌด๊ฐ์ค์ ๊ธฐ๊ฐํ๋ฏ๋ก, 1์ฐจ ์ฐจ๋ถํ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ๋ถ์์ ์ํํด๋ณด์์ต๋๋ค. ์ผ๋จ ํ์ฌ๊น์ง โ ๋จ๊ณ์ธ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๋ ์๋ฃ๋์๊ณ , โก๋จ๊ณ์ธ ์๋ฒ์ ์ผ๋ก ํ์ธํด๋ณผ ๋ชจ๋ธ ๊ตฌ์ถํ๊ธฐ ์ํด 1์ฐจ ์ฐจ๋ถ๋ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ACF์ PACF๋ฅผ ์๊ฐํํ์์ต๋๋ค.
์ด๋ฅผ ํ์ธํด๋ณธ ๊ฒฐ๊ณผ ACF์ PACF๊ฐ ์ง์์ ์ผ๋ก ๊ฐ์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์๊ณ , cut off์ ๊ฒฝ์ฐ๋ ๋ช ํํ๊ฒ ๋์ค์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. ์ด์ ์๋ ํ๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ ์ฉํ์ฌ (p,d,q)๋ฅผ (0,1,1)๋ก ํ๋ ARIMA๋ชจ๋ธ์ ์๋ฒ์ ์ผ๋ก ๊ตฌ์ถํด๋ณด์์ต๋๋ค.
(p,d,q)๋ฅผ (0,1,1)๋ก ํ๋ ์๋ฒ ARIMA๋ชจ๋ธ์ ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ตฌ์ถ๋ ๋ชจ๋ธ์ AIC๋ก 4767.825๋ฅผ ๊ฐ๊ณ , ๊ฐ๊ฐ์ constraint์ ๋ณ์์ p-value๋ 0.05๋ณด๋ค ์์ ํต๊ณ์ ์ผ๋ก ์ ์๋ฏธํ ๊ฐ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
1
2
3
4
5
6
# ARIMA model fitting
# p =1 , ์ฐจ๋ถ = 1, moving average = 0
model = ARIMA(train_data.values, order=(0,1,1))
model_fit = model.fit()
model_fit.summary()
๋ณธ๊ฒฉ์ ์ผ๋ก ๊ฐ์ฅ ์ ํฉํ parameter search๋ฅผ ์ํด ๊ฐ๊ฐ d๋ 1๋ก ๊ณ ์ (1์ฐจ ์ฐจ๋ถ)ํ๊ณ , p, q์ ๋ํ์ฌ grid search๋ฅผ ์ํํ์์ต๋๋ค. (p,q)๋ ๊ฐ๊ฐ 0์์ 5๊น์ง์ 6๊ฐ์ ์ซ์ ์กฐํฉ์ผ๋ก ์ด 36๊ฐ์ง ์กฐํฉ์ผ๋ก ์ต์ ์ ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ํด๋ณด์์ต๋๋ค. (ARIMA ์ถ๋ ฅ๋ฌผ์ ์ผ๋ถ ์๋ต)
1
2
3
4
5
6
7
8
9
10
# Parameter search
auto_arima_model = auto_arima(train_data,
start_p=0, max_p=5,
start_q=0, max_q=5,
seasonal=False,
d=1,
trace=True,
error_action='ignore',
suppress_warnings=True,
stepwise=False)
์ต์ ์ ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ด ํ์ํด๋ณธ ๊ฒฐ๊ณผ, p = 4, d =1, q = 0 ์ผ ๋ AIC๊ฐ ๊ฐ์ฅ ์๊ฒ ๋์ค๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. (4,1,0)์ผ๋ก ๊ตฌ์ถ๋ ๋ชจ๋ธ์ AIC๋ 4749.253๋ก, ์ด์ ๋จ๊ณ์์ ์๋ฒ์ ์ผ๋ก ๋ง๋ค์ด์ง ๋ชจ๋ธ๋ณด๋ค ์์ AIC๊ฐ์ ๊ฐ์ต๋๋ค. ๊ฐ๊ฐ์ constraint์ ๋ณ์๋ค์ p-value๋ 0.05๋ณด๋ค ์์ ํต๊ณ์ ์ผ๋ก ์ ์๋ฏธํ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
-
๋ชจ๋ธ ํ๊ฐ
์์์ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ํํธ์์ ์ธ๊ธํ์ง๋ง, ํด๋น ๋ฐ์ดํฐ๋ฅผ 8:2 ๋น์จ๋ก train๊ณผ test๋ก ๋๋์ด train ๋ฐ์ดํฐ๋ ๋ชจ๋ธ ํ์ต ๋ฐ hyper parameter tuning์ ์ฌ์ฉ์ ํ์๊ณ , ๋๋จธ์ง test data๋ ์์ธก ํ ๋ชจ๋ธ ์ฑ๋ฅ์ ํ๊ฐํ๊ธฐ ์ํด ๋จ๊ฒจ๋์์ต๋๋ค. ๋ค์์ ์ง๊ธ ๊ตฌ์ถํ ๋ชจ๋ธ์ ๋ํ test ๊ธฐ๊ฐ์ ๋ํ ์์ธก์ ์ํํ๊ณ ์ด์ ๋ํ ํ๊ฐํด ๋ณด์์ต๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pandas import Timestamp
%matplotlib inline
# set index
true_index = list(data.index)
predict_index = list(test_data.index)
# make array of true value
true_value = np.array(list(data['customer']))
# plot
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(true_index, true_value, label = 'True')
ax.plot(predict_index, pred, label = 'Prediction')
ax.vlines(Timestamp('2017-01-01 00:00:00'), 0, 100, linestyle='--', color='r', label='Start of Forecast');
ax.fill_between(predict_index, predicted_lb, predicted_ub, color = 'k', alpha = 0.1, label='0.95 Prediction Interval')
ax.legend(loc='upper left')
plt.show()
2002๋ 01์๋ถํฐ 2016๋ 12์๊น์ง์ ๋ฐ์ดํฐ๋ก ํ์ตํ ARIMA(4,1,0) ๋ชจ๋ธ์ ํตํด 2017๋ 1์๋ถํฐ 2020๋ 1์๊น์ง์ ๊ธฐ๊ฐ์ ์ฌ๊ฐ๊ธฐ ์ด์ฉ์์๋ฅผ ์์ธกํ๊ณ ์์ ๊ทธ๋ํ๋ฅผ ๊ทธ๋ ธ์ต๋๋ค. ARIMA ๋ชจ๋ธ์ Trend๋ฅผ ์ ๋ฐ์ํ์ฌ ์์ธก์ ํ๋ ๊ฒ์ ํ์ธํ ์ ์๊ณ , ๊ณ์ ์ฑ์ด ๋ฐ์๋์ง ์์๊ฒ ๋๋ฌธ์ seasonal cycle์ ์ ์์ธกํด๋ด์ง ๋ชปํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ํ์ง๋ง 95% ์ ๋ขฐ๊ตฌ๊ฐ์์ ๋๋ถ๋ถ์ ์์ธก ๊ฐ๋ค์ด ์ ๋ค์ด์ค๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฅผ ๋ค์ performance metric๋ค์ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ ์ฑ๋ฅ์ ํ๊ฐํด๋ณด์์ต๋๋ค. ๋ํ ์ด๋ฅผ ์์ธก๊ฐ๊ณผ ์ค์ ๊ฐ์ residual์ด ์ ๊ท์ฑ์ ๋๊ณ , autocorrelation์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ธด ๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค^~^