본문으로 건너뛰기

020 분류 평가 지표 - Accuracy, Precision, Recall

키워드: 평가 지표, 정확도, 정밀도

개요

분류 모델의 성능을 평가하는 지표들을 이해하는 것은 필수입니다. 이 글에서는 가장 기본적인 세 가지 지표인 Accuracy, Precision, Recall을 깊이 있게 다룹니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

혼동 행렬 (Confusion Matrix)

모든 평가 지표의 기초가 되는 혼동 행렬:

                예측
Positive Negative
실제 Positive TP FN
Negative FP TN
  • TP (True Positive): 양성을 양성으로 정확히 예측
  • TN (True Negative): 음성을 음성으로 정확히 예측
  • FP (False Positive): 음성을 양성으로 잘못 예측 (1종 오류)
  • FN (False Negative): 양성을 음성으로 잘못 예측 (2종 오류)

Accuracy (정확도)

전체 예측 중 맞은 비율.

Accuracy = (TP + TN) / (TP + TN + FP + FN)
from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 020 모델 생성
model = create_model('rf')

# 020 Accuracy 확인
results = pull()
print(f"Accuracy: {results['Accuracy'].mean():.4f}")

장점:

  • 직관적이고 이해하기 쉬움
  • 균형 잡힌 데이터에서 유용

단점:

  • 불균형 데이터에서 오해 유발
# 020 예: 99%가 정상인 사기 탐지
# 020 모든 것을 "정상"으로 예측해도 Accuracy = 99%
# 020 하지만 사기를 하나도 못 잡음!

Precision (정밀도)

양성으로 예측한 것 중 실제 양성 비율.

Precision = TP / (TP + FP)

의미: "양성이라고 예측했을 때, 얼마나 믿을 수 있나?"

# 020 Precision이 중요한 경우
# 020 - 스팸 메일 분류 (정상 메일을 스팸으로 오판하면 안 됨)
# 020 - 추천 시스템 (잘못된 추천은 사용자 경험 저하)

Recall (재현율, 민감도)

실제 양성 중 양성으로 예측한 비율.

Recall = TP / (TP + FN)

의미: "실제 양성을 얼마나 잘 찾아내는가?"

# 020 Recall이 중요한 경우
# 020 - 질병 진단 (암 환자를 놓치면 안 됨)
# 020 - 사기 탐지 (사기를 놓치면 손실)
# 020 - 결함 탐지 (불량품을 놓치면 안 됨)

Precision vs Recall 트레이드오프

from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd

data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

# 020 모델 생성
model = create_model('rf')
results = pull()

print(f"Precision: {results['Prec.'].mean():.4f}")
print(f"Recall: {results['Recall'].mean():.4f}")

# 020 일반적으로:
# 020 - 임계값을 높이면: Precision ↑, Recall ↓
# 020 - 임계값을 낮추면: Precision ↓, Recall ↑

실전 예제: 지표 선택 가이드

from pycaret.classification import *
from pycaret.datasets import get_data

# 020 사기 탐지 시나리오
data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)

# 1. Recall 중시 (사기를 놓치면 안 됨)
print("=== Recall 최적화 ===")
best_recall = compare_models(sort='Recall', n_select=1)

# 2. Precision 중시 (오탐이 비용 발생)
print("\n=== Precision 최적화 ===")
best_precision = compare_models(sort='Prec.', n_select=1)

# 3. 균형 (F1)
print("\n=== F1 최적화 ===")
best_f1 = compare_models(sort='F1', n_select=1)

시각화로 이해하기

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)

model = create_model('rf', verbose=False)

# 020 혼동 행렬 시각화
plot_model(model, plot='confusion_matrix')

# 020 분류 리포트
plot_model(model, plot='class_report')

지표 선택 가이드

상황권장 지표이유
균형 데이터Accuracy직관적
불균형 데이터AUC, F1편향 방지
놓침 비용 큼RecallFN 최소화
오탐 비용 큼PrecisionFP 최소화
균형 필요F1조화 평균

코드로 직접 계산

from sklearn.metrics import accuracy_score, precision_score, recall_score
import numpy as np

# 020 예측 결과가 있다고 가정
y_true = np.array([1, 0, 1, 1, 0, 1, 0, 0, 1, 0])
y_pred = np.array([1, 0, 1, 0, 0, 1, 1, 0, 1, 0])

# 020 직접 계산
TP = np.sum((y_true == 1) & (y_pred == 1))
TN = np.sum((y_true == 0) & (y_pred == 0))
FP = np.sum((y_true == 0) & (y_pred == 1))
FN = np.sum((y_true == 1) & (y_pred == 0))

accuracy = (TP + TN) / (TP + TN + FP + FN)
precision = TP / (TP + FP)
recall = TP / (TP + FN)

print(f"TP={TP}, TN={TN}, FP={FP}, FN={FN}")
print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")

# 020 sklearn으로 검증
print(f"\nsklearn Accuracy: {accuracy_score(y_true, y_pred):.4f}")
print(f"sklearn Precision: {precision_score(y_true, y_pred):.4f}")
print(f"sklearn Recall: {recall_score(y_true, y_pred):.4f}")

정리

  • Accuracy: 전체 정확도, 균형 데이터에 적합
  • Precision: 양성 예측의 신뢰도, 오탐 비용이 클 때
  • Recall: 양성 탐지율, 놓침 비용이 클 때
  • 불균형 데이터에서는 Accuracy만 보면 안 됨
  • 비즈니스 맥락에 따라 적절한 지표 선택

다음 글 예고

다음 글에서는 분류 평가 지표 - F1 Score, AUC를 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #020