일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 밑바닥부터 시작하는 딥러닝2
- 감성분석
- 구글 BERT의 정석
- 다층 퍼셉트론
- 코사인 유사도
- 텍스트 분류
- 기술통계학
- F분포
- 가설검정
- 머신러닝
- 파이썬 pandas
- 기초통계
- 모두의 딥러닝
- 최소자승법
- 군집화
- numpy
- 회귀분석
- Pandas
- word2vec
- 밑바닥부터 시작하는 딥러닝
- 결정계수
- 자연어 처리
- 히스토그램
- 오래간만에 글쓰네
- 은준아 화이팅
- student t분포
- 차원축소
- Django
- 텐서플로2와 머신러닝으로 시작하는 자연어처리
- rnn
- Today
- Total
데이터 한 그릇
머신러닝 분류 평가 보충 본문
정밀도 재현율 트레이드 오프
정밀도 / 재현율 트레이드 오프 (Trade-off)
- 업무에 따라 정밀도/재현율 중요도 다름
- 분류하려는 업무 특성사 정밀도 도는 재현율이 특별히 강조되어야 할 경우
- 분류의 결정 임계값(Threshold)을 조정해서
- 정밀도 도는 재현율의 수치를 높일 수 있음
- 그러나 정밀도와 재현율은 상호 보완적인 평가 지표이기 때문에
- 어느 한쪽을 강제로 높이면 다른 하나의 수치는 떨어지는데
- 이를 정밀도/재현율의 트레이드 오프라고 함
- 사이킷런에서는 분류 결정 임계값을 조절해서
- 정밀도와 재현율의 성능 수치를 상호 보완적으로 조정 가능
분류 결정 임계값
- Positive 예측값을 결정하는 확률의 기준
- 임계값을 낮출수록 True 값이 많아짐
사이킷런의 분류 알고리즘에서 결정 확률을 구하는 방식
- 예측 데이터가 특정 레이블(결정 클래스 값)에 속하는지를 계산하기 위해
- 먼저 개별 레이블 별로 결정 확률을 구하고
- 예측 확률이 큰 레이블 값으로 예측
- 예: 이진 분류 모델
- 특정 데이터가 0이 될 확률 : 10%
- 1이 될 확률 : 90%로 예측한 경우
- 최종 예측은 더 큰 확률을 가진 1로 예측
- 일반적으로 이진 분류에서는 이 임계값을 0.5(50%)로 정하고
- 기준값보다 확률이 크면 Positive
- 작으면 Negative로 결정
result = np.concatenate([pred_proba, pred.reshape(-1,1)],axis = 1)
임계값은 보통 0.5로 고정. target 데이터의 레이블 각각이 나올 확률을 구하고 그 확률이 0.5 이상이면 positive 로 예측, 낮으면negative 로 예측.
위 코드는 확률과 각 레이블에 대해서 예측한 결과
Binarizer 로 임계값 조정
from sklearn.preprocessing import Binarizer
X = [[1,-1,2],
[2,0,0],
[0,1.1,1.2]]
binarizer = Binarizer(threshold = 1.1)
print(binarizer.fit_transform(X))
threshold 를 1.1 로 지정하면, 1.1 이상이면 positive, 1.1 이하이면 negative 로 분류한다.
임계값 0.5
custom_threshold = 0.5
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_eva(y_test, custom_predict)
임계값 0.4
custom_threshold = 0.4
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_eva(y_test, custom_predict)
여기서 주의할게 pred_proba에서 1번째 열을 꺼내와서 그 열에서 threshold와 비교한다는 점이다.
내가 착각한 지점은 [사망확률, 생존확률] 이 존재하면, 임계값과 이 두 확률을 비교해서 더 높은 확률을 택하는 걸로 생각했다.
완전히 이상한 착각을한 셈이다.
생존칼럼이나 사망칼럼 중 하나를 택하여 뽑고 그것을 binarizer 에 넣어서 비교해야만 custom_pred 가 도출이 된다.
여러 개의 분류 결정 임계값을 변경하면서 binarizer를 이용하여 예측값 변환
thresholds= [0.4,0.45,0.5,0.55,0.60]
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('\n임계값 : ', custom_threshold)
get_clf_eva(y_test, custom_predict)
get_eval_by_threshold(y_test, pred_proba_1, thresholds)
임계값이 높아질수록 positive로 예측하는 횟수가 적어지기 때문에 tp 가 줄어든다.negative 를 많이 하기 때문에 fn 이 높아진다. 따라서 재현율은 낮아진다.
반면에 정밀도는 positive 로 예측한 횟수가 줄어들기 때문에 fp 의 개수가 줄어들어서 높아진다.
따라서 정밀도와 재현율은 서로 트레이드 오프 관계임을 알 수 있다.
임계값의 변화에 따른 정밀도-재현율 변환 곡선을 그래프로 표현
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
%matplotlib inline
def precision_recall_curve_plot(y_test, pred_proba_c1): #curve 함수는 확률이 필요하기 때문에
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], linestyle = '--', label = 'precision')
plt.plot(thresholds, recalls[0:threshold_boundary], label='recall')
plt.xlabel('Threshold Value')
plt.ylabel('Precision and Recall Value')
plt.legend(), plt.grid()
plt.show()
precision_recall_curve_plot(y_test, lr_clf.predict_proba(X_test)[:,1])
이와 같은 결과를 확인 가능하다.F1_SCORE
F1 Score
- 정밀도와 재현율을 결합한 지표
- 정밀도와 재현율이 어느 한쪽으로 치우치지 않는 수치를 나타낼때
- 높은 값을 가짐
- 예: 2개의 예측 모델 비교 A 예측 모델
- 정밀도 : 0.9
- 재현율 : 0.1 (극단적 차이)
- F1 스코어 : 0.18
- 정밀도 : 0.5
- 재현율 : 0.5 (큰 차이 없음)
- F1 스코어 : 0.5
ROC Curve와 AUC
**이진 분류** 모델을 평가할 때 사용한다.
ROC 곡선
- FPR이 변할 때 TPR 이 어떻게 변하는지를 나타내는 곡선
- 양성으로 잘못 판단한 것에 대한 진짜 양성의 비율을 나타내는 곡선 (정의)
ROC(Receiver Operation Characterisic Curve)
- 임계값을 1부터 0까지 변화시키면서 FPR(X축)을 구하고
- FPR(X축)의 변화에 따른 TPR(Y축)을 구하는 곡선
- 머신러닝의 이진 분류 모델의 예측 성능을 판단하는 평가 지표
TPR(True Positie Rate) : 재현율(민감도)
- 실제 Positive를 Positive로 예측한 비율
- 질병이 있는 사람을 질병이 있는 것으로 양성 판정
- 값이 클수록 좋음 (양성을 잘 예측)
FPR(False Positive Rate)
- 실제는 Negative인데 Positive로 잘못 예측한 비율
- 1 - 특이성
TNR(True Negative Rate) : 특이성 (Specificity)
- 실제 음성인데 음성으로 예측한 비율
- 질병이 없는 사람을 질병이 없는 것으로 음성 판정
- 값이 클수록 좋음 (음성을 잘 예측)
사이킷런의 roc_curve() APi 이용해서 타이타닉 생존자 예측 모델의 FPR, TPR, 임계값 구하기
정밀도와 재현율에서 학습한 LogisticRegression의 predic_proba() 결과 이용
roc_curve(실제 데이터, 예측 확률)
- FPR, TRP, thresholds 반환
from sklearn.metrics import roc_curve
# 레이블 값이 1일때의 예측 확률 추출
prd_proba_class1 = lr_clf.predict_proba(X_test)[:, 1]
fprs, tprs, thresholds = roc_curve(y_test, prd_proba_class1)
thr_index = np.arange(0, thresholds.shape[0], 5)
print('샘플 추출을 위한 임계값 배열의 index : ', thr_index)
print('샘플임계값 : ', np.round(thresholds[thr_index], 2))
# 5단계 단위로 추출된 임계값에 따른 FPR, TPR 값 출력
print('샘플 임계값 FPR : ', np.round(fprs[thr_index], 3))
print('샘플 임계값 TPR : ', np.round(tprs[thr_index], 3))
# 결과
# 임계값이 1에 가까운 값에서 점점 작아지면서 FPR이 점점 커짐
# FPR이 조금씩 커질 때 TPR은 가파르게 증가
값 확인
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.savefig('graph_roc_auc')
plt.show()
roc_curve_plot(y_test, lr_clf.predict_proba(X_test)[:, 1] )
# 그래프 설명
# 일반적으로 곡선 자체는 RPR과 TRP의 변화값을 보든데 이용하고
# 분류의 성능 지표로 사용되는 것은 ROC 곡선 면적에 기반한 AUC 값으로 결정
# AUC(Area Under Curve) 값은 ROC 곡선 밑의 면적을 구한 것으로
# 일반적으로 1에 가까울수록 좋음
# AUC 수치가 커지려면 FPR이 작은 상태에서 얼마나 큰 TPR을 얻을 수 있느냐가 관건
# 가운데 직선에서 멀어지고 왼족 상단 모서리 쪽으로 가파르게 곡선이 이동할 수록
# 직사각형에 가까운 곡선이 되어 면적이 1에 가까워지는
# 좋은 ROC AUC 성능 수치를 얻게 됨
# 가운데 직선은 랜덤 수준의 이진 분류 AUC 값으로 0.5
# 따라서 보통의 분류는 0.5이상의 AUC 값을 가짐
ROC_AUC 그래프 그리기
선 밑의 넓이가 1에 가까울수록 성능이 좋은 것
중간 선과 거리가 멀어야 좋은 성능의 모델
'머신러닝 > 분류' 카테고리의 다른 글
분류7)앙상블 학습, 부스팅 중 LightGBM (0) | 2021.04.15 |
---|---|
분류6)앙상블 학습, 부스팅 중 XGBoost(eXtra Gradient Boost) (0) | 2021.04.15 |
분류4)앙상블 학습 배깅, 랜덤 포레스트(Random Forest) (1) | 2021.04.14 |
분류5)앙상블 학습, 부스팅 중 GBM(Gradient Boosting Machine) (0) | 2021.04.07 |
분류3)앙상블 학습 개요와 보팅 유형 (0) | 2021.04.05 |