dew's CSE Studying

Ch03 평가 본문

Machine Learning/파이썬 머신러닝 완벽 가이드

Ch03 평가

dew₍ᐢ.ˬ.⑅ᐢ₎ 2025. 1. 9. 16:03

회귀의 평가는 대부분 실제값과 예측값의 오차평균값에 기반한다. 분류의 평가는 정확도만으로는 판단할 수 없다.

분류의 성능 평가 지표(이진/다중 모두 가능)

  • 정확도(Accuracy)
  • 오차 행렬(Confusion Matrix)
  • 정밀도(Precision)
  • 재현율(Recall)
  • F1 score
  • ROC AUC

 

01 정확도(Accuracy)

정확도: 실제 데이터에서 예측 데이터가 얼마나 같은지를 판단하는 지표

정확도(Accuracy)=예측 결과가 동일한 데이터 건수 / 전체 예측 데이터 건수

 

 

binary classification에서는 정확도 지표가 어떻게 ML 모델의 성능을 왜곡할까?

이렇게 단순한 코드로도 수치가 나올 수 있기 때문에 적합한 평가지표가 필요하다.

 

정확도 평가 지표의 맹점: 무조건 특정한 결과로 찍어도 데이터 분포도가 균일하지 않은 경우 높은 수치가 나타날 수 있다

모든 것을 0으로 예측했는데도 정확도가 90%라고 뜬다.

 

02 오차 행렬(confusion matrix)

ndarray 형태의 오차행렬 출력

 

03 정밀도와 재현율

정밀도와 재현율은 positive 데이터 셋의 예측 성능에 좀 더 초점을 맞춘 평가지표!

정밀도 = TP / (FP+TP)

재현율 = TP / (FN+TP)

 

정밀도는 진짜 P / P라고 예측한 모든 데이터 건수. 양성 예측도라고도 한다. FP을 낮추는 데 초점.

재현율은 P라고 잘 예측한 것 / 실제로 P였던 모든 데이터 건수. 민감도(Sensitivity) 또는 TPR(True Positive Rate)라고도 불린다. FN를 낮추는 데 초점.

그럼 둘은 어떨 때 쓰일까? 

 

재현율: 실제 Positive 양성 데이터를 Negative로 잘못 판단하면 업무상 큰 영향이 발생하는 경우(ex.암 판단 모델, 금융 사기 적발 모델)
정밀도: 실제 Negative인 음성 데이터 예측을 Positive 양성으로 잘못 판단하게 되면 업무상 큰 영향이 발생하는 경우(ex.스팸 메일 여부 판단 모델)

둘다 높은 수치를 얻는 게 바람직하다. 

 

이렇게 get_clf_eval 함수를 작성해주었다

이제 로지스틱 회귀 기반으로 타이타닉 생존자를 예측하고 평가를 수행해보자.

 

 

정밀도/재현율 트레이드 오프

정밀도/재현율이 특별히 강조돼야 할 경우 분류의 결정 임곗값(Threshold)를 조정할 수 있다. 근데 둘중 하나를 강제로 높이기 보다 상호 보완적인 평가지표임을 유지하는 것이 좋다. 이걸 정밀도/재현율의 Trade-off 라고 한다.

 

사이킷런에서의 predict_proba()

특정 레이블에 속할 확률이 임곗값 이상이 되면 positive로 분류한다.(보통 0.5 사용)

predict_proba(): 개별 데이터별로 에측 확률을 반환
  • 학습이 완료된 사이킷런 Classifier 객체에서 호출 가능
  • 테스트 피처 데이터셋을 파라미터로 입력해주면 테스트피처 레코드의 개별 클래스 예측 확률을 반환한다
  • precit()와 유사하지만 반환 결과가 예측 결과 클래스값이 아니라 예측확률결과이다
입력 파라미터 predict() 메서드와 동일하게 보통 테스트 피처 데이터셋을 입력
반환값 개별 클래스의 예측 확률을 ndarray mxn(m:입력값의 레코드 수, n:클래스 값 유형) 형태로 반환

Binarizer클래스를 이용하여 threshold보다 작거나 같으면 0을, 크면 1을 반환하도록 구현해보았다.

 

predict()의 기능을 하도록 구현

 

threshold를 낮췄더니 정밀도가 내려가고 재현율이 높아졌다. positive예측이 더 너그러워져서 FP가 올라가고 FN이 내려갔기 때문이다.

 

이번엔 threshold를 0.4에서 0.6까지 0.05씩 증가시켜보자.

 

precision_recall_curve()

입력 파라미터 y_true: 실제 클래스값 배열(배열크기=[데이터 건수])
probas_pred: positive: 컬럼의 예측 확율 배열(배열크기=[데이터 건수])
반환 값 정밀도:입곗값별 정밀도 값을 배열로 반환
재현율:입곗값별 재현율 값을 배열로 반환

임곗값이 증가할수록 정밀도는 높아지고 재현율은 낮아진다.

이번엔 정밀도와 재현율 곡선을 시가화해보자

 

0.45정도가 적당!

 

정밀도와 재현율의 맹점

정밀도가 100%가 되는 방법

:확실한 기준이 되는 경우만 positive로 예측하고 나머지는 모두 negative로 예측

 

재현율이 100%가 되는 방법

:모든 환자를 positive로 예측

 

04 F1 스코어

-정밀도와 재현율을 결합한 지표

-정밀도와 재현율이 어느 한쪽으로 치우치지 않은 수치에서 높은 값을 가짐

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

 

이번엔 타이타닉 생존자 예측에서 임곗값을 변화시키면서 F1 스코어를 포함한 평가 지표를 구해보자.

임곗값=0.6일 때 F1 score이 가장 좋지만 재현율이 떨어지는 점 유의~

 

05 ROC 곡선과 AUC

ROC 곡선(Receiver Operation Characteristic Curve): 수신자 판단 곡선

  • FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate, 재현율=민감도)이 어떻게 변하는지를 나타내는 곡선
  • TPR에 대응하는 지표는 TNR(True Negative Rate, 특이성specificity): 실제값 Negative가 정확히 예측되어야 하는 수준
  • FPR = FP/(FP+TN) = 1-TNR = 1-특이성

 

임곗값이 1에 가까운 값에서 점점 작아지면서 FPR이 점점 커진다.

이걸 시각화해보자

 

AUC(Area Under Curve): ROC 곡선 밑의 면적을 구한 것.

  • 1에 가까울 수록 좋은 수치
  • FPR이 작은 상태에서 얼마나 큰 TPR을 얻을 수 있느냐가 관건
  • 왼쪽 상단 모서리쪽에 가까울수록 좋음

get_clf_eval 수정

06 피마 인디언 당뇨병 예측

 

null값이 없고 모두 숫자형 데이터인 것을 확인했다(별도의 피처 인코딩 필요X)

임곗값을 0.42정도로 낮추면 좋을 것 같지만 여전히 두 지표의 값이 낮다, 데이터값을 다시 점검해보자,

min에 0값이 너무 많다.

0값이 5개 존재하는 것 확인

skinThickness와 Insulin의 0값을 평균값으로 대체하자

 

이제 이 데이터셋을 갖고 피처스케일링을 적용해 변환할 것이다.

성능수치가 일정 수준 개선된 걸 확인할 수 있다. 재현율 수치는 개선 필요!! 임곗값을 바꿔가며 변화를 출력해보자

 

임곗값이 0.48일 때가 좋겠다

07 정리

  • 정밀도와 재현율은 positive 데이터셋의 예측성능에 더 초점을 맞춘 평가지표
  • F1 score은 정밀도와 재현율을 결합한 평가지표