시계열 데이터는 관측값이 관측된 시점에 의존하는지에 따라 정상성(stationary) 데이터와 비정상성(non-stationary) 데이터로 나눌 수 있다.
비정상성 데이터는 시간에 따라 통계적 특성이 변하는 데이터이다.
비정상 시계열은 정상 시계열에 자료의 특성인 추세성(trend) 또는 계절성(seasonality)이 내포되어 있어 데이터가 시간의 흐름에 따라 불규칙적으로 변동된다. 시계열 데이터는 현재의 상태가 과거와 미래의 상태에 밀접한 연관을 지니는 자기상관(autocorrelation)이 있는 비정상성 데이터가 많다.
비정상 시게열의 특징을 정리하면,
불규칙한 자료에서 나타나는 특성을 단순화하여 불규칙하게 만드는 요인을 정리하면 다음과 같다.
추세성
장기적으로 데이터에 상승이나 하강 경향성이 존재하는 것을 의미한다.
계절성
일정한 빈도로 반복되는 패턴으로, 해마다 규칙적이고 주기적으로 나타나는 것을 의미한다.
일 년 이하의 주기로 관찰했을 때 자연의 조건, 사회적 관습, 제도 등으로 인해 주기적 패턴을 갖고 계절적인 차이를 보이는 것이다.
주기성
고정된 빈도가 아닌 형태로 증가나 감소의 형태를 보이는 것이다.
계절성으로 설명되지 않는 장기적 변동이다.
참고 : https://sodayeong.tistory.com/m/19
예시)
<캐나다 북서부의 맥킨지 강 지역에서 연간 포획된 스라소니의 전체 수>![]()
위 그래프에서 주기가 보이기에 비정상 시계열로 생각할 수 있지만, 주기가 불규칙적이기 때문에 정상성 시계열이다. y축 값이 변하는 이유를 살펴보면, 먹이를 구하기 힘들만큼 살쾡이 개체수가 너무 많이 늘어나 번식을 멈춰서 개체수가 작은 숫자로 줄어들게 되고, 그후에 먹이를 구할 수 있게 되어 개체수가 다시 늘어나는 식이다. 장기적으로 볼 때, 이러한 주기의 시작이나 끝은 예측할 수 없기에 정상성 시계열이다.
참고 : https://otexts.com/fppkr/stationarity.html
y축의 주기가 예측 가능한 기간에 맞춰 규칙적으로 나타나는지, 불규칙적으로 나타나는지를 통해 주기성과 계절성을 구분하면 될 것 같다.
불규칙성
사전적으로 예상할 수 없는 특수한 사건에 의해 변동되는 것이다.
비정상성 시계열 예시로는 확률보행(random walk)이 있다. 확률보행이란 임의의 방향으로 움직이는 연속적인 값으로, 시간에 따른 편차의 평균은 0이고 분산은 시간에 비례해서 증가한다. 앞/뒤로 움직일 확률이 동일해도 시간의 흐름에 따라 평균에서 점차 벗어나는 경향을 보인다. 이것이 확률보행이 비정상성인 이유가 될까.
참고 : https://codetorial.net/articles/python_random_walk.html
확률보행을 파이썬으로 구현해보자.
<확률보행 1>
import numpy as np
import matplotlib.pyplot as plt
probability = [0.5, 0.5]
# up, down일 확률
start = 0
rand_walks = [start]
rand_point = np.random.random(300)
down_probability = rand_point < probability[0]
#random 300개의 실수들이 앞으로 갈 확률(0.5)보다 작으면 True로 저장
up_probability = rand_point >= probability[1]
#random 300개의 실수들이 뒤로 갈 확률(0.5)보다 크거나 같으면 True로 저장
print(down_probability)
print(up_probability)
<출력>
(생략)
for down, up in zip(down_probability, up_probability):
rand_walks.append(rand_walks[-1]-down+up)
#down, up이 True/False로 저장되어 있지만
#숫자와 연산할 땐 False->0, True->1로 취급되는것 같다.
print(rand_walks)
<출력>
plt.plot(rand_walks)
plt.show()
<출력>
from pandas import Series
series = Series(rand_walks)
print(series.describe())
<출력>