작성자: admin 작성일시: 2016-04-22 15:48:16 조회수: 1398 다운로드: 145
카테고리: 시계열 분석 태그목록: 추세

결정론적 추세 추정

추세

확률 과정의 기대값이 시간 $t$에 대한 함수로 표현될 수 있으면 이를 추세(trend)라고 한다.

$$ \mu_t = \text{E}[Y_t] = f(t) $$

보통은 추세 함수 $f(t)$가 상수가 아니라 $t$에 따라 변화하는 경우, 추세를 가진다고 말한다. 이 추세는 확률 변수가 아닌 함수로 표현할 수 있기 때문에 결정론적 추세(deterministic trend)라고도 한다.

다음 시계열들은 모두 추세를 가지는 확률 과정의 샘플이다.

In:
np.random.seed(0)
t = np.arange(20)
x = 2 * t + sp.stats.norm.rvs(size=20)
plt.plot(t, x, 'o-')
plt.show()
In:
np.random.seed(0)
t = np.arange(20)
x = -5 * np.sin(0.25 * np.pi * t) + sp.stats.norm.rvs(size=20)
plt.plot(t, x, 'o-')
plt.show()

다시 말하지만 확률 과정의 기댓값은 앙상블(Ensemble) 개념이므로 앞으로 이야기할 정상 가정과 에르고딕 가정이 없다면 하나의 샘플에서 추세가 있다고 판단하거나 추세를 추정하는 것은 원리적으로 불가능하다. 이러한 가정 없이 추세를 추정하기 위해서는 다음과 같이 복수개의 시계열 자료 샘플이 있어야 한다.

In:
np.random.seed(0)
t = np.arange(20)
y = np.zeros((30, 20))
for i in range(30):
    y[i,:] = t + 3 * sp.stats.norm.rvs(size=20)
    plt.plot(t, y[i], lw=1);
plt.plot(t, np.mean(y, axis=0), 'r-', lw=4)
plt.show()

결정론적 추세 추정

확률 과정의 기댓값이 시간에 대한 함수로 표현될 수 있을 때 추세(trend)를 가진다고 한다. (결정론적) 추세 추정(trend estimation)은 것은 이 기댓값 함수의 형태를 알아내는 것을 말한다.

추세에 대한 소개는 다음 노트북을 참조한다.

추세를 가진다는 것은 결국 확률 과정이 정상 과정(stationary process)이 아니라 비정상 과정(non-stationary process)임을 뜻한다. 그러나 분석을 쉽게 하기 위해 보통 다음과 같은 가정을 한다.

  • 우리가 분석하고자하는 확률 과정 $Y_t$이 일반적인 비정상 과정이 아니라 추정이 가능한 결정론적 추세 함수 $f(t)$와 확률 정상 과정 $X_t$의 합으로 표현될 수 있다.
$$ Y_t \sim f(t) + X_t $$

계절성도 추세에 포함 된다고 볼 수 있다.

  • 다항식 추세 (polynomial trend)
  • 계절성 추세 (seasonality)

다항식 추세

다항식 추세 분석 방법은 추세 함수 즉, 확률 과정의 기댓값을 시간에 대한 다항식으로 나타낼 수 있다고 가정하는 것이다.

$$ f(t) = \sum_{i=0}^M a_i t^i = a_0 + a_1 t + a_2 t^2 + \cdots $$

가장 단순한 모형으로 선형 추세를 가지는 경우를 살펴보자.

미국 항공운송량 자료의 선형 추세를 구해본다.

In:
df = sm.datasets.get_rdataset("AirPassengers").data

def yearfraction2datetime(yearfraction, startyear=0):
    import datetime, dateutil
    year = int(yearfraction) + startyear
    month = int(round(12 * (yearfraction - year)))
    delta = dateutil.relativedelta.relativedelta(months=month)
    date = datetime.datetime(year, 1, 1) + delta
    return date

df["datetime"] = df.time.map(yearfraction2datetime)

df.tail()
Out:
time AirPassengers datetime
139 1960.583333 606 1960-08-01
140 1960.666667 508 1960-09-01
141 1960.750000 461 1960-10-01
142 1960.833333 390 1960-11-01
143 1960.916667 432 1960-12-01
In:
result = sm.OLS.from_formula("AirPassengers ~ time", data=df).fit()
print(result.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:          AirPassengers   R-squared:                       0.854
Model:                            OLS   Adj. R-squared:                  0.853
Method:                 Least Squares   F-statistic:                     828.2
Date:                Thu, 06 Jul 2017   Prob (F-statistic):           4.02e-61
Time:                        14:16:31   Log-Likelihood:                -754.82
No. Observations:                 144   AIC:                             1514.
Df Residuals:                     142   BIC:                             1520.
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept  -6.206e+04   2166.077    -28.649      0.000   -6.63e+04   -5.78e+04
time          31.8862      1.108     28.778      0.000      29.696      34.076
==============================================================================
Omnibus:                       24.637   Durbin-Watson:                   0.537
Prob(Omnibus):                  0.000   Jarque-Bera (JB):               33.905
Skew:                           0.940   Prob(JB):                     4.34e-08
Kurtosis:                       4.454   Cond. No.                     1.10e+06
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.1e+06. This might indicate that there are
strong multicollinearity or other numerical problems.

위 회귀 분석 결과 보고서에서 추세 함수가 다음과 같다는 것을 할 수 있다.

$$ f(t) = 31.8862 t - 62060 $$

이를 플롯으로 나타내면 아래와 같다.

In:
t = df.time
y = df.AirPassengers
trend = result.params[0] + result.params[1] * t
plt.plot(t, y, 'o-', t, trend, '-')
plt.show()

만약 추세가 2차 함수 형태라면 다음과 같이 추세를 추정할 수 있다.

In:
result2 = sm.OLS.from_formula("AirPassengers ~ time + I(time ** 2)", data=df).fit()
print(result2.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:          AirPassengers   R-squared:                       0.862
Model:                            OLS   Adj. R-squared:                  0.860
Method:                 Least Squares   F-statistic:                     439.8
Date:                Thu, 06 Jul 2017   Prob (F-statistic):           2.49e-61
Time:                        14:16:32   Log-Likelihood:                -750.67
No. Observations:                 144   AIC:                             1507.
Df Residuals:                     141   BIC:                             1516.
Df Model:                           2                                         
Covariance Type:            nonrobust                                         
================================================================================
                   coef    std err          t      P>|t|      [0.025      0.975]
--------------------------------------------------------------------------------
Intercept     3.795e+06   1.33e+06      2.848      0.005    1.16e+06    6.43e+06
time         -3913.9257   1363.368     -2.871      0.005   -6609.211   -1218.641
I(time ** 2)     1.0092      0.349      2.894      0.004       0.320       1.699
==============================================================================
Omnibus:                       19.218   Durbin-Watson:                   0.569
Prob(Omnibus):                  0.000   Jarque-Bera (JB):               23.828
Skew:                           0.810   Prob(JB):                     6.70e-06
Kurtosis:                       4.161   Cond. No.                     1.36e+12
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.36e+12. This might indicate that there are
strong multicollinearity or other numerical problems.
In:
trend2 = result2.params[0] + result2.params[1] * t + result2.params[2] * t**2
plt.plot(t, y, 'o-', t, trend2, '-')
plt.show()