단위근(Unit root)
단위근과 통계적 검정 방법
근은 방정식의 해이므로 단위근은 그 식의 해가 1이 됨을 의미합니다. 단위근은 시계열을 비정상적으로 만드는 특성입니다.
회귀모형인 회귀식 역시 방정식이므로 그 식의 해를 결정할 수 있습니다. 그러나 일반식과는 다르게 모형의 근(해)는 확률적 특성을 가진 추정치입니다. 예를 들어 간단한 자기회기모형은 AR(1)의 형태는 다음과 같습니다.
$$y_t = \alpha y_{t-1} + \epsilon_t$$- α는 지귀회귀의 계수로 해 즉, 근이 됩니다.
- Yt,Yt-1 : 시계열 데이터. 현재와 이전 값
- εt: 오차항으로 백색잡음입니다.
α에 따라 다음과 같이 설명할 수 있습니다.
- |α|<1이라면, 이 시계열은 정상성(stationarity)을 가집니다. 정상성을 갖는 시계열은 평균과 분산이 시간에 따라 일정하고, 공분산은 시차에만 의존하는 특징을 보입니다.(오차항은 평균, 표준편차가 0, 1인 정규분포에 부합하고 긴 과거일수록 현재에 미치는 영향이 작아지므로 평균과 표준편차등 통계량이 오차항에 의존됩니다.)
- α=1이라면, 이 시계열은 단위근(unit root)을 가지며 비정상적(non-stationary)입니다. 단위근을 갖는 시계열은 과거의 충격이 현재와 미래에 지속적으로 영향을 미치기 때문에, 평균과 분산이 시간에 따라 변할 수 있습니다. 이러한 시계열은 분석이나 예측 전에 적절한 변환(예: 차분)을 통해 정상성을 확보해야 합니다.
- α>1이라면, 시계열은 **폭발적(explosive)**인 형태를 보이며 비정상적입니다.
단위근 검정(Unit Root Test):
시계열 데이터에 단위근이 존재하는지 여부를 통계적으로 검정하는 방법을 단위근 검정이라고 합니다. 대표적인 단위근 검정 방법은 다음과 같습니다.
- ADF 검정 (Augmented Dickey-Fuller Test): AR(p) 모형으로 확장하여 자기상관 문제를 해결합니다. 귀무 가설은 "시계열에 단위근이 존재한다"이며, 대립 가설은 "시계열이 정상성을 갖는다"입니다.
- Phillips-Perron (PP) 검정: ADF 검정과 유사하지만, 오차항의 자기상관 및 이분산성을 고려하는 비모수적 방법입니다.
- KPSS 검정 (Kwiatkowski-Phillips-Schmidt-Shin Test): 귀무 가설과 대립 가설이 ADF 및 PP 검정과 반대입니다. 귀무 가설은 "시계열이 정상성을 갖는다"이며, 대립 가설은 "시계열에 단위근이 존재한다" 또는 "추세 정상성을 갖지 않는다"입니다.
시계열 데이터가 단위근을 갖는 것으로 확인되면, 정상 시계열로 변환하기 위한 방법을 적용해야 합니다. 가장 일반적인 방법은 차분(Differencing)입니다. 1차 차분은 현재 값에서 바로 이전 값을 빼는 것이며, 필요에 따라 2차, 3차 차분을 적용할 수도 있습니다. 계절성(seasonality)이 있는 데이터의 경우 계절성 차분을 사용하기도 합니다.
Augmented Dickey Fuller test (ADF Test)
Augmented Dickey Fuller test (ADF Test)는 시계열이 정상적인지를 검정하는 통계적 방법입니다.
시계열 정상성 테스트에 KPSS 테스트와 함께 일반적으로 사용하는 통계적 유의성 검정입니다. 즉, 귀무가설와 대립가설에 대한 가설 검정으로 구성됩니다.
H0: 단위근이 존재합니다.
검정은 statsmodels.tsa.stattools.adfuller(x, maxlag: 'int | None' = None, regression='c', autolag='AIC', store=False, regresults=False) 함수를 사용합니다.
- x: 검정할 데이터로 1차원 객체
- maxlag: ADF에 포함될 최대 시차(lag)수이며 None이면 자동으로 설정
- regression: 검정 방정식($y_t =c+\beta t + \alpha y_{t-1}+ \phi \Delta y_{t-1}+e_t$) 에 포함할 항을 지정
- 'c': 상수항만을 포함(random walk에 대한 검정)
- 'ct': 상수항과 추세(trend)항 포함(추세가 있는 random walk에 대한 검정)
- 'ctt': 상수항, 선형 추세항, 이차 추세항 포함
- 'nc': 상수항과 추세항을 포함하지 않음(단위근이 0인지 검정)
- autolag: 시차선택방법을 지정, 'AIC', 'BIC', 't-stat'등, None인 경우 maxlag 값을 사용
- store: 검정 결과의 반환 여부
- 다음을 반환
- adf: 검정통계량
- p-value
- usedlag: 사용된 시차(lag)의 수
- nobs: 회귀분석에 사용된 관측치의 수
- critical values(임계값): 각 유의수준 (1, 5, 10%)에 대응하는 임계값
- icbest: autolag != None인 경우 maximized information criterion
검정 통계량 < 임계값 : 귀무가설 기각 즉, 정상성을 따름 p-value < 유의수준(일반적으로 0.05): 귀무가설 기각 즉, 정상성을 따름
from statsmodels.tsa.stattools import adfuller import pandas as pd import numpy as np
url = 'https://raw.githubusercontent.com/selva86/datasets/master/a10.csv' df = pd.read_csv(url, parse_dates=['date'], index_col='date') df.tail(3)
value | |
---|---|
date | |
2008-04-01 | 23.107677 |
2008-05-01 | 22.912510 |
2008-06-01 | 19.431740 |
df.plot(figsize=(5, 3), title='a10 - Drug Sales Series', legend=None)
result=adfuller(df, autolag="AIC") resultnme=['검정통계량', 'p-value', 'usedlag', '사용된 자료수', "임계값", "정보기준"] for i in range(len(result)): print(f"{resultnme[i]}: {result[i]}")
검정통계량: 3.145185689306738 p-value: 1.0 usedlag: 15 사용된 자료수: 188 임계값: {'1%': -3.465620397124192, '5%': -2.8770397560752436, '10%': -2.5750324547306476} 정보기준: 549.6705685364172
p-value가 0.05보다 매우 크고 검정통계량의 3개의 임계값들에 비해 매우 높으므로 귀무가설을 기각 할 수 없습니다. 이 자료는 비정상시계열입니다.
랜덤수에 대해 ADF 검정을 실시합니다.
np.random.seed(9) d=pd.Series(np.random.randn(100)) d.plot(figsize=(5,3), title="Random Number")
res=adfuller(d, autolag="AIC") resultnme=['검정통계량', 'p-value', 'usedlag', '사용된 자료수', "임계값", "정보기준"] for i in range(len(res)): print(f"{resultnme[i]}: {res[i]}")
검정통계량: -9.672283589524222 p-value: 1.2674995766333434e-16 usedlag: 0 사용된 자료수: 99 임계값: {'1%': -3.498198082189098, '5%': -2.891208211860468, '10%': -2.5825959973472097} 정보기준: 263.83311381786416
p-value가 0.05보다 매우 작고 검정통계량은 1%의 임계값에 비해 매우 낮은 값으로 귀무가설을 기각 할 수 있습니다. 이 자료는 정상시계열입니다.
KPSS(Kwiatkowski-Phillips-Schmidt-Shin) test
H0: 추세안정적(trend stationary)이거나 수준안정적(level stationary)입니다.
추세안정적 : 데이터가 추세 주변에서 변동함
수준 안정적 : 데이터가 일정한 평균 주변에서 변동
특징 | ADF 검정 | KPSS 검정 |
---|---|---|
귀무 가설 | 단위근이 존재 (불안정) | 추세 또는 수준 안정적 (안정적) |
대립 가설 | 안정적 | 단위근이 존재 (불안정) |
검정 통계량 (< 임계값) | 귀무 가설 채택(불안정) | 귀무 가설 채택(안정) |
안정성 판단 | p-값이 작을수록 안정적이라고 판단 | p-값이 클수록 안정적이라고 판단 |
위와같은 차이로 두 검정은 상호보완적으로 사용, 예를 들어 ADF 결과 안정적, KSPP 결과 불안정적인 결과이면 구조적 변화 즉, 추세에 의한 큰 변동이 있을 가능성을 고려할 수 있습니다.
검정은 statsmodels.tsa.stattools.kpss(x, regression='c', nlags='auto', store=False) 함수를 사용합니다.
- x: 검정할 데이터로 1차원 객체
- regression: 검정 방정식($y_t =c+\beta t + \alpha y_{t-1}+ \phi \Delta y_{t-1}+e_t$) 에 포함할 항을 지정
- 'c': 상수항(level stationary 검정, 기본값)
- 'ct': 상수항과 추세항(trend stationary 검정)
- nlags: 시차선택방법을 지정
- 'auto': 기본값으로 데이터 길이에 따라 자동 결정
- 'legacy: Liung-Box 통계량 기반, 또는 정수값을 직접 지정할 수 있음
- 다음을 반환
- kpss_stat: 검정통계량
- p-value
- lag: 사용된 시차(lag)의 수
- nobs: 회귀분석에 사용된 관측치의 수
- critical values(임계값): 각 유의수준 (1, 5, 10%)에 대응하는 임계값
검정 통계량 < 임계값 : 귀무가설 채택 즉, 정상성을 따름 p-value < 유의수준(일반적으로 0.05): 귀무가설 기각 즉, 비정상성을 따름
from statsmodels.tsa.stattools import kpss import matplotlib.pyplot as plt
url ='https://raw.githubusercontent.com/selva86/datasets/master/daily-min-temperatures.csv' df = pd.read_csv(url) df.tail(3)
Date | Temp | |
---|---|---|
3647 | 1990-12-29 | 13.5 |
3648 | 1990-12-30 | 15.7 |
3649 | 1990-12-31 | 13.0 |
df1=df["Temp"] df1.index=df["Date"] df1.tail(3)
Date 1990-12-29 13.5 1990-12-30 15.7 1990-12-31 13.0 Name: Temp, dtype: float64
df1.plot(figsize=(5, 3), title='Daily Temp.', legend=None) plt.xticks(rotation=45, ha="right") #ha는 회전시 정렬을 오른쪽으로 plt.tight_layout() #레이아웃 조정으로 레이블을 잘 보이게 함 plt.show()
statics, pvalue, lag_n, critical=kpss(df["Temp"]) print(f"검정통계량: {statics}") print(f"p-value: {pvalue}") print(f"# of used lag: {lag_n}") print(f"임계값: {critical}")
statics, pvalue, lag_n, critical=kpss(df["Temp"]) 검정통계량: 0.05570612670427435 p-value: 0.1 # of used lag: 36 임계값: {'10%': 0.347, '5%': 0.463, '2.5%': 0.574, '1%': 0.739}
댓글
댓글 쓰기