데이터 불균형이란?
데이터 불균형은 머신러닝 모델을 훈련할 때 특정 클래스의 데이터 개수가 다른 클래스에 비해 현저히 적거나 많은 경우를 말합니다. 주로 분류(classification) 문제에서 발생하며, 모델이 데이터가 많은 클래스에 편향되어 학습하는 문제가 생깁니다.
예를 들어 금융 사기 탐지 모델인 경우, 정상 거래에 비해 사기 거래가 현저히 적으므로 모델이 사기 거래를 거의 탐지하지 못하는 경우가 있습니다.
불균형 데이터에서 다수를 차지하는 범주를 ‘다수 범주(majority class)’라고 하고, 적은 수를 차지하는 범주는 ‘소수 범주 (minority class)’ 라고 합니다.
해결 방법
1. 샘플링 방법
✅ 언더샘플링(Undersampling)
- 데이터가 많은 클래스의 샘플 수를 줄여 균형을 맞추는 방법
- 대표적인 기법: 랜덤 언더 샘플링 (RUS)
- 장점: 모델이 모든 클래스를 균등하게 학습
- 단점: 중요한 정보를 잃을 가능성 있음
- 예: 정상 거래 데이터를 일부만 사용하여 사기 거래와 비율을 맞춤
✅ 오버샘플링(Oversampling)
- 데이터가 적은 클래스를 증강하여 데이터 균형을 맞추는 방법
- 대표적인 기법: *SMOTE(Synthetic Minority Over-sampling Technique), 랜덤 오버 샘플링 (ROS)
- 장점: 데이터 손실 없이 클래스 균형 유지
- 단점: 과적합(overfitting) 위험 증가
2. 비용 또는 가중치 조정 방법
✅ 가중치 조정(Class Weight Balancing)
- 데이터가 적은 클래스에 가중치를 더 부여하여 학습 시 반영
- ex 양성 클래스에 10배 가중치
✅ 앙상블 학습(Ensemble Learning)
- 여러 개의 모델을 결합하여 예측 성능을 높이는 방법
- 랜덤 포레스트, XGBoost 등이 효과적
✅ Anomaly Detection(이상 탐지 기법 활용)
- 불균형한 데이터에서 극히 적은 클래스를 이상치(Outlier)로 간주하여 탐지
✅ 코스트 센서티브 학습(Cost-Sensitive Learning)
- 잘못된 분류에 대해 비용을 다르게 부여하여 학습 진행
기존의 데이터 불균형을 문제를 접했을 때는 언더 샘플링방식을 활용하여 주로 해결했는데,
SMOTE를 사용해서 오버 샘플링을 사용해보려고 합니다.
SMOTE(Synthetic Minority Over-sampling Technique) 이란?
데이터 불균형을 해결하기 위한 오버샘플링 기법으로, 소수 클래스(Minority Class)의 데이터를 무작위로 복제하는 것이 아니라, 기존 데이터의 특성을 고려하여 새로운 데이터를 생성하는 방식을 말합니다.
🔹 SMOTE 작동 방식
- 소수 클래스 데이터 샘플 선택
- 기존 데이터에서 소수 클래스 샘플을 랜덤하게 선택
- 기존 소수 클래스 데이터에서 새로운 데이터를 생성 - KNN 알고리즘을 이용
- 선택한 샘플과 가장 가까운 K개의 소수 클래스 데이터를 찾음
- 랜덤하게 한 개의 이웃 선택
- 찾은 K개의 이웃 중 하나를 랜덤으로 선택
- 새로운 샘플 생성(선형 보간법, Interpolation)
- 선택한 소수 클래스 샘플과 이웃 샘플 사이에서 랜덤한 위치를 생성하여 새로운 데이터를 만듦
- 람다는 0과 1사이 랜덤한 값
예제 코드는 다음과 같이 작성해 보았습니다.
import numpy as np
from collections import Counter
from imblearn.over_sampling import SMOTE
# 불균형 데이터 셋 생성
X = np.array([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8],
[8, 9], [9, 10], [10, 11], # 다수 클래스
[20, 21], [21, 22], [22, 23]]) # 소수 클래스
y = np.array([0] * 10 + [1] * 3) # 0 클래스 10개, 1 클래스 3개 (불균형)
# 클래스 비율 확인
print("Before SMOTE:", Counter(y))
# SMOTE 적용
smote = SMOTE(sampling_strategy='auto', random_state=42, k_neighbors=2)
X_resampled, y_resampled = smote.fit_resample(X, y)
print("After SMOTE:", Counter(y_resampled))
코드 실행 결과:
Before SMOTE: Counter({0: 10, 1: 3})
After SMOTE: Counter({0: 10, 1: 10})
로 데이터가 잘 생성된 것을 알 수 있습니다.
랜덤 스테이트(Random State)란?
Random State는 난수(random number)의 시드를 고정하여 실행할 때마다 같은 결과가 나오도록 만드는 설정 값입니다. 여기서 시드란, 같은 규칙을 반복해서 사용하면 항상 같은 숫자가 나오도록 설정할 수 있도록 하는 값을 말합니다.
즉, 머신러닝 모델이나 데이터 샘플링을 실행할 때 재현 가능성을 보장하기 위해 사용됩니다.
'BigData' 카테고리의 다른 글
선형대수학과 데이터 분석(Data Analysis) : 데이터 구조와 ML을 기반으로 (1) | 2025.03.13 |
---|