본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 시계열 결측치 0으로 해결하는 MICE 알고리즘의 한계와 3가지 대안 방법

by Papa Martino V 2026. 4. 23.
728x90

MICE(Multivariate Imputation by Chained Equations)
MICE (Multivariate Imputation by Chained Equations)

 

 

데이터 사이언스 실무에서 가장 까다로운 데이터 중 하나는 바로 시계열(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. 결론: 어떤 방법을 선택해야 하는가?

시계열 결측치 해결의 핵심은 "데이터의 주기성이 있는가?"입니다.

  1. 주기성이 뚜렷하다면 Seasonal Decomposition 기반 대치를 사용하세요.
  2. 변동성이 크고 노이즈가 많다면 Kalman Filter가 정답입니다.
  3. 단순히 흐름을 이어가야 한다면 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.
728x90