지수 평활 :: 시계열 분석 - mindscale
Skip to content

지수 평활

이번 시간에는 지수평활이라는 기법에 대해서 알아보도록 하겠습니다

평활(smoothing)은 시계열 그래프를 매끄럽게 그린다는 뜻입니다. 이동 평균이랑 좀 비슷한 아이디어인데 이동 평균은 어떤 구간이 있으면 이 구간의 모든 값을 다 평균 내는 이런 방식이죠. 12달 이동 평균을 한다 그러면 12달 전에 데이터하고 이번 달 거하고 똑같이 12분의 1씩 반영이 된다는 얘기입니다. 좀 불합리하다고 할 수 있죠.

지수평활은 가까운 일에는 많이, 먼 과거의 일은 적게 반영하는 방식으로 평활을 합니다. 이렇게 하면 시간이 갈수록 현재의 평활된 값에 미치는 영향은 지수적으로 감소하게 됩니다.

호주 관광객 데이터

우리가 실습해볼 데이터는 호주 관광객 데이터입니다.

import pandas as pd
df = pd.read_excel('ausvisitor.xlsx')
y = df.visitor

이 데이터에서 df.visitor를 지수 평활해서 그려보겠습니다. $\alpha = 0.1$로 설정합니다. 이것은 직전의 평활치 90% 반영하고, 현재 값에 10%를 반영하여 새로운 평활치를 계산하는 방식입니다.

y.plot()
y.ewm(alpha=0.1).mean().plot();

단순 지수 평활: ETS(A, N, N)

ETS 모형은 오차(Error), 추세(Trend), 계절성(Seasonality)으로 구성된 모형입니다. 이 모형은 각각의 형태에 따라 다양한 모형으로 나눠집니다.

ETS(A, N, N)은 덧셈(Additive) 오차를 가지고 추세와 계절성은 가지지 않는 모형으로 단순 지수 평활과 동일한 모형입니다.

이 모형은 ETSModel 함수로 추정할 수 있습니다. initial_level은 초기값, smoothing_level이 $\alpha$가 됩니다.

from statsmodels.tsa.api import ETSModel
ets_ann = ETSModel(y).fit()
ets_ann.summary()
ETS Results
Dep. Variable: visitor No. Observations: 68
Model: ETS(ANN) Log Likelihood -240.535
Date: Sun, 28 May 2023 AIC 487.070
Time: 16:05:13 BIC 493.729
Sample: 0 HQIC 489.709
- 68 Scale 69.178
Covariance Type: approx
coef std err z P>|z| [0.025 0.975]
smoothing_level 0.1964 0.048 4.101 0.000 0.103 0.290
initial_level 27.5115 4.976 5.529 0.000 17.758 37.265
Ljung-Box (Q): 10.91 Jarque-Bera (JB): 1.20
Prob(Q): 0.00 Prob(JB): 0.55
Heteroskedasticity (H): 2.57 Skew: -0.00
Prob(H) (two-sided): 0.03 Kurtosis: 2.35




Warnings:

[1] Covariance matrix calculated using numerical (complex-step) differentiation.

predict 함수에다가 start는 0, end는 100 하면 여기서부터 0부터 100까지 예측을 하게 됩니다.

실제 데이터가 있는 곳까지는 실제 데이터를 바탕으로 에러를 포함해서 평활하게 되고, 그곳을 넘어가면 에러가 없기 때문에 옆으로 주욱 가게 됩니다.

import matplotlib.pyplot as plt
y.plot(label='y')
ets_ann.predict(start=0, end=100).plot(label='ETS(A, N, N)')
plt.legend();

홀트 선형 추세 기법: ETS(A, A, N)

그 다음에 홀트의 선형 추세 기법이라고 하는 기법이 있는데요. 이 기법은 ETS(A, A, N)과 같습니다. 이 모형은 덧셈 오차와 덧셈 추세가 있는 모형입니다.

이 모형은 ETSModel에서 trend=add라고만 넣어서 추정할 수 있습니다.

from statsmodels.tsa.api import ETSModel
ets_aan = ETSModel(y, trend='add').fit()
ets_aan.summary()
ETS Results
Dep. Variable: visitor No. Observations: 68
Model: ETS(AAN) Log Likelihood -231.928
Date: Sun, 28 May 2023 AIC 473.856
Time: 13:13:08 BIC 484.954
Sample: 0 HQIC 478.254
- 68 Scale 53.707
Covariance Type: approx
coef std err z P>|z| [0.025 0.975]
smoothing_level 0.0097 nan nan nan nan nan
smoothing_trend 0.0097 0.006 1.680 0.093 -0.002 0.021
initial_level 25.1272 1.738 14.461 0.000 21.722 28.533
initial_trend 0.1841 0.169 1.089 0.276 -0.147 0.516
Ljung-Box (Q): 11.15 Jarque-Bera (JB): 0.85
Prob(Q): 0.00 Prob(JB): 0.65
Heteroskedasticity (H): 2.53 Skew: 0.01
Prob(H) (two-sided): 0.03 Kurtosis: 2.45




Warnings:

[1] Covariance matrix calculated using numerical (complex-step) differentiation.
y.plot(label='y')
ets_aan.predict(start=0, end=100).plot(label='ETS(A, A, N)')
plt.legend();

감쇠 추세 기법: ETS(A, Ad, N)

홀트의 선형 기법은 현재 추세가 영원히 계속된다는 가정이 있습니다. 이것을 바꾼 것이 감쇠 추세 기법입니다. 이 기법은 추세가 점점 꺾인다는 가정이 있습니다. 추정을 할 때는 damped_trend=True라고 설정해주시면 됩니다.

ets_aadn = ETSModel(y, trend='add', damped_trend=True).fit()
ets_aadn.summary()
ETS Results
Dep. Variable: visitor No. Observations: 68
Model: ETS(AAdN) Log Likelihood -232.737
Date: Sun, 28 May 2023 AIC 477.473
Time: 16:13:15 BIC 490.790
Sample: 0 HQIC 482.750
- 68 Scale 54.999
Covariance Type: approx
coef std err z P>|z| [0.025 0.975]
smoothing_level 0.0164 0.089 0.185 0.853 -0.158 0.191
smoothing_trend 0.0164 0.023 0.730 0.466 -0.028 0.061
damping_trend 0.9800 0.069 14.112 0.000 0.844 1.116
initial_level 26.2533 3.205 8.192 0.000 19.972 32.535
initial_trend 0.1244 0.318 0.392 0.695 -0.498 0.747
Ljung-Box (Q): 10.90 Jarque-Bera (JB): 0.91
Prob(Q): 0.00 Prob(JB): 0.63
Heteroskedasticity (H): 2.59 Skew: 0.02
Prob(H) (two-sided): 0.03 Kurtosis: 2.43




Warnings:

[1] Covariance matrix calculated using numerical (complex-step) differentiation.
y.plot(label='y')
ets_aadn.predict(start=0, end=100).plot(label='ETS(A, Ad, N)')
plt.legend();

홀트-윈터스 계절성 기법: ETS(A, A, A)

ETS(A,A,A)는 계절성도 덧셈 형태로 추가되는 모형입니다. 추정을 할 때는 seasonal='add'로 해주고, 계절성의 주기를 입력해줍니다. 4분기 단위의 계절성이 있으므로 seasonal_periods=4로 설정해줍니다.

from statsmodels.tsa.api import ETSModel
ets_aaa = ETSModel(y, trend='add', seasonal='add', 
                   seasonal_periods=4).fit()
ets_aaa.summary()
ETS Results
Dep. Variable: visitor No. Observations: 68
Model: ETS(AAA) Log Likelihood -150.480
Date: Sun, 28 May 2023 AIC 320.960
Time: 13:13:52 BIC 343.155
Sample: 0 HQIC 329.754
- 68 Scale 4.894
Covariance Type: approx
coef std err z P>|z| [0.025 0.975]
smoothing_level 0.3042 0.099 3.075 0.002 0.110 0.498
smoothing_trend 3.042e-05 nan nan nan nan nan
smoothing_seasonal 0.4154 0.082 5.057 0.000 0.254 0.576
initial_level 29.4939 nan nan nan nan nan
initial_trend 0.5711 0.113 5.076 0.000 0.351 0.792
initial_seasonal.0 -3.4686 nan nan nan nan nan
initial_seasonal.1 -5.9855 nan nan nan nan nan
initial_seasonal.2 -11.4778 nan nan nan nan nan
initial_seasonal.3 0 nan nan nan nan nan
Ljung-Box (Q): 5.11 Jarque-Bera (JB): 8.62
Prob(Q): 0.75 Prob(JB): 0.01
Heteroskedasticity (H): 0.48 Skew: -0.68
Prob(H) (two-sided): 0.08 Kurtosis: 4.10




Warnings:

[1] Covariance matrix calculated using numerical (complex-step) differentiation.
y.plot(label='y')
ets_aaa.predict(start=0, end=100).plot(label='ETS(A, A, A)')
plt.legend();