728x90
- 머신러닝은 데이터 가공/변환, 모델 학습/예측, 그리고 평가(Evaluation)의 프로세스로 구성됩니다.
- 모델의성능 평가 지표는 일반적으로 모델이 분류냐 회귀냐에 따라 여러 종류로 나뉩니다.
- 분류의 평가방법도 일반적으로는 실제 결과 데이터와 예측 결과 데이터가 얼마나 정확하고 오류가 적게 발생하는가에 기반하지만, 단순히 이러한 정확도만 가지고 판단했다가는 잘못된 평가 결과에 빠질수 있습니다.
※ 분류의 성능 평가 지표
- 정확도(Accuracy)
- 오차행렬(Confusion Matrix)
- 정밀도(Precision)
- 재현율(Recall)
- F1 스코어
- ROC AUC
01. 정확도(Accuracy)¶
- 정확도 = 예측 결과가 동일한 데이터 건수 / 전체 예측 데이터 건수
- 정확도는 직관적으로 모델 예측 성능을 나타내는 평가 지표입니다. 하지만 이진 분류의 경우 데이터의 구성에 따라 ML 모델의 성능을 왜곡할 수 있기에 정확도 수치 하나만 가지고 성능을 평가하지 않습니다.
- 그 이유는 특정 조건 하나만을 가지고 결정하는 별거 아닌 알고리즘도 높은 정확도를 나타내는 상황이 발생할 수도 있기 때문입니다. 특히 정확도는 불균형한(imbalanced) 레이블 값 분포에서 ML 모델의 성능을 판단하는 경우, 적합한 평가 지표가 아닙니다.
In [1]:
# 예제
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()
# digits 번호가 7번이면 True이고 이를 astype(int)로 1로 변환, 7번이 아닌면 False이고 0으로 변환
y=(digits.target==7).astype(int)
X_train, X_test, y_train, y_test = train_test_split(digits.data, y, random_state=11)
# Dummy Classifier로 학습/예측/정확도 평가
fakeclf = MyFakeClassifier()
fakeclf.fit(X_train, y_train)
fakepred = fakeclf.predict(X_test)
print('모든 예측을 0으로 하여도 정확도는 :{:.3f}'.format(accuracy_score(y_test,fakepred)))
모든 예측을 0으로 하여도 정확도는 :0.900
□ 모두 0 값으로 반환함에도 불구하고 예측 정확도는 90%이다. 이러만 문제점 때문에 정확도 평가 지표는 불균형한 레이블 데이터 세트에서 성능 수치로 사용돼서는 안 됩니다.
02. 오차 행렬¶
- 오차 행렬은 이진 분류의 예측 오류가 얼마인지와 더불어 어떠한 유형의 예측 오류가 발생하고 있는지를 함께 나타내는 지표입니다.
- 오차 행렬은 4분면의 왼쪽, 오른쪽을 예측된 클래스 값 기준으로 Negatvie와 Positive로 분류하고, 4분면의 위, 아래를 실제 클래스 값 기준으로 Negative와 Positive로 분류하면 예측 클래스와 실제 클래스의 값 유형에 따라 결정되는 TN, FP, FN, TP 형태로 오차 행렬의 4분면을 채울 수 있습니다.
◇ TN는 예측값을 Negative 값 0으로 예측했고 실제 값 역시 Negative 값 0
◇ FP는 예측값을 Positive 값 1로 예측했는데 실제 값은 Negative 값 0
◇ FN은 예측값을 Negative 값 0으로 예측했는데 실제 값은 Positive 값 1
◇ TP는 예측값을 Positive 값 1로 예측했는데 실제 값 역시 Positive 값 1
In [2]:
# 위의 예제 fakepred와 실제 결과인 y_test를 Confusion_matrix()를 이용해 배열 형태로 출력
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, fakepred)
Out[2]:
array([[405, 0],
[ 45, 0]], dtype=int64)
□ 위의 결과에서 TN은 405, FP는 0, FN은 45, TP는 0에 해당합니다.
□ TP, TN, FP, FN을 조합해 Classifier의 성능을 측정할 수 있는 주요 지표인 정확도, 정밀도, 재현율 값을 알 수 있습니다.
□ 정확도 = (TN + TP) / (TN + TP + FN + FP) => 정확도 지표는 비대칭한 데이터 세트에서 Positive에 대한 예측 정확도를 판단하지 못한 채 Negative에 대한 예측 정확도만으로도 분류 정확도가 매우 높게 나타나는 수치적인 판단 오류를 일으키게 됩니다.
03. 정밀도와 재현율¶
- 정밀도와 재현율은 Positive 데이터 세트의 예측 성능에 좀 더 초점을 맞춘 평가 지표입니다.
- 정밀도 = TP / (FP + TP) , 재현율 = TP / (FN + TP)
- 정밀도는 예측을 Positive로 한 대상 중에 예측과 실제 값이 Positive로 일치한 데이터의 비율을 뜻하며 양성 예측도라고도 불립니다.
- 재현율은 실제 값이 Positive인 대상 중에 예측과 실제 값이 Positive로 인치한 데이터의 비율을 뜻하며 민감도(Sensitivity) 또는 TPR(True Positive Rate)라고도 불립니다.
- 재현율은 실제 Positive 양성 데이터를 Negative로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우 중요한 지표입니다. 예를 들어 암 판단 모델은 재현율이 훨씬 중요한 지표입니다. Positive인 암 환자를 Negative 음성으로 잘못 판단했을 경우 오류의 대가가 생명을 앗아갈 정도로 심각하지만 Negative인 건강한 혼자를 Positive로 예측한 경우면 다시 한번 재검사를 하는 수준의 비용이 소모되기 때문입니다.
- 정밀도는 실제 Negative 음성인 데이터 예측을 Positivie 양성으로 잘못 판단하게 되면 업무상 큰 영향이 발생할 경우 중요한 지표로 인지합니다.
- 재현율과 정밀도 모두 TP를 높이는 데 동일하게 초점을 맞추지만, 재현율은 FN을 낮추는 데, 정밀도는 FP를 낮추는 데 초점을 맞춥니다. 따라서 서로 보완적인 지표로 분류의 성능을 평가하며 재현율과 정밀도 모두 높은 수치를 얻는 것이 가장 좋은 성능이라고 할 수 있습니다.
- 사이킷런은 정밀도 계산을 위해 precision_score()를, 재현율 계산을 위해 recall_score()를 API로 제공합니다.
◎ 정밀도/재현율 트레이드오프¶
- 정밀도 또는 재현율이 특별히 강조돼야 할 경우 분류의 결정 임곗값(Treshold)을 조정해 정밀도 또는 재현율의 수치를 높일 수 있습니다. 하지만 정밀도와 재현율은 상호 보완적인 평가 지표이기 때문에 어느 한쪽을 강제로 높이면 다른 하나의 수치는 떨어지기 쉽습니다. 이를 정밀도/재현율의 트레이드오프(Trade-off)라고 부릅니다.
- 사이킷런은 개별 데이터별로 예측 확률을 반환하는 메서드인 predict_proba()를 제공합니다. predict_proba()를 수행해 반환되는 ndarray는 첫 번째 칼럼이 클래스 값 0에 대한 예측 확률, 두 번째 칼럼이 클래스 값 1에 대한 예측 확률입니다. 즉 predict() 메서드는 predict_proba() 메서드에 기반해 생성된 API입니다.
- predict_proba()과 같은 구현을 위해 Binarizer 클래스를 객체로 생성해보겠습니다.
In [3]:
# Binarizer 예제
from sklearn.preprocessing import Binarizer
X = [[1,-1,2],
[2,0,0],
[0,1.1,1.2]]
# X의 개별 원소들이 threshold값보다 같거나 작으면 0을, 크면 1을 반환
binarizer = Binarizer(threshold=1.1)
print(binarizer.fit_transform(X))
[[0. 0. 1.]
[1. 0. 0.]
[0. 0. 1.]]
- 임계값을 낮출수록 Positve를 True로 하는 값이 많아지게 되므로 상대적으로 재현율 값이 높아집니다. 즉 TP는 증가하고 FN은 감소하지만 FP는 증가합니다.
- precision_recall_curve() 메서드를 이용해 임곗값별 정밀도와 재현율을 구해 볼 수 있습니다.
◎ 정밀도와 재현율의 맹점¶
- 임계값에 따라 정밀도와 재현율의 수치가 변경되기에 업무 환경에 맞게 두 개의 수치를 상호 보완할 수 있는 수준에서 적용돼야 합니다. 그렇지 않고 단순히 하나의 성능 지표 수치를 높이기 위한 수단으로 사용돼서는 안 됩니다.
§ 정밀도가 100%가 되는 방법 : 확실한 기준이 되는 경우만 Positive로 예측하고 나머지는 모두 Negative로 예측합니다.
§ 재현율이 100%가 되는 방법 : 모든 경우를 Positive로 예측합니다.
- 이처럼 정밀도와 재현율 성능 수치도 어느 한쪽만 참조하면 극단적인 수치 조작이 가능합니다. 따라서 정밀도와 재현율의 수치가 적절하게 조합돼 분류의 종합적인 성능 평가에 사용될 수 있는 평가 지표가 필요합니다.
04. F1 스코어¶
- F1 스코어는 정밀도와 재현율을 결합한 지표입니다.
- F1 = 2 ( (정밀도 재현율) / (정밀도 + 재현율) ) 이며 정밀도와 재현율이 어느 한쪽으로 치우치지 않는 수치를 나타낼 때 상대적으로 높은 값을 가집니다.
- from sklearn.metrics import f1_score로 불러와 f1_score() 메서드를 통해 사용합니다.
05. ROC 곡선과 AUC¶
- ROC 곡선과 이에 기반한 AUC 스코어는 이진 분류의 예측 성능 측정에서 중요하게 사용되는 지표입니다.
- ROC 곡선은 FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)이 어떻게 변하는지를 나타내는 곡선입니다. FPR을 X 축으로, TPR을 Y 축으로 잡아 곡선 형태로 나타냅니다. TPR은 재현율이며 그에 대응하는 지표로 TNR이라고 불리는 특이성이 있습니다. FPR = FP / (FP + TN) = 1 - TNR로도 표현됩니다.
- ROC 곡선은 FPR을 0부터 1까지 변경하면서 TPR의 변화 값을 구합니다. 사이킷런은 ROC 곡선을 구하기 위해 roc_curve() API를 제공합니다.
- 대부분 임계값이 1에 가까운 값에서 점점 작아지면서 FPR이 점점 커집니다. 그리고 FPR이 조금씩 커질 때 TPR은 가파르게 커짐을 알 수 있습니다.
- 일반적으로 ROC 곡선 자체는 FPR과 TPR의 변화 값을 보는 데 이용하며 분류의 성능 지표로 사용되는 것은 ROC 곡선 면적에 기반한 AUC 값으로 결정합니다. AUC(Area Under Curve) 값은 ROC 곡선 밑의 면적을 구한 것으로 일반적으로 1에 가까울수록 좋은 수치입니다.
06. 피마 인디언 당뇨병 예측¶
- 생략
07. 정리¶
- 이진 분류의 레이블 값이 불균형하게 분포될 경우(즉 0이 매우 많고, 1이 매우 적을 경우 또는 반대의 경우) 단순히 예측 결과와 실제 결과가 일치하는 지표인 정확도만으로는 머신러닝 모델의 예측 성능을 평가할 수 없습니다. 오차 행렬을 통해 예측 성능을 평가해야하며 정밀도와 재현율은 Positive 데이터 세트의 예측 성능에 좀 더 초점을 맞춘 형가 지표입니다. 또한, F1 스코어는 정밀도와 재현율을 결합한 평가 지표이며, 정밀도와 재현율이 어느 한쪽으로 치우치지 않을 때 높은 지표값을 가지게 됩니다. ROC-AUC는 일반적으로 이진 분류의 성능 평가를 위해 가장 많이 사용되는 지표입니다. 이번 장에서는 분류 평가 지표를 배웠습니다.
728x90
'Book report > 파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
[파이썬 머신러닝 완벽가이드] 06. 차원 축소 (0) | 2022.09.12 |
---|---|
[파이썬 머신러닝 완벽가이드] 05. 회귀 (0) | 2022.09.11 |
[파이썬 머신러닝 완벽가이드] 04. 분류 (0) | 2022.04.24 |
[파이썬 머신러닝 완벽가이드] 02. 사이킷런으로 시작하는 머신러닝 (0) | 2022.03.27 |
[파이썬 머신러닝 완벽가이드] 01. 파이썬 기반의 머신러닝과 생태계 이해 (0) | 2022.03.26 |