- 정확도가 제일 만만한 평가지표이긴 하나, 불균형한 레이블 클래스를 가지는 이진 분류 모델의 경우 e.x.(1000건이 Negative이고 1건이 Postive) Negative로 예측하는 경향이 더 강해진다.
따라서 이런 경우에 예측 정확도는 높지만 실제로는 틀린 예측일 수 있기에 정확도만으로는 모델의 신뢰도가 떨어질 수 있다.
- 따라서 정밀도(Precision), 재현율(Recall), F1-score, ROC 곡선과 AUC socre와 같이 여러가지 평가 지표들을 함께 고려하는 것이 좋다.
[정밀도와 재현율]
- 정밀도: 예측을 Positive로 하고, 실제 Postive인 데이터의 비율 (Positive를 잘 맞출수록 정밀도 높아짐)
- 재현율: 실제로 Positive인데 예측과 실제 값이 모두 Positive로 일치하는 데이터의 비율.
- 이 둘은 trade-off 관계로, 어느 한 쪽을 강제로 높이면 다른 하나의 수치는 떨어질 수 있다.
따라서, 분류의 "결정 임계값(threshold)"을 조정해가면서 정밀도, 재현율이 둘 다 좋은 순간을 잡아낼 수 있다.
- 일반적으로 이진 분류에서는 임계값을 0.5로 정하고, 예측 확률이 이보다 크면 Positive, 작으면 Negative로 결정한다.
그래서 우리가 지금 필요한 건 개별 데이터별로 예측 확률이 어떤지 보는거 --> sklearn의 predict_proba() 메서드를 사용!
<predict_proba()>
입력 파라미터: featrue 데이터셋
리턴: 각 샘플이 0일 확률, 1일 확률을 한 행(column)으로 하는 2차원 배열 (행의 개수는 샘플 수와 같겠지)
pred_proba = lr_clf.predict_proba(X_test) #pred_proba -- 0일 확률, 1일 확률이 리턴됨
pred = lr_clf.predict(X_test) #predict -- 0이냐, 1이냐가 리턴됨
print('pred_proba() 결과 Shape: {0}'.format(pred_proba.shape))
print('pred_proba 요소 3개만 추출해서 확인: \n', pred_proba[:3])
-> 샘플 개수(179)만큼의 행, 2개의 열을 갖는 2차원 배열이 리턴되었다.
- 사이킷런은 분류 결정 임계값(threshold)을 조절해서 정밀도와 재현율이 어떨 때 상호보완적으로 최적인지 조정할 수 있다. --> sklearn의 Binarizer 클래스를 사용!
<Binarizer>
객체 생성시 입력 파라미터: threshold 값
fit_transform() 메서드 - 입력 파라미터: 넘파이 ndarray (Positive 칼럼의 예측 확률 배열)
- 리턴: 지정된 threshold 보다 같거나 작으면 0으로, 크면 1값으로 변환해 반환함.
<여러 개의 threshold값을 변경하면서 Binarizer를 이용하여 예측값 변환해보기>
thresholds = [0.4, 0.45, 0.50, 0.55, 0.60]
#threshold 바꿔가며 transform 해주는 함수
def get_eval_by_threshold(y_test, pred_proba_c1, thresholds):
for custom_threshold in thresholds:
binarizer = Binarizer(threshold=custom_threshold).fit(pred_proba_c1)
custom_predict = binarizer.transform(pred_proba_c1)
print('임계값:', custom_predict)
get_clf_eval(y_test, custom_predict) #오차행렬, 정확도, 정밀도, 재현율 출력해줌(사용자정의)
get_eval_by_threshold(y_test, pred_proba[:, 1].reshape(-1,1), thresholds)
*헷갈릴 수 있는 것!
pred_proba[:, 1]이 뭔가?
-> 함수의 입력 파라미터로 pred_proba로 나온 배열을 넣어줘야 하는데, 우리 task에서 필요한 확률은 0일 확률과 1일 확률 중 1일 확률값이 필요하다. 따라서 [[0일 확률, 1일 확률], 에서 [:, 1] 부분이 필요한 것.
[0일 확률, 1일 확률],
.....
]]
나아가서, 이 1일 확률 부분을 y_test랑 비교할 수 있으려면 2차원 배열 형태여야 하므로 reshape 해주는 거다.