혼동행렬로 분류 모델이 어디서 틀리는지 뜯어보기
TP·FP·FN·TN 네 칸으로 분류 모델의 예측 결과를 나누고, 여기서 파생되는 정확도·정밀도·재현율·F1·특이도 지표와 불균형 데이터에서의 함정을 정리한다.
2026-08-13 · 최초 발행 2025-05-23
분류 문제에서 단순히 정확도(accuracy)만으로는 모델의 성능을 정확히 판단하기 어렵다. 특히 데이터가 불균형한 경우, 높은 정확도에도 불구하고 모델이 특정 클래스에 대해 심각한 오분류를 하고 있을 수 있다. 혼동행렬은 예측 결과와 실제 결과의 관계를 표 형태로 정리해, 모델이 어떤 클래스를 어떻게 예측했는지 한눈에 보여준다.
TP·FP·FN·TN으로 나뉘는 예측 결과
기본적인 이진 분류 문제에서 혼동행렬은 2×2 행렬로 구성된다.
- True Positive (TP): 실제 양성을 양성으로 올바르게 예측
- False Positive (FP): 실제 음성을 양성으로 잘못 예측 (Type I 오류)
- False Negative (FN): 실제 양성을 음성으로 잘못 예측 (Type II 오류)
- True Negative (TN): 실제 음성을 음성으로 올바르게 예측
다중 클래스 분류 문제에서는 이 행렬이 N×N 형태로 확장된다(N은 클래스 수).
혼동행렬에서 뽑아내는 지표들
혼동행렬은 표 하나로 끝나지 않는다. 여기서 다양한 성능 지표가 계산된다.
정확도(Accuracy)는 전체 예측 중 올바른 예측의 비율이다.
Accuracy = (TP + TN) / (TP + FP + FN + TN)
정밀도(Precision)는 양성으로 예측한 것 중 실제 양성의 비율이다.
Precision = TP / (TP + FP)
재현율(Recall) 또는 민감도(Sensitivity)는 실제 양성 중 양성으로 예측된 비율이다.
Recall = TP / (TP + FN)
특이도(Specificity)는 실제 음성 중 음성으로 예측된 비율이다.
Specificity = TN / (TN + FP)
F1 점수(F1 Score)는 정밀도와 재현율의 조화평균이다.
F1 Score = 2 * (Precision * Recall) / (Precision + Recall)
암 진단과 스팸 필터, 같은 행렬이 다르게 읽힌다
암 진단 모델에서는 TP가 암이 있는 환자를 암으로 올바르게 진단한 경우, FP가 암이 없는 환자를 암으로 잘못 진단해 불필요한 치료와 심리적 부담을 유발한 경우, FN이 암이 있는 환자를 정상으로 잘못 진단해 치료 지연으로 생명이 위험해질 수 있는 경우, TN이 암이 없는 환자를 정상으로 올바르게 진단한 경우다. 이 경우 FN(암을 놓치는 것)이 FP보다 더 치명적일 수 있으므로 높은 재현율이 요구된다.
스팸 메일 필터에서는 TP가 스팸을 스팸으로 올바르게 분류한 경우, FP가 일반 메일을 스팸으로 잘못 분류해 중요 메일을 놓치는 경우, FN이 스팸을 일반 메일로 잘못 분류해 사용자가 불편을 겪는 경우, TN이 일반 메일을 일반 메일로 올바르게 분류한 경우다. 이 경우는 FP(중요 메일을 스팸으로 잘못 분류)가 더 문제가 될 수 있어 높은 정밀도가 중요하다.
Python으로 혼동행렬 그리기
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# 가상의 예측 결과와 실제 값
y_true = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
y_pred = [0, 0, 0, 1, 0, 1, 1, 1, 0, 1]
# 혼동행렬 계산
cm = confusion_matrix(y_true, y_pred)
# 시각화
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['Predicted 0', 'Predicted 1'],
yticklabels=['Actual 0', 'Actual 1'])
plt.ylabel('Actual')
plt.xlabel('Predicted')
plt.title('Confusion Matrix')
plt.show()
다중 클래스 분류 문제에서는 혼동행렬이 더 복잡해진다. N개 클래스에 대해 N×N 행렬이 생성되며, 대각선 요소는 올바르게 분류된 사례, 비대각선 요소는 오분류된 사례를 나타낸다.
불균형 데이터에서 정확도가 거짓말할 때
데이터 불균형이 심한 경우, 단순한 정확도는 오해의 소지가 있다. 예를 들어 사기 탐지 시스템에서 사기 거래가 전체의 1%에 불과하다면, 모든 거래를 '정상'으로 예측해도 99%의 정확도를 얻을 수 있지만 이는 의미 없는 모델이다. 이런 경우 혼동행렬을 통해 계산되는 정밀도·재현율·F1 점수가 더 유용한 지표가 된다.
임계값을 움직이면 행렬도 함께 움직인다
대부분의 분류기는 확률 값을 출력하고, 이를 임계값(보통 0.5)을 기준으로 클래스를 결정한다. 이 임계값을 조정하면 혼동행렬의 요소들도 변화한다. 임계값을 높이면 FP는 줄고 FN은 늘어 정밀도가 오르고 재현율이 내려간다. 반대로 임계값을 낮추면 FP는 늘고 FN은 줄어 정밀도가 내려가고 재현율이 오른다. 이 관계는 Precision-Recall 곡선이나 ROC(Receiver Operating Characteristic) 곡선으로 시각화할 수 있다.
혼동행렬만으로 부족할 때 보완하는 것들
혼동행렬만으로는 모델의 확률적 성능을 완전히 파악하기 어렵다. 특히 의사결정 임계값에 따른 변화를 한 번에 보여주지 못한다. 이를 보완하기 위해 다양한 임계값에서의 민감도(TPR)와 1-특이도(FPR)의 관계를 보여주는 ROC 곡선, ROC 곡선 아래 면적으로 전체 분류 성능을 나타내는 AUC(Area Under the Curve), 불균형 데이터셋에서 특히 유용한 Precision-Recall 곡선, 서로 다른 유형의 오류에 다른 비용을 할당하는 Cost-sensitive 평가를 함께 쓴다.
실무에 적용할 때 놓치기 쉬운 것들
분야마다 중요한 지표가 다르다. 의료 진단에서는 높은 재현율이, 법적 판단에서는 높은 정밀도가 중요할 수 있다. 각 유형의 오류가 갖는 실제 비용(금전적·사회적)을 고려해야 하고, 모델은 시간이 지나며 성능이 변할 수 있어 주기적인 평가가 필요하다. 혼동행렬은 결과의 해석과 설명이 쉬워 의사결정자에게 모델의 성능을 설명할 때도 유용하다.