상세 컨텐츠

본문 제목

[시계열 스터디 1주차(조성윤)]: 2장 Review

본문

*본 게시물은 Practical Time Series Analysis(O'Reily)를 기반으로 작성되었습니다.

 

[2장: Finding and Wrangling Time Series Data]

 

(1) 데이터 수집

Kaggle(competition) 아니면 여러 개의 repository dataset에서 데이터를 수집할 수 있다.

- UCI Machine Learning Repository: https://archive.ics.uci.edu/ml/index.php

- UEA and UCR Time Series Classification Repository: https://timeseriesclassification.com/

- The Federal Reserve Bank of St.Louis: https://www.stlouisfed.org/

 

(2) 데이터 전처리

 

어느 데이터 분석 과정에서나 그렇듯 데이터 전처리 과정은 중요하다. 일반 데이터 분석처럼 결측치 처리, up/down sampling, smoothing 등의 방식을 적용하면 된다. 하지만 이외에도, 시계열 데이터만의 각별히 유념해야할 전처리 방식들이 있다.

 

i) Timestamp 데이터의 처리

Timestamp 데이터는 이처럼 연/월/일/시간/분/초 등의 정보가 담긴 것을 말한다. Timestamp를 면밀히 살펴보는 것이 굉장히 중요하다. 일반 데이터와 달리 Timestamp는 데이터의 의미가 모호한 경우가 굉장히 많다. 내가 생각했던 Timestamp의 의미가 작성자가 의도한 것이 아닐수도 있다. 따라서 언제, 어떻게 데이터가 만들어졌는지 꼼꼼히 점검해야 한다. 로그 기록일수도 있고, 사용자가 직접 작성한 CSV 파일의 형태일수도 있다.

다음의 예시를 살펴보면 동일 시간대에 pancake, sandwich, pizza를 모두 구입했음을 알 수 있다. 하지만 여기서 멈춰서는 안 되고 맥락을 고려하여 더 구체적인 정보를 추출해야 한다. 3개의 음식을 정말 모두 구매하려고 한 것인지, 여러 사람이 구매한 것인지 아니면 동일인물이 3개를 모두 주문한 것인지, 시간대는 어느 곳을 기준으로 한 것인지 등의 context를 구체적으로 확인할 필요가 있다. (특히, 시간 데이터에서 Local Time vs Universal Time 등을 보고 TIME ZONE을 구분하는 것이 매우 중요하다.) 데이터를 이해하기 가장 좋은 방법은 해당 데이터를 기록한 사람들에게 문의하거나 직접 자료 수집 방식이 어떻게 이루어졌는지 등을 살펴볼 필요가 있다. 

 

<결측치 처리 기법>

 

iii) Forward Fill 

결측치가 존재할 경우 바로 그 직전 값으로 채우는 방식이다. R의 zoo 패키지의 na.locf을 사용하면 문제를 해결할 수 있다.

다음은 unemployed 데이터셋에 해당 처리를 적용한 경우다.

## R
> rand.unemp[, impute.ff := na.locf(UNRATE, na.rm = FALSE)]
> bias.unemp[, impute.ff := na.locf(UNRATE, na.rm = FALSE)]

*Backward Fill은 금지: lookahead를 야기시킴.

 

iv) Moving Average

과거 여러 시점의 정보를 활용하여 미래 시점의 결측값들을 채우는 방식이다. 데이터가 noisy하고 개별 관측치들을 사용하기 어려울 경우 forward fill을 대신하여 averaging을 통해 noise를 제거하기 때문에 사용하기 적합하다. 반드시 arithmetic mean일 필요는 없고, geomtric mean이나 exponentiatlly weighted average등의 방법을 사용해도 괜찮다. 해당 경우 최근 데이터에 기본 데이터보다 더 weight를 제공할 수 있다. 주의할 점은 mean을 사용할 경우 전체 데이터의 분산을 줄이기 때문에, 모델링의 과접합 문제가 발생할 수 있다.

## R
> ## rolling mean without a lookahead
> rand.unemp[, impute.rm.nolookahead := rollapply(c(NA, NA, UNRATE), 3,
> function(x) {
> if (!is.na(x[3])) x[3] else mean(x, na.rm = TRUE)
> })] 
> bias.unemp[, impute.rm.nolookahead := rollapply(c(NA, NA, UNRATE), 3,
> function(x) {
> if (!is.na(x[3])) x[3] else mean(x, na.rm = TRUE)
> })]

 

 

<Seasonal Data 처리>

계절성은 특정 trend의 빈도가 자주 반복되어 stable한 경우를 뜻한다. 반드시 "계절(봄여름가을겨울)" 요인뿐만 아니라 daily, weekly, yearly 등 cycle이 존재하여 일정 시기에 반복되는 행위를 통틀어 칭한다. LOESS smoothing 기법을 통해 특정 시계열 데이터를 seasonal, trend, residuals로 decompose할 수 있다.

 

<Preventing Lookahead>

Lookahead는 시계열에서 미래에 대한 지식을 사용하는 것을 뜻한다. 모델링은 기본적으로 과거 데이터를 활용하여 "미지의" 미래 데이터를 예측하는 데 핵심이 있다. 즉, 미래 시점의 데이터는 절대 모델링, 학습, 평가 등의 일련의 과정에서 절대 활용되어서는 안 된다는 뜻이다. 모델링을 통해 미래를 예측을 하기도 전에 미래에 대한 정보를 파악하여 모델에 반영하는 것은 따라서 논리적으로 맞지 않다. 

미래에 일어날 일에 대한 정보가 모델링에서 과거로 전파되어 모델이 이전에 동작하는 방식에 영향을 미칠 수 있다. 예를 들어 모형에 대한 초모수(hyperparameter)를 선택할 때 데이터 집합에서 여러 번 모형을 검정한 다음 최적의 모형을 선택하고 이 모형을 검정하기 위해 데이터의 앞 부분에서 시작할 수 있다. 이것은 후속 시간에 발생할 일을 알고 모형을 선택했기 때문에 문제가 있다. 또 과거 데이터 분석에 구성원의 현재 상태를 적용하는 경우에는 당시에는 알 수 없는 시계열 모델에 무언가를 입력하기 때문에 이 또한 lookahead의 사례다.

 

Lookahead를 진단하는 정확한 통계적 방법은 없기 때문에 데이터를 임의로 변형, 평활, 샘플링 등의 기법을 적용할 때 수시로 점검하고 각별히 주의해야할 것이다. 한 가지 방법은 아직 알지 말아야 할 정보를 생성하는 타임스탬프에 대한 데이터를 사용하지 않음으로써 미래를 내다보는 것을 방지할 수 있다.

 

*참고: 데이터의 형태 변환 (tidy vs wide)

tidy data: 각 column은 변수명, 각 row는 관측치, 각 셀에는 하나의 관측치만 들어간 데이터.

관련글 더보기

댓글 영역