Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
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
29 30
Archives
Today
Total
관리 메뉴

잡동사니 블로그

[Python] Class imbalance -> Class weight 본문

Python

[Python] Class imbalance -> Class weight

코딩부대찌개 2024. 2. 19. 01:43

Class imbalance?

 

주로 분류(classification)에서 다수의 데이터와 소수의 데이터 차이

예를 들어 위와같은 데이터로 모델을 만든다고 가정할 때 모델이 불균형한 클래스에 대해 편향되도록 학습됨.

모든 데이터를 0으로 학습하더라도 95%의 Accuracy를 가진 모델이 됨.

이를 해결하기 위해 Over Sampling, Under Sampling이 있지만, Class weight라는 방법도 있다.

 


\[ \text{LogLoss} = - \frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i) \right] \]

 

여기서 Class weight인 - \( w_{0} \)와 - \( w_{1} \)을 추가하게 된다면 수식은 다음과 같이 바뀐다.

 

\[ -\frac{1}{N} \sum_{i=1}^{N} \left[ w_{1} \cdot y_{i} \cdot \log(\hat{y}_{i}) + w_{0} \cdot (1 - y_{i}) \cdot \log(1 - \hat{y}_{i}) \right] \]

 

Class weight를 편하게 구하기위해 sklearn 라이브러리에서 제공 된다.

 

from sklearn.utils.class_weight import compute_class_weight
import numpy as np
num_samples_0 = 950
num_samples_1 = 50
labels = np.array([0] * num_samples_0 + [1] * num_samples_1)
class_weights = compute_class_weight(class_weight='balanced', classes=np.unique(labels), y=labels)
print("Class 0 weight:", class_weights[0])
print("Class 1 weight:", class_weights[1])
#Class 0 weight: 0.5263157894736842
#Class 1 weight: 10.0

 

Class 0 weight = 1000 / (2 * 950) ≈ 0.5263

Class 1 weight = 1000 / (2 * 50) = 10.0

 

이렇게 구해진 Class weight는 다음과 같이 적용하면 된다.

from catboost import CatBoostClassifier
model = CatBoostClassifier(class_weights=class_weights)

 

보통 자주 쓰이는 모델에 자체적으로 있거나 딕셔너리 등 들어가는 형태는 다르나 지원함.