데이터 한 그릇

분류1)머신러닝 평가 중 분류모형 평가 본문

머신러닝/분류

분류1)머신러닝 평가 중 분류모형 평가

장사이언스 2021. 3. 26. 00:55
  • 정확도(Accuracy)
  • 오차행렬(Confusion Matrix)
  • 정밀도(Precision)
  • 재현율(Recall)
  • F1 스코어
  • ROC AUC

 

먼저 머신러닝이 진행되는 프로세스에 대해서 살펴보도록 하자. 머신러닝 프로세스는 거칠게 3가지로 나뉠 수 있다. 

 

  1. 데이터 가공/변환
  2. 모델 학습/예측
  3. 평가(Evaluation)

  앞서 타이타닉 생존자 예측 모델의 경우에도, 로지스틱 회귀 분석과 의사결정나무를 통해 만든 모델을 "정확도"를 통해서 평가하였다. 이처럼 모델은 어떤 척도를 가지고 평가를 받게 되는데, 평가의 척도(성능평가지표)는 머신러닝 모델이 회귀모형인지 분류모형인지에 따라 나뉜다.

 

  회귀모델의 경우 대부분이 실제값과 예상값의 오차의 평균을 지표로 삼아 평가한다. 실제값과 예상값의 오차에 제곱을 하고 루트를 씌운 값들을 모조리 더하여 평균을 낸다거나, 오차에 절대값을 씌운 값들을 모조리 합하여 평균을 낸다거나 하여 통계적 수치를 만들고 그 수치를 기준으로 모델을 평가하는 것이다. 회귀모델의 평가같은 경우는 파이썬 머신러닝 완벽가이드 회귀 파트에서 더 자세히 할 예정이다.

 

  회귀모형은 이후의 파트에 맡기기로 하고 이번 장에서는 분류모형의 성능 평가 지표에 대해서 살펴볼 예정이다. 분류모형 또한 실제값과 예측값의 오차에 집중하기도 하지만 그 이외에 다른 지표도 사용한다. 분류모형의 다양한 성능평가 지표는 아래와 같다.

 

  1. 정확도
  2. 오차행렬
  3. 정밀도
  4. F1 스코어
  5. ROC AUC

  분류는 긍정과 부정과 같은 2개의 결과값만을 가지는 이진 분류와 여러 개의 결과값을 가지는 멀티 분류로 나뉠 수 있다. 위에 적힌 성능 평가 지표는 모든 종류의 분류(이진 분류, 멀티 분류)에 사용 가능하지만 그 중에서 이진 분류일 때 더 중요하다고 할 수 있다. 먼저 성능 평가 지표 중 하나인 "정확도(Accuracy)" 에 대해서 살펴보도록 하자.

 


정확도

 

  정확도는 실제 데이터에서 예측 데이터가 얼마나 같은지를 판단하는 지표이다. (실제값과 예측값이 얼마나 동일한지 판단하는 지표) 정확도는 다음과 같이 구해진다.

 

 

"정확도(Accuracy) = 예측 결과가 같은 데이터 건수 / 전체 예측 데이터 건수"

 

 

  정확도는 직관적으로 모델을 평가하는 성능 평가 지표이긴 하지만 이진 분류의 경우 데이터의 구성에 따라서 ML모델의 성능을 왜곡할 가능성도 있다. 아래 링크의 타이타닉 생존자예측 모델을 만들었을 때, 생존의 여부는 성별에 지대한 영향을 받는다. 따라서 왠만하면 성별이 여성이면 살고 남성이면 죽는 결과를 내어놓게 된다. 그렇다면 단순히 성별 조건 하나만을 가지고 생존 여부를 결정하는 별거 아닌 알고리즘도 높은 정확도를 나타내는 상황이 발생할 수 있다. 따라서 정확도만을 가지고 모델, 특히 이진 분류모델을 평가하기엔 문제가 있다.

  또한 이진분류의 결과값들이 불균형하게 퍼져 있을 경우에도 정확도만을 가지고 모델 성능을 평가하기엔 무리가 있다. 예를 들어서 0이 90개 1이 10개인 총 100개의 label 데이터가 있다고 해보자. 이 때 무조건 0을 반환하는 모델이 있다고 가정했을 때, 이 모델의 정확도는 90%로 나온다.

 

밑의 코딩은 사이킷런에서 제공하는 load_digits의 데이터를 통한 분류모델을 만든 코딩이다..

데이터는 레이블 데이터이며, 레이블 데이터 값은 0~9까지 존재한다.

이 데이터를 7일 경우에는 true로, 7이 아닐 경우에는 false로 변환해보자.

그렇다면 데이터의 10%는 true이고 나머지 90%는 false인 불균형한 데이터가 될 것이다.

 

이 때 이 데이터 세트의 모든 데이터를 false로 예측하는 classifier를 생성하여 정확도를 계산해본다면 90%가 나올 것이다. 이처럼 정확도 만으로 모델의 성능을 평가하는 것은 무리다.

 

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

class MyFakeClassifier(BaseEstimator):
    def fit(self, X,y):
        pass

    def predict(self, X):
        return np.zeros((len(X),1), dtype=bool)

digits = load_digits()

y = (digits.target ==7).astype(int)
X_train,X_test,y_train,y_test = train_test_split(digits.data,y,random_state=11)

 

fakeclf = MyFakeClassifier()
fakeclf.fit(X_train,y_train)
fakepred = fakeclf.predict(X_test)

오차 행렬

 

  이진 분류에서 모델 성능 평가 지표로 사용되는 오차 행렬(confusion matrix)에 대해서 살펴보도록 하자. 오차 행렬은 학습된 분류 모델이 얼마나 헷갈리고 있는지도 판단해주는 지표이다. 즉, 이진 분류의 예측 오류가 얼마인지와 더불어서 어떤 유형의 예측 오류가 발생하고 있는지도 말해준다.

 

  예측 값
실제 값 TN FP
FN TP

 

  만일 모델이 예측을 Negative로 했는데 실제 데이터가 Negative일 경우에는 TN라고 말한다. 뒤의 글자 N은 모델이 예측한 결과 값을 의미한다. 앞의 글자는 실제 데이터와 예측 결과 값의 논리값 결과라고 할 수 있다. 만일 예측값과 실제값이 동일하다면 T를 도출하고 동일하지 않다면 F를 도출한다. 만일 POSITIVE로 예측했는데, 실제값도 POSITIVE라면 TP라고 부른다. 오차 행렬을 사이킷런으로 구현하면서 오차 행렬을 통한 모형 평가를 살펴보도록 하자.

 

  

  먼저 사이킷런의 metrics에서 confusion_matrix를 통해 오차 행렬을 구현할 수 있다. 앞서 load_digit()데이터에 관하여 7은 true이고 나머지 레이블들은 false로 변환한 데이터에 관해 무조건 false를 반환하는 모델을 만들었었다. 이번에는 정확도로 평가하지 말고 오차 행렬을 통해서 모델을 평가해보도록 하자.

 

  이 모델에 관하여 confusion_matrix함수를 통해서 오차 행렬을 구현해 본다면 TN자리에 405개 FN자리에 45개가 나온다. TN이라고 한다면 NEGATIVE라고 예측을 했을 때 실제값과 일치한 것을 말한다. 모델은 항상 FALSE만을 반환하기 때문에 모든 데이터 중에 실제 FALSE인 값들이 405개라는 것을 의미한다. FP의 경우 P라고 예측을 한 경우가 없으므로 0개 일수밖에 없다. TP의 경우도 마찬가지이다. FN 같은 경우 모델이 무조건 FALSE으로 예측을 하고 실제 데이터 값이 0이 아닌 경우를 말한다. 이 경우 45개의 실제 데이터가 0이 아님을 나타내준다. 

 

from sklearn.metrics import confusion_matrix

confusion_matrix(y_test, fakepred)

 

  이처럼 불균형한 데이터일 경우에는 POSITIVE 데이터 보다는 NEGATIVE 데이터가 많은 경우가 많다. 따라서 데이터를 기반으로 하여 만들어진 머신러닝 모델 같은 경우에 NEGATIVE를 많이 예측을 하게 되면서 모델 성능을 높이게 될 것이다. 따라서 TN은 매우 커지게 되고 TP는 매우 작아지게 된다. 또한 FN의 수치는 작아지게 되고 POSITIVE라고 예측을 하는 경우가 적어지기 때문에 FP의 수치도 작아지게 된다.

 

  정확도의 개념도 오차 행렬을 통해서 재정의 될 수 있다. 정확도는 다음과 같다.

 

정확도 = (TN + TP) / (TN+TP+FN+FP)

 

  그렇다면 불균형한 데이터가 존재할 때 이 데이터를 통해서 만든 모델의 성능을 판단할 수 있는 성능 평가 지표는 무엇일까? 바로 정밀도(Precision) 과 재현도(Recall) 이다.(불균형한 데이터의 경우 NEGATIVE 판단에 초점을 두어서 모델이 만들어짐)

 

 


정밀도와 재현율

  먼저 오차 행렬을 통해서 정밀도와 재현율을 계산할 수 있다. 다음은 정밀도와 재현율을 오차 행렬로 계산하는 식이다.

 

 

정밀도 = TP / (FP+TP)

재현율 = TP / (FN+TP)

 

  정밀도와 재현율은 Positive 데이터 세트의 예측 성능에 좀 더 초점을 맞춘 평가 지표이다. 정밀도는 예측을 POSITIVE로 한 대상 중에 예측과 실제 값이 POSITIVE로 일치한 데이터의 비율을 뜻한다. 그렇기 때문에 POSITIVE로 예측한 것 중에서 실제 값이 POSITIVE 인게 분자로 들어가고 POSITVIE로 예측한 모든 경우의 수인 TP, FP가 분자로 들어간 것이다.

 

  재현율은 실제 값이 POSITIVE인 대상 중에 예측과 실제 값이 POSITIV로 일치한 데이터의 비율을 뜻한다. 따라서 분자는 POSITVIE 대상 중 예측이 POSITIVE인 경우이기 때문에 TP이며, 모든 POSITIVE 대상인 경우의 수를 따져야 하기 때문에 FN, TP가 분자가 될 수 밖에 없다. 재현율은 민감도라고도 불린다.

 

 

  정리하면 예측을 POSITIVE로 한 것들 중에서 실제값과 일치한 비율이 정밀도이고, 대상이 POSITIVE인 것들 중에서 예측과 대상이 일치한 비율이 재현율이다.

 

  그렇다면 재현율과 정밀도는 어느 때 사용해야 하는가? 재현율과 정밀도 중에 더 중요한 지표를 고르라고 한다면 업무의 상황을 고려해서 선택해야만 한다. 예를들어서 실제는 POSITIVE인데 모델이 NEGATIVE라고 했을 경우 큰일이 나는 경우는 재현율을 고려해야만 한다. 예를 들어서 어떤 사람이 실제로는 암인데 그것을 NEGATIVE라고 모델이 선택을 할 경우에는 생명을 잃을 수도 있는 큰손실을 발생시킨다. 반대로 NEGATIVE인데 POSTIVE라고 한다면 큰일이 나는 경우에는 정밀도를 사용해야만 한다. 예를 들어서 스팸메일을 판독하는 모델이 있을 때 모델이 스펨메일을 아닌 것을 POSITIVE로 분류하게 된다면 받아야 할 메일을 받지 못할 수도 있는 상황이 온다. 재현율과 정밀도를 선택해야 하는 상황을 일반화해서 정리하면 다음과 같다.

 

실제 POSITIVE이지만 NEGATIVE라고 했을 때 큰일 나는 일이면 "재현율"

 

실제 NEGATIVE이지만 POSITIVE라고 했을 때 큰일 나는 일이면 "정밀도"

 

 

  그렇다면 재현율은 POSITIVE이지만 NEGATIVE라고 하는 경우를 경계해야하므로 FN의 수치를 낮추려고 할 것이고, 정밀도는 POSITIVE로 예측했지만 NEGATIVE인 경우를 경계해야하므로 FP의 수치를 낮추려고 할 것이다. 어떤 데이터를 분석했을 때 가장 좋은 경우는 정밀도와 재현율이 높은 경우이며 나쁜 경우는 두 수치의 차이가 클 때이다.

 

 

1)정밀도/재현율 트레이드 오프

 

  분류하는 업무상 정밀도와 재현율이 특히 강조되어야 하는 경우, 정밀도와 재현율은 인위적으로 올릴 수가 있다. 하지만 정밀도와 재현율은 상호 보완적이기 때문에 한 수치의 값을 올리게 되면 다른 수치의 값이 떨어지게 된다. 이를 정밀도와 재현율의 트레이드 오프라고 한다.

 

  정밀도와 재현율 값을 인위적으로 조작하는 방법을 이해하기 위해서는 predict_proba() 함수에 대해서 알아야 한다. 예를 들어서 사망0,생존1의 이진 분류 데이터가 존재할 때, 로지스틱 회귀분석 모델을 만들고 그 데이터를 모델에 집어넣었다고 해보자. 긜고 predict_proba 에 모델을 집어넣어서 [0.9,0.1] 이 나왔다고 한다면, 임계값 0.5를 기준으로 더 큰 값을 선택하게 된다. 따라서 사망의 확률을 선택하게 된다. 그런데 임계값에 대한 조정을 Binarizer 을 이용해서 할 수 있다.

 

  먼저 싸이킷런에서 제공하는 Binarizer의 사용법은 다음과 같다. threshold를 통해서 임계값을 설정하고 Binarizer는 fit_transform 메서드를 제공한다. 배열을 이 함수에 집어넣으면 임계값을 기준으로 0과 1을 도출한다.

 

from sklearn.preprocessing import Binarizer
X = ([1,-1,2],
     [2,0,0],
     [0,1.1,1.2]
)

binarizer = Binarizer(threshold = 1.1)
binarizer.fit_transform(X)

 

  이를 이용해서 모델의 임계값을 조절하게 된다면 재현율을 높일 수 있다. 만일 임계값을 낮춘다면 POSITIVE로 예측하는 횟수가 증하게 되고 따라서 실제 POSITIVE를 POSITIVE라고 할 확률이 높아지기 때문에 재현율이 높아진다. 재현율이 높아지면 POSITIVE라고 예측하는 횟수가 적어지기 때문에 재현율이 떨어진다. 

 


F1 스코어

 

  F1 스코어는 정밀도와 재현율을 결합한 수치이다. F1 스코어가 높게 나오기 위해서는 정밀도와 재현율이 각각 극단적인 값으로 치우쳐져 있지 않으면 된다. 만일 재현율이 0.1이고 정밀도가 0.9인 것과 재현율이 0.5이고 정밀도가 0.5인 경우가 있다면 후자의 경우가 F1 스코어가 더 높게 나온다. F1 스코어를 구하는 공식은 다음과 같다.

 

F1 SCORE = 2 X PRECISION * RECALL / PRECISION + RECALL

 

F1스커어는 다른 수치들과 마찬가지로 from sklearn.metrics import f1_score를 통해서 확인할 수 있다.

 


ROC 곡선과 AUC 스코어

 

  ROC곡선과 이에 기반한 AUC 스코어는 이진 분류 모델을 평가하는 중요한 지표이다. ROC곡선은 FPR(False Positive Rate) 의 변화에 따른 TPR(True Positive Rate) 이다.

 

  TPR은 True Positive Rate 이기 때문에 재현율(Recall)과 같다. 재현율은 민감도라고도 불린다. 민감도를 구하는 식은 앞서서 살펴봤듯이 TP/ TP+FN 이다. 재현율(민감도)과 반대되는 개념은 TNR(True Negative Rate) 이다. 이는 특이성(Specificity)이라고도 불린다. 구하는 공식은 TN / TN + FP 이다. 그런데 FPR을 구하는 공식은 FP / FP + TN 이다. 따라서 FPR은 1 - 특이성으로도 표현이 된다. 왜냐하면 FPR의 개념자체가 실제로는 NEGATIVE 인데 POSITIVE라고 할 확률이며 TNR의 개념이 실제로 NEGATIVE인데 NEGATIVE로 예측할 확률이기 때문이다.

 

민감도 = TP / TP  + FN

 

FPR = FP / FP + TN

 

특이도(TNR) = TN/TN + FP -> 민감도의 반대 (민감도는 실제가POSITIVE,예측이 POSITIVE)

 

  ROC곡선을 구하기 위해서는 FPR의 값이 0부터 시작하여 1로 끝날 때 까지의 TPR의 변화를 기록한다. 그렇다면 어떻게 FPR의 값을 0으로 설정을할까? 바로 임계값을 조정하면 된다. 만일 임계값을 1로 조정하게 된다면 모델이 POSITIVE로 판단할 수 없게 되면서 P가 0이 되면서 분자가 0이 되어 FPR 값은 자동으로 0이 된다.(FP / FP + TN = FPR) 반대로 FPR을 1로 만들기 위해서는 임계값을 0으로 만들면 된다. 모든 것들에 대해서 전부 POSITIVE를 하게 된다면 TN의 확률을 0이 되게 되고 따라서 FPR은 1이 되게 된다.

 

  이 때 ROC의 그래프가 전부 그려지게 된다면 ROC 그래프의 아래의 면적이 모델 성능 평가의 지표가 된다. 이 값을 AUC라고 부른다. AUC 1에 가까울수록 ROC그래프는 왼쪽 상단 모서리에 붙게 그려질 것이고 가운데 직선과 멀어지게 될 것이다. 만일 가운데 직선과 멀어지고 면적이 전체 면적에 가까워 진다면 그 모델은 좋은 성능을 가지고 있다고 할 수 있다.

 


정리

 

  모델을 평가하는 것은 모델의 종류에 따라서 나뉘게 된다. 이번에는 분류 모델의 성능 평가 지표에 대해서 알아보았다. 분류 모델은 크게 이진 분류와 멀티 분류로 나뉜다. 이번 장에서 살펴볼 지표들은 특히 이진 분류에 특화되어 있는 평가 지표라고 할 수 있다. 

  먼저 정확도란 모델이 예측한 것이 실제의 값과 동일한 것을 말한다. 정확도만으로 모델을 평가하면 문제점이 발생한다. 만일 어떤 데이터가 불균형적인 데이터를 가지고 있다고 해보자. 그 데이터의 90%는 FALSE이고 10%는 TRUE 라고 해보자. 어떤 모델은 무조건 FALSE라고 예측하는 모델이 있을 때 그 모델이 이 데이터를 예측하게 되어도 90%의 정확도를 가지고 있을 것이다. 즉, 엄청나게 단순한 알고리즘도 불균형한 데이터를 만나게 되면 높은 정확도를 가질 수 있게 된다. 따라서 다른 지표가 필요한데 바로 오차 행렬이다.

  오차 행렬은 예측 POSITIVE, FALSE, 실제값 POSITIVE FALSE에 따른 표를 그려 놓은 것이다. 정확도는 오차행렬에 따라서 재정의 될 수 있는데 바로 TP + TN / TP +TN + FP + FN 이다. 또한 오차행렬을 통해서 재현도와 정밀도를 계산할 수 있는데 재현도는 민감도라고도 불리며 TP / TP + FN 이며 정밀도는 TP / TP + FP 이다. 정밀도와 재현도는 분석의 사안에 따라서 정확도를 보완하여 사용하게 된다. 만일 실제값이 POSITIVE인데 예측을 NEGATIVE 하게 되면 큰일이 나는 분석 사안일 경우에는 재현율을 사용하게 된다. 그리고 실제값이 NEGATIVE인데 POSITIVE라고 예측하는 경우에 큰일이 나는 경우에는 정확도를 사용하게 된다. 재현율과 정밀도는 서로 반비례 관계를 가지고 있따. 만일 정밀도가 높아지면 재현율이 낮아지고 재현율이 높아지면 정밀도가 낮아진다. 이를 정밀도와 재현율의 트레이드 오프라고 부른다. 

  그렇다면 재현율과 정밀도를 어떻게 조정할 수 있는가? 바로 임계값을 조정하면 된다. 임계값을 1에 가깝게 높일수록 POSITIVE로 예측할 확률이 떨어지게 되고 따라서 양성 예측의 양이 줄어들다 보니 실제 양성을 양성이라고 예측할 확률도 떨어지게 되므로 재현율이 떨어지게 된다. 따라서 정밀도가 높아지게 된다. 반대로 임계값을 낮춰서 POSITIVE 예측의 양을 늘리게 되면 실제 POSITIVE를 POSITIVE라고 예측할 확률이 높아지게 되므로 재현율이 높아지고 정밀도가 떨어지게 된다. 

  그리고 F1스코어는 정밀도와 재현도의 조합적인 성능 평가 지표라고 할 수 있다. F1스코어를 구하는 공식은 (PRECISION * RECALL / PRECISION + RECALL) * 2 라고 할 수 있다. F1스코어는 정밀도와 재현도의 각각의 비중이 극단적이지만 않다면 좋은 수치를 기록하게 된다. F1스코어 또한 임계값을 조절하면서 조절 가능하다. 

  ROC곡선은 FPR이 0과 1사이에서 움직이면서 기록하는 TPR 수치(그래프)를 의미한다. 가운데 직선과 멀리 떨어져 있을 수록 좋은 평가라고 할 수 있다. 또한 AUC는 ROC그래프 아래의 면적을 나타내며 수치가 1과 가까울수록 좋은 성능의 모델이라고 판정 가능하다.  FPR은 FP / FP + TN 이며 TNR = TN / TN + FP 이기 때문에 FPR은 다시 1 - TNR(특이도) 로 나타낼 수 있다. 

 

  다음으로는 캐글의 피마 인디언 당뇨병을 예측하면서 모델을 위의 방법들로 평가해보겠다.

 

Comments