Day to_day

[지도 학습 분류] 분류 예측의 불확실성 추정 개념 잡고 가기! 본문

Machine Learning/지도 학습

[지도 학습 분류] 분류 예측의 불확실성 추정 개념 잡고 가기!

m_inglet 2023. 2. 12. 01:15
728x90
반응형

❗본 포스팅은 권철민 선생님의 '파이썬 머신러닝 완벽가이드' 강의와 '파이썬 라이브러리를 활용한 머신러닝' 서적을 기반으로 개인적인 정리 목적 하에 재구성하여 작성된 글입니다. 

 

포스팅 개요

모델의 성능 평가 지표를 공부하다가 계속해서 분류 예측의 불확실성에 대한 개념이 필요해서 이참에 한번 정리하고 진행하기로 했다. 

이번 포스팅에선 이진 분류의 불확실성 추정에 대해서, 그리고 불확실성을 추정할 수 있는 함수인 decision_functionpredict_proba에 대해서 간략하게 정리하고 넘어가겠다.

 

 

불확실성 추정

불확실성을 추정한다는 것은 예측한 클래스가 무엇인지 뿐만 아니라 정확한 클래스임을 얼마나 확신하는지를 나타내는 것으로써 확률로 나타낼 수 있다. scikit-learn에서 지원하는 불확실성을 추정할 수 있는 함수는 decision_function과 predict_proba가 있다.

 

 

결정 함수 - decision_function

decision_function은 데이터가 양성인 클래스 1에 속한다고 믿는 정도(확률)를 반환한다.

이진 분류에서 decision_function은 (sample 수, ) 크기로 확률을 반환한다.

기준: 0 (0 이상이면 양성, 0 이하면 음성으로 판별)

 

[코드]

print("X_test.shape", X_test.shape)
print("결정함수 결과 형태:", gbrt.decision_function(X_test).shape)
# gbrt는 GradientBoostingClassifier 모델
print("결정함수: ", gbrt.decision_function(X_test))

[출력 결과]

X_test.shape (25, 2)
결정함수 결과 형태: (25,)
결정함수:  [ 4.13592603 -1.67785652 -3.95106099 -3.62604651  4.28986642  3.66166081
 -7.69097179  4.11001686  1.10753937  3.40782222 -6.46260856  4.28986642
  3.90156346 -1.20031247  3.66166081 -4.17231157 -1.23010079 -3.91576223
  4.03602783  4.11001686  4.11001686  0.65709014  2.69826265 -2.65673274
 -1.86776596]

출력 결과를 보면 sample 수에 맞게 각 데이터의 확률이 1차원으로 반환된다. 

양수는 양성으로, 음수는 음성으로 판별된다.

 

 

예측 확률 - predict_proba

이진 분류에서 predict_proba의 크기는 (sample 수, 2)이다.

하나의 데이터에 대해 음성일 확률, 양성일 확률이 구해지고 그 둘의 합은 1이다.

각 열에 데이터에 대한 음성일 확률, 양성일 확률이 들어있다.

기준 : 0.5 (0.5 이상은 양성, 0.5 이하는 음성)

 

[코드]

print("확률 값의 형태: ", gbrt.predict_proba(X_test).shape)
print("예측 확률 : \n", gbrt.predict_proba(X_test[:6]))

 

[출력 결과]

확률 값의 형태:  (25, 2)
예측 확률 : 
 [[0.01573626 0.98426374]
 [0.84262049 0.15737951]
 [0.98112869 0.01887131]
 [0.97406909 0.02593091]
 [0.01352142 0.98647858]
 [0.02504637 0.97495363]]

출력 결과를 보면 decision_function과 다르게 2차원의 배열로 이루어져있다.

 

한 가지 더 주목해서 볼 점은 출력 값을 보면 분류기가 얼마나 강하게 확신하는 가를 볼 수 있다.

 

예를 들어 [0.9, 0.1]로 확신하는 것이 [0.45, 0.55]로 확신하는 것보다 강하게 확신한다고 할 수 있다.

이것은 과대 적합된 모델은 혹 잘못된 예측이라 하더라도 예측의 확신이 강한 편이다. (DecisionTree에서 강한 확신이 잘 나오는 이유도 과대 적합 될 확률이 높은 모델이기 때문)

반면 모델의 복잡도가 낮은 모델은 예측에 불확실성이 더 많다.

이런 불확실성과 모델의 정확도가 동등하다면 이 모델이 보정(calibration)되었다고 한다. 즉 보정된 모델에서 70%의 확신을 가진 예측은 70%의 정확도를 낼 것이다.

 

 

결정 함수와 예측 확률의 활용

결정 함수(decision_function)와 예측 확률(predict_proba)은 같은 기능을 하고 모델에 따라 둘 중 하나만 지원을 하는 경우도 있다. (자세한 건 찾아봐야겠다.)

그러면 불확실성을 추정하는 이 함수들을 어디에 활용할 것인가.

먼저 결정 임계점을 바꾸고자 할 때 활용이 가능하다.

 

예제로 보자면, scikit-learn에서 제공하는 Binarizer를 이용하여 결정 임계값을 바꿀 수 있다. 

Binarizer은 설정한 임계값을 기준으로 기준보다 같거나 작으면 0을 크면 1을 반환하는 모듈이다.

 

 

[예제 코드]

# Binarizer 사용하기
from sklearn.preprocessing import Binarizer

X = [[1,-1,2],
    [2,0,0],
    [0,1.1,1.2]]

# threshold 기준값(1.1로 설정함) 보다 같거나 작으면 0을, 크면 1을 반환
binarizer = Binarizer(threshold=1.1)
print(binarizer.fit_transform(X))

[출력 결과]

[[0. 0. 1.]
 [1. 0. 0.]
 [0. 0. 1.]]

 

 

[예제 코드 2]

아래의 예제 코드는 결정 임계값을 0.5에서 0.4로 변환하는 코드이다.

from sklearn.preprocessing import Binarizer

custom_threshold = 0.4
# lr_clf는 LogisticRegression 모델
pred_proba = lr_clf.predict_proba(X_test)

# predict_proba( ) 반환값의 두번째 칼럼, 즉 양성 클래스 칼럼 하나만 추출하여 Binarizer를 적용
# Binarizer에 넣어주기 위해서 2차원으로 만들어야함
pred_proba_1 = pred_proba[:, 1].reshape(-1,1)

binarizer = Binarizer(threshold=custom_threshold).fit(pred_proba_1)
custom_predict = binarizer.transform(pred_proba_1)

get_clf_eval(y_test, custom_predict)

predict_proba(X_test)로 X_test에 대해서 불확실성 추정했다. 

이때 predict_proba는 2차원 배열로 반환되니 양성 확률 칼럼만 가져오기 위해서 슬라이싱([ : , 1])을 진행한다. 

그리고 Binarizer에 넣기 위해 reshape 하여 적용하면 결정 임계값을 조절할 수 있다.

 

 

[출력 결과 2]

(왼) custom_threshold = 0.5, (오) custom_threshold = 0.4

결정 임계값을 0.4로 낮추니 양성이 나올 확률이 높아진 셈이다.

그래서 정밀도(TP / (FP + TP))는 떨어졌지만 재현율(TP / (FN + TP))은 상승한 것을 볼 수있다.

 

그 외에도 평가 지표(precision_recall_curve, average_precision_score, roc_curve, roc_auc_score)를 구할 때 인자로도 많이 사용된다. 

728x90
반응형