비정상성(Non-stationary)의 정상성(Stationary) 변환
- 목적: 정상성 확보를 통해 안정성이 높아지고 예측력 향상
- 장점: 절약성 원칙(Principle of Parsimony)(파라미터를 적게 써도됨)에 따라 적은 모수만으로 모델링 가능하기에 과적합 확률이 줄어듬
- 방법: 제곱, 루트, 로그, 차분 등
- 비정상 데이터는 범위가 무제한, 하지만 정상성데이터는 범위가 제한되기 때문에 예측이 더 쉬워지지만 무조건 정상성이 필요한 것은 아님.
- 정상성 변환을 하면 모델이 단조로워지기 때문에 과적합이 일어날 확률이 낮아짐
- Trend: a/c/e/f/i
- Seasonality: d/h/i
- Cycle: g
- Non-constant Variance: i
- 정상성 만족 : b
1) 로그변환
- 시간흐름에 비례하여 값이 커지는 경우(분산 증가)
- 비정상 확률 과정으로 표준편차가 자료의 크기에 비례하여 증가하거나 지수함수적으로 증가하는 경우
- 로그 변환한 확률 과정의 분산은 일정하기에 추세 제거로 기댓값이 0이 되면 정상 과정으로 모형화 가능
2) 차분(Difference):특정 시점 또는 시점들의 데이터가 발산할 경우 시점간 차분(변화량)으로 정상성 변환 가능
- 계절성(Seasonality,St): 특정한 달/요일에 따라 기대값이 달라지는 것, 변수 더미화를 통해 추정 가능
- 계절성 제거: 1) 계절성 추정(f(t)) 후 계절성 제거를 통한 정상성 확보
- 확률과정의 계절변수 더미화를 통해 기댓값 함수를 알아내는 것
- 확률과정(Yt)이 추정이 가능한 결정론적 계절성함수(f(t))와 정상확률과정(Yst)의 합
- 계절성 제거: 2) 차분 적용 후 계절성 제거를 통한 정상성 확보
- 계절성 제거: 1) 계절성 추정(f(t)) 후 계절성 제거를 통한 정상성 확보
- 추세(Trend, TtTt): 시계열이 시간에 따라 증가, 감소 또는 일정 수준을 유지하는 경우
- 추세 제거: 1) 추세 추정(f(t)) 후 추세 제거를 통한 정상성 확보
- 확률과정의 결정론적 기댓값 함수를 알아내는 것
- 확률과정(Yt)이 추정이 가능한 결정론적 추세함수(f(t))와 정상확률과정(Yst)의 합
- 추세 제거: 2) 차분 적용후 추세 제거를 통한 정상성 확보
- 추세 제거: 1) 추세 추정(f(t)) 후 추세 제거를 통한 정상성 확보
3) Box-Cox 변환: 정규분포가 아닌 자료를 정규분포로 변환하기 위해 사용
- 거듭곱변환(power transformation) : 제곱근과 세제곱근을 사용
- 모수(parameter)λ를 가지며, 보통 여러가지λ값을 시도하여 가장 정규성을 높여주는 값을 사용
- 박스-칵스(Box-Cox) 변환에서 로그는 항상 자연 로그(즉, 밑이 e).
- λ=0이면, 자연 로그를 사용, λ≠0이면, 어떤 단순한 눈금에 따라 거듭곱 변환(power transformation)을 사용
대기중 CO2 농도 추세 제거
# 방법(1) : 잔차로 추세와 계절성이 제거 된 것을 추정
plt.plot(raw.time, result.resid)
plt.show()
display(stationarity_adf_test(result.resid, []))
display(stationarity_kpss_test(result.resid, []))
sm.graphics.tsa.plot_acf(result.resid, lags=100, use_vlines=True)
plt.tight_layout()
plt.show()
- adf(추세에 민감한 통계량) : 비정상(추세가 남아있음)
- kpss(계절성에 민감한 통계량) : 정상
- acf그래프는 아직 계절성이 남아있다고 볼 수 있음
# 방법(2) : 차분1회
plt.plot(raw.time[1:], raw.value.diff(1).dropna())
plt.show()
display(stationarity_adf_test(raw.value.diff(1).dropna(), []))
display(stationarity_kpss_test(raw.value.diff(1).dropna(), []))
sm.graphics.tsa.plot_acf(raw.value.diff(1).dropna(), lags=100, use_vlines=True)
plt.tight_layout()
plt.show()
- lags=100 이란 lags 100개의 수치를 전부 알려달라는 내용이다. lag란 데이터상 과거의 몇 번째 뒤로 간 데이터를 의미한다. 만약 lag=1이고 시간 설정을 일로 했다면, 전날 데이터와 현재 데이터를 비교하는 것이다.
- adf(추세에 민감한 통계량) : 정상
- kpss(계절성에 민감한 통계량) : 정상
- acf그래프는 아직 계절성이 남아있다고 볼 수 있으며 추세는 어느정도 제거 된것을 볼 수 있음
호흡기 질환 사망자수 계절성 제거
# 계절성 제거 및 정상성 확인 -> 차분
sm.graphics.tsa.plot_acf(raw.value, lags=50, use_vlines=True)
plt.show()
plt.plot(raw.time, raw.value)
plt.title('Raw')
plt.show()
seasonal_lag = 3 #3개월 차분했을 때
plt.plot(raw.time[seasonal_lag:], raw.value.diff(seasonal_lag).dropna(), label='Lag{}'.format(seasonal_lag))
seasonal_lag = 6 # 6개월 차분했을 때
plt.plot(raw.time[seasonal_lag:], raw.value.diff(seasonal_lag).dropna(), label='Lag{}'.format(seasonal_lag))
seasonal_lag = 12 # 12개월 차분했을 때
plt.plot(raw.time[seasonal_lag:], raw.value.diff(seasonal_lag).dropna(), label='Lag{}'.format(seasonal_lag))
plt.title('Lagged')
plt.legend()
plt.show()
- 3개월 차분(파란색), 6개월 차분(주황색)은 아직 계절성이 남아있는 것을 볼수 있지만, 12개월 차분(녹색)은 계절성이 많이 없어진 것을 볼 수 있다.
#lag 6일 때 통계량 및 시각화
seasonal_lag = 6
display(stationarity_adf_test(raw.value.diff(seasonal_lag).dropna(), []))
display(stationarity_kpss_test(raw.value.diff(seasonal_lag).dropna(), []))
sm.graphics.tsa.plot_acf(raw.value.diff(seasonal_lag).dropna(), lags=50,
use_vlines=True, title='ACF of Lag{}'.format(seasonal_lag))
plt.tight_layout()
plt.show()
- adf(추세에 민감한 통계량) : 정상
- kpss(계절성에 민감한 통계량) : 정상
- acf그래프는 아직 계절성이 남아있음
# 12개월 차분했을 때 통계량과 시각화
seasonal_lag = 12
display(stationarity_adf_test(raw.value.diff(seasonal_lag).dropna(), []))
display(stationarity_kpss_test(raw.value.diff(seasonal_lag).dropna(), []))
sm.graphics.tsa.plot_acf(raw.value.diff(seasonal_lag).dropna(), lags=50,
use_vlines=True, title='ACF of Lag{}'.format(seasonal_lag))
plt.tight_layout()
plt.show()
- adf(추세에 민감한 통계량) : 정상
- kpss(계절성에 민감한 통계량) : 정상
- acf그래프에는 계절성이 보이지 않음
랜덤워크의 정상성 변환
실제값 = 이전 시점의 값 + 백색 잡음의 값
-> 따라서 랜덤워크 값을을 차분하면 백색잡음이 나옴
# 차분 전 랜덤워크 정상성 테스트
display('Before a difference:')
display(stationarity_adf_test(random_walk, []))
display(stationarity_kpss_test(random_walk, []))
sm.graphics.tsa.plot_acf(random_walk, lags=100, use_vlines=True)
plt.tight_layout()
plt.show()
- adf(추세에 민감한 통계량) : 비정상
- kpss(계절성에 민감한 통계량) : 비정상
- acf그래프 : 추세가 있음(비정상)
# 차분 후 랜덤워크 정상성 테스트
display('After a difference:')
display(stationarity_adf_test(pd.Series(random_walk).diff(1).dropna(), []))
display(stationarity_kpss_test(pd.Series(random_walk).diff(1).dropna(), []))
sm.graphics.tsa.plot_acf(pd.Series(random_walk).diff(1).dropna(), lags=100, use_vlines=True)
plt.tight_layout()
plt.show()
- adf(추세에 민감한 통계량) : 정상
- kpss(계절성에 민감한 통계량) : 정상
- acf그래프 : 정상
해당 포스팅은 패스트캠퍼스의 <파이썬을 활용한 시계열 데이터 분석 A-Z 올인원 패키지> 강의를 듣고 정리한 내용입니다
728x90
반응형
'Data Analysis & ML > 시계열분석' 카테고리의 다른 글
[시계열분석] 시계열 알고리즘 - 일반 선형확률 과정(1) - MA(이동평균) (0) | 2021.08.07 |
---|---|
[시계열분석] 항공사 승객수요 스케일 및 정상성 변환 (1) | 2021.06.27 |
[시계열분석] 정상성이란 (0) | 2021.06.19 |
[시계열분석] 시계열 데이터 전처리 실습(Python)(2) - 다중공선성 제거 (0) | 2021.03.08 |
[시계열분석] 시계열 데이터 전처리 실습(Python)(1) - 시간현실반영 및 Scaling (0) | 2021.03.08 |