시계열 분해
주요 개념:
- 덧셈 분해
- 곱셈 분해
- 고전적 분해법
- STL 분해
- 추세와 계절성의 강도
덧셈 분해 additive decomposition
- : 종속 변수
- : 계절 성분
- : 추세 성분(주기 성분을 포함)
- : 나머지 성분
곱셈 분해 multiplicative decomposition
- : 종속 변수
- : 계절 성분
- : 추세 성분(주기 성분을 포함)
- : 나머지 성분
전자 장비 주문
- 전자 장비에 대한 신규 주문 지수 데이터
- 유럽 지역(16개국)에서 전자 장비(컴퓨터, 전자, 광학 제품)에 대한 신규 주문량
- 근무일 기준으로 조정
- 2005년 값이 100이 되도록 조정
실습 준비
- 실습 데이터
import pandas as pd
df = pd.read_excel('elecequip.xlsx')
- 행은 연도, 열은 월 형태로 되어 있는 데이터
- pd.melt로 연-월별 데이터로 변환
ym = pd.melt(df, id_vars=['year'], var_name='month', value_name='demand')
월 순서대로 정렬
- 월을 정렬된 범주형 데이터로 변환
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
ym['month'] = pd.Categorical(ym['month'], categories=months, ordered=True)
- 연월 순으로 정렬하고, 값이 비어있는 행은 삭제, 행번호 재지정
ym = ym.sort_values(['year', 'month']).dropna().reset_index()
고전적 분해법
- 1920년대에 창안, 단순하지만 다른 시계열 분해 방법의 기초
- 계절 성분이 매년 일정하다고 가정
- 덧셈 분해:
- 1단계: 이동평균으로 추세 성분 계산
- 2단계: 시계열에서 추세 성분을 제거
- 3단계: 계절성의 각 주기(분기, 월, 요일 등)를 평균내어 계절 성분 구함
- 4단계: 시계열에서 추세 성분과 계절 성분을 제거하여 나머지 성분 계산
- 곱셈 분해:
- 덧셈 분해와 동일하나 성분을 제거할 때 뺄셈 대신 나눗셈
- 또는 시계열에 로그를 취한 후, 덧셈 분해를 하고 다시 지수 함수를 적용하면 곱셈 분해와 같음
덧셈 분해 실습: 추세 성분 제거
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(ym['demand'], model='additive', period=12) # 1년 주기
result.plot();
- demand
- Trend
- Seasonal
- Resid
성분별 보기
- 추세 성분
result.trend
- 계절 성분
result.seasonal
- 나머지 성분
result.resid
계절적 조정
- 데이터에서 계절성을 제거하거나
adjusted = ym.demand - result.seasonal
- 추세와 나머지 성분을 더함
adjusted = result.trend + result.resid
- 시각화
adjusted.plot()
LOESS
- locally estimated scatterplot smoothing
- 국소 회귀 (local regression)
- 시계열의 각 부분을 t에 대해 회귀 분석하여 얻은 추세선을 이어 붙임
- 장점:
- 어떤 종류의 계절성도 다룰 수 있음
- 계절적인 성분이 시간에 따라 변해도 괜찮음
- 추세의 매끄러운 정도를 사용자가 조절할 수 있음
- 이상값의 영향을 조절
STL 분해
- LOESS를 사용한 계절성과 추세 분해
- Seasonal and Trend decomposition using LOESS
- R. B. Cleveland, Cleveland, McRae, & Terpenning (1990)
- STL 분해. period에는 계절성 주기
from statsmodels.tsa.seasonal import STL
result = STL(ym.demand, period = 12).fit()
result.plot();
- demand
- Trend
- Seasonal
- Resid
STL: 이상점의 영향 조절
robust=True로 설정하면 이상점을 더 허용- 일시적으로 크게 이탈한 사건의 영향을 추세와 계절 성분에 적게 반영
STL(ym.demand, period = 12, robust=True).fit().plot()
- demand
- Trend
- Seasonal
- Resid
STL: 추세의 매끄러움
trend: 클 수록 추세가 매끄러워짐.period보다 큰 홀수여야 함
STL(ym.demand, period = 12, trend = 13).fit().trend.plot()
STL: 계절 성분의 매끄러움
seasonal: 클 수록 추세가 매끄러워짐. 3보다 큰 홀수여야 함(기본값 7)
STL(ym.demand, period = 12, seasonal=3).fit().seasonal.plot()
추세의 강도 strength
- 계절성을 조정한 데이터의 분산과 나머지 성분의 분산을 비교
- 0~1 범위의 값 (0보다 작을 경우는 0으로)
- 0에 가까울 수록 추세가 거의 없음
- 1에 가까울 수록 추세가 매우 강함
1 - result.resid.var() / (result.trend + result.resid).var()
계절성의 강도
- 추세를 제거한 데이터의 분산과 나머지 성분의 분산을 비교
- 0~1 범위의 값 (0보다 작을 경우는 0으로)
- 0에 가까울 수록 계절성이 거의 없음
- 1에 가까울 수록 계절성이 매우 강함
1 - result.resid.var() / (result.seasonal + result.resid).var()