ML_guide/Evaluation
Evaluation
평가 지표
오차 행렬 (confusion matrix)
- 학습된 분류 모델이 예측을 수행할 때의 상태를 나타낸다.
- 정확도 = 예측결과와 실제 값이 동일한 건수 / 전체 데이터 수 = (TN + TP) / (TN + TP + FP + FN)
정밀도, 재현율 (precision, recall)
- 정밀도 = TP / (FP + TP)
- 재현율 = TP / (FN + TP)
- 즉, 정밀도는 예측을 positive로 한 대상 중에 예측과 실제 값이 일치하는 데이터의 비율이다.
- 반면 재현율은 실제 값이 positive인 대상 중에 예측과 실제 값이 positive로 일치한 데이터의 비율을 말한다.
-
두 지표 모두 높은 수치를 얻는 것이 바람직하다.
- 임계값에 따라 두 지표를 조정할 수 있다.
def precision_recall_curve_plot(y_test, pred_proba_c1):
precisions, recalls, thresholds = precision_recall_curve(y_test, pred_proba_c1)
plt.figure(figsize =(8,6))
threshold_boundary = thresholds.shape[0]
plt.plot(thresholds, precisions[0:threshold_boundary], ls = '--', label='precision')
plt.plot(thresholds, recalls[0:threshold_boundary],label='recall')
start, end = plt.xlim()
plt.xticks(np.round(np.arange(start,end,0.1),2))
plt.xlabel('Threshold value')
plt.ylabel('Precision and Recall value')
plt.legend()
plt.grid()
plt.show()
단 정밀도와 재현율은 예측기준을 각각의 지표에 유리하게 한다면, 두 수치 모두 적절한 지점을 찾기가 어려워 진다.
F1 스코어
- F1 = 2*(precision * recall) / (precision + recall)
- F1 스코어는 정밀도와 재현율을 결합한 지표이다.
- 두 지표가 치우치지 않을 때, 높은 값을 가지게 된다.
ROC 곡선, AUC
- FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)의 변화를 나타내는 곡선이다.
- 임계값을 1부터 0까지 변경하면 곡선을 나타낼 수 있다.
def roc_curve_plot(y_test, pred_proba_c1):
fprs, tprs, thresholds = roc_curve(y_test, pred_proba_c1)
plt.plot(fprs, tprs, label='ROC')
plt.plot([0,1],[0,1],'k--', label = 'Random')
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()
실제 데이터를 이용한 평가
Pima Indian Diabetes
- 데이터를 불러오고 feature의 타입과 null 개수를 살펴본다.
RangeIndex: 768 entries, 0 to 767 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Pregnancies 768 non-null int64 1 Glucose 768 non-null int64 2 BloodPressure 768 non-null int64 3 SkinThickness 768 non-null int64 4 Insulin 768 non-null int64 5 BMI 768 non-null float64 6 DiabetesPedigreeFunction 768 non-null float64 7 Age 768 non-null int64 8 Outcome 768 non-null int64
- null 값이 없고 모두 숫자형이므로 따로 인코딩이 필요 없어 보인다.
- 위에서 공부한 평가지표를 계산하는 함수를 이용하여 지표를 출력한다.
오차 행렬
[[88 12]
[23 31]]
정확도 0.7727, 정밀도 0.7209, 재현율 : 0.5741, F1 : 0.6392, AUC : 0.7919
- 재현율과 정밀도가 균형을 맞추는 지점에서 두 지표가 각각 0.7도 안되는 것을 볼 수 있다.
- 이는 데이터의 값을 다시 조정해야 할 필요가 있음을 말한다.
diabetes_data.describe()
- min값이 0이 되면 안되는 feature들이 보인다.
- 총 데이터의 개수가 적으므로 지우기보다는 평균값으로 이들을 대체한다.
mean_zero_features = diabetes_data[zero_features].mean()
diabetes_data[zero_features] = diabetes_data[zero_features].replace(0,mean_zero_features)
- 다시 학습을 시킨다. (로지스틱 회귀의 경우 숫자 데이터에 스케일링을 적용하는 것이 좋다.)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.2, random_state = 156, stratify=y)
lr_clf = LogisticRegression()
lr_clf.fit(X_train, y_train)
pred = lr_clf.predict(X_test)
pred_proba = lr_clf.predict_proba(X_test)[:,1]
get_clf_eval(y_test, pred, pred_proba)
get_clf_eval 함수는 5가지 지표들을 얻는 함수
임계값 : 0.3
오차 행렬
[[68 32]
[10 44]]
정확도 0.7273, 정밀도 0.5789, 재현율 : 0.8148, F1 : 0.6769, AUC : 0.8404
임계값 : 0.33
오차 행렬
[[71 29]
[11 43]]
정확도 0.7403, 정밀도 0.5972, 재현율 : 0.7963, F1 : 0.6825, AUC : 0.8404
임계값 : 0.36
오차 행렬
[[74 26]
[14 40]]
정확도 0.7403, 정밀도 0.6061, 재현율 : 0.7407, F1 : 0.6667, AUC : 0.8404
임계값 : 0.39
오차 행렬
[[77 23]
[14 40]]
정확도 0.7597, 정밀도 0.6349, 재현율 : 0.7407, F1 : 0.6838, AUC : 0.8404
임계값 : 0.42
오차 행렬
[[80 20]
[16 38]]
정확도 0.7662, 정밀도 0.6552, 재현율 : 0.7037, F1 : 0.6786, AUC : 0.8404
임계값 : 0.45
오차 행렬
[[81 19]
[17 37]]
정확도 0.7662, 정밀도 0.6607, 재현율 : 0.6852, F1 : 0.6727, AUC : 0.8404
임계값 : 0.48
오차 행렬
[[88 12]
[19 35]]
정확도 0.7987, 정밀도 0.7447, 재현율 : 0.6481, F1 : 0.6931, AUC : 0.8404
임계값 : 0.5
오차 행렬
[[89 11]
[20 34]]
정확도 0.7987, 정밀도 0.7556, 재현율 : 0.6296, F1 : 0.6869, AUC : 0.8404
- 가장 균형 있는 지표를 가진 임계값은 0.48로 보인다.
- 임계값을 0.48로 고정한 뒤에 에측을 실행한다.
binarizer = Binarizer(threshold=0.48)
pred_th_048 = binarizer.fit_transform(pred_proba[:,1].reshape(-1,1))
get_clf_eval(y_test, pred_th_048, pred_proba[:,1])
오차 행렬
[[88 12]
[19 35]]
정확도 0.7987, 정밀도 0.7447, 재현율 : 0.6481, F1 : 0.6931, AUC : 0.8404
- 데이터 조작을 통해서 조금 더 안정적인 정밀도와 재현율을 얻은 것을 확인할 수 있다.