
데이터 사이언스 실무에서 가장 까다로운 데이터 중 하나는 바로 시계열(Time-Series) 데이터입니다. 시계열 데이터는 연속성(Continuity)과 계절성(Seasonality)을 기반으로 하기 때문에 일반적인 정형 데이터와는 결측치 처리 방식이 근본적으로 달라야 합니다. 많은 분석가들이 다중 대치법인 MICE(Multivariate Imputation by Chained Equations)를 만능 해결사로 생각하지만, 시계열 데이터에서는 오히려 독이 될 수 있습니다. 본 포스팅에서는 MICE 알고리즘이 시계열에서 가지는 치명적인 한계 2가지를 분석하고, 이를 해결할 수 있는 실무적인 대안과 파이썬 기반의 구현 예제 7가지를 상세히 다룹니다.
1. MICE 알고리즘과 시계열 전용 대치법의 차이 비교
일반적인 다변량 대치법과 시계열 전용 대치법이 어떻게 다른지 명확한 기준을 통해 비교해 보겠습니다.
| 비교 항목 | MICE (다중 대치법) | Time-Series Specific (시계열 전용) |
|---|---|---|
| 데이터 가정 | 변수 간의 상관관계 기반 | 시간 순서에 따른 자기상관성 기반 |
| 순서 의존성 | 행(Row)의 순서를 무시함 | 행의 순서가 가장 중요함 |
| 주요 알고리즘 | Iterative Imputer (Bayesian Ridge 등) | Kalman Filter, STL Decomposition |
| 결측치 분포 | MCAR(무작위 발생)에 최적 | 연속적 결측(Gap) 발생 시 유리 |
| 한계점 | 시계열의 '추세'와 '계절성'을 파괴함 | 변수가 하나일 때만 강력함 |
2. MICE 알고리즘이 시계열에서 실패하는 이유
MICE는 여러 변수가 서로를 예측하는 과정을 반복하여 결측치를 채웁니다. 하지만 시계열 데이터에서 $t$ 시점의 값은 $t-1$ 시점의 값에 강한 영향을 받습니다(자기상관). MICE는 기본적으로 각 행을 독립적인 샘플로 간주하기 때문에 다음과 같은 문제가 발생합니다.
- Temporal Leakage: 미래의 정보가 과거의 결측치를 채우는 데 비정상적으로 사용될 수 있습니다.
- Seasonality Distortion: 주 단위, 월 단위로 반복되는 패턴을 변수 간 관계만으로 설명하려다 보니 패턴이 뭉개집니다.
3. 실무자를 위한 파이썬 코드 샘플 (7가지 해결 예제)
시계열 데이터의 특성을 보존하면서 결측치를 완벽하게 복원하는 실무 코드를 소개합니다. pandas, scipy, statsmodels를 활용합니다.
#1. 보간법(Interpolation)을 활용한 선형 복원
가장 기본적이면서 강력한 방법으로, 앞뒤 데이터 포인트를 연결하여 결측치를 채웁니다.
import pandas as pd
import numpy as np
# 시계열 샘플 생성
df = pd.DataFrame({'value': [10, np.nan, np.nan, 40, 50, np.nan, 70]})
# 'linear' 방식은 등간격으로 값을 채움
df['linear'] = df['value'].interpolate(method='linear')
print(df)
#2. 시간 가중치 보간법 (Time-weighted Interpolation)
단순 인덱스가 아닌 실제 '시간 간격'에 비례하여 값을 할당합니다. 데이터 수집 간격이 불규칙할 때 필수적입니다.
df.index = pd.to_datetime(['2024-01-01', '2024-01-02', '2024-01-05', '2024-01-06', '2024-01-07', '2024-01-10', '2024-01-11'])
df['time_weighted'] = df['value'].interpolate(method='time')
#3. 칼만 필터(Kalman Filter)를 이용한 상태 공간 대치
노이즈가 섞인 시계열 데이터에서 최적의 추정치를 찾아내는 알고리즘입니다. 금융 데이터 복원에 자주 쓰입니다.
from pykalman import KalmanFilter
def kalman_impute(series):
kf = KalmanFilter(transition_matrices=[1], observation_matrices=[1],
initial_state_mean=series.mean(),
initial_state_covariance=1,
observation_covariance=1,
transition_covariance=0.01)
state_means, _ = kf.filter(series.fillna(0).values)
return state_means
# 주의: 실제 적용 시 파라미터 튜닝이 필요합니다.
#4. 계절성 조정 보간 (Seasonal Decomposition Imputation)
시계열을 추세(Trend)와 계절성(Seasonality)으로 분리한 후, 각각을 대치하고 다시 합치는 고난도 기술입니다.
from statsmodels.tsa.seasonal import seasonal_decompose
# 데이터를 분해하여 계절성 성분을 유지한 채 결측치 처리
result = seasonal_decompose(df['value'].fillna(method='ffill'), model='additive', period=7)
# 분해된 성분을 활용하여 정교한 대치 로직 구현 가능
#5. LOCF(Last Observation Carried Forward) & NOCB
직전 값 혹은 직후 값을 그대로 가져오는 방식입니다. 센서 데이터에서 짧은 결측이 발생했을 때 지연(Latency) 없이 처리하기 좋습니다.
# 이전 값으로 채우기 (LOCF)
df['locf'] = df['value'].ffill()
# 이후 값으로 채우기 (NOCB)
df['nocb'] = df['value'].bfill()
#6. Rolling Mean (이동 평균) 기반 대치
국소적인 평균을 활용하여 변동성을 억제하며 결측치를 채웁니다.
df['rolling_mean'] = df['value'].fillna(df['value'].rolling(window=3, min_periods=1, center=True).mean())
#7. 스플라인(Spline) 보간법으로 곡선 복원
데이터가 급격하게 변하지 않고 부드러운 곡선을 이룰 때 사용합니다. 차수(order)를 조절하여 유연성을 확보합니다.
# 2차 스플라인 보간
df['spline'] = df['value'].interpolate(method='spline', order=2)
4. 결론: 어떤 방법을 선택해야 하는가?
시계열 결측치 해결의 핵심은 "데이터의 주기성이 있는가?"입니다.
- 주기성이 뚜렷하다면 Seasonal Decomposition 기반 대치를 사용하세요.
- 변동성이 크고 노이즈가 많다면 Kalman Filter가 정답입니다.
- 단순히 흐름을 이어가야 한다면 Time Interpolation이 가장 안정적입니다.
MICE는 변수 간 상관관계가 시계열적 특성보다 압도적으로 중요할 때만 제한적으로 사용해야 함을 명심하시기 바랍니다.
내용 출처:
- Moritz, S., & Bartz-Beielstein, T. (2017). "imputeTS: Time Series Missing Value Imputation in R." The R Journal.
- Hyndman, R.J., & Athanasopoulos, G. (2018). "Forecasting: Principles and Practice." OTexts.
- Pandas Official Documentation: Working with missing data.
'Artificial Intelligence > 60. Python' 카테고리의 다른 글
| [PYTHON] 고차원 데이터 시각화를 위한 t-SNE vs UMAP 2가지 알고리즘 성능 및 해석 차이 해결 방법 (0) | 2026.04.23 |
|---|---|
| [PYTHON] 고차원 카테고리 데이터 해결을 위한 Target Encoding 오버피팅 방지 7가지 방법 (0) | 2026.04.23 |
| [PYTHON] 효율적인 데이터 라벨링을 위한 Active Learning 샘플링 전략 7가지 해결 방법 (0) | 2026.04.23 |
| [PYTHON] 저작권 데이터 학습 모델의 법적 리스크 해결을 위한 7가지 관리 방법과 차이점 (0) | 2026.04.23 |
| [PYTHON] 멀티코어 AI 서버 성능 저하를 해결하는 GIL 우회 및 최적화 7가지 방법 (0) | 2026.04.23 |