불균형 데이터 (imbalanced data)

Angie An·2023년 12월 6일
1

AI

목록 보기
2/4

불균형 데이터(Imbalanced Data)란?

  • 분류 문제에서, 각 클래스가 가지고 있는 데이터 양의 차이가 커서 분포가 불균형한 상태를 말한다.
    • 예를 들면, 최근에 진행하고 있는 국민건강영양조사 데이터셋을 가지고 우울증 위험군 여부를 예측하는 프로젝트에서 예측할 라벨 값으로 활용할 현재 우울증을 가지고 있는 사람이 전체 샘플에서 약 10%도 되지 않는다.
    • 즉, depressed == 0 or depressed == 1 로 구분한다면, 이 y값 클래스 (0, 1)의 분포가 크게 차이가 나는 것이다.
      depressedcountdist
      02001991%
      119589%

불균형 데이터의 문제점

  • 만약, 분포가 불균형한 상태 그대로 예측을 하게 된다면, 과적합(over-fitting) 문제가 발생할 수 있다. 모델은 분포도가 높은 클래스 (depressed == 0), 즉 가중치가 높은 클래스를 더 예측하려고 하기 때문에 Accuracy는 높아질 수 있지만, 분포가 작은 클래스(depressed == 1)에 대한 Precision이 낮고 재현율 또한 낮아지는 문제가 발생할 수 있다.
    • train set에서만 성능이 좋고, test set에서는 성능이 떨어질 수 있음. → 모델의 일반화에 악영향을 줌
    • 만약, 불균형 데이터를 그대로 사용한다면, 모델의 평가지표를 신중하게 선택해야 함. (Confusion Matrix, ROC Curve 등을 고려)

불균형 데이터의 처리 방법 - Resampling

  • 딥러닝 모델을 사용하는 경우에는, 주로 Over-sampling을 많이 활용한다고 함.
    • 프로젝트를 해보니, Over-sampling 배수가 너무 늘어나서, 어느정도 비율을 맞추기 위해 Under-sampling도 함께 활용함. 다만, 어느정도까지 늘리고 줄일지는 모델 성능을 보면서 해야 할 듯.
  • 다만, sampling은 모델 학습(train)과정 중에서만 진행해야 함. sampling은 불균형한 데이터를 해결해주는 것이 아닌, 모델 학습을 도와주는 과정임.
    - 테스트 셋은 sampling을 진행하지 않고 pure하게 두어야 함.

1) Under-sampling: 비중이 큰 클래스의 데이터 수를 낮은 클래스 만큼 줄이기

  • depressed == 0 을 20000→ 2000까지 줄이기.
  • 정보가 유실되는 단점이 있음.
  • 어떤 방식으로 줄여야 할까?
    • Random Under Sampling
      from imblearn.under_sampling import RandomUnderSampler
      
        X = df
        rus = RandomUnderSampler(sampling_strategy=0.5, random_state=42) # 0.1 -> 0.5로 변경
        X_under, y_under = rus.fit_resample(X, y)
        X_under.shape, y_under.shape
    • Tomek Links
    • Condensed Nearest Neighbour (CNN)
    • Edited Nearest Neighbours (ENN)

2) Over-sampling: 비중이 작은 클래스의 데이터 수를 큰 클래스만큼 늘리기

  • depressed == 1을 2000 → 20000까지 늘리기

  • 정보의 손실을 막을 수는 있지만, 오히려 over fitting 을 초래할 수 있음.

  • 어떤 방식으로 늘릴 수 있을까?

    • Random Over Sampling

    • Synthetic Minority Oversampling Technique (SMOTE)

      • Random Over Sampling과는 다르게, 데이터에 새로운 ‘정보’를 추가하기 때문에 더 효과적임.
        - 비중이 작은 클래스에서 무작위로 k포인트 선택
        - 랜덤한 데이터와 k개의 최근접 이웃 간의 유클리디안 거리를 계산 (=k-nearest neighbors 계산)
        - 거리를 0과 1 사이의 랜덤한 수로 곱한 다음, 합성 샘플로 비중이 작은 클래스에 결과를 추가
        - 합성 포인트는 선택한 포인트와 인접 포인트 사이에 추가
        - 이를 원하는 비율을 충족할 때까지 반복

        # over sampling
        from imblearn.over_sampling import SMOTE
        
        smote = SMOTE(random_state=42)
        X_over, y_over = smote.fit_resample(X_under, y_under)
        
        X_over.shape, y_over.shape
      • Adaptive Synthetic Sampling (ADASYN)

        X_samp, y_samp = ADASYN(random_state=0).fit_sample(X_imb, y_imb)

3) Over-sampling followed by under-sampling

  • SMOTE를 이용해 Over-sampling을 하고, Tomek links를 이용해 Under-sampling을 결합해서 사용하는 방법
    from imblearn.combine import SMOTETomek
    
    smt = SMOTETomek(sampling_strategy='auto')
    X_sm, y_sm = smt.fit_resample(X,y)

Reference

0개의 댓글