Classification Evaluation
2023. 8. 2. 21:51ㆍ개인활동/파이썬 머신러닝 완벽가이드
평가
- 모델을 돌렸다면 얼마나 이 모델이 정확한지 파악할 수 있어야 한다.
- 어떤 모델을 사용하냐에 따라 성능평가지표가 달라진다.
- 평가가 가능한 것은 정답이 있는 학습 방식이다.
- Quiz1
- 정답이 있는 학습방식에서만 평가가 가능한 이유는 무엇일까?
- 머신러닝에서 성능평가지표를 이용해 평가할 수 있는 것은 supervised learning (지도학습)이다.
- 딥러닝 모델들 중 label(정답)이 존재하는 모델이라면 마찬가지로 성능평가지표를 이용해 모델의 성능을 파악할 수 있다.
성능평가지표
- Classification 성능평가지표
- Regression 성능평가지표
1. Classification 성능 평가지표
1 ) Accuracy
2 ) Confusion Matrix
3 ) Precision, Recall
4 ) F1 Score
5 ) ROC, AUC Curve
1) Accuracy
- 실제데이터와 예측데이터가 얼마나 같은지를 알려주는 지표이다.
- Accuracy = 예측 값 중 실제 값과 일치한 데이터 건수 / 전체 데이터 건수
- 이 지표는 모델의 성능을 왜곡해 보여줄 수 있어 다른 지표들도 함께 봐야 한다.
- 특히 Binary Classification의 경우 모델의 성능을 왜곡시키기 쉽다.
- 아래는 Accuracy를 보기 위한 예시 코드이다.
import pandas as pd
from sklearn.datasets import load_breast_cancer # 분류해볼 데이터
from sklearn.linear_model import LogisticRegression # Classification 모델 중 하나
from sklearn.model_selection import train_test_split # 학습용 데이터와 테스트용 데이터를 분리해주는 메소드
from sklearn.metrics import accuracy_score # 정확도를 평가해주는 함수
data = load_breast_cancer()
X = data.data # load_breast_cancer()에서 제공하는 함수를 이용해 feature 추출
y = data.target # 우리가 맞춰야 할 target 추출
# train, test set으로 분리해주기
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
train_test_split()란?
- train set과 test set을 분리시켜주는 메소드
- 각 feature와 target을 파라미터로 넣어줌
- 몇대몇의 비율로 train set과 test set을 나눠주고 싶은지 test_size를 이용해 설정
- random_state가 설정되지 않은 경우 이 메소드를 불러올 때마다 다른 데이터들이 train set, test set에 들어가게 됨
- 이때 항상 같은 값이 train, test set에 들어가길 바랄 때 random_state를 설정해줌
- 이 숫자의 경우 본인이 원하는 숫자로 설정해도 괜찮음
- train, test set을 분리하는 다른 방법은?
- k-fold 교차 검증이라는 방식이 있음
- 이는 overfitting을 해결하는데 도움이 되는 학습 방식
- train, test set이 분리되어있을 때 train set 중 일부를 validation set으로 만들어주고 test set으로 검증하기 전 validation set으로 검증 해보는 과정을 거침
- 여기서 k-fold는 train set을 k등분 하여 1개의 셋은 validation set으로 이용하고 나머지는 train set으로 이용
- 그리고 이 과정을 k번 거치는 것을 의미함
<img src="https://img1.daumcdn.net/thumb/R1280x0/?fname=http://t1.daumcdn.net/brunch/service/user/ErZ/image/VrIxn4n25zQBuoF7uK4k8gP_WPk.png", witdh=600> - 이 외에도 stratified k-fold 등이 존재함
# train, test set으로 나누어준 데이터를 모델에 넣어 학습
# Logistic Regression(로지스틱 회귀): 회귀라는 이름을 가지고 있으나 분류문제를 해결할 때 사용, 특히 binary classification
lr = LogisticRegression()
lr.fit(X_train, y_train) # train set을 넣어 학습시키기
y_pred = lr.predict(X_test)
# accuracy_score 메소드를 이용한 accuracy 확인해보기
acc = accuracy_score(y_test, y_pred)
acc
2) Confusion matrix
- 위에서 본 데이터는 위스콘신주의 유방암 데이터셋이다.
- 이 데이터셋은 binary Classification으로 걸렸는가, 걸리지 않았는가를 보여준다.
- 이런 binary class의 경우에는 target값이 불균형 한 경우 accuracy만 보는 것은 잘못된 결론을 도출할 수 있다.
- 이런 일을 막기 위해 확인해야하는 다른 지표들 중 하나는 바로 confusion matrix이다.
- 모델이 예측하는 과정에서 얼마나 헷갈리고 있는지를 파악할 수 있는 지표이다.
- 예측 오류가 어느정도인지, 어떤 유형의 예측 오류가 발생하였는지를 파악할 수 있다.
- True Negativ(TN): Negative 값인 0으로 예측했는데, 실제로도 Negative 값인 0인 경우 = Negative 값을 제대로 예측한 경우
- False Positive(FP): Positive 값인 1로 예측했는데, 실제로는 Negative 값인 0인 경우 = Negative 값을 제대로 예측하지 못한 경우
- False Negative(FN): Negative 값인 0으로 예측했는데, 실제로는 Psitive 값인 1인 경우 = Positive 값을 제대로 예측하지 못한 경우
- True Positive(TP): Positive 값인 1로 예측했는데, 실제로도 Positive 값인 1인 경우 = Positive 값을 제대로 예측한 경우
# 이 데이터에서는 양성종양인지, 악성종양인지 여부가 y(target=class)값에 존재함
# 0인 경우 malignant(악성종양), 1인 경우 benign(양성종양)
from sklearn.metrics import confusion_matrix
cf_mat = confusion_matrix(y_test, y_pred)
cf_mat
# value_counts의 경우에는 data frame 이나 series 데이터에서만 사용할 수 있음
pd.Series(y_test).value_counts()
- 위의 confusion matrix를 해석해보자.
- matrix는 행렬을 의미한다.
- 양성종양을 양성종양으로 파악한 데이터는 51개, 악성종양을 악성종양으로 예측한 것은 107개이다.
- 양성종양을 악성종양으로 예측한 것은 12개
- 악성종양을 양성종양으로 예측한 것은 1개
- 잘못 예측한 양성을 악성으로, 악성을 양성으로 중 더 위험한 경우는 무엇일까?
- FP를 1종오류, FN을 2종 오류라고 이야기함
- 1종 오류가 더 위험하기에 특히 제약, 의료분야에서는 1종 오류를 통제하려 노력함
3) Precision, Recall
- 위의 confusion matrix를 바탕으로 몇가지 비율을 보고자 한다.
- Precision은 정밀도로 Positive로 예측한 것 중 맞춘 것의 비율이라고 할 수 있다.
- Positive 예측 성능을 더욱 정밀하게 측정하기 위한 평가지표이며 양성 예측도라고도 한다.
- Precision = TP / (TP + FP)
- Recall은 재현율로 실제로 Positive인 것중 맞춘 것의 비율이라고 할 수 있다.
- 다른 말로 True Positive Rate(TPR), Sensitivity(민감도)
- Negative 값을 Positive라고 예측할 때 큰 문제가 생기는 분야에서 중요하게 다루는 지표이다.
- Precision과 분모의 값이 다르다.
- Recall = TP / (TP + FN)
- 두 지표가 모두 높을 수록 성능이 좋다고 해석할 수 있다. 근데 왜?
- 제대로 맞춘 것이 많을수록 Precision 값과 Recall값이 커지기 때문이다.
- 따라서 두 값이 클수록 모델의 성능이 좋다고 판단할 수 있는 것이다.
- 그러나 이 둘은 trade-off 관계를 가지고 있다.
- 한쪽이 커지면 한쪽은 작아지는 관계이다.
- 이런 이유로 두 지표의 값을 모두 키우는데 어려움이 많다.
- 모델이 예측하는 방식: binary classification 기준
- 어느 한쪽을 예측할 때 기준값을 두고 기준 이상으로 예측하였다면 P, 기준 이하로 예측하였다면 N으로 예측한다.
- predict_proba()라는 메소드를 이용해 예측한 각 값들이 어느정도의 확률로 예측되었는지 확인할 수 있다.
- 이때 기준값을 조절하여 precision과 recall을 조절할 수 있다.
from sklearn.metrics import precision_score, recall_score
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
print(precision, recall)
# 두 값이 모두 크게 나왔다는 것은 잘못 예측한 값이 충분히 작았기 때문에 가능한 것
# 굉장히 잘 예측하였음을 파악할 수 있음
4) F1 Score
- Precision과 Recall을 이용한 평가지표로 데이터의 클래스가 불균형할 때 평가지표로 사용하면 좋다.
- F1_score = 2 * ( Precision * Recall / Precision + Recall)
- Precision과 Recall의 값이 어느 한쪽으로 치우치지 않았을 때 큰 값을 보임
from sklearn.metrics import f1_score
f1 = f1_score(y_test, y_pred)
f1
5) ROC Curve, AUC
- ROC(Receiver Operation Characteristic) Curve
- 과거 통신장비 성능 평가를 위해 고안된 수치로 현재는 의학분야에서 많이 사용된다.
- X축은 False Positive Rate(FPR), Y축은 True Positive Rate(TPR, 재현율, 민감도)으로 잡혀있다.
- TPR에 대응하는 지표로 True Negative Rate(TNR, 특이성, Specifity)이 있다.
- 실제로 Negative인 것 중 Negative가 얼마나 정확히 예측되었는가를 보여준다.
- TNR = TN / (FP + TN)
- FPR의 변화에 따라 TPR이 어떻게 변하는지를 보여준다.
- AUC(Area Under Curve)
- ROC Curve의 밑 면적을 구한 것으로 1에 가까울수록 좋은 수치이다.
- AUC가 커지기 위해서는 FPR이 작은 상태에서 TPR이 얼마나 커질 수 있는지가 관건이다.
from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt
import numpy as np
def roc_curve_plot(y_test, pred_proba):
# 임계값(Thresholds)에 따른 FPR, TPR 값을 반환받음
fprs, tprs, thresholds = roc_curve(y_test, pred_proba)
# ROC Curve 그리기
plt.plot(fprs, tprs, label='ROC')
# 가운데 기준이 되는 직선을 그려줌: binary에서 최소한 50:50의 확률로 찍어서 맞출 수 있음
plt.plot([0, 1], [0, 1], 'k--', label='Random')
start, end = plt.xlim()
# x축의 scale을 0.1 단위로 설정
plt.xticks(np.round(np.arange(start, end, 0.1), 2))
# X, Y축의 범위 0~1로 설정
plt.xlim(0, 1)
plt.ylim(0, 1)
# 각 축에 이름을 붙여줌
plt.xlabel('FPR(1 - Sensitivity)')
plt.ylabel('TPR(Recall)')
plt.legend()
plt.show()
# 첫번째 열은 0으로 분류할 확률, 두번째 열은 1로 분류할 확률
pred_proba = lr.predict_proba(X_test)
pred_proba
# 두번째 열만 추출 만들어줌
# 1로 분류할 확률만 추출
pred_proba = lr.predict_proba(X_test)[:, 1]
roc_curve_plot(y_test, pred_proba)
# AUC 값도 확인해보자
from sklearn.metrics import roc_auc_score
roc_score = roc_auc_score(y_test, pred_proba)
roc_score
- ROC Curve의 밑 면적의 거의 대부분이 나온 것을 확인할 수 있게된다.
'개인활동 > 파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
Regression Evaluation (0) | 2023.08.03 |
---|---|
앙상블 분류 모델 (0) | 2023.05.01 |