본문으로 건너뛰기

024 불균형 데이터 처리 - fix_imbalance 옵션

키워드: 불균형 데이터, fix_imbalance

개요​

실제 데이터는 대부분 불균형합니다. 사기 탐지, 질병 진단, 이탈 예측 등에서 양성 클래스가 희소합니다. 이 글에서는 PyCaret의 fix_imbalance 옵션을 활용한 불균형 처리를 다룹니다.

실습 환경​

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

불균형 데이터란?​

from pycaret.datasets import get_data

# 024 신용 데이터 - 불균형 예시
data = get_data('credit')

# 024 클래스 분포 확인
print(data['default'].value_counts())
print(data['default'].value_counts(normalize=True))

# 024 출력 예시:
# 0 7725 (77.3%)
# 1 2275 (22.7%)

불균형의 문제점​

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')

# 024 불균형 처리 없이
clf = setup(data, target='default', session_id=42, verbose=False)

# 024 모델 비교
best = compare_models(n_select=1)

# 024 Accuracy는 높지만 Recall이 낮을 수 있음
# 024 → 소수 클래스(default=1)를 잘 예측하지 못함

fix_imbalance 옵션​

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')

# 024 fix_imbalance 활성화
clf = setup(
data,
target='default',
fix_imbalance=True, # 핵심 옵션
session_id=42,
verbose=False
)

# 024 모델 비교
best = compare_models(sort='F1', n_select=1)

비교: fix_imbalance 전후​

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')

# 1. 불균형 처리 없이
print("=== 불균형 처리 없음 ===")
clf1 = setup(data, target='default', session_id=42, verbose=False)
model1 = create_model('rf', verbose=False)
results1 = pull()

# 2. fix_imbalance 적용
print("\n=== fix_imbalance 적용 ===")
clf2 = setup(data, target='default', fix_imbalance=True, session_id=42, verbose=False)
model2 = create_model('rf', verbose=False)
results2 = pull()

# 024 비교
print(f"\n처리 전 - Accuracy: {results1['Accuracy'].mean():.4f}, Recall: {results1['Recall'].mean():.4f}")
print(f"처리 후 - Accuracy: {results2['Accuracy'].mean():.4f}, Recall: {results2['Recall'].mean():.4f}")

fix_imbalance 내부 동작​

기본적으로 SMOTE (Synthetic Minority Over-sampling Technique) 사용:

# 024 PyCaret 내부에서 imbalanced-learn 라이브러리 사용
# 024 기본 설정: SMOTE

from pycaret.classification import *
from pycaret.datasets import get_data

data = get_data('credit')

clf = setup(
data,
target='default',
fix_imbalance=True,
# fix_imbalance_method='smote', # 기본값
session_id=42,
verbose=False
)

fix_imbalance_method 옵션​

from pycaret.classification import *
from pycaret.datasets import get_data
from imblearn.over_sampling import SMOTE, ADASYN, RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler

data = get_data('credit')

# 1. SMOTE (기본)
clf = setup(
data, target='default',
fix_imbalance=True,
fix_imbalance_method=SMOTE(),
session_id=42, verbose=False
)

# 2. ADASYN
clf = setup(
data, target='default',
fix_imbalance=True,
fix_imbalance_method=ADASYN(),
session_id=42, verbose=False
)

# 3. Random Over Sampling
clf = setup(
data, target='default',
fix_imbalance=True,
fix_imbalance_method=RandomOverSampler(),
session_id=42, verbose=False
)

# 4. Random Under Sampling
clf = setup(
data, target='default',
fix_imbalance=True,
fix_imbalance_method=RandomUnderSampler(),
session_id=42, verbose=False
)

샘플링 방법 비교​

방법설명장점단점
SMOTE소수 클래스 합성 생성정보 손실 없음노이즈 생성 가능
ADASYN어려운 샘플 위주 생성결정 경계 개선계산 비용
RandomOverSampler소수 클래스 복제단순, 빠름과적합 위험
RandomUnderSampler다수 클래스 제거단순, 빠름정보 손실

실전 예제: 최적 샘플링 방법 찾기​

from pycaret.classification import *
from pycaret.datasets import get_data
from imblearn.over_sampling import SMOTE, ADASYN, RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
from imblearn.combine import SMOTETomek

data = get_data('credit')

methods = {
'None': None,
'SMOTE': SMOTE(random_state=42),
'ADASYN': ADASYN(random_state=42),
'RandomOver': RandomOverSampler(random_state=42),
'RandomUnder': RandomUnderSampler(random_state=42),
'SMOTETomek': SMOTETomek(random_state=42)
}

results = []

for name, method in methods.items():
print(f"\n=== {name} ===")

if method is None:
clf = setup(data, target='default', session_id=42, verbose=False)
else:
clf = setup(
data, target='default',
fix_imbalance=True,
fix_imbalance_method=method,
session_id=42, verbose=False
)

model = create_model('rf', verbose=False)
metrics = pull()

results.append({
'method': name,
'accuracy': metrics['Accuracy'].mean(),
'recall': metrics['Recall'].mean(),
'f1': metrics['F1'].mean(),
'auc': metrics['AUC'].mean()
})

# 024 결과 비교
import pandas as pd
df = pd.DataFrame(results)
print("\n=== 결과 비교 ===")
print(df.sort_values('f1', ascending=False))

주의사항​

1. 테스트 데이터에는 적용 안 됨​

# 024 PyCaret은 자동으로 학습 데이터에만 샘플링 적용
# 024 테스트 데이터는 원본 그대로 유지 → 올바른 평가

2. 과도한 샘플링 주의​

# 024 극단적 불균형 (1:100 이상)에서는
# 024 오버샘플링으로 데이터가 너무 커질 수 있음
# 024 → 언더샘플링이나 하이브리드 방법 고려

3. 평가 지표 선택​

# 024 불균형 데이터에서는 반드시:
# 024 - F1 Score
# 024 - AUC
# 024 - Recall (양성 탐지 중요 시)

# 024 Accuracy만 보면 안 됨!
best = compare_models(sort='F1') # 또는 sort='AUC'

정리​

  • fix_imbalance=True로 자동 불균형 처리
  • 기본적으로 SMOTE 사용
  • fix_imbalance_method로 다른 방법 지정 가능
  • 테스트 데이터는 자동으로 원본 유지
  • 평가 시 F1/AUC 사용 권장

다음 글 예고​

다음 글에서는 불균형 데이터 처리 - SMOTE 활용을 더 깊이 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #024