수리통계 분석 코딩 실습

cost-sensitivity machine learning 본문

공모전

cost-sensitivity machine learning

얼려먹는 요구르트 2024. 10. 28. 03:52
✔️ 불량 여부 예측에 사용되는 cost-sensitivity 모델을 알아보자!

 

[process]

[배경] - [사용 방법] - [학습 코드]

 

 

1. 배경

 

목적: 불균형 데이터 셋에 대한 학습 편향을 개선

 

불량 여부를 판별하는 모델의 경우 불량을 1로 분류하여 대다수의 데이터 셋이 0에 치중되어 있는 imbalanced model의 형태입니다.

이때, 하나의 클래스(0)이 과도하게 많을 경우 모두 0으로 예측하여도 예측 성능이 나쁘지 않기 때문에 불량 제품도 정상으로 판단하는 오류를 범하게 됩니다. 

 

다시 말해, confusion matrix에서 FN을 무시하고 학습을 진행하는 결과를 초래합니다. 이를 해결하기 위해선, 데이터셋의 크기를 고려해, FN의 위험도를 크게 주어 학습하도록 합니다. 

 

먼저, 불량 예측에서 사용되는 confusion matrix에 대해 알아보겠습니다. 

흔히 사용되는 confusion matrix의 경우 $C(i,i) =0$으로 두고 $C(i,j) =1$ for $ i \ineq j$로 [ [0,1],[1,0]]의 값을 부여합니다.

이때, c10 := FP (정상 제품인데 불량으로 판별한 경우), c01 := FN (불량 제품인데 정상으로 판별한 경우)를 동일한 가중치로 두는 것을 의미합니다. 앞서 설명드렸듯이 이런 학습 과정을 거치게 되면, FN의 경우를 무시하고 학습이 진행될 수 있으므로, c10에 imbalace rate를 주어 패널티를 부여합니다. 

 

 

다시말해, 아래와 같은 분류기를 활용해 학습을 진행할 수 있습니다. 

confusion matrix에 IR 부여

이때, IR(imbalance ratio)란, 

$$ IR = \frac{\vert \chi_1 }{\vert \chi_0}$$

where $\vert \dot \vert $ denotes the cardinality of a set.

 

를 의미합니다. $\chi_i$, i = 0,1은 각 클래스 별 비율을 의미합니다. 

다시 말해, IR은 #(1의 클래스비율)/ #(0의 클래스 비율) 로 정의되며, 예를 들어 불량: 정상 = 0.05 : 0.95의 데이터 수 비율이라면, 

IR은 0.05/0.95가 될 것입니다.

 

그럼, 정상을 불량으로 판별할 때보다 불량을 정상으로 판별할 때의 cost가 훨씬 큰 값이 되므로, 불량 데이터 수가 소수라고 할 지라도 이를 줄이는 방향으로 학습이 진행될 것입니다. 

 

➡️참고로, 데이터 수가 너무 적거나, 클래스별 유사도가 높거나 데이터에 노이즈가 있을 경우 단순히 각 클래스 비율의 비율로 정의하는 것이 아닌 IR의 값도 model selection의 hyperparemter로 두어 추정하기도 합니다. 

 

 

2. 사용 방법

 

그러므로 기존 클래스 분류기 모델에 confusion matrix에 weight를 부여해 학습을 시키면 될 것입니다. 

sklearn에 이미 있으므로,  weight에 대해 아래를 고려해 설정해주면 됩니다. 

weight 변수 값 설정

 

 

3. 실습

 

[1] 데이터 생성 

설명변수의 경우 2개 이중 클래스 분류 모델입니다.  -> 한계 x의 차원이 2이상이면 시각화 불가

X, y = sklearn.datasets.make_classification(n_samples=5000, n_features=2, n_informative=2,
                                            n_redundant=0, n_repeated=0, n_classes=2,
                                            n_clusters_per_class=1,
                                            weights=[0.95, 0.05],
                                            class_sep=0.5, random_state=0)

dataset_df = pd.DataFrame({'X1':X[:,0],'X2':X[:,1], 'Y':y})

 

X,y 관계 시각화

 

[2] 학습

IR을 설정해 이를 기준으로 class weight를 지정하고 학습합니다. 

이때 IR이 없는 baseline도 함께 그려 비교해보도록 하겠습니다. 

IR=0.05/0.95
class_weight={0:IR,1:1}

classifier = sklearn.tree.DecisionTreeClassifier(max_depth=5,class_weight = class_weight, random_state=0)


(results_df_dt_baseline, classifier_0, train_df, test_df) = kfold_cv_with_classifier(classifier, 
                                                                                     X, y, 
                                                                                     n_splits=5,
                                                                                     strategy_name="Decision tree - Baseline")

fig_decision_boundary = plot_decision_boundary(classifier_0, train_df, test_df)

 

 

 

왼: 바닐라 모델 , 오:IR 부과

 

해석:
1. 중간 - 분류 경계
2. 왼쪽 분류 경계 + 훈련 데이터 분류
3. 오른쪽: 분류 경계 + 테스트 데이터 분류

색깔: 디시전 트리의 경우 소수의 클래스를 다수의 클래스로 분류하는 경향이 있음 이를 시각화 하고자, 노란색은 결정이 불분명함을 의미함.

즉, 색깔은 특정 샘플을 어느 정도 확신을 가지고 분류하는 지를 나타냄.
빨간색 파란색이 많이 겹쳐있는 부근에서 노란색으로 색칠되어 있는 것은 이 경계에서의 디시전 트리의 분류가 불확실하게 분류했음을 의미함.

 

  

 

 

 

[3] 학습 결과

 

pd.concat([results_df_dt_baseline, 
           results_df_dt_cost_sensitive])

 

 

결과 해석: 위의 defalut 값보다 결정경계가 확실하게 구분지어져서 "불량"값을 측정함을 알 수 있었고,
balanced accuracy의 경우 0.789 -> 0.898로 상당히 향상됨을 알 수 있다.
그러나, AUC, ROC와 Average Precision의 경우 값이 낮아져 이에 대한 보강이 필요해 보인다.

 

 

fig_decision_boundary

 

 

 

➡️ Decision treer가 아닌 다른 모델을 사용하고 싶으면 sklearn.tree의 모델을 선택하면 됨. 

 

 

 

* 로지스틱 회귀

아래 모형이 조금더 두껍게 불량에 대해 잘 판단하는 것을 알 수 있습니다.

 

 

 

 

최종 모델별 비교

 

클래스별 정확도

로지스틱 with IR > DT with IR > 로지스틱 > DT

AUC ROC 까지 고려 -> 로지스틱 with IR이 베스트 모형임을 알 수 있습니다.