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

[PYTHON] 데이터 드리프트(Data Drift) 탐지를 위한 7가지 통계적 방법과 해결 차이점

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

데이터 드리프트(Data Drift) 탐지
데이터 드리프트(Data Drift) 탐지

 

인공지능 모델이 배포된 후, 시간이 지남에 따라 성능이 저하되는 현상을 겪어보셨나요? 이는 모델 자체의 결함보다는 입력되는 데이터의 분포가 학습 당시와 달라지는 데이터 드리프트(Data Drift) 때문인 경우가 많습니다. 특히 금융, 이커머스, 제조 공정 등 변화가 빠른 도메인에서 드리프트 탐지는 MLOps의 필수적인 생존 전략입니다. 본 포스팅에서는 단순히 모델 성능(Accuracy, F1)을 모니터링하는 것을 넘어, 데이터의 '분포 변화'를 정밀하게 포착할 수 있는 통계적 방법론 7가지를 심층 분석합니다. 각 기법의 메커니즘 차이를 이해하고, 파이썬을 활용해 실무 환경에서 즉시 구동 가능한 해결 코드를 제시합니다.


1. 데이터 드리프트 탐지 알고리즘별 특징 및 적합성 비교

데이터의 특성(수치형, 범주형)과 데이터양에 따라 최적의 통계 검정 방법이 달라집니다. 아래 표는 실무에서 가장 자주 사용되는 기법들을 비교한 결과입니다.

검정 방법론 대상 데이터 타입 핵심 메커니즘 성능 및 민감도 차이
KS Test 수치형 (Continuous) 두 누적분포함수(CDF)의 최대 거리 측정 표본 크기가 작아도 민감하게 반응
Chi-Squared 범주형 (Categorical) 기대 빈도와 실제 빈도의 차이 합산 범주가 많을수록 신뢰도 높음
PSI 수치형/범주형 공용 분포 버킷별 비율 차이(Entropy 기반) 금융권 표준, 변화 크기 정량화 우수
JS Divergence 확률 분포 KL Divergence의 대칭적/유한한 버전 두 분포 간의 거리를 0~1 사이로 정규화
Wasserstein Dist. 수치형 (Continuous) 한 분포를 다른 분포로 옮기는 최소 비용 분포의 이동(Shift) 감지에 탁월

2. 실무 MLOps를 위한 데이터 드리프트 탐지 Sample Example 7가지

개발자가 파이썬 데이터 사이언스 환경에서 즉시 복사하여 자동화 파이프라인에 적용할 수 있는 핵심 코드셋입니다.

Example 1: Kolmogorov-Smirnov (KS) Test를 이용한 수치형 변수 탐지

Scipy 라이브러리를 활용하여 두 데이터 집단이 동일한 분포에서 왔는지 가설 검정을 수행합니다.

import numpy as np
from scipy.stats import ks_2samp

# Reference: 학습 데이터, Current: 실제 운영 데이터
reference_data = np.random.normal(0, 1, 1000)
current_data = np.random.normal(0.2, 1.1, 1000) # 평균이 살짝 이동한 상황

statistic, p_value = ks_2samp(reference_data, current_data)

if p_value < 0.05:
    print(f"[Alert] Drift Detected! P-value: {p_value:.4f}")
else:
    print("Data distribution is stable.")
    

Example 2: Population Stability Index (PSI) 함수 구현 및 해결

금융권에서 가장 신뢰받는 지표인 PSI를 수동으로 구현하여 분포 안정성을 수치화합니다.

def calculate_psi(expected, actual, buckets=10):
    def scale_range(data, bins):
        return np.histogram(data, bins=bins)[0] / len(data)

    breakpoints = np.histogram(expected, bins=buckets)[1]
    expected_per = scale_range(expected, breakpoints)
    actual_per = scale_range(actual, breakpoints)

    # 0으로 나누기 방지
    actual_per = np.where(actual_per == 0, 0.0001, actual_per)
    expected_per = np.where(expected_per == 0, 0.0001, expected_per)

    psi_val = np.sum((actual_per - expected_per) * np.log(actual_per / expected_per))
    return psi_val

psi = calculate_psi(reference_data, current_data)
# 통상적으로 0.2 이상이면 큰 변화(Drift)로 판단
print(f"PSI Value: {psi:.4f}")
    

Example 3: 카이제곱 검정(Chi-Squared)을 통한 범주형 변수 변화 포착

성별, 지역, 상품 카테고리 등 범주형 데이터의 빈도 변화를 탐지하는 표준 방법입니다.

from scipy.stats import chisquare

# 각 카테고리별 빈도수 (Reference vs Current)
f_exp = [200, 300, 500] # 학습 당시 비율
f_obs = [180, 350, 470] # 운영 중 관측 비율

chi_stat, p_val = chisquare(f_obs, f_exp=f_exp)

if p_val < 0.05:
    print(f"Categorical Drift Detected! P-value: {p_val:.4f}")
    

Example 4: Jensen-Shannon Divergence 기반의 분포 거리 측정

KL Divergence의 단점(비대칭성)을 해결한 지표로, 두 확률 분포 사이의 거리를 계산합니다.

from scipy.spatial.distance import jensenshannon

# 확률 밀도 함수(PDF)로 변환 후 계산
p = np.histogram(reference_data, bins=50, density=True)[0]
q = np.histogram(current_data, bins=50, density=True)[0]

js_dist = jensenshannon(p, q)
print(f"JS Divergence Distance: {js_dist:.4f}")
    

Example 5: Wasserstein Distance (Earth Mover's Distance) 활용

분포가 얼마나 '이동'했는지 물리적인 관점에서 정량화하는 기법입니다.

from scipy.stats import wasserstein_distance

w_dist = wasserstein_distance(reference_data, current_data)
print(f"Wasserstein Distance: {w_dist:.4f}")
    

Example 6: Evidently AI 라이브러리를 활용한 대시보드 리포팅

수동 계산 대신 전문 라이브러리를 사용하여 시각화된 리포트를 생성하는 자동화 해결책입니다.

# pip install evidently
import pandas as pd
from evidently.report import Report
from evidently.metric_preset import DataDriftPreset

ref_df = pd.DataFrame({'feature': reference_data})
cur_df = pd.DataFrame({'feature': current_data})

drift_report = Report(metrics=[DataDriftPreset()])
drift_report.run(reference_data=ref_df, current_data=cur_df)
drift_report.save_html("drift_report.html")
    

Example 7: 다변량 드리프트 탐지를 위한 Reconstruction Error (Autoencoder)

변수가 너무 많을 때 각 변수를 따로 검사하는 대신, 오토인코더의 재구성 오차 변화를 통해 전체적인 드리프트를 탐지합니다.

# 개념 예시: 모델이 익숙하지 않은 데이터(Drifted)를 만났을 때 에러율 상승을 모니터링
# 1. Reference 데이터로 Autoencoder 학습
# 2. 새로운 데이터 입력 시 MSE(Mean Squared Error) 계산
# 3. MSE가 임계치(Threshold)를 넘으면 다변량 드리프트로 판단
    

3. 전문가의 시각: 드리프트 탐지 시 주의사항과 비즈니스 가치

단순히 통계적 유의성(P-value)만 보고 드리프트라고 판단하는 것은 위험합니다. 데이터의 양이 수만 건을 넘어가면 통계적 검정은 아주 미세한 차이에도 P-value < 0.05를 뱉어내기 때문입니다. 이를 해결하기 위해 '통계적 유의성''실질적 유의성(Effect Size)'을 반드시 병행 검토해야 합니다. 드리프트 탐지의 비즈니스적 가치는 '선제적 대응'에 있습니다. 모델의 정확도가 떨어지기 전에 데이터의 변화를 미리 포착함으로써 리트레이닝(Retraining) 시점을 과학적으로 결정할 수 있고, 이는 인프라 비용 절감과 예측 신뢰도 유지로 직결됩니다.


4. 결론 및 요약

효율적인 데이터 드리프트 탐지를 위해 다음 로드맵을 제안합니다.

  • 단계 1: 수치형 변수에는 KS Test와 PSI를 최우선 적용하십시오.
  • 단계 2: 범주형 변수에는 Chi-Squared를 통해 분포 변화를 모니터링하십시오.
  • 단계 3: 드리프트가 탐지되면, 이것이 데이터 수집 과정의 오류(Data Quality)인지 실제 환경 변화(Concept Drift)인지 구분하십시오.
  • 단계 4: 자동화된 파이프라인(Evidently, Alibi Detect 등)을 구축하여 실시간 경보 시스템을 확보하십시오.

정보 출처 및 기술 참조

  • Scipy Stats Documentation: "Statistical functions for Python"
  • MLOps Engineering on AWS - "Monitoring Data Drift in Production"
  • Statistical Stability Analysis in Banking: "Population Stability Index Guidelines"
  • Evidently AI: "Drift Detection Algorithms and Frameworks"
728x90