Day to_day

[모델 평가] 이진 분류에서 평가 지표 개념 바로 알기 (오차행렬, 정밀도, 재현율) 본문

Machine Learning/머신러닝 기초

[모델 평가] 이진 분류에서 평가 지표 개념 바로 알기 (오차행렬, 정밀도, 재현율)

m_inglet 2023. 2. 6. 01:08
728x90
반응형

❗본 포스팅은 권철민 선생님의 '파이썬 머신러닝 완벽가이드' 강의와 '파이썬 라이브러리를 활용한 머신러닝' 서적을 기반으로 개인적인 정리 목적 하에 작성된 글입니다. 

 

 

포스팅 개요

 분류 모델을 공부하면서 가장 쉽고 직관적으로 모델의 성능을 판단할 수 있었던 '정확도(accuracy)'를 보고 모델을 판단했었다. 간단한 예제나 처음 공부할 땐 정확도라는 지표는 쉽게 받아들일 수 있는 개념이었고, 모델이 예측에 성공했느냐 못했느냐 정도만 판단해 평가했다. 

 

 하지만 사실 분류 모델의 성능을 판단하기엔 정확도라는 지표는 한계가 있고, 이진 분류 모델에서는 정밀도(precision)와 재현율(recall)이 더 정확한 지표로 사용된다. 분야마다 다른 지표를 사용할 수 있지만 오늘은 정확도의 한계오차 행렬에 대해서 적어보려고 한다. 

 

 

정확도의 한계

정확도는 이진 분류에서 데이터가 불균형 할 때 문제가 발생한다.

 

 예를 들어보자. 데이터는 90개의 정상 메일과 10개의 스팸 메일이 있고, 이때 어떤 데이터든 간에 무조건 정상 메일로 예측해 버리는 모델이 있다고 가정하자. 이 모델이 100개의 데이터를 예측한다고 했을 때 정확도는 어떻게 될까?

 100개 중에 90개는 맞출 것이니 정확도는 90%가 된다. 하지만 이 모델을 스팸 메일을 잘 판별하는 좋은 모델이라고 할 수 있을까?

분명 잘못된 모델임은 확실하다. 이렇게 데이터가 불균형 할 때 정확도는 좋은 지표가 될 수 없다.

 

간단한 코드 예제로 또 다른 데이터로 살펴보겠다.

mnist 필기체 숫자 데이터를 이용해서 이진 분류를 해볼 것이다. 

0부터 9까지의 숫자 중 '이 숫자가 7인가 아닌가?'를 분류하는 것이 목적이다. 이진 분류이면서 데이터 불균형을 만들기 위함이다.

그러면 타겟 데이터(라벨 데이터)는 7일 때 1, 7이 아닐 때 0으로 라벨링 하면 90%는 0이고, 10%는 1이 들어있을 것이다.

이제 내가 만들 멍청한 모델은 입력된 데이터의 크기에 맞춰 모든 값을 0으로 만들어 반환하는 모델이다. 

 

그러면 결과적으로? 

0으로 모든 값을 예측했으니 90%는 예측에 성공하고, 10%는 틀렸을 것이다. 코드는 다음과 같다.

 

 

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.base import BaseEstimator
from sklearn.metrics import accuracy_score
import numpy as np
import pandas as pd

class MyFakeClassifier(BaseEstimator):
    def fit(self,X,y):
        pass
    
    # 입력값으로 들어오는 X 데이터 셋의 크기만큼 모두 0값으로 만들어서 반환
    def predict(self,X):
        return np.zeros((len(X), 1) , dtype=bool)

# 사이킷런의 내장 데이터 셋인 load_digits( )를 이용하여 MNIST 데이터 로딩
digits = load_digits()

print(digits.data)
print("### digits.data.shape:", digits.data.shape) # 8x8 array로 데이터가 이루어져있음
print(digits.target)
print("### digits.target.shape:", digits.target.shape) # 타겟 데이터는 1767개
# digits번호가 7번이면 True이고 이를 astype(int)로 1로 변환, 7번이 아니면 False이고 0으로 변환. 
y = (digits.target == 7).astype(int) # False = 0, True = 1로 바꾸는 구문 90% 0이고, 10%가 1임
X_train, X_test, y_train, y_test = train_test_split(digits.data, y, random_state=11)

 

# 불균형한 레이블 데이터 분포도 확인. 
print('레이블 테스트 세트 크기 :', y_test.shape)
print('테스트 세트 레이블 0 과 1의 분포도')
print(pd.Series(y_test).value_counts())

# Dummy Classifier로 학습/예측/정확도 평가
fakeclf = MyFakeClassifier()
fakeclf.fit(X_train , y_train)
fakepred = fakeclf.predict(X_test)
print('모든 예측을 0으로 하여도 정확도는:{:.3f}'.format(accuracy_score(y_test , fakepred)))

 

 

<코드 실행 결과>

레이블 테스트 세트 크기 : (450,)
테스트 세트 레이블 0 과 1의 분포도
0    405
1     45
dtype: int64
모든 예측을 0으로 하여도 정확도는:0.900

 

 

 

오차 행렬

오차 행렬은 이진 분류 평가 결과를 나타낼 때 가장 널리 사용되는 방법 중 하나이다. 

그림으로 보면 한눈에 볼 수 있다.

행은 실제 클래스에 해당하고, 열은 예측 클래스에 해당한다. 

대각 행렬에 해당하는 값들(T를 가진 것)은 양성인지 음성인지에 관계없이 정확하게 분류된 경우이고, F가 있는 경우는 실제 틀리게 예측한 케이스이다.

P가 의미하는 것은 양성으로 예측한 것이며, N이 의미하는 것은 음성으로 예측한 경우이다. 

 

네 가지 경우는 다음과 같다.

 

- TN : 음성으로 예측해서 맞은 경우

- FN : 음성으로 예측해서 틀린 경우 (거짓 음성)

- TP : 양성으로 예측해서 맞은 경우

- FP : 양성으로 예측해서 틀린 경우 (거짓 양성)

 

 

양성 음성?

잠깐 양성과 음성의 의미를 살짝 짚고 넘어가자면,

이진 분류에서 양성 클래스는 학습하고자 하는 대상을 의미한다. 만약 스팸 메일을 분류하는 경우 찾고자 하는 경우가 '스팸 메일'이기 때문에 그 경우를 양성 클래스라고 정한다.

 

 

거짓 양성, 거짓 음성은 왜 중요한가?

각 업무에 따라 상대적으로 거짓 양성, 거짓 음성이 중요한 경우가 다르다.

예를 들어 암 진단의 경우 '암이 걸렸는데 정상이라고 판단한 경우'는 생명과 직결되는 최악의 경우이기 때문에 실제 양성인 데이터를 음성으로 예측했기 때문에 이 경우는 거짓 음성에 속한다. 이 때문에 암 진단 예시에서는 거짓 음성을 최대한 피해야 하는 반면, 거짓 양성은 비교적 중요도가 낮다.

 

반면, 스팸 메일을 분류하는 경우 '중요한 메일이 스팸 메일로 분류되는 경우'가 업무에서 최악의 경우일 것이다. 이때는 실제 음성인 데이터를 양성으로 분류하였기 때문에 이 경우는 거짓 양성에 속한다. 스팸 메일 분류에서는 거짓 양성을 최대한 피해야 하며 거짓 음성의 중요도는 비교적 낮다.

 

 

1. 정밀도 (Precision)

정밀도는 FP의 수를 줄이는 것이 목표일 때 중요한 성능지표가 된다. (FP가 줄어들면, 정밀도가 증가하기 때문)

예측을 Positive로 한 대상 중(분모)에서 예측과 실제 값이 Positive로 일치한 데이터(분자)의 비율을 뜻한다.

정밀도가 중요한 예시 : 스팸 메일 분류 작업

2. 재현율 (Recall)

재현율은 모든 양성 샘플을 식별해야 할 때 성능 지표로 사용된다. (FN이 최소화 되는 경우, 재현율은 증가한다

실제 값이 positivie인 대상 중(분모)에 예측과 실제 값이 positive로 일치한 데이터(분자)의 비율을 뜻한다.

재현율이 중요한 예시 : 암 진단 판별

3. 정확도 (Accuracy)

예측 결과와 실제 값이 동일한 건수/전체 데이터 수

 

 

정밀도와 재현율의 트레이드오프 (Trade-off)

 위에서 업무에 따라 FN(거짓 음성)을 최소화하거나, FP(거짓 양성)를 최소화하는 것이 중요하다고 말했었는데 그 말을 다시 하면 특정 업무에 따라 정밀도 혹은 재현율이 중요한 지표로 작용한다고 할 수 있다. 이 정밀도와 재현율은 분류 결정 임계값에 의해 약간 조정을 할 수 있다. 

 

 좀 더 자세히 말하자면, 이진 분류에서 양성과 음성을 판별할 때 그 결과는 확률로 나오고 '분류 결정 임계값'에 의해서 양성 혹은 음성으로 분류한다. 아래의 예시는 임계값이 0.5일 때 분류된 것이다.

첫번째 열: 0이 될 확률, 두번째 열: 1이 될 확률, 세번째 열: 분류

 

예를 들어 양성(positive)일 확률이 0.45이고 임계값이 0.5라면 음성으로 분류될 것이다. 하지만 임계값을 0.4로 낮춘다면 확률은 그대로임에도 불구하고 임계값이 낮아졌기 때문에 양성으로 분류될 것이다. 이렇게 임계값이 낮아질 수록 양성으로 분류할 확률이 높아진다는 것이고 그 결과는 다음과 같다.

 

정밀도 = TP / (FP + TP) ⇒ 정밀도에서 FP는 positive로 예측할 확률이니 그 값이 올라가면 정밀도는 낮아질 것이다.

재현율 = TP / (FN + TP) ⇒ 재현율에서 FN은 negative로 예측할 확률이니 그 값은 낮아질것이고 재현율은 증가할 것이다.

 

이렇듯 정밀도와 재현율은 상호보와적인 관계이고, 어느 한쪽을 강제로 높이면 다른 하나의 수치는 떨어지기 쉽다.

이것을 정밀도와 재현율의 트레이드 오프(Trade-off)라고 부른다.

 

 

임계값에 따른 정밀도와 재현율을 그래프로 그리면 다음과 같다.

 

 

 

하지만 평가지표를 정밀도와 재현율만으로 사용하기엔 맹점이 있다.

자세한 내용과 그 대안에 대해서는 다음 포스팅으로 넘어가야겠다.

 

728x90
반응형
Comments