본문으로 건너뛰기

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