본문 바로가기
머신러닝

Statsmodels 이용한 시계열 분석에 대해

by 제리의 세계 2023. 5. 4.

안녕하세요! 제리입니다.

오늘 소개할 것은 Statsmodels를 이용한 시계열 분석에 대해서 다뤄보도록하겠습니다.

자세한 라이브러리 소개하는 이곳을 참고하시면 도움이 될것입니다.

 

statsmodels

statsmodels is a Python module that provides classes and functions for the estimation of many different statistical models, as well as for conducting statistical tests, and statistical data exploration. An extensive list of result statistics are available

www.statsmodels.org

이름부터 통계적인 방법이라고 소개하는 이 라이브러리 사용에 대해 자세히 알아봅시다!

  1. 추세 (trends)
  2. 계절성 (seasonality)
  3. 순환성 (cyclical) - 반복적 추세가 없는

Hodrick-Prescott filter

y_t = T_t + c_t

여기서 T_t는 추세 요소이고, c_t는 순환 요소입니다.

이후 약간의 계산 수식 이후 lambda가 추세요소의 증가율을 변동폭을 조절하는 기능을 함.

계산을 진행하면 분기별 람다 값은 1600, 연간 데이터는 6.25, 월별 람다 값은 129600으로 추천됩니다. => 표준화된 값이라고 보면 됩니다.

그렇다면 코드로 어떻게 하는지 보시죠

임의의 데이터 plot

# 호드릭 프레스콧 필터 불러오기

from statsmodels.tsa.filters.hpfiltter import hpfilter

# 튜플형식으로 반환이 되고 앞에는 순환성, 뒤에는 추세가 반환

# lamb에 입력 값에 따라서 월, 분기, 연간 나눠짐

gdp_cycle, gdp_trend = hpfilter(df['realgdp'], lamb=1600)

# 추세성과 실제값을 같이 보여주는 코드

df['trend'] = gdp_trend  
df[['trend','realgdp']].plot().autoscale(axis='x',tight=True)

trend와 실제 값 같이 출력

추세성이 확실히 좀 더 smooth하다는 것을 알 수 있습니다.

여기서 만일 특정 튀는 일부 값을 보고 싶다면 그 값을 넣어 확인하실 수 있습니다.

df[['trend','realgdp']]['2000-03-31':].plot(figsize=(12,8)).autoscale(axis='x',tight=True);

특정 부분 확대

ETS 모델

statsmodel 중 ETS (Error/Trend/Seasonality) model이 있습니다.

전체적으로 보여준다는 장점이 있습니다! 또한 additive model과 multiplicative model로 나뉘는데 증감의 정도에 따라 달라집니다.

  • additive model (덧셈모델)은 추세가 선형에 가깝고, 계절성이 거의 일정해 보일때
  • multiplicative model (곱셈모델)은 추세가 비선형, 지수 증감일 때 더 유용

만일 데이터가 위와 같을 시 증가하는 것 같은데 선형성보다 좀 더 크게 증가하는 지수적으로 증가하는 형태일 경우에는

앞서 말한것처럼 multiplicative를 사용합니다.

from statsmodels.tsa.seasonal import seasonal_decompose

result = seasonal_decompose(airline['Thousands of Passengers'], model='multiplicative')  # model='mul' also works
result.plot();
 

ETS

맨 위에서부터 관측값, 추세, 계절성, 에러(잔차)를 보여줍니다.

관측값은 위에 있던 것과 같은 그림을 길게 한 것이며, 추세는 어떤 추세 (증가,감소)인지 보여줍니다.

계절성은 관측값에서 추세를 제외하여 계절성을 띄는 지 확인할 수 있고,

잔차는 관측값과 계절성으로는 설명이 되지 않는 값을 그려줍니다.

 

EWMA

자세한 내용은 이곳에 살피시면 좋습니다!

 

Exponential smoothing - Wikipedia

From Wikipedia, the free encyclopedia Generates a forecast of future values of a time series Exponential smoothing is a rule of thumb technique for smoothing time series data using the exponential window function. Whereas in the simple moving average the p

en.wikipedia.org

EWMA는 Exponentially Weighted Moving Averages의 약자로 이전에 배웠던 rolling과의 개념을 좀 더 복잡하고 성능이 좋은 개념입니다.

SMA (Simple Moving Average)는 윈도우에 맞게 단순히 rolling을 했는데, 위 방식은 약간의 단점이 있습니다.

 

* Smaller windows will lead to more noise, rather than signal
* It will always lag by the size of the window
* It will never reach to full peak or valley of the data due to the averaging.
* Does not really inform you about possible future behavior, all it really does is describe trends in your data.
* Extreme historical values can skew your SMA significantly

번역하자면!

  • 창 크기가 작을수록 신호가 아닌 노이즈가 더 많이 발생합니다.
  • 항상 창 크기에 따라 지연됩니다.
  • 평균값으로 인해 데이터의 전체 피크 또는 밸리에 도달하지 못합니다.
  • 미래의 행동 가능성에 대한 정보를 제공하지 않으며, 데이터의 추세를 설명할 뿐입니다.
  • 극단적인 과거 값은 SMA를 크게 왜곡할 수 있습니다.

그렇기에 EWMA는 과거의 값보다 현재와 가까운 값들에 더 많은 가중치를 줘서 SMA의 단점을 없애 시차를 줄여줍니다.

EWMA 원리 전반적 흐름

 

 

SMA

airline['6-month-SMA'] = airline['Thousands of Passengers'].rolling(window=6).mean()
airline['12-month-SMA'] = airline['Thousands of Passengers'].rolling(window=12).mean()
airline.plot();

SMA

airline['EWMA12'] = airline['Thousands of Passengers'].ewm(span=12,adjust=False).mean()
airline[['Thousands of Passengers','EWMA12']].plot();

EWMA

ewm 안에서 com, span, halflife, alpha를 조정하여 가중치를 조절할 수 있습니다.

span을 통해 원하는 기간만큼 지수 가중 이동 평균 가능

com을 통해 span과의 역관계

halflife는 지수적 가중치가 반으로 줄어드는데 걸리는 기간

alpha는 smooth 정도

 

airline[['Thousands of Passengers','EWMA12','12-month-SMA']].plot(figsize=(12,8)).autoscale(axis='x',tight=True);

SMA과 EWMA 비교

Holt-Winters

자세한 내용은 아래에서 참고해주시기 바랍니다.

 

7.3 Holt-Winters’ seasonal method | Forecasting: Principles and Practice (2nd ed)

2nd edition

otexts.com

EWMA의 단점은 추세성과 계절성에 대해서 반영하는 요소가 없다는 점인데요! 그래서 나온 것이 이 홀트윈터 방법입니다.

holt-winters에서는 smoothing한 정도에 따라서 세가지로 나뉩니다.

1. Simple Exponential Smoothing - EWMA와 같은 값을 가지고 있습니다.

2. Double Exponential Smoothing - 추세성을 더한 방법입니다. additive, multiplicative 나눠서 사용 됩니다.

3. Triple Exponential Smoothing - 계절성과 추세성을 모두 더한 방법입니다.

 

Simple부터 어떻게 사용이 되는지 보면

from statsmodels.tsa.holtwinters import SimpleExpSmoothing

span = 12
alpha = 2/(span+1)

df['EWMA12'] = df['Thousands of Passengers'].ewm(alpha=alpha,adjust=False).mean()
df['SES12']=SimpleExpSmoothing(df['Thousands of Passengers']).fit(smoothing_level = alpha, optimized=False).fittedvalues.shift(-1)

다만 유의해야할 점은 fit을 이용하여 fittedvalues 값들을 계산하는데 계산 결과가 하나 씩 밀려서 출력이 되기에 EWMA와 같게 하기 위해서는 shift를 이용하여 하나씩 앞당겨줘야합니다.

 

from statsmodels.tsa.holtwinters import ExponentialSmoothing

df['DESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='add').fit().fittedvalues.shift(-1)
df[['Thousands of Passengers','EWMA12','DESadd12']].iloc[:24].plot(figsize=(12,6)).autoscale(axis='x',tight=True);

보시는바와 같이 EWMA보다 Double Exponential Smoothing 한 방법이 더 본래의 값과 유사하게 나타납니다.

만일 additive가 아니라면 trend = 'mul'를 사용하시면 됩니다.

 

df['TESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'],trend='add',seasonal='add',seasonal_periods=12).fit().fittedvalues
 

triple 또한 add와 mul 에따라서 나눠 작성해주시면 됩니다.

 

현재까지 시계열 데이터를 어떻게 표현할 수 있고 분석할 지에 대해서 알아보았습니다..

다음에는 이 방법들을 통해 예측을 진행하는 것을 해보겠습니다.

 

감사합니다.

 

참고 : 유데미 시계열 데이터 분석 with 파이썬