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 | 편향 방지 |
| 놓침 비용 큼 | Recall | FN 최소화 |
| 오탐 비용 큼 | Precision | FP 최소화 |
| 균형 필요 | 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