Data Analysis & ML/시계열분석

[시계열분석] 시계열 알고리즘 - 적분 선형확률 과정(3) - SARIMA 모델링 해석

YSY^ 2021. 9. 26. 16:50

SARIMA  모델링 해석

원 데이터

  • ADF 정상성 테스트 -> p가 0.05보다 작으므로 정상상태임.
  • 테스트는 정상으로 나오지만, 계절성과 추세가 있는 것으로 보임
  • p:2? (PACF 기준 lag 2까지 유의하고 그 뒤로는 유의하지 않음)  
  • d:1? (ACF를 봤을때 추세가 어느정도 보이므로 추세 1차 차분)  
  • q:1? (ACF 기준 필요성 인지)  
  • P:1? (PACF 기준 lag 24 간격 유의성으로 필요성 인지)    
  • D:1? (계절성 차분 필요함 인지)  
  • Q:2? (ACF 기준 lag 24 간격 유의성으로 필요성 인지)  
  • m:24 (ACF/PACF 기준 lag 24 간격으로 유의한 진동 존재)  

 

계절 차분 후 데이터

  • ADF 정상성 테스트 -> p가 0.05보다 작으므로 정상상태임. 
  • 하지만 계절성이 반복되고 있기 때문에 추세제거가 필요해 보임
  • p:1? (PACF 기준 lag 1까지 유의하고 그 뒤로는 유의하지 않음)  
  • d:1? (ADF가 대중가설을 기각하고 그래프 상 추세가 보이므로 일단 추세 1차 차분)  
  • q:3? (ACF 기준 필요성 인지)  
  • P:2? (PACF 기준 lag 24 간격 유의성으로 필요성 인지)    
  • D:1 (계절성 차분 필요)  
  • Q:0? (ACF 기준 계절 시차는 유의한 간격안에 들어와 있음)  
  • m:24 (ACF/PACF 기준 lag 24 간격으로 유의한 진동 크게 사라짐)  

 

계절성 및 추세차분 후 데이터

  • ADF 정상성 테스트 -> p가 0.05보다 작으므로 정상상태임.
  • 진동이 거의 사라졌음
  • p:max4 (PACF 기준 lag 4까지 유의하고 그 뒤로는 유의하지 않음, 그래프가 lag4까지 튐)  
  • d:1 (ADF가 대중가설을 기각하고 그래프 상 추세도 없어졌으므로 추세 1차 차분 확정)  
  • q:max4 (ACF 기준 lag 4까지 유의하고 그 뒤로는 유의하지 않음, 그래프가 lag4까지 튐)  
  • P:max2 (PACF 기준 lag 24 간격으로 2번정도 유의함)    
  • D:1 (계절성 차분 필요함 인지)  
  • Q:max1 (ACF 기준 lag 24 간격으로 1번정도 유의함)  
  • m:24 (lag 24 간격으로 진동 존재)  

 

잔차검증 : SARIMA(4,1,4)(2,1,1,24)

  • ADF 정상성 테스트 -> p가 0.05보다 작으므로 정상상태임.
  • ACF와 PACF는 유의한 수준을 보임 -> White Noise에 가깝다고 볼 수 있음

 

호흡기질환 사망자수 SARIMA 모델링

추세만 반영 : SARIMA(1,0,1)(0,0,0,0) -> ARMA(1,1)

import warnings
warnings.filterwarnings('always')
warnings.filterwarnings('ignore')

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

# 데이터로딩 및 확인
data = sm.datasets.get_rdataset("deaths", "MASS")
raw = data.data
raw.value = np.log(raw.value)
raw.plot(x='time', y='value')
plt.show()

# ACF/PACF 확인
plt.figure(figsize=(10, 8))
sm.graphics.tsa.plot_acf(raw.value.values, lags=50, ax=plt.subplot(211))
plt.xlim(-1, 51)
plt.ylim(-1.1, 1.1)
plt.title("ACF")

sm.graphics.tsa.plot_pacf(raw.value.values, lags=50, ax=plt.subplot(212))
plt.xlim(-1, 51)
plt.ylim(-1.1, 1.1)
plt.title("PACF")
plt.tight_layout()
plt.show()

# ARMA(1,1) 모델링
fit = sm.tsa.SARIMAX(raw.value, trend='c', order=(1,0,1), seasonal_order=(0,0,0,0)).fit()
display(fit.summary())

# 잔차진단
fit.plot_diagnostics(figsize=(10,8))
plt.tight_layout()
plt.show()

  • Skew, Kurtosis를 봤을 때 정규분포처럼 보임
  • JB테스트 결과 정규분포가 아님
  • Heteroskedasticity 결과 등분산성이라고 판단
  • Ljung-BOX 테스트 결과 자기 상관성이 있다고 판단
  • 즉, 정규분포가 아니며 등분산성이 있으며 자기상관성이 있는 모델

잔차진단

  • 계절성 시차의 영향력이 보임
  • 자기상관도 ACF를 봤을때 잔존하고 있는 것이 보임

 

계절성 모델링 추가 : SARIMA(1,0,1)(1,1,1,12)

  • M : 12 -> ACF를 봤을 때 12만큼 반복됨
# SARIMA 모델링
fit = sm.tsa.SARIMAX(raw.value, trend='c', order=(1,0,1), seasonal_order=(1,1,1,12)).fit()
display(fit.summary())

# 잔차진단
fit.plot_diagnostics(figsize=(10,8))
plt.tight_layout()
plt.show()

  • AIC, BIC가 훨씬(2배정도) 작아짐
  • Skew, Kurtosis를 봤을 때 정규분포가 아님.
  • JB테스트 결과 정규분포가 아님
  • Heteroskedasticity 결과 등분산성이라고 판단
  • Ljung-BOX 테스트 결과 자기 상관성이 없다고 판단
  • 잔차진단 결과 훨씬 안정화 되었음
  • 정규분포가 아니라고 판단되는 것은 OUTLIER 때문임. -> 실제로 정규분포에 가깝다고 보면됨
  • Trend와 season 요소가 잘 적합되어 잔차가 White Noise에 가까워졌음

 

항공사 승객수요 SARIMA 모델링

 

# 라이브러리 호출
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

# 데이터 준비
data = sm.datasets.get_rdataset("AirPassengers")
raw = data.data.copy()

# 데이터 전처리
## 시간 인덱싱
if 'time' in raw.columns:
    raw.index = pd.date_range(start='1/1/1949', periods=len(raw['time']), freq='M')
    del raw['time']

## 정상성 확보
plt.figure(figsize=(12,8))
raw.plot(ax=plt.subplot(221), title='Y', legend=False)
np.log(raw).plot(ax=plt.subplot(222), title='log(Y)', legend=False)
raw.diff(1).plot(ax=plt.subplot(223), title='diff1(Y)', legend=False)
np.log(raw).diff(1).plot(ax=plt.subplot(224), title='diff1(log(Y))', legend=False)
plt.show()

추세 1 차분

# ARIMA 모델링 (raw)
fit = sm.tsa.SARIMAX(raw.value, trend='c', order=(1,1,1), seasonal_order=(0,0,0,0)).fit()
display(fit.summary())

# 잔차진단
fit.plot_diagnostics(figsize=(10,8))
plt.tight_layout()
plt.show()

로그를 취한 후 추세 1차분 -> 로그의 효과 체크

# ARIMA 모델링 (log(raw))
fit = sm.tsa.SARIMAX(np.log(raw.value), trend='c', order=(1,1,1), seasonal_order=(0,0,0,0)).fit()
display(fit.summary())

# 잔차진단
fit.plot_diagnostics(figsize=(10,8))
plt.tight_layout()
plt.show()

  • AIC, BIC가 단순히 1회 차분했을 때보다 훨씬 작아졌음
  • 통계량을 봤을때 여전히 정규분포가 아니고 자기상관성이 있음
  • 하지만 잔차진단을 했을 때 분산이 일정하며,  정규분포에 가까워 졌으며, ACF도 좀더 안정화 되었음
  • 즉 log를 취하면 분산을 잡아주기 때문에 지표가 더 좋음

 

SARIMAX(1,1,1)(1,1,1,12) 모델링

# SARIMA 모델링 (log(raw))
fit = sm.tsa.SARIMAX(np.log(raw.value), trend='c', order=(1,1,1), seasonal_order=(1,1,1,12)).fit()
display(fit.summary())

# 잔차진단
fit.plot_diagnostics(figsize=(10,8))
plt.tight_layout()
plt.show()

  • AIC, BIC가 훨씬 작아짐
  • 파라미터들도 더 유의해짐
  • 통계량을 봤을 때, 정규분포에 가까우며, 자기상관도 없으며, 등분산도 만족함
  • 잔차분석 결과도 정규분포에 거의 가까우며, ACF도 자기상관이 없는 것을 볼 수 있음

 

결론

  • SARIMA 함수는 정상화를 해줄 필요는 없음 -> SARIMA는 비정상데이터를 그대로 반영함
  • raw데이터만 넣고 log를 취할지 말지만 결정하면 됨
  • 아직까지는 x를 사용하지 않았음
    • Y = c + f(x) + e => Y = SARIMA + f(x) + e 로 바꾼것이며 f(x)를 사용하지 않았으니
      • Y = SARIMAX + e 가 된것이며, 이것만 해도 잔차가 WH에 가까워졌음
  • 우리가 쓰는 것은  SARIMA임.

 

해당 포스팅은 패스트캠퍼스의 <파이썬을 활용한 시계열 데이터 분석 A-Z 올인원 패키지> 강의를 듣고 정리한 내용입니다

728x90
반응형