본문 바로가기
/ 학습 / 안내서 / 예측·분석
L3 심화 · 12분 읽기

예측 모델 운영, 드리프트 감지와 재학습 시점

2026.07.12 갱신 예측 모델을 만들어 운영 단계에 들어선 분석 담당자
#예측#드리프트#모니터링#재학습
검토 상태: 전문 검토 전 위험도 미분류

이 안내서는 공식 절차·법령·현장 판단을 대체하지 않으며, 적용 전 소속 기관 기준과 담당자 검토를 확인하세요.

전편에서 위험도 예측 모델을 만들었다면, 이제 다른 종류의 문제가 시작됩니다. 모델은 배포한 다음 날부터 낡기 시작합니다. 재개발로 건물 분포가 바뀌고, 기후가 밀려 건조기가 이동하고, 신고 행태가 달라집니다. 코드가 그대로여도 세상이 변하면 모델은 틀리기 시작하는데 — 오류 메시지는 없습니다. 지난달과 똑같이 그럴듯한 위험 지도가 나올 뿐입니다.

🎯 이 장의 목표
  • 롤링 백테스트로 모델의 평상시 변동 범위를 기록할 수 있습니다.
  • 성능·입력 분포·데이터 이벤트를 다른 신호로 분리해 감시할 수 있습니다.
  • 드리프트와 수집 파이프라인 장애를 구분하는 원인 가설을 세울 수 있습니다.
  • 재학습·유지·은퇴 후보를 동일한 검증 기준으로 비교할 수 있습니다.

낡음을 알리는 3가지 신호

신호무엇을 보나성격
1 성능 하락상위 K% 포착률의 추세확실하지만 늦다 — 화재가 나야 계산된다
2 입력 드리프트피처 분포의 변화(PSI)간접적이지만 빠르다 — 즉시 계산된다
3 캘린더계절 전환·데이터 소스 개편예측 가능 — 달력에 미리 적는다

셋 중 하나만 보면 놓칩니다. 성능만 보면 몇 달 늦고, 드리프트만 보면 오탐에 시달리고, 캘린더만 보면 갑작스러운 변화를 놓칩니다.

1. 백테스트 — 배포 전에 운영을 리허설한다

전편의 시간 분할 검증은 한 번의 시험입니다. 운영 판단에는 그걸로 부족합니다 — 기준 시점을 옮겨 가며 여러 번 반복해, 성능이 원래 얼마나 출렁이는지부터 재야 합니다. 이 범위가 없으면 운영 중 점수가 떨어졌을 때 "정상 변동"인지 "진짜 하락"인지 구분할 수 없습니다.

PYTHON
import pandas as pd

# 롤링 백테스트: 기준월을 한 달씩 밀며 '과거로 학습 → 다음 달 검증' 반복
scores = []
for cut in pd.period_range("2025-01", "2025-12", freq="M"):
    train = df[df["기간"] <  str(cut)]
    test  = df[df["기간"] == str(cut)]
    m = fit_model(train)                      # 전편의 모델 학습 그대로
    topk = predict_topk(m, test, k=0.10)      # 위험 상위 10% 구역
    hit = test[test["격자"].isin(topk)]["화재"].sum() / max(test["화재"].sum(), 1)
    scores.append({"기준월": str(cut), "포착률": hit})

bt = pd.DataFrame(scores)
print(bt["포착률"].mean(), bt["포착률"].std())   # 예: 평균 0.61 ± 0.08

이렇게 얻은 "평시 0.61±0.08" 같은 범위가 운영 대시보드의 기대 밴드가 됩니다. 이 밴드 밑으로 내려가는 것이 신호 1입니다.

2. 드리프트 감시 — 성능은 늦고, 입력은 빠르다

포착률은 그 달의 화재가 실제로 나야 계산됩니다. 반면 입력 피처의 분포는 예측을 돌리는 순간 바로 비교할 수 있습니다. 학습 당시 분포와 지금 들어오는 분포가 벌어졌다면, 성능이 떨어지기 전에 경보를 받을 수 있습니다.

이 시간차가 핵심입니다. 지표에는 선행후행이 있습니다. 댐을 지킬 때 수위계만 보면 물이 넘치고 나서야 압니다 — 후행이라 늦습니다. 반면 상류의 강우량계는 물이 불어나기 전에 신호를 줍니다 — 선행입니다. 포착률(성능)은 화재가 나야 계산되는 후행 지표이고, 입력 분포는 예측을 돌리는 순간 재는 선행 지표입니다. 입력을 감시하는 이유가 이것입니다 — 결과가 나빠지기를 기다리지 않고 원인 쪽 변화를 먼저 잡으려는 것입니다.

가장 널리 쓰는 잣대가 PSI(Population Stability Index)입니다. 두 분포를 같은 구간으로 나눠 비율 차이를 합산한 값입니다.

PYTHON
import numpy as np

def psi(train_col, live_col, bins=10):
    """학습 시점 분포 대비 현재 분포의 이동량. 구간은 학습 분포 기준."""
    edges = np.quantile(train_col.dropna(), np.linspace(0, 1, bins + 1))
    edges[0], edges[-1] = -np.inf, np.inf
    p = np.histogram(train_col, bins=edges)[0] / max(len(train_col), 1)
    q = np.histogram(live_col,  bins=edges)[0] / max(len(live_col), 1)
    p, q = np.clip(p, 1e-4, None), np.clip(q, 1e-4, None)   # 0 나눗셈 방지
    return float(np.sum((q - p) * np.log(q / p)))

for col in ["건조지수", "건물나이", "최근출동"]:            # 전편의 핵심 피처
    print(col, round(psi(train_df[col], live_df[col]), 3))
PSI해석(업계 관례 기준)대응
< 0.1안정없음
0.1 ~ 0.25주의 — 분포가 움직이는 중원인 확인, 다음 달 재측정
> 0.25경보 — 학습 때와 다른 세상재학습 검토(신호 2 발동)

가상의 예로 감을 잡아 보겠습니다(실제 수치가 아닙니다). 학습 데이터에서 건물나이가 대부분 20~40년 구간에 몰려 있었다고 합시다. 그런데 관할에 재개발이 끝나 신축이 대거 들어오면, 올해 들어오는 건물나이는 5~10년 쪽으로 확 쏠립니다. 두 분포를 같은 구간에 얹어 비교하면 겹치는 면적이 줄고, PSI는 위 표의 '주의'를 지나 '경보' 쪽으로 올라갑니다. 코드가 한 줄로 뱉는 PSI 숫자 뒤에는 이런 '동네가 젊어졌다'는 실제 변화가 들어 있는 셈입니다.

💡 팁
PSI가 튀면 먼저 데이터 쪽 사고부터 의심하세요. 기상 API 단위 변경, 건축물대장 스키마 개편, 결측 급증 같은 수집·정제 단계의 문제가 드리프트로 위장하는 경우가 가장 흔합니다. 세상이 변한 게 아니라 파이프라인이 깨진 것이면 재학습이 아니라 수리가 답입니다.

한 가지 함정을 더 짚자면, PSI는 표본이 적을수록 튑니다. 어느 달 들어온 데이터가 유난히 적으면(격자 몇 개뿐이라면) 세상이 그대로여도 우연히 PSI가 높게 나올 수 있습니다. 그러니 PSI가 튀었다고 곧장 재학습으로 달려가지 말고, 표본 수가 충분한지부터 확인하세요 — 파이프라인 점검과 같은 맥락입니다.

3. 재학습 — 주기가 아니라 조건으로

"분기마다 재학습"은 기억하기 좋지만, 조용한 분기엔 낭비이고 급변한 달엔 늦습니다. 조건으로 정합니다.

  • 트리거 ① 성능: 상위 K% 포착률이 기대 밴드 하한 아래로 2기간 연속
  • 트리거 ② 드리프트: 핵심 피처 중 하나라도 PSI > 0.25
  • 트리거 ③ 캘린더: 난방기 진입·해제(계절 전환), 데이터 소스 개편, 행정구역·격자 변경

재학습은 "다시 fit 한 번"이 아니라 작은 프로젝트입니다. 전편의 절차를 다시 밟습니다 — 시간 분할 검증, 베이스라인 비교, 그리고 이전 모델과 같은 검증 기간에서 나란히 비교해 이길 때만 교체합니다. 교체할 때는 학습 데이터 기간·코드 버전·검증 점수를 기록으로 남깁니다.

모델 카드 — 한 장짜리 신분증

담당자가 바뀌어도 모델이 설명 가능하도록, 카드 한 장을 모델과 함께 보관합니다.

TEXT
[모델 카드] 화재 위험도 v3 (2026-07 재학습)
- 목적: 격자별 월간 화재 위험 우선순위 (상위 10% 예방점검 배치 참고)
- 학습 데이터: 2022-01 ~ 2026-05 (출동·기상·건축물대장, 격자 500m)
- 기대 성능: 상위 10% 포착률 0.61 ± 0.08 (롤링 백테스트 12회)
- 알려진 한계: 신축 밀집 지역 과소평가 경향, 점검 이력 피드백 편향
- 재학습 트리거: 포착률 < 0.53 2개월 연속 / 핵심 피처 PSI > 0.25 / 계절 전환
- 담당: 예방연구팀 ○○○ · 이력: v1 2025-03, v2 2025-11, v3 2026-07

운영 루틴 한 장

언제무엇을통과 기준
매월 (화재 집계 확정 후)상위 K% 포착률 기록기대 밴드 안
매월 (예측 직후)핵심 피처 PSI전부 < 0.25
트리거 발동 시재학습 + 신구 모델 비교새 모델이 같은 기간에서 우세할 때만 교체
재학습 때마다피드백 루프 편향 재점검점검 이력 분포 함께 확인
▸ 소방 활용 포인트
순찰·예방점검 배치의 근거가 되는 위험 지도가 "언제까지 믿을 수 있는 지도인지"를 숫자로 관리합니다. 포착률 밴드와 PSI 경보는 "모델을 계속 써도 되는가"라는 질문에 감이 아닌 기록으로 답하게 해 주고, 모델 카드는 담당자가 바뀌어도 판단 기준을 물려줍니다.

설계 판단

재학습은 모니터링 경보의 자동 답이 아닙니다. 원인이 데이터 장애면 수리가, 현실의 관계 변화면 재설계가, 신호가 약하면 단순한 방식으로의 회귀가 후보가 됩니다.

선택지맞는 상황트레이드오프사람이 확인할 것
기존 모델 유지성능이 기대 범위에 있고 입력 변화의 원인이 설명될 때불필요한 교체를 피하지만 늦게 나타나는 하락을 계속 감시최신 표본과 예외 구역
조건부 재학습수집 오류를 제거한 뒤에도 입력·성능 변화가 반복될 때새 데이터에 맞추며 과거 조건의 성능을 잃을 수 있음신구 모델의 동일 기간 비교
은퇴 후 베이스라인 사용데이터가 희소하거나 새 모델이 반복 검증에서 이점을 보이지 못할 때자동화 범위는 줄지만 설명 가능한 기준으로 돌아감남아 있는 업무 필요와 사람 검토 여력

운영 시나리오

아래 두 사례는 실제 성능·기관 수치가 아닌 가상 운영 연습입니다. 경보가 울린 순간의 조치보다, 경보가 무엇을 대리하는지 입증하는 순서를 보여 줍니다.

가상 시나리오 1: 행정코드 결합률이 급격히 떨어진 경우

  • 탐지: 예측 성능을 평가할 시점은 아직 아닌데 입력 열의 결측과 조인 실패 기록이 함께 늘었습니다.
  • 원인 가설: 세상의 위험 분포가 바뀐 것이 아니라, 원천 행정코드 개편이 대응표에 반영되지 않아 특정 구역 자료가 빠졌다고 봅니다.
  • 대응: 현재 예측 산출물의 공유를 멈추고 원천 건수·고유 키·결합 커버리지를 대조한 후 코드 매핑을 수정해 같은 입력을 재처리합니다.
  • 재발 확인: 재처리 전·후의 결합 커버리지와 예측 분포를 비교하고, 코드 개편 픽스처를 수집 회귀 점검에 추가합니다.

가상 시나리오 2: 입력 분포는 비슷한데 실제 포착률이 낮아진 경우

  • 탐지: 핵심 피처의 분포 신호는 평상 범위였지만, 늦게 확정된 결과로 계산한 포착률이 기대 범위 밖에 머물렀습니다.
  • 원인 가설: 입력 값의 모양은 같지만 점검·신고 과정이 바뀌어 피처와 결과 사이의 관계가 달라졌거나, 결과 확정 지연이 비교 구간을 흐렸다고 봅니다.
  • 대응: 즉시 재학습하지 않고 시기·구역·데이터 확정 상태로 하락 항목을 나눙니다. 기존 모델의 활용 범위를 축소하고 재학습과 은퇴 후보를 함께 만듭니다.
  • 재발 확인: 확정된 동일 기간을 사용해 기존·재학습·베이스라인을 롤링 비교하고, 하락 구간이 반복되지 않음을 확인한 후 담당자가 교체를 승인합니다.

한계와 리스크

리스크발생 조건영향완화·사람 승인
대리 지표에 의한 오경보입력 분포는 바뀌었지만 업무 성능은 유지됨불필요한 재학습과 운영 부담수집 장애·표본 수·실제 성능을 함께 보고 담당자가 트리거 승인
재학습으로 과거 성능 손실최근 데이터에만 맞춘 후보를 바로 교체함과거 계절·예외 구역에서 품질 하락신구 모델을 동일한 여러 기간에서 비교하고 도메인 담당자 승인
피드백 편향의 고착모델 순위로 배치한 기록을 다시 학습함자주 본 구역은 더 위험하게, 사각지대는 더 안전하게 보임정기 점검 범위와 점검 선택 이력을 별도 검토하고 자원 배분은 사람 승인

자주 묻는 질문

Q. PSI가 울리면 바로 재학습해야 하나요?

아닙니다. 결측·단위·스키마·조인 문제와 표본 수를 먼저 확인합니다. 수집 장애면 모델이 아니라 데이터 경계를 고쳐야 합니다.

Q. 입력 드리프트가 없으면 모델은 안전한가요?

그렇지 않습니다. 입력 분포가 비슷해도 입력과 결과의 관계가 바뀌면 성능은 낮아집니다. 늦게 확정되는 성능 지표와 예외 표본을 계속 보아야 합니다.

Q. 재학습 후보가 기존 모델보다 일부 기간에서만 좋으면 교체해도 되나요?

즉시 교체하지 않습니다. 여러 시간 구간·예외 구역·베이스라인에서 나란히 비교하고, 알려진 한계와 활용 범위를 기록한 후 담당자가 승인합니다.

Q. 모델을 은퇴하는 것은 실패인가요?

아닙니다. 신호가 약하거나 데이터 사각지대를 설명하기 어려울 때 설명 가능한 베이스라인과 사람 검토로 돌아가는 것은 안전한 운영 판단입니다.

핵심 정리

  • 성능, 입력 분포, 데이터 이벤트는 속도와 의미가 다른 신호입니다.
  • 드리프트 경보 뒤에는 현실 변화와 파이프라인 장애를 나누는 원인 확인이 먼저입니다.
  • 재학습 후보는 기존 모델과 동일한 기간·지표·베이스라인으로 비교합니다.
  • 재학습만큼 유지와 은퇴도 기록·승인해야 할 정상적인 선택지입니다.

다음 단계

  • 지역별 화재 위험도 예측: 감시할 타깃·베이스라인·시간 분할 계약을 원 설계에서 다시 확인합니다.
  • 데이터 정제: 드리프트로 위장하는 결측·중복·표기 불일치를 수집 경계에서 점검합니다.
  • AI 출력 검토: 모델 카드와 운영 보고서의 단정·근거 누락을 외부 공유 전에 확인합니다.

사람 검토 체크리스트

TEXT
- [ ] 롤링 백테스트로 기대 성능 범위(평균±표준편차)를 배포 전에 쟀습니다.
- [ ] 상위 K% 포착률을 매월 기록하고 기대 밴드와 비교합니다.
- [ ] 핵심 피처의 PSI를 매월 계산하고, 튀면 파이프라인 사고부터 확인합니다.
- [ ] 재학습 트리거 3종(성능·드리프트·캘린더)이 문서화돼 있습니다.
- [ ] 새 모델은 이전 모델과 같은 기간에서 비교해 이길 때만 교체합니다.
- [ ] 모델 카드에 데이터 기간·기대 성능·한계·담당자·이력이 적혀 있습니다.
⚠️ 흔한 실수
드리프트 지표도 대리 신호일 뿐입니다 — PSI가 조용해도 세상은 변할 수 있습니다. 그리고 전편의 피드백 루프 편향은 재학습을 반복할수록 오히려 굳어질 수 있으니, 재학습 때마다 점검 이력 분포를 함께 봐야 합니다. 낡은 모델을 억지로 쓰는 것보다 "이 모델은 은퇴시킨다"고 인정하는 쪽이 언제나 안전합니다.