그동안 여러 포스팅에 나누어서 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, http://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]:

timeseriestrendcycleseasonalirregular
2020-01-312.5961190.00.0000000.0000002.596119
2020-02-296.7461601.11.3321983.5656840.748278
2020-03-318.1121002.22.6406476.136825-2.865371
2020-04-308.2559413.33.9020216.996279-5.942358
2020-05-3116.8896554.45.0938345.9043271.491495
2020-06-3016.1823575.56.1948393.1655361.321981
2020-07-3114.1280876.67.185409-0.4561870.798865
2020-08-3111.9433137.78.047886-3.9506710.146099
2020-09-309.7280958.88.766892-6.343231-1.495567
2020-10-3112.4834899.99.329612-6.9665330.220411
2020-11-3012.14180811.09.726013-5.646726-2.937480
2020-12-3115.14333412.19.949029-2.751930-4.153764
2021-01-3121.77451613.29.9946840.910435-2.330604
2021-02-2828.43289214.39.8621644.318862-0.048134
2021-03-3132.35058315.49.5538326.5226690.874082
2021-04-3030.59655616.59.0751846.907169-1.885797
2021-05-3132.51052317.68.4347535.3651181.110653
2021-06-3030.42551918.77.6439552.3266241.754939
2021-07-3124.30095819.86.716890-1.360813-0.855119
2021-08-3120.45091720.95.670082-4.668691-1.450475
2021-09-3018.87088122.04.522195-6.674375-0.976939
2021-10-3121.32631023.13.293690-6.8184381.751059
2021-11-3022.90244824.22.006469-5.0606991.756678
2021-12-3126.62057825.30.683478-1.8914262.528526
2022-01-3127.62649926.4-0.6516961.8054040.072791
2022-02-2831.85892327.5-1.9752534.9986701.335506
2022-03-3135.93046928.6-3.2635986.7977043.796363
2022-04-3030.17787029.7-4.4937626.700718-1.729087
2022-05-3130.01616530.8-5.6438164.7347640.125217
2022-06-3026.59172931.9-6.6932581.448187-0.063200
2022-07-3121.11848133.0-7.623379-2.242320-2.015820
2022-08-3116.63603134.1-8.417599-5.307397-3.738973
2022-09-3017.68261335.2-9.061759-6.892132-1.563496
2022-10-3121.16329836.3-9.544375-6.5545090.962182
2022-11-3022.45567237.4-9.856844-4.388699-0.698786
2022-12-3126.91952938.5-9.993595-0.998790-0.588086
2023-01-3133.96462339.6-9.9521912.6697021.647112
2023-02-2837.45977640.7-9.7333695.5935590.899586
2023-03-3140.79376641.8-9.3410316.9572571.377540
2023-04-3043.83841542.9-8.7821716.3804333.340153
2023-05-3141.30178044.0-8.0667514.0239751.344556
2023-06-3039.21786645.1-7.2075260.5451470.780245
2023-07-3135.12550246.2-6.219813-3.085734-1.768952
2023-08-3133.84192647.3-5.121219-5.855940-2.480916
2023-09-3038.77051148.4-3.931329-6.9928031.294643
2023-10-3137.37121649.5-2.671356-6.179230-3.278198
2023-11-3046.58763350.6-1.363760-3.6421420.993536
2023-12-3146.40332651.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)를 해보겠습니다. (https://rfriend.tistory.com/509)


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

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



Posted by R Friend R_Friend

댓글을 달아 주세요