일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 토스
- BERT
- 스타터스부트캠프
- 스타터스
- 서비스기획부트캠프
- 특성중요도
- 사이드프로젝트
- NLP
- sql정리
- NLU
- 유데미코리아
- 유데미큐레이션
- pytorch
- 서비스기획
- AWS builders
- 데이터도서
- 임베딩
- MatchSum
- 취업부트캠프 5기
- 부트캠프후기
- 유데미부트캠프
- SLASH22
- 그로스해킹
- 딥러닝
- SQL
- 추천시스템
- AARRR
- 알고리즘
- 취업부트캠프
- 그래프
- Today
- Total
다시 이음
트리 기반 모델 - 3 Evaluation Metrics for Classification 본문
Evaluation Metrics for Classification
안녕하세요.
오늘은 분류분석모델을 평가할 수 있는 평가지표에 대해서 알아보려고 합니다.
평가지표의 종류에 대해서 알아보기 전에
평가지표들의 기본이 되는 Confusion Matrix(오차행렬,혼동행렬)에 대해서 먼저 알아볼게요.
Confusion Matrix
- 혼동행렬,오차행렬 이라고도 부릅니다.
- Confusion Matrix는 Training 을 통한 Prediction 성능을 측정하기 위해 예측 value와 실제 value를 비교하기 위한 표를 말합니다.
- 이 행렬을 기초로 우리는 분류분석모델을 평가할 수 있는 여러가지 지표를 살펴볼 수 있습니다.
1) 구성
Actual Class - 실제값
Predicted Class - 예측값
True Positives(TP) : 실제로 True인 값을 가지면서 예측한 값도 True인 경우
True Negatives(TN) : 실제로 False인 값을 가지면서 예측한 값이 False인 경우
False Positives(FP) : 실제로 True인 값을 가지나, 예측한 값이 False로 잘못 예측한 경우 - Type I error
False Negatives(FN) : 실제로 False인 값을 가지나, 예측한 값이 True로 잘못 예측한 경우 - Type II error
Tip) 위의 해석이 어렵다면?
뒤의 Positive, Negative부터 먼저 해석합니다. Postive = 실제값이 True, Negative = 실제값이 False
그 후 앞의 True, False 부분을 해석합니다. True = Postive,Negative와 예측값이 같다. False = Postive,Negative와 예측값이 다르다.
이렇게 해석을 하게되면 덜 헷갈리겠죠?
2) Confusion Matrix를 기초로 하는 지표들
3) 파이썬에서는 어떻게 Confusion Matrix를 시각화할까?
## 랜덤포레스트 모델 만들기
from sklearn.pipeline import make_pipeline
from category_encoders import OrdinalEncoder
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 파이프라인을 만들어 봅시다.
pipe = make_pipeline(
OrdinalEncoder(),
SimpleImputer(),
RandomForestClassifier(n_estimators=100, random_state=2, n_jobs=-1)
)
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_val)
## confusion matrix 시각화
from sklearn.metrics import plot_confusion_matrix
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
pcm = plot_confusion_matrix(pipe, X_val, y_val,
cmap=plt.cm.Blues,
ax=ax, values_format = '.0f');
plt.title(f'Confusion matrix, n = {len(y_val)}', fontsize=15)
plt.show()
분류분석모델을 평가할 수 있는 평가지표
1) Accuracy ( 정확도 )
정확도란, 전체 범주를 모두 바르게 맞춘 경우를 전체 수로 나눈 값입니다.
공식 : (TP+TN) / (TP+TN+FP+FN)
정확도 역설(Accuracy Paradox)
예시 ) 100명의 사람이 악성 종양 검사를 받았다고 생각해볼게요.이 때 진짜 악성 종양을 가지고 있는 사람이 5명이라고 가정하겠습니다. Accuracy(정확도)는 전체 개수 중 양성을 양성이라 말하고, 음성을 음성이라고 말한 개수의 비율입니다.
우리가 만든 모델에 넣었을 때, 정확도가 90%가 나왔다고 가정해보겠습니다.
정확도 90%를 살펴보니 악성 종양을 가진 사람(TP)은 맞추지 못했고 악성 종양을 가지지 못한 사람(TN)을 90%까지 맞췄습니다.
이와 같이 실제 데이터에 Negative 비율이 너무 높아서 희박한 가능성으로 발생할 상황에 대해 제대로 된 분류를 해주는지 평가해줄 지표는 바로 recall(재현율)입니다.
2) Recall ( 재현율 )
재현율이란, 실제 Positive인 것 중 올바르게 Positive를 맞춘 것의 비율 입니다.
암진단과 같이 양성이지만 음성으로 잘못 판단(FN)하는 경우가 없어야 할 때 사용됩니다.
공식 : TP / (TP+FN)
예시 ) 전체 양성 수(TP+FN)에서 검출된 양성 수(TP)의 비율을 뜻합니다.
앞에서 사용했던 예제에서 진짜 악성 종양을 가지고 있는 5명이라고 가정했습니다.
그중에 2명만을 양성이라고 검출했을 경우 재현율은 40%의 확률입니다.
여기서 Precision과 Recall 둘다 높으면 가장 좋은 방법이겠지만 이 둘은 반비례하는 경향이 있습니다.
3) Precision ( 정밀도 )
정밀도란, Positive로 예측한 경우 중 올바르게 Positive를 맞춘 비율입니다.
스팸메일과 같이 중요한 메일이 스팸메일로 분류되지 않아야 하는 경우 사용합니다.
공식 : TP / (TP+FP)
예시 ) 양성이라고 판정한 환자 중에서 실제 양성인 수의 비율을 말한다. 환자 100명 중에 분석을 통해 2명만 악성 종양을 가지고 있다고 예측하고 그 결과 2명이 양성 환자가 맞다면 Precision은 100%가 나오게 된다. 이것 또한 이상적인 모델이 아니다. 양성 환자를 몇 명 놓쳤지만 정밀도는 100% 이기 때문이다.
Recall(재현율)과 Precision(정밀도)가 모두 높은게 좋지만 둘은 반비례 관계이다. 이것을 보완하기 위해 F-beta score 가 있습니다.
4) F-beta score
Precision과 Recall의 조화평균입니다. F beta socre가 높아야 성능이 좋습니다.
흔히 말하는 평균(산술평균)을 쓰지 않고 조화평균을 구하는 이유는 recall, precision 둘 중 하나가 0에 가깝게 낮을 때 지표에 그것이 잘 반영되도록, 다시말해 두 지표를 모두 균형있게 반영하여 모델의 성능이 좋지 않다는 것을 잘 확인하기 위함입니다.
공식 :
궁금증 타임) 조화평균이라지만 재현율과 정밀도 중에 누가 더 중요하다고 설정 못하나요?
쌉가능입니다.
False Negative를 최소화하는 것보다 False Positive을 최소화하는 데 더 관심 이 있는 경우 F-베타 점수에 대해 < 1 의 베타 값 을 선택하면 됩니다. 즉, 재현율보다 정밀도에 더 많은 가중치가 부여됩니다.
반면에 False Negative을 최소화하는 것이 우선 순위인 경우 F-베타 점수에 대해 >1 의 베타 값 을 선택하면 됩니다 . 이 때, 재현율이 정밀도보다 더 중요한 것으로 간주됩니다.
##F-beta score
from sklearn.metrics import fbeta_score
fbeta_score(y_true, y_pred, *, beta, labels=None,
pos_label=1, average='binary', sample_weight=None, zero_division='warn')
## 주의점으로는 기본적으로 positive에 대한 f스코어를 반환해줌으로 negative에 대한 점수는 1-f스코어를 해야 합니다.
## 정밀도, 재현율을 확인하기
from sklearn.metrics import classification_report
print(classification_report(y_val, y_pred))
임계값(thresholds), 예측확률
임계값을 설명하기 위해 우리는 어제 배운 랜덤포레스트에 대해서 상기할 필요가 있습니다.
랜덤포레스트란 기본모델을 여러개 병렬화하여 생성하여 그 모델들의 예측결과를 다수결이나 평균을 내어 예측(Bagging)하는 방법을 사용한다고 배웠죠?
그래서 RandomForestClassifier을 사용할 때, y_pred_proba(예측 확률) Attribute를 사용하면 예측값이 [0일 확률, 1일 확률]로 나누어서 표기가 가능합니다.
여기서 임계값이라는 개념이 등장을 합니다.
임계값은 기본으로 0.5라는 값을 가집니다.
즉, 다수결로 생긴 확률이 0.5보다 작으면 예측값이 0으로 되고, 0.5보다 크면 예측값이 1이 됩니다.
여기서 잘 구분하셔야 하는 것이 구하고자 하는 것(중점을 둘 부분)이 positive 인지 negative인지에 따라 임계값에 따른 정밀도와 재현율이 달라집니다.
Positive에 중점을 두면
이 임계값을 낮추면 예측값이 1이되는 경우가 많아져서(양성판정(TP)에 엄격, 음성판정의 수(FP)가 많아짐), 정밀도는 떨어지지만 재현율은 올라갈 것입니다.
반대로 임계값을 올리면 예측값이 0이 되는 경우가 많아져서(음성판정(FP)에 엄격, 양성판정의 수(TP)가 많아짐), 정밀도는 올라가지만 재현율은 떨어질 것입니다.
Negative에 중점을 두면
이 임계값을 낮추면 예측값이 1이되는 경우가 많아져서(양성판정(TP)에 엄격, 음성판정의 수(FP)가 많아짐), 정밀도는 올라가지만 재현율은 떨어질 것입니다.
반대로 임계값을 올리면 예측값이 0이 되는 경우가 많아져서(음성판정(FP)에 엄격, 양성판정의 수(TP)가 많아짐), 정밀도는 떨어지지만 재현율은 올라갈 것입니다.
임계값을 시각화해보자
# Randomforestclassifier 기본 임계값은 0.5입니다.
import seaborn as sns
threshold = 0.5
y_pred_proba = pipe.predict_proba(X_val)[:, 1]
y_pred = y_pred_proba > threshold
ax = sns.histplot(y_pred_proba)
ax.axvline(threshold, color='red')
pd.Series(y_pred).value_counts()
## 임계값을 조정하면서 그래프 변화와 평가지표 확인
from ipywidgets import interact, fixed
def explore_threshold(y_true, y_pred_proba, threshold=0.5):
y_pred = y_pred_proba >= threshold
vc = pd.Series(y_pred).value_counts()
ax = sns.histplot(y_pred_proba, kde=True)
ax.axvline(threshold, color='red')
ax.set_title(f'# of target, 1={vc[1]}, 0={vc[0]}')
plt.show()
print(classification_report(y_true, y_pred))
interact(explore_threshold,
y_true=fixed(y_val),
y_pred_proba=fixed(y_pred_proba),
threshold=(0, 1, 0.01));
실제 타겟 값과 예측확률을 데이터프레임으로 만들어 같이 확인하면
실제 타겟값으로 하나의 열, 예측확률(True일 확률)을 하나의 열로 데이터프레임을 만들겠습니다.
거기서 임계값인 0.5 이하인 확률. 즉, False의 값을 가져야할 값을 오름차순으로 정렬하면 예측으로는 0의 값을 가져야 하지만 1의 값을 가진 데이터가 있을 겁니다.
이러한 데이터를 활용하면 0의 값을 예측했지만 1의 값인 경우(FN)와 0의 값을 예측했고 0의값을 가진 경우(TN)을 파악할 수 있습니다.
예를 들어 한 마을에 백신을 투여를 해야하는 상황에서 마을 시민이 10000명일 경우 무료 백신이 4500명분 밖에 없고 총 시민중에 70%가 백신 투여를 해야 집단면역이 된다고 가정해봅시다.
10000명 중 7000명의 백신투여자가 있어야하는데, 이중 무료일 때만 백신을 투여받을 의사가 있는 사람(A)이 5000명, 유료여도 백신을 투여받고 싶은 사람(B)이 3000명, 2000명은 벌써 백신을 맞았다(C)고 가정을 해볼게요.
7000명(집단면역을 위한 투여 인원수) - 투여받은 인원(2000명=C) = 5000명이 추가로 백신을 맞아야하는데 무료인 4500명분의 백신을 무작위로 배포할 경우, B유형의 사람이 다 투여를 하게되면 A유형의 사람들은 유료로 백신을 맞을 생각이 없기에 집단면역이 불가능하게 됩니다.
그렇기에 우리는 접종 확률이 낮지만 맞은사람(FN)과 접종 확률이 낮아 맞을 생각이 없는사람(TN)을 확인하여 TN 유형의 사람들에게 우선적으로 무료 백신을 투여할 수 있습니다.
그럼으로 인해 우리는 좀더 효과적인 결과를 낼 수 있게 활용할 수 있습니다.
ROC, AUC (Receiver Operating Characteristic, Area Under the Curve)
위에서 보듯 분류문제에서 임계값을 잘 설정한다면 보다 효율적으로 문제를 해결할 수 있습니다.
모든 임계값을 한 눈에 보고 모델을 평가할 수 있는 방법이 있을까요?
그래서 필요한 것이 ROC curve 입니다.
ROC curve, AUC를 사용하면 분류문제에서 여러 임계값 설정에 대한 모델의 성능을 구할 수 있게 됩니다.
ROC curve는 여러 임계값에 대해 TPR(True Positive Rate, recall)과 FPR(False Positive Rate) 그래프를 보여줍니다.
- 재현율을 높이기 위해서는 Positive로 판단하는 임계값을 계속 낮추어 모두 Positive로 판단하게 만들면 됩니다. 하지만 이렇게 하면 동시에 Negative이지만 Positive로 판단하는 위양성률도 같이 높아집니다.
- 재현율은 최대화 하고 위양성률은 최소화 하는 임계값이 최적의 임계값입니다.
from sklearn.metrics import roc_curve
# roc_curve(타겟값, prob of 1)
fpr, tpr, thresholds = roc_curve(y_val, y_pred_proba)
roc = pd.DataFrame({
'FPR(Fall-out)': fpr,
'TPRate(Recall)': tpr,
'Threshold': thresholds
})
roc
# 그래프 시각화
plt.scatter(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('FPR(Fall-out)')
plt.ylabel('TPR(Recall)');
# 최적의 임계값 찾기
# threshold 최대값의 인덱스, np.argmax()
optimal_idx = np.argmax(tpr - fpr)
optimal_threshold = thresholds[optimal_idx]
print('idx:', optimal_idx, ', threshold:', optimal_threshold)
- AUC 는 ROC curve의 아래 면적을 말합니다.
from sklearn.metrics import roc_auc_score
auc_score = roc_auc_score(y_val, y_pred_proba)
auc_score
'AI 일별 공부 정리' 카테고리의 다른 글
EDA의 여러가지 방법 (0) | 2021.08.23 |
---|---|
트리 기반 모델 - 4 모델선택(Model Selection) (0) | 2021.08.21 |
트리 기반 모델 - 2 랜덤포레스트 (Random Forests) (0) | 2021.08.18 |
Feature Engineering - Pipe line(파이프라인) (0) | 2021.08.18 |
트리 기반 모델 - 1 결정 트리 (Decision Trees) (0) | 2021.08.18 |