본문 바로가기

DEVELOP_NOTE/MLOps

Drift를 감지하는 방법 (2) Concept Drift Detection (+ADWIN, Page-Hinkley Test, CUSUM, DDM)

오늘은 concept drift를 detectioin하는 여러가지 방법론들을 살펴보려한다.
'concept drift'는 시간이 지남에 따라 모델에 input되는 데이터의 통계적 특성이 달라지거나,
feature와 label간의 관계가 달라질때 model의 성능이 저하되는 경우를 일컫는다.
 
concept drift가 data drift에 비해 갖는 특징중 하나는, 모델의 도메인에 따라 중요성이 달라질 수 있다는 것이다.
가령, 얼굴인식 또는 STT, TTS, 언어모델과 같은 경우에는 데이터의 특성이 달라지지 않기 때문에 concept drift가 발생할 확률이 낮다.
하지만, 그 외 과제를 해결하기 위한 예측모델의 경우 데이터 분포나 feature와 label의 관계에 변화가 생기는 concept drift 문제가
빈번하게 발생할 수 있기때문에 중요하게 고려되어야한다.

 

그리고, concept drift는 모델이 개발 및 배포된 후 프로덕트단에서 발생하는현상이지만,
모델 개발 및 데이터 전처리 단계에서도 이를 최소화 하기 위한 여러 조치를 취할 수 있다.
 
따라서, concept drift를 예방하고 detection할 수 있는 방법들을 차례로 알아보도록 하자.
 

 

 


1. 모델 개발 단계에서 Concept Drift를 피하기 위해 고려해야하는 점

 

1) 학습과정에서 최대한 다양한 데이터를 사용한다.

프로덕트 단에서는  다양한 형태의 예측하지 못한 데이터가 input될 수 있기 때문에, 수집할 수 있는 최대한 다양한 데이터를 활용해
모델을 학습해, 프로덕트 단에서도 concept drift에 강건한 모델이 될 수 있도록 할 수 있다.
예를들어, 온라인에서 많이 팔릴 제품에 대한 예측모델을 개발한다고 가정할때, 시즌별로 구매패턴이 다를것이므로,
계절 또는 연말, 연초등 다양한 시기의 데이터를 통해 학습하면, 시즌에 영향을 덜 받는 모델을 만들 수 있다.

 

2) Feature Engineering

이와는 반대로 모델 학습 시 위 1)번 항목에서는 프로덕트에서 발생할 다양한 데이터를 통해 학습하는 방법을 설명했다면, 
모델학습 전 Feature를 선택할때, 일관되고 시계열에 영향을 많이 받지않는 일정한 특성을 지닌 Feature를 
선택할 수도 있다. 
 

3) 모델 선택

모델을 선택할때, 단일 모델이 아닌 여러 특성을 지닌 데이터에 대응할 수 있는 앙상블 형태로 모델을 구축할 경우,
Concept Drift에 좀 더 강건한 모델을 만들 수 있다.
 

4) 정기적인 모델 업데이트 및 재학습

1번에서는 프로덕트단에서 발생할 수있는 다양한 데이터를 미리 학습 당시에 반영하여 최대한 다양한 데이터패턴을 학습한다면,
반대로 짧은 주기를 가지고 적시의 데이터로 모델을 업데이트하고 재학습하여 concept drift를 피하고
안정적인 performance를 유지할 수 있다.

 

 


2. Drift Detection Algorithms

다음은 실시간 데이터 스트림에서 Drift를 감지하는 데 사용되는 알고리즘들이다.

이 알고리즘들은 데이터 스트림의 통계적 특성이 시간이 흐름에 따라 변화하는지 여부를 식별하는데 중점을 둔다.

1) ADWIN (Adaptive Windowing)

ADWIN은 데이터스트림에서 변화를 감지하기 위해 동적으로 조정되는 window의 크기를 기반으로,

두개의 연속적인 데이터 블록간의 평균값이 통계적으로 유의미하게 차이나는지 확인하고, 

데이터 스트림 내 변화가 발생하는 시점을 감지하는 방법이다.

아래 예시를 보자.

 

먼저, 가장 처음에는 모든 데이터 포인트를 포함하는 하나의 window(전체 데이터스트림이라보면 됨)로 시작한다.

ex)

1) 주어진 데이터 스트림 : [1, 1, 1, 1, 1, 1, 0.8, 0.8, 0.6, 0.6, 0.4, 0.4, 0.2, 0.2, 0]

2) 초기 window : [1, 1, 1, 1, 1, 1, 0.8, 0.8, 0.6, 0.6, 0.4, 0.4, 0.2, 0.2, 0] -> 전체 스트림과 동일

3) [1...n] <- 쪼개어진 window간 평균값을 비교한다-> [n+1 ...m] 

4) 평균값이 처음 설정한 임계치(drift를 탐지하기 위한 기준)를 초과할 경우,

     해당 window 경계점의 포인터값이 drift로 의심할 만큼 차이가 커진것으로 간주하고 window의 

     크기를 조정한다.

 

from river import drift

adwin = drift.ADWIN()
data_stream = [0, 1, 0, 0, 1, 1, 0, 1, 1, 1]  # 예시 데이터 스트림

for i, value in enumerate(data_stream):
    adwin.update(value)  # ADWIN에 데이터 포인트 업데이트
    if adwin.change_detected:
        print(f"Drift detected index {i}")

 

 

2. Page-Hinkley Test

Page-Hinkley Test는 데이터 스트림의 평균 변화를 모니터링하여 설정된 임계값을 초과하면

변화가 감지된것으로 판단하여 drift를 감지한다.

 

간단한 방법으로 예를들어, [0,0,0,1,1,1,0,0,0]과 같은 데이터스트림이 주어지고, 

임계값을 0.5라고 가정했을때, 첫번째 데이터포인트부터 차례대로 누적평균을 구한다.

4번째 데이터포인트에서 1-0(이전 데이터포인트)=1이 되어 임계값을 초과하는 변화량을 감지하여

drift를 관측하는 방법이다.

from river import drift

ph = drift.PageHinkley()
data_stream = [0, 1, 0, 0, 1, 1, 0, 1, 1, 1]  # 예시 데이터 스트림

for i, value in enumerate(data_stream):
    ph.update(value)  # Page-Hinkley에 데이터 포인트 업데이트
    if ph.change_detected:
        print(f"Drift detected index {i}")

 

 

3. CUSUM (Cumulative Sum Control Chart)

cusum은 데이터스트림에서 작은 변화를 감지하는데 사용되는데, 누적된 차이수가 특정 임계값을 초과할 경우

Drift가 감지된것으로 판단하는 방법이다.

예를들어, 주어진 데이터 스트림이 [1, 1, 2 ,2 ,2, 3, 3, 3, 3]이고 임계값이 2일때, 

두번째에서 세번째 인덱스에서 차이가 '1' 관측되고(누적), 5번째에서 6번째로 넘어갈때 차이가 다시 '1'관측되어

누적 차이가 2가되어 임계값에 충족하게된다. 이때, 임계값 이상의 차이가 발생한 이후 시점의 

3,3,3,3에 해당하는 부분에서 Drift가 발생한것으로 간주하는 방식이다.

 

import numpy as np

def cusum(data, threshold=5, drift=0):
    S = 0
    change_points = []

    for i in range(1, len(data)):
        S = max(0, S + data[i] - data[i-1] - drift)
        if S > threshold:
            change_points.append(i)
            S = 0
    return change_points

data_stream = np.random.normal(0, 1, 100)  # 예시 데이터 스트림
change_points = cusum(data_stream)
print("Drift points:", change_points)​

 

 

4. DDM (Drift Detection Method)

DDM은 분류모델에서 오류율의 변화를 감지하는 데 사용되며, 오류율이 특정 수준이상 증가하면 변화가 

감지된것으로 판단하는 방법이다.

예를들어, classification task에서 

'[정답, 정답, 오류, 정답, 오류, 오류, 정답, 정답, 오류, 오류]' 과 같이 측정되었다고 가정하자.

이를 DDM 알고리즘을 통해 오류율의 변화를 모니터링 하고, 임계값은 0.3으로 설정하고 진행해보자.

 

  1. 첫 번째 데이터 포인트 (정답): 오류율 = 0/1 = 0
  2. 두 번째 데이터 포인트 (정답): 오류율 = 0/2 = 0
  3. 세 번째 데이터 포인트 (오류): 오류율 = 1/3 ≈ 0.333
  4. 네 번째 데이터 포인트 (정답): 오류율 = 1/4 = 0.25
  5. 다섯 번째 데이터 포인트 (오류): 오류율 = 2/5 = 0.4
  6. 여섯 번째 데이터 포인트 (오류): 오류율 = 3/6 = 0.5
  7. 일곱 번째 데이터 포인트 (정답): 오류율 = 3/7 ≈ 0.429
  8. 여덟 번째 데이터 포인트 (정답): 오류율 = 3/8 = 0.375
  9. 아홉 번째 데이터 포인트 (오류): 오류율 = 4/9 ≈ 0.444
  10. 열 번째 데이터 포인트 (오류): 오류율 = 5/10 = 0.5

결국, 세번째 포인트부터 임계점인 0.3을 초과했지만, 다섯번째 이후부터 오류율이 지속적으로 크게 나타나는것을

볼 수 있다. 

이렇게, 오류율이 지속적으로 임계점 이상을 초과할 경우 model에 drift가 발생한것으로 간주할 수 있다.

from river import drift

ddm = drift.DDM(min_num_instances=30, warning_zone=2, out_control_zone=3)
data_stream = [0, 1, 0, 0, 1, 1, 0, 1, 1, 1]  # 예시 데이터 스트림의 결과

for i, value in enumerate(data_stream):
    ddm.update(value)  # DDM에 결과 업데이트
    if ddm.change_detected:
        print(f"Change detected index {i}")
    elif ddm.warning_detected:
        print(f"Drift warning index {i}")

 

 

마치며

오늘은 concept drift를 예방하고 탐지하기 위한 여러가지 방법론을 정리해보았다.

drift에 대응하기 위한, 생각보다 다양한 방법이 있다는것을 알게되었고, 

실제 모델 구축 및 배포시 Drift로 인한 모델 성능저하를 빠르게 탐지하기 위해

적절한 모니터링 및 탐지 프로세스를 구축해야한다는 점을 이해하게 되었다.

다음에는 위 탐지 방법론들을 어떻게 프로세스로 녹여낼것인지에 대해 고민하고 정리해보도록 하자.

 

 

 

Reference

[1] Blog

https://calmmimiforest.tistory.com/120

 

[Model Drift] Model Drift에 대한 A to Z # 2. Detection 방법과 Handling 방법

앞서 Model Drift 개념과 유형에 대해서 알아보았습니다. 이번 글에서는 Model Drift를 감지하는 방법과 Model Drift를 방지하고 해결하는 방법에 대해서 정리해 보겠습니다. Model Drift Detection 방법 첫 번

calmmimiforest.tistory.com

https://danbi-ncsoft.github.io/works/2019/02/07/churn_prediction_in_practice-2.html

 

실전 이탈 예측 모델링을 위한 세 가지 고려 사항 #2

 

danbi-ncsoft.github.io