evaluation

AI(인공지능) 2분류 모델 성능 평가 완벽 정리

Confusion Matrix, Accuracy, Precision, Recall, Specificity, F1-score 이해하기

머신러닝 모델을 개발할 때 모델을 학습시키는 것만큼 중요한 과정이 있습니다.
바로 모델 성능 평가(Model Evaluation) 입니다.

학습된 모델이 실제 데이터에서 얼마나 정확하게 동작하는지 확인하기 위해 다양한 평가 지표를 사용합니다.

특히 Classification(분류) 문제에서는 단순히 Accuracy(정확도)만 확인하는 것은 충분하지 않습니다.
데이터 불균형(Class Imbalance)이 존재하거나 의료 진단과 같은 중요한 분야에서는 Precision, Recall, Specificity, F1-score 등 다양한 지표를 함께 확인해야 합니다.

이번 글에서는 Python scikit-learn을 이용하여 대표적인 분류 모델 평가 방법을 정리합니다.


1. Classification 문제와 성능 평가의 필요성

Classification은 데이터를 미리 정의된 여러 클래스(Class)로 분류하는 머신러닝 문제입니다.

대표적인 예시는 다음과 같습니다.

  • 정상 메일 / 스팸 메일 분류
  • 정상 환자 / 질병 환자 진단
  • 정상 제품 / 불량 제품 검사
  • 주가 상승 / 하락 예측

등이 있습니다.

하지만 모델의 성능을 Accuracy 하나만으로 판단하면 잘못된 결과를 얻을 수 있습니다.


2. Class Imbalance (클래스 불균형) 문제

예를 들어 이메일 분류 데이터가 다음과 같다고 가정합니다.

클래스데이터 개수
Normal (정상 메일)950
Spam (스팸 메일)50

총 1000개의 데이터가 있습니다.

만약 모델이 모든 이메일을 Normal이라고 예측한다면:

정확하게 맞춘 데이터:950개950

입니다.

따라서 Accuracy는:Accuracy=9501000=0.95Accuracy= \frac{950}{1000} =0.95

즉,95%95\%

가 됩니다.

하지만 실제로는 Spam 메일을 하나도 찾지 못했습니다.

따라서:

높은 Accuracy가 항상 좋은 분류 모델을 의미하지는 않는다.

라는 점을 이해해야 합니다.


3. Confusion Matrix (혼동 행렬)

Confusion Matrix는 모델의 예측 결과를 4가지 경우로 나누어 표현한 표입니다.

예측 Positive예측 Negative
실제 PositiveTPFN
실제 NegativeFPTN

True Positive (TP)

실제 Positive이고 모델도 Positive라고 예측한 경우(정답)입니다.

예:

실제 Spam
예측 Spam

True Negative (TN)

실제 Negative이고 모델도 Negative라고 예측한 경우(정답)입니다.

예:

실제 Normal
예측 Normal

False Positive (FP)

실제는 Negative인데 Positive라고 잘못 예측한 경우(오답)입니다.

예:

실제 Normal
예측 Spam

이를 False Alarm(오탐) 이라고 합니다.


False Negative (FN)

실제는 Positive인데 Negative라고 잘못 예측한 경우(오답)입니다.

예:

실제 Spam
예측 Normal

이를 Miss(미탐) 라고 합니다.


4. Confusion Matrix

import pandas as pd
from sklearn.metrics import confusion_matrix
import seaborn as sns


labels = [
    "Spam",
    "Normal"
]


y_true = [
    "Normal","Normal","Normal","Normal",
    "Normal","Normal","Normal","Normal",
    "Spam","Spam"
]


y_pred = [
    "Normal","Normal","Spam","Normal",
    "Normal","Normal","Spam","Normal",
    "Normal","Spam"
]


matrix = confusion_matrix(
    y_true,
    y_pred,
    labels=labels
)


print(matrix)

실행 결과:

표로 표현하면:

실제\예측SpamNormal
Spam1(TP)1(FN)
Normal2(FP)6(TN)

5. Confusion Matrix 시각화

혼동 행렬은 Heatmap을 이용하면 쉽게 확인할 수 있습니다.

import matplotlib.pyplot as plt

sns.heatmap(
    matrix,
    annot=True,
    fmt="d",
    cmap="Greens",
    xticklabels=labels,
    yticklabels=labels
)

plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show()

실행 결과:

이를 통해 어떤 클래스에서 오류가 많이 발생하는지 직관적으로 확인할 수 있습니다.


6. Accuracy (정확도)

Accuracy는 전체 데이터 중 올바르게 예측한 데이터의 비율입니다.

공식:Accuracy=TP+TNTP+TN+FP+FNAccuracy= \frac{TP+TN} {TP+TN+FP+FN}

Python:

from sklearn.metrics import accuracy_score


accuracy = accuracy_score(
    y_true,
    y_pred
)

print(accuracy)

실행 결과:

예를 들어:

전체 데이터:10개10개

정확한 예측:7개7개

라면:Accuracy=710=0.7Accuracy= \frac{7}{10} =0.7

입니다.


7. Precision (정밀도)

Precision은 모델이 Positive라고 예측한 데이터 중 실제 Positive의 비율입니다.

공식:Precision=TPTP+FPPrecision= \frac{TP} {TP+FP}

Python:

from sklearn.metrics import precision_score

precision = precision_score(
    y_true,
    y_pred,
    pos_label="Spam"
)

print(precision)

실행 결과:

쉽게 표현하면:

모델이 Positive라고 판단한 결과가 얼마나 믿을 만한가?

를 의미합니다.


예:

모델이 Spam이라고 예측한 메일:33개

실제 Spam:11개

이면:Precision=130.33Precision= \frac{1}{3} ≈0.33

입니다.

Precision이 낮으면:

  • 정상 메일을 Spam으로 잘못 판단
  • 불필요한 경고 증가

문제가 발생합니다.


8. Recall (Sensitivity, 민감도)

Recall은 실제 Positive 데이터를 모델이 얼마나 찾아냈는지를 의미합니다.

또한 의료 분야에서는 Sensitivity(민감도) 라고 표현합니다.

공식:Recall(Sensitivity)=TPTP+FNRecall(Sensitivity)= \frac{TP} {TP+FN}

Python:

from sklearn.metrics import recall_score

recall = recall_score(
    y_true,
    y_pred,
    pos_label="Spam"
)

print(recall)

실행 결과:

쉽게 표현하면:

실제 Positive 중 얼마나 발견했는가?

입니다.


예:

실제 Spam:22개

모델이 발견:11개

이면:Recall=12=0.5Recall= \frac{1}{2} =0.5

즉 실제 Spam 중 50%를 찾았다는 의미입니다.


9. Specificity (특이도)

Specificity는 실제 Negative 데이터를 얼마나 정확하게 Negative라고 판단하는지를 나타내는 지표입니다.

특히 의료 진단, 바이오 분석, 검사 시스템에서 매우 중요합니다.

공식:Specificity=TNTN+FPSpecificity= \frac{TN} {TN+FP}

scikit-learn에서는 Specificity를 직접 제공하지 않기 때문에 confusion matrix의 TN(True Negative)과 FP(False Positive)를 이용하여 계산합니다. 또는 Negative class를 Positive로 간주하여 Recall을 계산하면 동일한 결과를 얻을 수 있습니다.

Python:


# matrix = [[1, 1],
#           [2, 6]]

TP = matrix[0, 0]   # 1
FN = matrix[0, 1]   # 1
FP = matrix[1, 0]   # 2
TN = matrix[1, 1]   # 6

specificity = TN / (TN + FP)

print(specificity)

실행 결과:

의미:

실제 정상 데이터를 얼마나 정확하게 정상으로 판단하는가?

입니다.


예:

Confusion Matrix:

실제\예측SpamNormal
Spam11
Normal26

Normal을 Negative라고 하면:TN=6TN=6FP=2FP=2

따라서:Specificity=66+2=0.75Specificity= \frac{6}{6+2} =0.75

즉 정상 메일 중 75%를 정확하게 정상으로 판단했습니다.


10. Sensitivity와 Specificity 비교

의료 진단에서는 두 지표를 함께 확인합니다.

지표의미공식
Sensitivity (Recall)질병 환자를 얼마나 찾는가TPTP+FN\frac{TP}{TP+FN}
Specificity정상인을 얼마나 정확히 구분하는가TNTN+FP\frac{TN}{TN+FP}

Sensitivity가 중요한 경우

예:

암 진단

목표:

환자를 놓치지 않는 것

따라서:

  • FN 감소
  • Recall 증가

가 중요합니다.


Specificity가 중요한 경우

예:

스팸 메일 필터

목표:

정상 메일을 정상으로 판단(불필요한 추가 검사 방지)

따라서:

  • FP 감소
  • Specificity 증가

가 중요합니다.


11. F1-score

Precision과 Recall은 서로 반대 방향으로 변하는 경우가 많습니다.

따라서 두 지표를 동시에 고려하기 위해 F1-score를 사용합니다.

공식:F1=2×Precision×RecallPrecision+RecallF1= 2 \times \frac{ Precision\times Recall } { Precision+Recall }

Python:

from sklearn.metrics import f1_score

f1 = f1_score(
    y_true,
    y_pred,
    pos_label="Spam"
)

print(f1)

실행 결과:

F1-score는 Precision과 Recall의 조화 평균(Harmonic Mean)입니다.


12. Classification Report 분석

Python:

from sklearn.metrics import classification_report


report = classification_report(
    y_true,
    y_pred,
    labels=["Spam", "Normal"]
)

print(report)

실행 결과:

Spam 행은 Spam 클래스를 Positive(양성) 클래스로 간주하여 계산한 결과입니다.

Normal 행은 Normal 클래스를 Positive(양성) 클래스로 간주하여 계산한 결과입니다.


Precision

예측한 결과의 신뢰도입니다.

Normal:0.860.86

의미:

모델이 Normal이라고 판단한 데이터 중 86%가 실제 Normal입니다.


Recall

실제 데이터를 얼마나 찾았는지를 의미합니다.

Spam:0.500.50

의미:

실제 Spam 데이터 중 50%를 발견했습니다.


F1-score

Precision과 Recall을 동시에 고려한 종합 성능입니다.


Support

Support는 실제 데이터 개수입니다.

예:

Normal = 8개
Spam = 2개

이며 예측 개수가 아니라 실제 Label 개수입니다.


13. Macro Average

Macro average는 각 클래스의 성능을 동일한 비중으로 평균합니다.

공식:Macro=Class1+Class2+...+ClassnnMacro= \frac{Class_1+Class_2+…+Class_n}{n}

특징:

  • 클래스별 중요도가 동일
  • 불균형 데이터에서 작은 클래스 성능 확인 가능

14. Weighted Average

Weighted average는 각 클래스의 데이터 개수(Support)를 고려한 평균입니다.

공식:Weighted=Score1×Support1+Score2×Support2TotalWeighted= \frac{ Score_1\times Support_1+ Score_2\times Support_2 } {Total}

특징:

  • 데이터가 많은 클래스 영향 증가
  • 전체적인 평균 성능 평가에 적합

15. Multi-class Classification 평가 방법

다중 클래스 분류(Multi-class Classification)에서도 기본적인 평가 방식은 이진 분류(Binary Classification)와 동일합니다.

다만 하나의 클래스를 Positive로 설정하고 나머지 모든 클래스를 Negative로 변환하는 One-vs-Rest(One-vs-All) 방식으로 각 클래스별 Precision, Recall, F1-score를 계산합니다.

예를 들어 3개 클래스(A, B, C)가 있다면:

  • A vs (B+C)
  • B vs (A+C)
  • C vs (A+B)

형태로 각각 평가한 후 Macro avg 또는 Weighted avg를 이용하여 전체 모델 성능을 확인합니다.


16. 마무리

분류 모델의 성능 평가는 Accuracy 하나만으로 판단해서는 안 됩니다.

특히 실제 데이터에서는 클래스 불균형 문제가 자주 발생하기 때문에 Precision, Recall, Specificity, F1-score를 함께 확인하는 것이 중요합니다.

정리하면:

  • Confusion Matrix → 오류 유형 확인
  • Accuracy → 전체 정확도
  • Precision → Positive 예측의 신뢰도
  • Recall(Sensitivity) → Positive 탐지 능력
  • Specificity → Negative 판별 능력
  • F1-score → Precision과 Recall의 균형
  • Macro avg → 클래스별 균등 평가
  • Weighted avg → 데이터 비율을 고려한 평가

좋은 머신러닝 모델은 단순히 높은 Accuracy를 가지는 모델이 아니라,
문제의 목적에 맞는 오류를 최소화하고 실제 환경에서 안정적으로 동작하는 모델입니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다