머신 러닝 모델을 평가하는 것과 별개로 클래스 불균형은 모델이 훈련되는 동안 학습 알고리즘 자체에 영향을 미칩니다. 머신 러닝 알고리즘이 일반적으로 훈련하는 동안 처리한 샘플에서 계산한 보상 또는 비용 함수의 합을 최적화합니다. 결정 규칙은 다수 클래스 쪽으로 편향되기 쉽습니다.
다른 말로 하면 알고리즘이 훈련 과정에서 비용을 최소화하거나 보상을 최대화하기 위해 데이터셋에서 가장 빈도가 높은 클래스의 예측을 최적화하는 모델을 학습합니다.
모델을 훈련하는 동안 불균형한 클래스를 다루는 한 가지 방법은 소수 클래스에서 발생한 예측 오류에 큰 벌칙을 부여하는 것입니다. 사이킷런에서는 대부분의 분류기에 구현된 class_weight 매개변수를 class_weight='balanced'로 설정해서 이런 벌칙을 편리하게 조정할 수 있습니다.21
불균형한 클래스를 다루는 데 널리 사용하는 다른 전략은 소수 클래스의 샘플을 늘리거나 다수 클래스의 샘플을 줄이거나 인공적으로 훈련 샘플을 생성하는 것입니다. 아쉽지만 여러 도메인에 걸쳐 가장 잘 작동하는 보편적인 솔루션이나 기법은 없습니다. 실전에서는 주어진 문제에 여러 전략을 시도해서 결과를 평가하고 가장 적절한 기법을 선택하는 것이 좋습니다.
사이킷런 라이브러리는 데이터셋에서 중복을 허용한 샘플 추출 방식으로 소수 클래스의 샘플을 늘리는 데 사용할 수 있는 resample 함수를 제공합니다. 다음 코드는 불균형한 위스콘신 유방암 데이터셋에서 소수 클래스(여기서는 클래스 1)를 선택하여 클래스 레이블 0인 샘플 개수와 동일할 때까지 새로운 샘플을 반복적으로 추출합니다.
>>> from sklearn.utils import resample
>>> print('샘플링하기 전 클래스 1 의 샘플 개수:',
... X_imb[y_imb == 1].shape[0])
샘플링하기 전 클래스 1의 샘플 개수: 40
>>> X_upsampled, y_upsampled = resample(X_imb[y_imb == 1],
... y_imb[y_imb == 1],
... replace=True,
... n_samples=X_imb[y_imb == 0].shape[0],
... random_state=123)
>>> print('샘플링한 후 클래스 1의 샘플 개수:',
... X_upsampled.shape[0])
샘플링한 후 클래스 1의 샘플 개수: 357
21 역주 class_weight 매개변수에 클래스 레이블과 가중치 값을 쌍으로 갖는 딕셔너리를 직접 주입할 수도 있습니다. 'balanced'로 지정하면 클래스별 평균 샘플 개수(전체 샘플 개수/클래스 개수)를 각 레이블의 샘플 개수로 나누어 score 점수를 가중 평균합니다.