시계열 데이터 추세 - sigyeyeol deiteo chuse

그동안 여러 포스팅에 나누어서 Python pandas 라이브러리에서 사용할 수 있는 시계열 데이터 처리 함수, 메소드, attributes 들에 대해서 소개했습니다. 

이번 포스팅에서는 시계열(Time series)의 4가지 구성 요인(추세 요인, 순환 요인, 계절 요인, 불규칙 요인)에 대해서 소개하겠습니다. 

시계열 구성요인 간의 결합 방식에 따라서 (1) 구성요인 간 독립적이라고 가정하여 각 구성요인을 더하는 가법 모형 (additive model)과, (2) 구성요인 간 독립적이지 않고 상호작용을 한다고 가정하여 구성요인 간 곱해주는 승법 모형 (multiplicative model)으로 구분할 수 있습니다. 

  • 시계열 가법 모형 (time series additive model) 
    = 추세 요인(trend factor) + 순환 요인(cycle factor) + 계절 요인(seasonal factor)
     + 불규칙 요인(irregular/random factor) 
  • 시계열 승법 모형 (time series multiplicative model)
    = 추세 요인 * 순환 요인 x 계절 요인 x 불규칙 요인

    :

이번 포스팅에서는 이해하기 쉬운 가법 모형(additive model)을 가상으로 만든 예제 데이터를 가지고 설명해보겠습니다. 

[ 시계열 구성 요인 (Time Series Component Factors) ]

시계열의 4가지 구성 요인인 추세 요인, 순환 요인, 계절 요인, 불규칙 요인을 차례대로 설명해보겠습니다.  

(* Reference: '한국의 경기순환 분석', 김혜원, 2004, //kostat.go.kr/attach/journal/9-1-4.PDF)

(1) 추세 요인 (Trend factor) 은 인구의 변화, 자원의 변화, 자본재의 변화, 기술의 변화 등과 같은 요인들에 의해 영향을 받는 장기 변동 요인으로서, 급격한 충격이 없는 한 지속되는 특성이 있습니다. "10년 주기의 세계경제 변동 추세" 같은 것이 추세 요인의 예라고 할 수 있습니다. 

(2) 순환 요인 (Cycle factor) 은 경제활동의 팽창과 위축과 같이 불규칙적이며 반복적인 중기 변동요인을 말합니다. 주식투자가들이 "건설업/반도체업/조선업 순환주기"를 고려해서 투자한다고 말하는게 좋은 예입니다. 

만약 관측한 데이터셋이 10년 미만일 경우 추세 요인과 순환 요인을 구분하는 것이 매우 어렵습니다. 그래서 관측기간이 길지 않을 경우 추세와 순환 요인을 구분하지 않고 그냥 묶어서 추세 요인이라고 분석하기도 합니다. 

(3) 계절 요인 (Seasonal factor)  12개월(1년)의 주기를 가지고 반복되는 변화를 말하며, 계절의 변화, 공휴일의 반복, 추석 명절의 반복 등 과 같은 요인들에 의하여 발생합니다. 

(4) 불규칙 요인 (Irregular / Random factor, Noise) 은 일정한 규칙성을 인지할 수 없는 변동의 유형을 의미합니다. 천재지변, 전쟁, 질병 등과 같이 예 상할 수 없는 우연적 요인에 의해 발생되는 변동을 총칭합니다. 불규칙변동 은 경제활동에 미미한 영향을 미치기도 하지만 때로는 경제생활에 지대한 영향을 주기도 합니다. 

위의 설명에 대한 이해를 돕기 위하여 Python으로 위의 추세 요인, 순환 요인, 계절 요인, 불규칙 요인을 모두 더한 가법 모형의 시계열 자료(Yt = Tt + Ct + St + It)를 가상으로 만들어보겠습니다. 

import numpy as np

import pandas as pd

# DatetiemIndex

dates = pd.date_range('2020-01-01', periods=48, freq='M')

dates

[Out]:DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31', '2020-04-30', '2020-05-31', '2020-06-30', '2020-07-31', '2020-08-31', '2020-09-30', '2020-10-31', '2020-11-30', '2020-12-31', '2021-01-31', '2021-02-28', '2021-03-31', '2021-04-30', '2021-05-31', '2021-06-30', '2021-07-31', '2021-08-31', '2021-09-30', '2021-10-31', '2021-11-30', '2021-12-31', '2022-01-31', '2022-02-28', '2022-03-31', '2022-04-30', '2022-05-31', '2022-06-30', '2022-07-31', '2022-08-31', '2022-09-30', '2022-10-31', '2022-11-30', '2022-12-31', '2023-01-31', '2023-02-28', '2023-03-31', '2023-04-30', '2023-05-31', '2023-06-30', '2023-07-31', '2023-08-31', '2023-09-30', '2023-10-31', '2023-11-30', '2023-12-31'], dtype='datetime64[ns]', freq='M')

# additive model: trend + cycle + seasonality + irregular factor

timestamp = np.arange(len(dates))

trend_factor = timestamp*1.1

cycle_factor = 10*np.sin(np.linspace(0, 3.14*2, 48))

seasonal_factor = 7*np.sin(np.linspace(0, 3.14*8, 48))

np.random.seed(2004)

irregular_factor = 2*np.random.randn(len(dates))

df = pd.DataFrame({'timeseries': trend_factor + cycle_factor + seasonal_factor + irregular_factor, 

                   'trend': trend_factor, 

                   'cycle': cycle_factor, 

                   'seasonal': seasonal_factor, 

                   'irregular': irregular_factor},

                   index=dates)

df

[Out]:

timeseriestrendcycleseasonalirregular2020-01-312020-02-292020-03-312020-04-302020-05-312020-06-302020-07-312020-08-312020-09-302020-10-312020-11-302020-12-312021-01-312021-02-282021-03-312021-04-302021-05-312021-06-302021-07-312021-08-312021-09-302021-10-312021-11-302021-12-312022-01-312022-02-282022-03-312022-04-302022-05-312022-06-302022-07-312022-08-312022-09-302022-10-312022-11-302022-12-312023-01-312023-02-282023-03-312023-04-302023-05-312023-06-302023-07-312023-08-312023-09-302023-10-312023-11-302023-12-31
2.596119 0.0 0.000000 0.000000 2.596119
6.746160 1.1 1.332198 3.565684 0.748278
8.112100 2.2 2.640647 6.136825 -2.865371
8.255941 3.3 3.902021 6.996279 -5.942358
16.889655 4.4 5.093834 5.904327 1.491495
16.182357 5.5 6.194839 3.165536 1.321981
14.128087 6.6 7.185409 -0.456187 0.798865
11.943313 7.7 8.047886 -3.950671 0.146099
9.728095 8.8 8.766892 -6.343231 -1.495567
12.483489 9.9 9.329612 -6.966533 0.220411
12.141808 11.0 9.726013 -5.646726 -2.937480
15.143334 12.1 9.949029 -2.751930 -4.153764
21.774516 13.2 9.994684 0.910435 -2.330604
28.432892 14.3 9.862164 4.318862 -0.048134
32.350583 15.4 9.553832 6.522669 0.874082
30.596556 16.5 9.075184 6.907169 -1.885797
32.510523 17.6 8.434753 5.365118 1.110653
30.425519 18.7 7.643955 2.326624 1.754939
24.300958 19.8 6.716890 -1.360813 -0.855119
20.450917 20.9 5.670082 -4.668691 -1.450475
18.870881 22.0 4.522195 -6.674375 -0.976939
21.326310 23.1 3.293690 -6.818438 1.751059
22.902448 24.2 2.006469 -5.060699 1.756678
26.620578 25.3 0.683478 -1.891426 2.528526
27.626499 26.4 -0.651696 1.805404 0.072791
31.858923 27.5 -1.975253 4.998670 1.335506
35.930469 28.6 -3.263598 6.797704 3.796363
30.177870 29.7 -4.493762 6.700718 -1.729087
30.016165 30.8 -5.643816 4.734764 0.125217
26.591729 31.9 -6.693258 1.448187 -0.063200
21.118481 33.0 -7.623379 -2.242320 -2.015820
16.636031 34.1 -8.417599 -5.307397 -3.738973
17.682613 35.2 -9.061759 -6.892132 -1.563496
21.163298 36.3 -9.544375 -6.554509 0.962182
22.455672 37.4 -9.856844 -4.388699 -0.698786
26.919529 38.5 -9.993595 -0.998790 -0.588086
33.964623 39.6 -9.952191 2.669702 1.647112
37.459776 40.7 -9.733369 5.593559 0.899586
40.793766 41.8 -9.341031 6.957257 1.377540
43.838415 42.9 -8.782171 6.380433 3.340153
41.301780 44.0 -8.066751 4.023975 1.344556
39.217866 45.1 -7.207526 0.545147 0.780245
35.125502 46.2 -6.219813 -3.085734 -1.768952
33.841926 47.3 -5.121219 -5.855940 -2.480916
38.770511 48.4 -3.931329 -6.992803 1.294643
37.371216 49.5 -2.671356 -6.179230 -3.278198
46.587633 50.6 -1.363760 -3.642142 0.993536
46.403326 51.7 -0.031853 -0.089186 -5.175634

위에서 추세 요인(trend factor) + 순환 요인(cycle factor) + 계절 요인(seasonal factor) + 불규칙 요인(irregular factor, noise) 을 더해서 만든 시계열 가법 모형 (time series additive model) 자료를 아래에 시각화보았습니다. 

아래의 시도표 (time series plot)를 보면 '양(+)의 1차 선형 추세 (linear trend)', '1년 단위의 계절성(seasonality)', 그리고 불규칙한 잡음(noise)을 눈으로 확인할 수 있습니다. (기간이 4년으로서 길지 않다보니 추세와 순환 요인을 구분하기는 쉽지가 않지요?)

# Time series plot

import matplotlib.pyplot as plt

plt.figure(figsize=[10, 6])

df.timeseries.plot()

plt.title('Time Series (Additive Model)', fontsize=16)

plt.ylim(-12, 55)

plt.show()

(1) 위에서 가법 모형으로 가상의 시계열 자료를 만들 때 사용했던 '1차 선형 추세 요인 (trend factor)' 데이터를 시각화하면 아래와 같습니다. 

# -- Trend factor

#timestamp = np.arange(len(dates))

#trend_factor = timestamp*1.1

plt.figure(figsize=[10, 6])

df.trend.plot()

plt.title('Trend Factor', fontsize=16)

plt.ylim(-12, 55)

plt.show()

(2) 위의 가법 모형으로 가상의 시계열 자료를 만들 때 사용했던 '4년 주기의 순환 요인 (cycle factor) '자료를 시각화하면 아래와 같습니다. 

# -- Cycle factor

#cycle_factor = 10*np.sin(np.linspace(0, 3.14*2, 48))

plt.figure(figsize=[10, 6])

df.cycle.plot()

plt.title('Cycle Factor', fontsize=16)

plt.ylim(-12, 55)

plt.show()

(3) 위에서 가법 모형으로 가상의 시계열 자료를 만들 때 사용했던 '1년 주기의 계절 요인 (seasonal factor)' 자료를 시각화하면 아래와 같습니다. 

# -- Seasonal factor

#seasonal_factor = 7*np.sin(np.linspace(0, 3.14*8, 48))

plt.figure(figsize=[10, 6])

df.seasonal.plot()

plt.title('Seasonal Factor', fontsize=16)

plt.ylim(-12, 55)

plt.show()

(4) 위에서 가법 모형으로 가상의 시계열 자료를 만들 때 사용했던 '불규칙 요인 (irregular factor)' 자료를 시각화하면 아래와 같습니다. 

# -- Irregular/ Random factor

#np.random.seed(2004)

#irregular_factor = 2*np.random.randn(len(dates))

plt.figure(figsize=[10, 6])

df.irregular.plot()

plt.title('Irregular Factor', fontsize=16)

plt.ylim(-12, 55)

plt.show()

추세 요인(trend factor), 순환 요인 (cycle factor), 계절 요인(seasonal factor), 불규칙 요인(irregular factor)와 이를 모두 합한 시계열 자료를 모두 모아서 하나의 그래프에 시각화하면 아래와 같습니다. 

# All in one: Time series = Trend factor + Cycle factor + Seasonal factor + Irregular factor


from pylab import rcParams

rcParams['figure.figsize'] = 12, 8

df.plot()

plt.ylim(-12, 55)

plt.show()

다음 포스팅에서는 위에서 만든 가상의 시계열 데이터를 Python과 R을 사용해서 시계열 구성요인 별로 분해(time series decomposition)를 해보겠습니다. (//rfriend.tistory.com/509)

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. :-)

Toplist

최신 우편물

태그