본문 바로가기

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

3.2 평가(F1 스코어, ROC와 AUC)

728x90

지난 시간에 아주 재현율과 정밀도에 대해 깊이 다뤄봤습니다.

서로는 상호 보완관계로 하나만 강조할 수는 없죠

따라서 두 평가지표를 모두 고려한

F1 스코어와 ROC에 대해 다뤄보도록 하겠습니다.

이는 '파이썬 머신러닝 완벽가이드'를 정리한 내용입니다.


1.  F1 스코어

F1 스코어 : 정밀도와 재현율을 결합한 지표로, 정밀도와 재현율 어느 쪽으로 치우치지 않을 때 상대적으로 높은 값을 가진다.

 

 

F1 스코어 공식의 다음과 같습니다.

F1 스코어는 f1_score()라는 API를 통해 구현이 가능합니다. 앞선 타이타닉 예제에서 F1 스크어를 구해보도록 하겠습니다.

from sklearn.metrics import f1_score 

def get_clf_eval(y_test , pred):
    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 = f1_score(y_test,pred)
   
    print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}, F1:{3:.4f}\n'.format(accuracy, precision, recall, f1))

thresholds = [0.4 , 0.45 , 0.50 , 0.55 , 0.60]
pred_proba = lr_clf.predict_proba(X_test)
get_eval_by_threshold(y_test, pred_proba[:,1].reshape(-1,1), thresholds)

 

임곗값: 0.4
정확도: 0.8324, 정밀도: 0.7183, 재현율: 0.8361, F1:0.7727

임곗값: 0.45
정확도: 0.8492, 정밀도: 0.7656, 재현율: 0.8033, F1:0.7840

임곗값: 0.5
정확도: 0.8492, 정밀도: 0.7742, 재현율: 0.7869, F1:0.7805

임곗값: 0.55
정확도: 0.8659, 정밀도: 0.8364, 재현율: 0.7541, F1:0.7931

임곗값: 0.6
정확도: 0.8771, 정밀도: 0.8824, 재현율: 0.7377, F1:0.8036

2. ROC

ROC 곡선: FPR(False Positive Rate)가 변할 때 TPR(True Positive Rate)의 변화를 나타낸 그래프

 

TPR(True Positive Rate) : 재현율(=민감도), 실제값 positive가  정확히 예측돼야하는 수준

                                                      TP / (FN + TP)

TNR(True Negative Rate) : 특이성, 실제값 negative가 정확히 예측돼야하는 수준

                                                      TN / (FP + TN)

FPR(False Positive Rate) : FP / (FP + TN) = 1 - TNR( = 1 - 특이성)

 

타이타닉 생존자 예측 모델의 ROC곡선을 구해보고 이를 통해 ROC 곡선에 대해 살펴보도록 하겠습니다.

from sklearn.metrics import roc_curve

pred_proba_class1 = lr_clf.predict_proba(X_test)[:, 1]

fprs, tprs, thresholds = roc_curve(y_test, pred_proba_class1)

thr_index = np.arange(1, thresholds.shape[0], 5)
print('샘플 추출을 위한 임곗값 배열의 index 11개:', thr_index)
print('샘플용 11개의 임곗값: ', np.round(thresholds[thr_index], 2))

# 5 step 단위로 추출된 임계값에 따른 FPR, TPR 값
print('샘플 임곗값별 FPR: ', np.round(fprs[thr_index], 3))
print('샘플 임곗값별 TPR: ', np.round(tprs[thr_index], 3))
샘플 추출을 위한 임곗값 배열의 index 10개: [ 1  6 11 16 21 26 31 36 41 46 51]
샘플용 10개의 임곗값:  [0.97 0.65 0.63 0.56 0.45 0.4  0.35 0.15 0.13 0.11 0.11]
샘플 임곗값별 FPR:  [0.    0.017 0.034 0.076 0.127 0.169 0.203 0.466 0.585 0.686 0.797]
샘플 임곗값별 TPR:  [0.033 0.639 0.721 0.754 0.803 0.836 0.885 0.902 0.934 0.967 0.984]

 

위의 결과를 살펴보면 FPR이 증가할수록 TPR의 값이 커짐을 확인 할 수 있습니다. 

 

이를 그래프로 표현하면 아래와 같습니다.

def roc_curve_plot(y_test , pred_proba_c1):
    # 임곗값에 따른 FPR, TPR 값을 반환 받음. 
    fprs , tprs , thresholds = roc_curve(y_test ,pred_proba_c1)

    # ROC Curve를 plot 곡선으로 그림. 
    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 - Sensitivity )'); plt.ylabel('TPR( Recall )')
    plt.legend()
    plt.show()
    
roc_curve_plot(y_test, lr_clf.predict_proba(X_test)[:, 1] )

 

AUC : ROC 곡선 밑의 면적을 구한 것으로 1에 가까울 수록 좋은 수치이다. 즉, FPS가 작은 상태에서 얼마나 큰 TPR을 얻을 수 있냐가 중요하다.

 

타이타닉 생존자 데이터의 AUC를 구하면 아래와 같습니다.

from sklearn.metrics import roc_auc_score

pred_proba = lr_clf.predict_proba(X_test)[:, 1]
roc_score = roc_auc_score(y_test, pred_proba)
print('ROC AUC 값: {0:.4f}'.format(roc_score))

 

ROC AUC 값: 0.9024

지금까지 다양한 평가지표에 대해서 알아봤습니다. 

솔직히 이런 평가지표들이 어떻게 사용되는지 아직은 감이 잘 오지 않습니다.

다양한 데이터셋을 앞으로 보면서 해당 지표들이 어떻게 사용되는지 

더욱 살펴봐야할 것 같습니다.

그럼 다음 시간에는 피마 데이터셋을 가지고 지금까지 배운 내용을

실습해보도록 하겠습니다.

 

 

 

 

 

 

 

 

 

 

반응형