예방은 사후 대응보다 언제나 비용이 낮습니다. 과거 데이터로 위험 구역을 미리 식별하면 순찰·예방점검 자원을 선제적으로 배치할 수 있습니다. 다만 목표를 정확히 잡아야 합니다. 우리가 만들 것은 "화재를 맞히는" 점쟁이가 아니라, 한정된 자원을 어디에 먼저 둘지 정하는 우선순위 도구입니다.
🎯 이 장의 목표
- 위험도 예측 문제를 어떻게 정의하는지
- 어떤 데이터를 어떤 키로 결합하는지
- 성능을 좌우하는 피처 엔지니어링과 데이터 누수 방지
- 불균형 데이터에서 모델을 정직하게 평가하는 법
- 운영 임계값·재학습·편향 등 현장 적용의 함정
문제를 먼저 정의한다
모델보다 정의가 먼저입니다. 세 가지를 정합니다.
- 공간 단위: 행정동 또는 격자(예: 500m × 500m). 자원 배치 단위와 맞춥니다.
- 시간 단위: 주 또는 월. 너무 짧으면 데이터가 희박하고, 너무 길면 둔감해집니다.
- 타깃: 해당 단위·기간의 화재 발생 여부(이진 분류) 또는 건수(회귀). 운영에는 보통 발생 여부가 직관적입니다.
📌 핵심
출력은 "절대 확률"이 아니라 상대 우선순위로 다루세요. "이 동은 12% 확률"이 아니라 "상위 10% 위험 구역"으로 쓰는 편이 오해와 책임 문제를 줄입니다.어떤 데이터를 결합하나
서로 다른 출처를 공간(좌표·행정코드) + 시간 키로 한 테이블에 모읍니다.
| 데이터 | 출처(예) | 주로 쓰는 변수 |
|---|---|---|
| 과거 출동·화재 | 국가화재정보시스템 | 발생 시각·장소·유형·원인 |
| 기상 | 기상청 ASOS·방재기상관측 | 기온·습도·풍속·강수 |
| 건축물 | 건축물대장 | 준공연도·주용도·구조·연면적 |
| 인구·시설 | 행정통계·안전지도 | 주거 밀집도·노유자시설 수 |
격자 단위로 만들 때는 각 출동·건물 좌표를 격자에 공간 조인(spatial join)한 뒤, 기간별로 집계합니다.
핵심은 피처 엔지니어링
원시값을 그대로 넣기보다 의미 있는 파생 변수를 만드는 것이 성능을 좌우합니다.
- 기상 파생: 건조지수, 최근 7일 누적 무강수일
- 시간 파생: 계절·요일·공휴일·난방 사용기(겨울)
- 건물 파생: 노후도(현재연도 − 준공연도), 용도별 위험 가중, 밀집도
- 이력 파생: 최근 N개월 출동 빈도, 직전 화재 이후 경과일
PYTHON
import pandas as pd df["건조지수"] = df["기온"] / (df["습도"] + 1) df["건물나이"] = 2026 - df["준공연도"] df["겨울"] = df["월"].isin([12, 1, 2]).astype(int) # 격자별 최근 3개월 출동 합계 — '직전까지'만 사용 df["최근출동"] = ( df.groupby("격자")["출동건수"] .transform(lambda s: s.rolling(3, min_periods=1).sum().shift(1)) )
⚠️ 흔한 실수
위 shift(1) 이 핵심입니다. 예측 시점에는 알 수 없는 그 기간의 출동 건수를 피처에 넣으면, 검증 점수는 높지만 실제로는 미래를 훔쳐본 데이터 누수입니다. 위험도 예측에서 가장 흔하고 치명적인 실수입니다.모델은 단순한 것부터
먼저 베이스라인을 세웁니다. "직전 기간 출동 빈도 순"으로 줄세우는 단순 규칙입니다. 머신러닝 모델이 이 베이스라인을 이기지 못하면 모델은 필요 없습니다.
다음으로 표 데이터·비선형·결측에 강한 트리 기반 모델(RandomForest, XGBoost)을 씁니다.
PYTHON
from sklearn.ensemble import RandomForestClassifier m = RandomForestClassifier( n_estimators=300, class_weight="balanced", # 화재는 드물다 — 불균형 보정 random_state=0, ) m.fit(X_train, y_train) risk = m.predict_proba(X_test)[:, 1] # 위험 점수
평가: 정확도의 함정
화재가 발생하는 단위가 전체의 1%라면, "전부 안전"이라고 찍는 모델도 정확도 99%입니다. 정확도(accuracy)는 여기서 무의미합니다. 대신 봐야 할 것:
- Recall(재현율): 실제 위험을 얼마나 놓치지 않았나 — 예방에서 가장 중요
- Precision(정밀도): 위험하다고 한 것 중 실제 비율
- PR-AUC: 불균형에서 ROC보다 정직한 종합 지표
- 상위 K% 포착률(운영 지표): 위험 상위 10% 구역이 실제 화재의 몇 %를 담는가
📌 핵심
검증은 반드시 시간 분할로. 과거로 학습하고 미래 기간으로 검증합니다. 무작위 분할은 미래 정보가 학습에 새어 점수를 부풀립니다.운영에 적용하기
- 모델 출력(점수)을 위험 지도와 순위표로 변환합니다.
- 임계값은 자원에 맞춰 정합니다. "상위 10% 구역 집중 예방점검"처럼 가용 인력에서 거꾸로 정하는 편이 현실적입니다.
- 재학습은 분기·반기 주기로. 계절·도시 변화로 분포가 바뀌므로(데이터 드리프트) 성능을 주기적으로 점검합니다.
한계와 책임 — 반드시 읽기
- 피드백 루프 편향: 과거 출동·점검이 많았던 곳일수록 "위험"으로 학습되고, 거기에 자원이 더 가고, 다시 데이터가 쌓입니다. 점검이 드물었던 사각지대는 영원히 낮게 나올 수 있습니다. 신고·점검 분포를 함께 보며 보정하세요.
- 상관 ≠ 인과: 변수는 원인이 아니라 신호입니다. 모델은 "왜"를 설명하지 않습니다.
- 개인정보: 분석은 격자·행정동 단위 집계로. 개별 세대·개인을 식별하지 않습니다.
▸ 소방 활용 포인트
예측 결과는 순찰·예방점검 우선순위 결정에 참고로 쓰되, 최종 배치는 반드시 현장 지식과 함께 내립니다. 모델이 낮게 본 구역도 정기 점검은 유지하세요 — 사각지대를 만들지 않는 것이 예측보다 중요합니다.