파이썬 머신러닝 완벽 가이드

ROC 곡선과 AUC 스코어
ROC 곡선
TPR 곡선
FPR,TNR은 다음과 같이 구할 수 있다.
FPR = FP / (FP + TN) = 1 -TNR = 1 - 특이성
TNR = TN/ ( FP + TN )
임곗값을 1부터 0까지 변화 시키면서 FPR을 구하고 이 FPR 값의 변화에 따른 TPR을 구하는 것이 ROC 곡선이다.
사이킷런은 ROC 곡선을 구하기 위해 roc_curve() API를 제공한다.
입력 파라미터:
반환 값:
from sklearn.metrics import roc_curve
#레이블 값이 1일때의 예측 확률을 추출
pred_proba_class1 = Ir_clf.predict_proba(X_test)[:,1]
fprs, tprs, thresholds = roc_curve(y_test, pred_proba_class1)
#반환된 임곗값 배열에서 샘플로 데이터를 추출하되, 임곗값을 5 step으로 추출
#thresholds[0]은 max(예측확률)+1로 임의 설정됨. 이를 제외하기 위해 np.arange는 1부터 시작
thr_index = np.arange(1, thresholds.shape[0],5)
print('샘플 추출을 위한 임곗값 배열의 index:', thr_index)
print('샘플 index로 추출한 임곗값:', np.round(thresholds[thr_index],2))
# 5step 단위로 추출된 임계값에 따른 TPR, FPR 값
print('샘플 임곗값별 FPR:', np.round(fprs[thr_index], 3))
print('샘플 임곗값별 TPR:', np.round(tprs[thr_index], 3))
[output]
샘플 추출을 위한 임곗값 배열의 index: [ 1 6 11 16 21 26 31 36 41 46]
샘플 index로 추출한 임곗값: [0.94 0.73 0.62 0.52 0.44 0.28 0.15 0.14 0.13 0.12]
샘플 임곗값별 FPR: [0. 0.008 0.025 0.076 0.127 0.254 0.576 0.61 0.746 0.847]
샘플 임곗값별 TPR: [0.016 0.492 0.705 0.738 0.803 0.885 0.902 0.951 0.967 1. ]
임곗값이 1에 가까운 값에서 점점 작아지면서 FPR이 점점 커지고 TPR은 가파르게 커짐을 알 수 있다.
이를 ROC 곡선으로 시각화 해보자
def roc_curve_plot(y_test, pred_proba_c1):
#임곗값에 따른 FPR, TPR값을 반환받음.
fprs, tprs, thresholds = roc_curve(y_test, pred_proba_c1)
#ROC 곡선을 그래프 곡선으로 그림
plt.plot(fprs, tprs, label='ROC')
#가운데 대각선 직선을 그림
plt.plot([0,1], [0,1], 'k--', label='Random')
#FPR X축의 Scale을 0.1 단위로 변경, X,Y축 명 설정 등
start, end = plt.xlim()
plt.xticks(np.round(np.arange(start,end,0.1),2))
plt.xlim(0,1);plt.ylim(0,1)
plt.xlabel('FPR(1-Specificity)');plt.ylabel('TPR(Recall)')
plt.legend()
roc_curve_plot(y_test, pred_proba[:,1])

ROC 곡선 자체는 FPR, TPR 의 변화를 보는데 이용하며 분류의 성능 지표로 사용되는 것은 ROC 곡선 면적에 기반한 AUC값이다.
이는 일반적으로 1에 가까울수록 좋은 수치
AUC 수치가 커지려면 FPR이 작은 상태에서 얼마나 큰 TPR을 얻을 수 있느냐가 관건이다.
from sklearn.metrics import roc_auc_score
pred_proba = Ir_clf.predict_proba(X_test)[:,1]
roc_score = roc_auc_score(y_test, pred_proba)
print('ROC AUC 값:{0:.4f}'.format(roc_score))
[output]
ROC AUC 값:0.8987
def get_clf_eval(y_test, pred=None, pred_proba=None):
confusion = confusion_matrix(y_test, pred)
accuracy = accuracy_score(y_test, pred)
precision = precision_score(y_test, pred)
recall = recall_score(y_test, pred)
f1 = f1_score(y_test, pred)
#ROC AUC 추가
roc_auc = roc_auc_score(y_test, pred_proba)
print('오차 행렬')
print(confusion)
#ROC-AUC print 추가
print('정확도:{0:.4f}, 정밀도:{1:.4f}, 재현율:{2:.4f}.\F1:{3:.4f}, AUC:[4:.4f]'.format(accuracy, precision, recall, f1, roc_auc))