시계열 데이터

  • 일정한 시간 간격으로 기록된 확률과정의 샘플
  • 독립변수($$x_{t}$$)와 알고자 하는 종속변수($$y_{t}$$)가 시간 단위를 포함
  • 모델의 출력은 y의 시간 t에서 예측값
  • 기계학습과 시계열예측의 큰 차이가 존재해서 조정이 필요

독자적인 시계열 성분들

  • 1) 빈도(Frequency) : 계절성 패턴이 나타나기 전까지 데이터 갯수로, 사람이 정해야 함
    • 계절성이 1년에 1회일 경우, Annual은 1, Monthly 12
    • 데이터가 일 단위로 수집되면 Weekly는 7, Annual 365
  • 2) 추세(Trend) : 시계열이 시간에 따라 증가, 감소, 일정 수준을 유지하는 경우
    • 확률과정의 결정론적 기댓값 함수를 알아내는 것 확률과정이 추정 가능한 결정론적 추세함수와 정상확률과정의 합
  • 3) 계절성(Seasonality) : 일정한 빈도로 주기적으로 반복되는 패턴, 특정한 달/요일에 따라 기대값이 달라지는 것
  • 4) 주기(Cycle) : 일정하지 않은 빈도로 발생하는 패턴

시계열 분해

  • 추세, 계절성, 잔차로 나누는 일

더미 변수

  • 이진수의 형태로 변수를 생성하는 것
  • 이벤트, 캠페인, 아웃라이어 등을 생성 가능
  • 확실한 패턴이 존재할 경우만 효과가 있음

지연값(Lag)

  • 변수의 지연된 값을 독립변수로 반영

시계열 알고리즘의 2가지 차별화 방향

  • 학습된 도메인 영역 내 패턴뿐 아니라 외부 시점으로 데이터를 확장할 수 있어야 함
  • 시계열 알고리즘은 점 추정이 아닌 구간추정 알고리즘으로 설명력 효과에 뿌리를 둠
  • 정확성과 설명력 반비례 관계 존재함

검증지표(Evaluation Metrics)과 잔차진단(Residuals Diagnostics)이 사용됨

  • 예측 분석 이후 예측이 잘 되었는지, 데이터의 시간패턴이 잘 추출되었는지 평가
    • 검증지표 : 예측값과 실제값이 얼마나 비슷한지 측정
    • 잔차진단 : 시간특성 패턴이 잘 추출되었는지 확인하기 위해, 백색잡음과 얼마나 유사한지 측정

잔차진단(Residual Diagnostics)

  • 백색잡음은 2가지 속성을 만족해야 하고, 만족하지 못하면 모델이 개선 여지가 있음을 뜻함
    • 1) 잔차들은 정규분포고, 평균 0과 일정한 분산을 가짐
    • 2) 잔차들이 시간의 흐름에 따라 상관성이 없어야 함
      • Autocorrelation Function(ACF)를 통해 Autocorrelation=0인지 확인
      • ACF : 자기상관함수
      • PACF : s와 k 사이의 상관성을 제거한 자기상관함수 ### 분석 효과에 도움될 시간영역(해상도)을 선택
  • 연단위? 월단위? 일단위?

시계열 회귀분석 요약

  • t개의 값을 가지는 k차원 독립변수 $$X_{i}$$와 이에 대응하는 종속 변수 Y간의 관계를 정량적으로 찾는 알고리즘

모델링

  • 독립 변수나 종속 변수가 정규 분포와 가까운 분포를 보일수록 선형회귀모형의 성능이 좋아지는 경우가 많음
  • 비선형변수 효과 : 로그/제곱근 등의 변환된 변수 사용시 회귀분석 성능 향상 가능
    • 독립 변수나 종속 변수가 한쪽으로 치우진 분포를 보이는 경우
    • 독립 변수와 종속 변수간의 관계가 곱셈 혹은 나눗셈으로 연결된 경우
    • 종속 변수와 예측치가 비선형 관계를 보이는 경우

검증 방향(계수 추정)

결정론적 모형(Deterministic Model)

  • 잔차제곱합 (Residual Sum of Squares)을 최소로 하는 베타를 추정
  • 정리
    • $$X^{T}X$$ 행렬이 역행렬이 존재해야 해를 추정할 수 있음
    • 역행렬이 미존재
      • X가 서로 독립이 아님, X가 Full Rank가 아님, $$X^{T}X$$가 정부호가 아님

확률론적 모형(Probabilistic Model)

  • 종속 변수의 발생가능성을 최대(최소)로 하는 베타를 추정
    • 필요성 : 결정론적 선형 회귀모형(OLS)는 데이터의 확률론적 가정이 없어서 점추정을 하나, 신뢰도는 확인할 수 없음
  • 정리
    • X, Y 중 어느것도 정규분포일 필요는 없음
    • Y는 X에 대해 조건부로 정규분포를 따르며 Y 자체가 무조건 정규분포일 필요는 없음
    • 잔차의 기대값은 0
    • 잔차의 조건부 기대값은 0
    • 잔차와 독립변수 X는 상관관계 없음
    • X와 무관하게 잔차들간의 공분산의 0

검증(Evaluation)

R-squared

  • 추정된 선형 모형이 주어진 데이터에 잘 적합된 정도

T 검정

  • t분포를 따르는 추정계수로 독립 변수와 종속 변수간의 선형 관계 의사결정을 위한 신뢰도
    • t값이 작으면 표준편차가 큰 것 => 독립변수와 종속변수의 상관성이 낮음
    • t값이 크면 표준편차가 작은 것 => 독립변수와 종속변수의 상관성이 높음
    • p value가 내 기준보다 높으면 영향력이 없는 feature

F 검정

  • 변수의 단위, 스케일이 달라지면 회귀분석과 상관없이 잔차제곱합이 달라짐
  • 분산 분석(ANOVA)은 종속변수의 분산과 독립변수의 분산의 관계를 사용해 성능 평가
  • 검정통계량(F-통계량)

정보량 기준

  • Information Criterion
  • 값이 작을수록 올바른 모형
  • AIC : 모형과 데이터의 확률 분포 사이의 Kullback-Leibler 수준을 가장 크게하기 위한 시도
  • BIC : 데이터가 exponential family라는 가정하에 주어진 데이터에서 모형의 likelihood를 측정하기 위한 값에서 유도

잔차 진단시 Flow

  • 1) 정상성 테스트 : 잔차가 백색잡음의 형태인지
  • 2) 정규분포 테스트 : 잔차가 정규분포의 형태인지
  • 3) 자기상관 테스트 : 잔차가 서로 시간흐름에서 독립적인지
  • 4) 등분산성 테스트 : 잔차의 분산이 일정한지

정상성 테스트

  • 우선 데이터 시각화를 통해 확인
  • Augmented Dickey-Fuller(ADF) test:

    • 가설확인
      • 대중주장(귀무가설, Null Hypothesis, $H_0$): 시계열 데이터는 단위근(Unit Root)를 있다 / 비정상 상태이다 / 시간의존 구조이다
      • 나의주장(대립가설, Alternate Hypothesis, $H_1$): 시계열 데이터는 단위근이 없다 / 정상 상태이다 / 시간의존 구조가 아니다
    • 의사결정
      • p-value >= 내기준(ex. 0.05): 내가 수집한(분석한) 시계열 데이터가 대중주장과 유사하기 때문에 대중주장 참 & 나의주장 거짓
        • 수집한(분석한) 시계열 데이터는 단위근니 있다 / 비정상 상태이다 / 시간의존 구조이다
      • p-value < 내기준(ex. 0.05): 내가 수집한(분석한) 시계열 데이터가 대중주장을 벗어나기 때문에 대중주장 거짓 & 나의주장 참
        • 수집한(분석한) 시계열 데이터는 단위근이 없다 / 정상 상태이다 / 시간의존 구조가 아니다
  • ADF-GLS test:

    • 가설확인: ADF와 동일
  • Phillips–Perron(PP) test:
    • 가설확인: ADF와 동일
  • Kwiatkowski Phillips Schmidt Shin(KPSS) test:
    • 가설확인: ADF와 반대

정규분포 테스트(Normality Test)

  • Shapiro–Wilk test:

    • 가설확인
      • 대중주장(귀무가설, Null Hypothesis, $H_0$): 데이터는 정규분포 형태이다
      • 나의주장(대립가설, Alternate Hypothesis, $H_1$): 데이터는 정규분포가 아닌 형태다
    • 의사결정
      • p-value >= 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장과 유사하기 때문에 대중주장 참 & 나의주장 거짓

        내가 수집한(분석한) 데이터는 정규분포 형태이다

      • p-value < 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장을 벗어나기 때문에 대중주장 거짓 & 나의주장 참

        내가 수집한(분석한) 데이터는 정규분포가 아닌 형태다

  • Kolmogorov–Smirnov test:

    • 가설확인: Shapiro–Wilk와 동일
  • Lilliefors test:

    • 가설확인: Shapiro–Wilk와 동일
  • Anderson–Darling test:

    • 가설확인: Shapiro–Wilk와 동일
  • Jarque–Bera test:

    • 가설확인: Shapiro–Wilk와 동일
  • Pearson's chi-squared test:

    • 가설확인: Shapiro–Wilk와 동일
  • D'Agostino's K-squared test:

    • 가설확인: Shapiro–Wilk와 동일

자기상관 테스트(Autocorrelation Test)

  • Ljung–Box test:

    • 가설확인
      • 대중주장(귀무가설, Null Hypothesis, $H_0$): 시계열 데이터의 Autocorrelation은 0이다(존재하지 않는다)
      • 나의주장(대립가설, Alternate Hypothesis, $H_1$): 시계열 데이터의 Autocorrelation은 0이 아니다(존재한다)
    • 의사결정
      • p-value >= 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장과 유사하기 때문에 대중주장 참 & 나의주장 거짓

        내가 수집한(분석한) 시계열 데이터의 Autocorrelation은 존재하지 않는다

      • p-value < 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장을 벗어나기 때문에 대중주장 거짓 & 나의주장 참

        내가 수집한(분석한) 시계열 데이터의 Autocorrelation은 존재한다

  • Portmanteau test:

    • 가설확인: Ljung–Box와 동일
  • Breusch–Godfrey test:

    • 가설확인: Ljung–Box와 동일
  • Durbin–Watson statistic:

    • 가설확인: Ljung–Box와 동일
    • 의사결정: 검정통계량 범위 - $[0, 4]$
      • 2 근방: 내가 수집한(분석한) 데이터가 대중주장과 유사하기 때문에 대중주장 참 & 나의주장 거짓

        내가 수집한(분석한) 시계열 데이터의 Autocorrelation은 존재하지 않는다

      • 0 또는 4 근방: 내가 수집한(분석한) 데이터가 대중주장을 벗어나기 때문에 대중주장 거짓 & 나의주장 참

        내가 수집한(분석한) 시계열 데이터의 Autocorrelation은 존재한다

        • 0: 양(Positive)의 Autocorrelation 존재한다
        • 4: 음(Negative)의 Autocorrelation 존재한다

등분산성 테스트(Homoscedasticity Test)

  • Goldfeld–Quandt test:

    • 가설확인
      • 대중주장(귀무가설, Null Hypothesis, $H_0$): 시계열 데이터의 Homoscedasticity 상태다(등분산이다)
      • 나의주장(대립가설, Alternate Hypothesis, $H_1$): 시계열 데이터의 Heteroscedasticity 상태다(등분산이 아니다 / 발산하는 분산이다)
    • 의사결정
      • p-value >= 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장과 유사하기 때문에 대중주장 참 & 나의주장 거짓

        내가 수집한(분석한) 시계열 데이터는 등분산이다

      • p-value < 내기준(ex. 0.05): 내가 수집한(분석한) 데이터가 대중주장을 벗어나기 때문에 대중주장 거짓 & 나의주장 참

        내가 수집한(분석한) 시계열 데이터는 등분산이 아니다

  • Breusch–Pagan test:

    • 가설확인: Goldfeld–Quandt와 동일
  • Bartlett's test:

    • 가설확인: Goldfeld–Quandt와 동일

In [1]:
import warnings
warnings.filterwarnings('always')
warnings.filterwarnings('ignore')

# System related and data input controls
import os

# Data manipulation and visualization
import pandas as pd
pd.options.display.float_format = '{:,.2f}'.format
pd.options.display.max_rows = 10
pd.options.display.max_columns = 20
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Modeling algorithms
# General
import statsmodels.api as sm
from scipy import stats

# Model selection
from sklearn.model_selection import train_test_split

# Evaluation metrics
# for regression
from sklearn.metrics import mean_squared_log_error, mean_squared_error,  r2_score, mean_absolute_error

In [3]:
location = '../data/Bike_Sharing_Demand_Full.csv'
raw_all = pd.read_csv(location)
raw_all


Out[3]:
datetime season holiday workingday weather temp atemp humidity windspeed casual registered count
0 2011-01-01 0:00 1 0 0 1 9.84 14.39 81 0.00 3 13 16
1 2011-01-01 1:00 1 0 0 1 9.02 13.63 80 0.00 8 32 40
2 2011-01-01 2:00 1 0 0 1 9.02 13.63 80 0.00 5 27 32
3 2011-01-01 3:00 1 0 0 1 9.84 14.39 75 0.00 3 10 13
4 2011-01-01 4:00 1 0 0 1 9.84 14.39 75 0.00 0 1 1
... ... ... ... ... ... ... ... ... ... ... ... ...
17374 2012-12-31 19:00 1 0 1 2 10.66 12.88 60 11.00 11 108 119
17375 2012-12-31 20:00 1 0 1 2 10.66 12.88 60 11.00 8 81 89
17376 2012-12-31 21:00 1 0 1 1 10.66 12.88 60 11.00 7 83 90
17377 2012-12-31 22:00 1 0 1 1 10.66 13.63 56 9.00 13 48 61
17378 2012-12-31 23:00 1 0 1 1 10.66 13.63 65 9.00 12 37 49

17379 rows × 12 columns


In [7]:
raw_all['datetime'] = pd.to_datetime(raw_all['datetime'])
raw_all['DateTime'] = pd.to_datetime(raw_all['datetime'])

In [8]:
if raw_all.index.dtype == 'int64':
    raw_all.set_index('DateTime', inplace=True)

In [10]:
raw_all


Out[10]:
datetime season holiday workingday weather temp atemp humidity windspeed casual registered count
DateTime
2011-01-01 00:00:00 2011-01-01 00:00:00 1 0 0 1 9.84 14.39 81 0.00 3 13 16
2011-01-01 01:00:00 2011-01-01 01:00:00 1 0 0 1 9.02 13.63 80 0.00 8 32 40
2011-01-01 02:00:00 2011-01-01 02:00:00 1 0 0 1 9.02 13.63 80 0.00 5 27 32
2011-01-01 03:00:00 2011-01-01 03:00:00 1 0 0 1 9.84 14.39 75 0.00 3 10 13
2011-01-01 04:00:00 2011-01-01 04:00:00 1 0 0 1 9.84 14.39 75 0.00 0 1 1
... ... ... ... ... ... ... ... ... ... ... ... ...
2012-12-31 19:00:00 2012-12-31 19:00:00 1 0 1 2 10.66 12.88 60 11.00 11 108 119
2012-12-31 20:00:00 2012-12-31 20:00:00 1 0 1 2 10.66 12.88 60 11.00 8 81 89
2012-12-31 21:00:00 2012-12-31 21:00:00 1 0 1 1 10.66 12.88 60 11.00 7 83 90
2012-12-31 22:00:00 2012-12-31 22:00:00 1 0 1 1 10.66 13.63 56 9.00 13 48 61
2012-12-31 23:00:00 2012-12-31 23:00:00 1 0 1 1 10.66 13.63 65 9.00 12 37 49

17379 rows × 12 columns


In [14]:
raw_all = raw_all.asfreq('H', method='ffill')
raw_all.isnull().sum()


Out[14]:
datetime      0
season        0
holiday       0
workingday    0
weather       0
             ..
humidity      0
windspeed     0
casual        0
registered    0
count         0
Length: 12, dtype: int64

In [15]:
raw_all[['count']].plot(kind='line', figsize=(20,6), linewidth=3, fontsize=20,
                                              xlim=('2012-01-01', '2012-03-01'), ylim=(0,1000))
plt.title('Time Series of Target', fontsize=20)
plt.xlabel('Index', fontsize=15)
plt.ylabel('Demand', fontsize=15)
plt.show()



In [17]:
sm.tsa.seasonal_decompose(raw_all['count'], model='additive').plot()
plt.show()



In [ ]: