분류 모델 성능을 평가하는 정밀도·재현율·ROC와 PR-AUC

혼동행렬을 바탕으로 정밀도, 재현율, 정확도, FPR, ROC·PR 곡선과 AUC를 해석하고 운영 임계값을 설정하는 방법

2026-08-14 · 최초 발행 2025-10-14

점수 하나로는 분류 모델의 품질을 판단할 수 없다

분류 모델은 점수를 예측하고, 운영 단계에서는 임계값을 기준으로 비와 맑음처럼 이산적인 결과를 낸다. 이때 어떤 오류를 줄일 것인지에 따라 같은 모델도 평가 결과와 선택할 임계값이 달라진다.

날씨예측의 이진 분류를 예로 들면, 실제 비를 비로 예측한 경우는 TP(True Positive), 실제 맑음을 비로 예측한 경우는 FP(False Positive)다. 실제 비를 맑음으로 예측하면 FN(False Negative), 실제 맑음을 맑음으로 예측하면 TN(True Negative)가 된다.

혼동행렬에서 자주 사용하는 지표는 다음과 같다.

  • Precision(정밀도, PPV): TP / (TP + FP)
  • Recall(재현율, Sensitivity, Hit rate): TP / (TP + FN)
  • Accuracy(정확도): (TP + TN) / (TP + FP + FN + TN)
  • Fall-out(FPR): FP / (FP + TN)

Precision은 비라고 예측한 결과가 얼마나 신뢰할 만한지, Recall은 실제 비를 얼마나 놓치지 않았는지를 보여준다. 둘 다 Positive 식별과 관련되지만 분모가 다르므로 운영에서 답하는 질문도 다르다.

Positive 영역을 어떻게 읽을 것인가

Venn 다이어그램 관점에서 실제 Positive인데 예측 Negative인 영역을 a, 실제 Positive와 예측 Positive가 겹치는 영역을 b, 예측 Positive이면서 실제 Negative인 영역을 c로 두면 Precision은 b / (b + c), Recall은 b / (a + b)가 된다.

이 관계는 가설검정의 오류와도 이어진다. H0이 참인데 기각하는 Type I Error(α)는 분류에서 FP에 해당하고, H0이 거짓인데 채택하는 Type II Error(β)는 FN에 해당한다.

임계값을 높이면 FP가 감소해 Precision은 올라가지만 FN이 늘어 Recall은 낮아진다. 반대로 임계값을 낮추면 Recall은 올라가고 Precision은 낮아진다. 어느 쪽을 우선할지는 모델의 정확도 자체보다 오류 비용에 달려 있다.

ROC와 PR 곡선이 보여주는 차이

ROC 곡선은 x축에 FPR, y축에 TPR(=Recall)을 두고 여러 임계값에서의 성능 변화를 표현한다. ROC-AUC는 ROC 곡선 아래 면적이며 최대는 1, 0.5는 무작위 수준이다.

PR 곡선은 x축이 Recall, y축이 Precision이다. Positive 클래스가 희소한 불균형 데이터에서는 PR 곡선과 PR-AUC가 모델 간 차이를 읽는 데 더 적합하다. ROC-AUC는 기준선이 안정적이지만, 극단적인 불균형에서는 PR-AUC가 더 높은 해석력을 제공한다.

임계값이 혼동행렬로 이어지는 과정

PP<θ실제실제 맑음실제실제 맑음입력: 날씨 특성 (습도, 기압,풍속 등)모델 점수 예측 P(rain)임계값 θ 비교예측:예측: 맑음TPFPFNTN집계: Recall = TP/(TP+FN)집계: Precision =TP/(TP+FP)집계: FPR = FP/(FP+TN)ROC/PR 곡선 업데이트

점수(score)는 임계값을 통과한 뒤 이산 예측이 되고, 그 결과가 혼동행렬로 집계된다. 운영 목적에 맞추려면 FP와 FN의 비용을 비교하는 비용함수 기반의 임계값 선택이 필요하다.

안전·규제 도메인에서는 Recall을 우선하는 경향이 있고, 스팸이나 추천 도메인에서는 Precision을 더 중시하는 경향이 있다. ROC와 PR 곡선, 지표-임계값 곡선, 비용곡선을 함께 두면 임계값 선택의 근거를 투명하게 설명할 수 있다.

검증 셋에서 운영 기준을 정하는 방법

개발 셋과 검증 셋의 점수 분포, 혼동행렬, FP/FN 비용 행렬(cost of FP/FN)을 입력으로 둔다. 점수 구간별 혼동행렬을 산출하고 지표와 비용을 비교해 운영 임계값을 고른다.

  1. 점수 구간별(예: 0.0~1.0, 간격 0.01)로 혼동행렬을 계산한다.
  2. Precision, Recall, FPR, TPR, ROC-AUC, PR-AUC를 계산한다.
  3. E[cost] = FP_cost·FP + FN_cost·FN이 최소가 되는 임계값을 찾는다.

선택한 임계값이 Recall≥0.9 at Precision≥0.6 같은 운영 목표를 충족하는지 검증한다. 운영 이후에는 데이터 쉬프트를 확인할 수 있도록 주간 지표 대시보드를 정의한다.

날씨 알림에서 채널별로 달라지는 기준

폭우 미탐지를 줄이는 기상 알림 시스템은 Recall 우선 전략이 필요하다. 운영 룰로 Recall≥0.95를 두고 허용 가능한 False Alarm Rate(FPR) 상한을 설정할 수 있다.

비 예보는 수력·배터리 스케줄 조정에도 연결된다. 이 경우 FP 비용이 상대적으로 낮다면 임계값을 낮춰 Recall을 확보하고, 비용함수로 FP의 허용 범위를 제어한다.

대민 알림은 채널마다 비용이 다르다. SMS는 불필요한 경보를 줄이기 위해 Precision을 높이고, 앱 푸시는 Recall을 우선하는 방식으로 채널별 임계값을 분리할 수 있다.

지표별로 확인하는 오류와 사용 맥락

Metric 수식 초점 민감 오류 적합 상황
Precision TP/(TP+FP) 예측 Positive의 신뢰도 FP 스팸필터, 경보 오경보 억제
Recall TP/(TP+FN) 실제 Positive 포착율 FN 의료/안전, 위험 탐지
Accuracy (TP+TN)/Total 전체 정답 비율 불균형 데이터 클래스 균형/베이스라인
FPR(Fall-out) FP/(FP+TN) 오경보 비율 FP ROC x축, 경보 시스템
ROC-AUC ∫ TPR dFPR 임계값 무관 평균 성능 클래스 불균형 균형/보편 비교
PR-AUC ∫ Precision dRecall Positive 품질/포착 균형 불균형 데이터 희소 Positive

코드로 확인하는 임계값별 변화

Python 3.9+, scikit-learn >= 1.2, numpy, matplotlib가 설치되어 있다고 가정한다.

import numpy as np
from sklearn.metrics import (
    confusion_matrix, precision_score, recall_score, accuracy_score,
    roc_auc_score, roc_curve, average_precision_score, precision_recall_curve
)

# 예시: 날씨 예측 (1=비, 0=맑음)
y_true  = np.array([1,0,1,0,0,1,0,0,1,0,1,0,0,0,1,0])
y_score = np.array([0.92,0.30,0.80,0.40,0.10,0.85,0.35,0.20,0.70,0.15,0.60,0.25,0.05,0.45,0.88,0.22])

theta = 0.5
y_pred = (y_score >= theta).astype(int)

tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
precision = precision_score(y_true, y_pred, zero_division=0)
recall    = recall_score(y_true, y_pred)
accuracy  = accuracy_score(y_true, y_pred)
fpr = fp / (fp + tn)

roc_auc = roc_auc_score(y_true, y_score)
ap = average_precision_score(y_true, y_score)  # PR-AUC

print(f"TP={tp}, FP={fp}, FN={fn}, TN={tn}")
print(f"Precision={precision:.3f}, Recall={recall:.3f}, Accuracy={accuracy:.3f}, FPR={fpr:.3f}")
print(f"ROC-AUC={roc_auc:.3f}, PR-AUC={ap:.3f}")

# 임계값 별 Precision-Recall 조회
prec, rec, th = precision_recall_curve(y_true, y_score)
for t, p, r in zip(th[::3], prec[:-1:3], rec[:-1:3]):
    print(f"θ={t:.2f} -> P={p:.2f}, R={r:.2f}")

theta를 조정하면 Precision과 Recall이 어떻게 변하는지 확인할 수 있다. ROC-AUC와 PR-AUC를 함께 보고하면 데이터 불균형에 대한 민감도를 보완할 수 있다.

측정값을 운영 판단으로 연결하기

임계값 최적화로 FN이 30% 감소하고 Recall이 +0.1p 상승하면, 위험 미탐지 건수는 월간 100건→70건으로 감소하는 효과를 기대할 수 있다. 동일 알림량을 유지하면서 Precision이 +0.05p 향상되면 불필요 경보는 10% 내외 감소할 수 있다.

비용 기반으로 의사결정하면 판단 기준의 일관성을 확보하고 이해관계자의 신뢰도를 높일 수 있다. 모니터링 대시보드는 조기 이상 탐지 체계도 강화한다. 혼동행렬과 각 성능 지표를 결합하고, 도메인별 오류 비용을 반영해 임계값을 조정해야 한다. 날씨예측처럼 공공 안전과 연결되는 환경에서는 Recall 우선 전략과 FPR 상한을 함께 설계한다.

머신러닝분류 모델혼동행렬모델 평가임계값