안 쓰던 블로그

평가(Evaluation)_2 본문

머신러닝/머신러닝

평가(Evaluation)_2

proqk 2021. 1. 24. 21:01
반응형

분류 성능 평가 지표

1. 정확도(Accuracy)

2. 오차행렬(Confusion Matrix)

3. 정밀도(Precision)

4. 재현율(Recall)

5. F1 스코어: 정밀도와 재현율가 얼마나 균형 잡혀 있는가?

6. ROC AUC: 이진분류에서 많이 활용하는 성적 지표

 

1~4: foxtrotin.tistory.com/403

5~6: 현재글

실습: foxtrotin.tistory.com/441


5. F1 스코어

정밀도와 재현율의 맹점

정밀도를 100%으로 만드는 법: 확실한 기준이 되는 경우만 Positive로 예측, 나머지는 모두 Negative로 예측한다(누가봐도 암인 너무 정확한 사람만 암이라고 진단)

좀 더 풀어서 말하면 정밀도=TP/(TP+FP)이다. 전체 환자 1000명 중 확실한 Positive징후를 가진 환자를 1명이라고 하면, 이 한 명만 Positive로 예측, 나머지는 Negative로 예측하면 FP는 0, TP는 1이 되니까 1/(1+0)=100%정밀도가 나옴

 

재현율을 100%으로 만드는 법: 모든 환자를 Positive로 예측한다(전체 환자를 암이라고 해 버림)

재현율=TP/(TP+FN)이다. 전체 환자 1000명을 다 Positive로 예측하면 실제 양성이 30명밖에 없다고 해도 TN이 수치에 포함되지 않고 FN은 아예 0이므로 30/(30+0)=100%재현율이 나옴

 

F1 Score

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

$$f1=\frac{2}{\frac{1}{recall}+\frac{1}{precision}}=2*\frac{precision*recall}{precision+recall}$$

 

예시) A예측모델: 정밀도 0.9, 재현율 0.1, B예측모델: 정밀도 0.5, 재현율 0.5 일 때

→ A예측모델 F1 스코어=0.18 , B예측모델 F1 스코어=0.5

 

사이킷런에서 F1스코어 측정을 위해 f1_score(실제값, 예측값)함수를 제공한다

from sklearn.metrics import f1_score 
f1 = f1_score(y_test , pred)
print('F1 스코어: {0:.4f}'.format(f1))

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('오차 행렬')
    print(confusion)
    # f1 score print 추가
    print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}, F1:{3:.4f}'.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)

전 글에서 했던 부분에 f1스코어를 추가한 코드다

 

6. ROC 곡선과 AUC

ROC곡선(Receiver Operation Characteristic Curve)과 이에 기반한 AUC 스코어->이진 분류의 예측 성능 측정에서 중요하게 사용되는 지표

ROC곡선: FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)이 어떻게 변하는지를 나타내는 곡선. FPR이 X축, TPR이 Y축이다

AUC값: ROC곡선 밑의 면적을 구한 것. 일반적으로 1에 가까울 수록 좋은 수치이다

TPR: True Positive Rate=재현율. 즉, TPR=TP/(FN+TP). 민감도라고도 불린다

FPR: 실제는 Nagetive인데 Positive또는 Negative로 예측한 것 중 Positive로 잘못 예측한 비율. FPR=FP/(FP+TN)

 

roc_curve(실제 클래스 값 array, Positive 컬럼의 예측 확률 값) : FPR, TPR, 임계값을 array로 반환

roc_auc_score(실제 클래스 값 array, Positive 컬럼의 예측 확률 값). AUC 면적을 구하는 사이킷런 API이다

from sklearn.metrics import roc_curve

# 레이블 값이 1일때의 예측 확률을 추출 
pred_proba_class1 = lr_clf.predict_proba(X_test)[:, 1] 

fprs , tprs , thresholds = roc_curve(y_test, pred_proba_class1)
# 반환된 임곗값 배열 로우가 47건이므로 샘플로 10건만 추출하되, 임곗값을 5 Step으로 추출. 
thr_index = np.arange(0, thresholds.shape[0], 5)
print('샘플 추출을 위한 임곗값 배열의 index 10개:', thr_index)
print('샘플용 10개의 임곗값: ', 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))

타이타닉 생존자 예측모델의 FPR, TPR, 임계값을 구한다

roc_curve()의 결과값을 보면 임계값이 1에서 가깝다가 점점 작아질 수록 FPR이 커진다

또한 FPR이 조금씩 커질 때 TPR은 가파르게 커진다

 

import matplotlib.pyplot as plt
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] )

ROC곡선을 그린다

일반적으로 ROC 곡선 자체는 FPR과 TPR의 변화 값을 보는데 이용하고, 분류의 성능지표로는 ROC면적에 기반한 AUC 값으로 결정한다

아래 코드로 AUC값을 구할 수 있다

 

from sklearn.metrics import roc_auc_score
 
### roc_auc_score(y_test, y_score)로 y_score는 predict_proba()로 호출된 예측 확률 ndarray중 Positive 열에 해당하는 ndarray 
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))

1에 가까울 수록 좋은 수치이며 대각선일 때가 0.5이다

반응형

'머신러닝 > 머신러닝' 카테고리의 다른 글

분류와 결정트리, 결정트리 시각화  (0) 2021.01.31
[평가] kaggle - Pima 인디언 당뇨병 예측  (0) 2021.01.25
평가(Evaluation)_1  (0) 2021.01.24
Linear Regression 선형 회귀  (0) 2021.01.21
RPN  (0) 2021.01.20
Comments