학습목표
머신러닝 모델의 성능을 평가할 때 사용되는 지표
#sklearn.metrics.plot_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='d'); #values_format=테이블 데이터 값 표시방법
plt.title(f'Confusion matrix, n = {len(y_val)}', fontsize=15)
plt.show()
#테이블 데이터만 가져오기
cm = pcm.confusion_matrix
cm[1][1]
가장 일반적인 모델 성능 평가 지표로 모델이 입력된 데이터에 대해 얼마나 정확하게 예측하는지를 나타낸다.
모델의 예측값이 얼마나 정확한가를 나타내는 지표로 Positive로 예측한 경우 중 올바르게 Positive를 맞춘 비율이다.
ex) 암을 진찰하는 기계, 넷플릭스 영화추천
모델의 실제값 중에서 모델이 검출한 실제값의 비율로 실제 Positive인 것 중 올바르게 Positive를 맞춘 것의 비율이다.
ex) 병원에서 초기 암진단을 하는 경우
정밀도와 재현율의 조화평균(harmonic mean)으로 정밀도와 재현율의 비율이 비슷하면 높은 값을 갖는 특징이 있다.F1 점수가 무조건 좋다고 좋은 분류기는 아니며 문제에 따라 정밀도와 재현율을 조절할 필요가 있다. 정밀도와 재현율의 트레이드오프가 이와 같은 경우이다.
베타 매개변수를 사용하여 문제에 따라 정밀도와 재현율 간의 균형에 가중치를 부여하는 방법을 결정하는 것
f1 = f1_score(y_test, y_test_preds)
f0_5 = fbeta_score(y_test, y_test_preds, beta=0.5)
f2 = fbeta_score(y_test, y_test_preds, beta=2)
예측을 Positive로 한 대상중에 예측값과 실제값이 Positive로 일치한 데이터의 비율로 Positive 예측 성능을 더욱 정밀하게 측정하기 위한 평가 지표로 양성 예측도라고도 불린다. 실제 Negative 음성인 데이터 예측을 Positive 양성으로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우에 중요 지표로 쓰인다.
실제값이 Positive인 대상중에 예측값과 실제값이 Positive로 일치한 데이터의 비율로 암 판단 모델이나 금융 사기 적발 모델과 같이 실제 Positive 양성 데이터를 Negative로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우에 중요 지표로 쓰인다.
재현율과 정밀도는 둘 다 TP를 높이는데 초점을 맞추고 있는 점이 같지만, 재현율은 FN을 낮추는 데, 정밀도는 FP를 낮추는 데 초점을 맞춘다는 점이 다르다. 이 특성때문에 재현율과 정밀도는 서로 보완적인 지표로 분류 모델의 성능을 평가하는데 적용되며, 둘 다 높은 수치를 얻는 것이 가장 좋은 성능을 의미한다. 반면 둘 중 어느 한 평가 지표만 매우 높고, 다른 하나는 매우 낮은 결과를 보이는 것은 바람직하지않다.
분류 모델이 사용될 업무의 특성을 고려하여 정밀도와 재현율 중 더 강조돼야 할 부분을 결정하기 위한 임계값(Threshold)를 조정해 정밀도나 재현율의 수치를 높일 수 있다. 하지만 정밀도와 재현율은 상호 보완적인 평가 지표이기 때문에 이 두 지표에는 트레이드오프(Trade-off)가 존재하며, 이를 정밀도/재현율의 트레이드오프라고 부른다.
사이킷런의 분류 알고리즘은 예측 데이터가 특정 label에 속하는지를 계산하기 위해 먼저 각각의 label별 결정 확률을 구한 후, 더 높은 확률의 label로 예측한다. 일반적으로 이진 분류에서는 결정 확률의 임계값이 0.5로 정해지고 확률이 크면 Positive, 낮으면 Negative로 결정한다. 사이킷런은 각각의 데이터 별 예측 확률을 반환하는 method로 predict_proba()를 제공한다. 학습이 완료된 Classifier 객체에서 호출이 가능하며 test feature dataset을 parameter로 입력하면 test faeture에 대한 개별 class
의 예측 확률을 반환한다.
사이킷런의 predict()는 predict_proba() method가 반환하는 확률값을 가진 ndarray에서 정해진 임계값(default=0.5)을 만족하는 column 위치를 최종 예측 class로 결정한다. 이러한 예측확률과 임계값을 잘 활용하면 필요한 범주의 정밀도나 재현율을 조정하여 보다 효율적으로 문제를 해결할 수 있다.
재현율 상승을 위해 Positive로 예측하는 임계값을 계속 낮추면(더 정확하게 진단하기 위해) 동시에 NP의 비율도 같이 높아짐(NP가 재현율의 부분집합이므로) =>그러므로 재현율 최대화 & 위양성률 최소화하는 적정한 임계값 찾아야함
pipe.classes_
pipe.predict(X_val)
#X_train으로 학습한 pipe가 X_val 데이터를 바탕으로 예측했을때 0과 1이 나올 확률을 각각 리스트업한 것
pipe.predict_proba(X_val)
# train을 학습한 알고리즘으로 val을 예측해보니 1이었다. 이때, 1일 확률이 0.54이다!
y_pred_proba = pipe.predict_proba(X_val)[:, 1]
y_pred_proba
#임계값 변화에 따른 정밀도, 재현율 변화 그래프
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));
# roc_curve:임계값에 따른 TPR, FPR 수치를 자동으로 계산
from sklearn.metrics import roc_curve
# roc_curve(타겟값, prob of 1) # 1=yes
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
optimal_idx = np.argmax(tpr - fpr) #최대값(재현율-위양성률)
optimal_threshold = thresholds[optimal_idx]
print('idx:', optimal_idx, ', threshold:', optimal_threshold)
from sklearn.metrics import roc_auc_score
auc_score = roc_auc_score(y_val, y_pred_proba)
auc_score #높을수록 좋음
분류문제에서 모델을 올바르게 평가하기 위해서는 정확도 외에도 정밀도, 재현율 을 잘 이해하고 사용해야 한다. 특히 각 범주를 예측하는 기준이 되는 임계값의 위치에 따라 정밀도나 재현율이 달라지기 때문에 문제의 상황에 따라 적절한 임계값을 선택할 필요성이 있습니다. 이진 분류문제에서는ROC curve와 AUC 점수를 잘 활용하면 좋은 결과를 만들수 있다.