본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 27. 14:52

LightGBM으로 불균형 데이터 처리 비교하기: SMOTE vs 언더샘플링 앙상블

요약

불균형 데이터셋 환경에서 LightGBM 모델의 성능을 최적화하기 위한 기법들을 비교합니다. Accuracy의 함정을 지적하며, SMOTE와 언더샘플링 앙상블을 통해 정밀도(Precision)와 재현율(Recall) 사이의 균형을 맞추는 방법을 다룹니다.

핵심 포인트

  • 불균형 데이터에서는 Accuracy보다 Precision과 Recall이 중요함
  • LightGBM을 활용한 정형 데이터 불균형 처리 기법 비교
  • 데이터 분할 시 stratify 옵션 사용의 중요성 강조
  • SMOTE 및 언더샘플링을 통한 모델 성능 개선 실험

서론

머신러닝 (Machine Learning)을 실무에서 다루다 보면 빈번하게 마주하게 되는 것이 바로 "불균형 데이터 (Imbalanced Data)"입니다.

예를 들어:

  • 신용카드 부정 결제 탐지
  • 과금 사용자 예측
  • 이탈 예측
  • 장애 탐지
  • BAN 대상 사용자 탐지
  • 의료 진단

등에서는 "탐지하고 싶은 현상" 자체의 발생률이 낮은 경우가 매우 많습니다.

예를 들어:

  • 부정률 0.1%
  • 과금률 2%
  • 중증 질환 0.5%

와 같은 케이스입니다.

이러한 상황에서는 단순한 정확도 (Accuracy)는 거의 의미가 없을 수 있습니다.

예를 들어, 부정률이 0.1%인 데이터에 대해:

"모두 정상입니다"

라고 예측하는 모델을 만드는 것만으로도 Accuracy는 99.9%가 됩니다.

하지만 당연하게도, 이 모델은 부정을 단 한 건도 탐지하지 못합니다.

즉, 불균형 데이터에서는:

"Accuracy가 높다 = 좋은 모델"

이 아닙니다.

이번에 비교할 기법

이번에는 다음 4가지를 비교합니다.

기법내용
Baseline아무것도 하지 않는 LightGBM
...

특히 이번에는,

"정밀도 (Precision)와 재현율 (Recall) 중 어느 쪽을 중시할 것인가"

라는 관점에서 비교해 나가겠습니다.

이번에 사용할 데이터셋

이번에는 Kaggle의 유명한 부정 탐지 데이터셋을 이용합니다.

이 데이터는:

  • 약 28만 건
  • 부정 데이터 492건
  • 부정률 0.172%

라는 매우 강한 불균형을 가지고 있습니다.

머신러닝의 불균형 학습에서는 정석적인 데이터셋입니다.

왜 Accuracy만으로는 위험한가

예를 들어 다음과 같은 혼동 행렬 (Confusion Matrix)을 생각해 봅시다.

실제 Positive실제 Negative
Positive 예측0
Negative 예측100

이 경우:

  • Accuracy = 99.9%
  • Recall = 0%

입니다.

즉:

"Accuracy는 높지만, 중요한 Positive를 전혀 탐지하지 못하고 있는"

상황입니다.

따라서 불균형 데이터에서는 다음과 같은 지표가 중요해집니다.

지표의미
PrecisionPositive 예측 중 실제로 Positive였던 비율
...

실험 환경

라이브러리 설치

pip install pandas numpy scikit-learn imbalanced-learn lightgbm matplotlib seaborn

데이터 불러오기

import pandas as pd
df = pd.read_csv("creditcard.csv")
print(df["Class"].value_counts())

Class:

  • 0 = 정상
  • 1 = 부정

입니다.

train / test 분할

from sklearn.model_selection import train_test_split
X = df.drop("Class", axis=1)
y = df["Class"]
...

stratify=y는 상당히 중요합니다.

불균형 데이터에서는 무작위 분할을 할 경우 test 세트에 Positive가 거의 포함되지 않는 경우가 있습니다.

평가 함수

from sklearn.metrics import (
precision_score,
recall_score,
...

LightGBM 모델 정의

이번에는 정형 데이터 (Tabular Data)에 강한 LightGBM을 이용합니다.

from lightgbm import LGBMClassifier
def create_lgbm_model(random_state=42):
return LGBMClassifier(
...

1. Baseline (아무것도 하지 않음)

먼저 아무것도 하지 않는 LightGBM을 시도합니다.

baseline_model = create_lgbm_model()
baseline_model.fit(X_train, y_train)
baseline_proba = baseline_model.predict_proba(X_test)[:, 1]

2. scale_pos_weight

2. scale_pos_weight

LightGBM은 클래스 가중치 조절 (Class Weight Adjustment)이 가능합니다.

scale_pos_weight = (
(y_train == 0).sum() /
(y_train == 1).sum()
...

3. SMOTE

다음으로 SMOTE를 시도합니다.

주의: CV 리크 (CV Leak)

SMOTE는 train/test split 전에 적용하면 리크 (Leak)가 발생합니다.

즉:

❌ 나쁜 예

X_smote, y_smote = smote.fit_resample(X, y)

이것은 test 데이터에 train 정보가 섞일 위험이 있습니다.

이번에는 train 데이터에만 적용합니다.

SMOTE 구현

from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline as ImbPipeline
smote_model = ImbPipeline([
...

4. 언더샘플링 앙상블 (UnderSampling Ensemble)

이번의 메인 기법입니다.

기법 개요

이번에는:

  • 다수 클래스 (Majority Class)를 랜덤하게 축소
  • 시드 (seed)를 바꿔가며 10회 학습
  • 각 모델의 예측 확률을 평균

이라는 방법을 채택합니다.

이미지로 표현하면:

모델1 → seed=0
모델2 → seed=1
...
...

입니다.

이는 EasyEnsemble과 유사한 발상입니다.

구현 코드

import numpy as np
from sklearn.utils import resample
ensemble_probs = []
...

결과 비교

threshold=0.5 의 결과입니다.

methodprecisionrecallf1pr_auc
Baseline0.7708330.7551020.7628870.733742
...

결과 고찰

1. LightGBM이 기본 상태에서도 상당히 강력함

Baseline에서도:

  • precision 0.77
  • recall 0.75

가 나왔습니다.

최근의 GBDT 계열 모델은 불균형 데이터에 상당히 강하다고 느껴집니다.

2. scale_pos_weight가 상당히 극단적임

Recall은 높아졌지만, Precision이 붕괴되었습니다.

이번 데이터는 불균형 비율이 매우 크기 때문에,

scale_pos_weight =
negative 수 / positive 수

를 그대로 넣으면,

"Positive를 절대 놓치지 마라"

라는 강력한 압박이 모델에 가해지는 듯합니다.

3. UnderSampling Ensemble은 Recall 특화가 됨

이번 구현에서는:

majority를 minority 수까지 축소

하고 있기 때문에, 상당히 공격적인 (aggressive) 밸런싱이 이루어지고 있습니다.

그 결과:

  • Recall은 0.93
  • 하지만 Precision은 0.05

가 되었습니다.

즉:

"Positive를 상당히 많이 잡아내지만, False Positive도 대량 발생한다"

는 모델이 되었습니다.

4. SMOTE는 이번에 상당히 균형이 좋았음

이번 실험에서는:

  • precision 0.73
  • recall 0.87

이 되어, 가장 균형이 좋은 결과가 나왔습니다.

단, 이것은:

  • 데이터 구조
  • 모델
  • threshold

에 따라 달라지기 때문에,

"SMOTE가 항상 최강이다"

를 의미하는 것은 아닙니다.

배운 점

이번에 상당히 중요하다고 느낀 점은:

"불균형 대책을 세운다고 해서 전부 좋아지는 것은 아니다"

라는 점입니다.

특히:

  • Recall을 높인다
    ↓ - False Positive 증가
    ↓ - Precision 붕괴

라는 트레이드오프 (trade-off)가 상당히 강하게 나타났습니다.

따라서 실무에서는:

  • 부정 탐지 (Fraud Detection)
  • 의료 진단
  • 자동 BAN
  • 광고 송출

등,

"무엇을 실수하면 곤란한가"

에 따라 최적의 기법이 달라질 것이라고 생각합니다.

threshold 조정도 중요

이번 비교는 threshold=0.5 고정이었습니다.

하지만 실무에서는:

"모델 변경"보다 threshold tuning이 더 효과적인

경우도 많습니다.

예를 들어:

pred = (proba >= 0.3).astype(int)

와 같이 threshold(임계값)를 낮추면:

  • Recall (재현율) ↑
  • Precision (정밀도) ↓

가 됩니다.

반대로 threshold를 높이면:

  • Precision (정밀도) ↑
  • Recall (재현율) ↓

가 됩니다.

즉:

「어떤 threshold가 비즈니스적으로 적절한가」

또한 중요한 의사결정 사항입니다.

요약

이번에는:

  • LightGBM
  • scale_pos_weight
  • SMOTE
  • 언더샘플링 앙상블 (UnderSampling Ensemble)

을 비교했습니다.

이번 결과에서는:

  • SMOTE → Precision (정밀도)가 비교적 유지됨
  • UnderSampling Ensemble → Recall (재현율)이 상당히 높아짐

이라는 결과가 나왔습니다.

하지만 중요한 것은:

「어느 쪽이 더 강력한가」가 아니라,

「무엇을 중시하고 싶은가」라고 생각합니다.

불균형 학습 (Imbalanced Learning)에서는:

  • Precision (정밀도)를 중시할 것인가
  • Recall (재현율)을 중시할 것인가
  • threshold를 어떻게 설정할 것인가

에 따라 최적의 기법이 달라집니다.

따라서:

「무엇을 최적화하고 싶은가」를 처음에 명확히 하는 것이 중요하다고 느꼈습니다.

참고

Kaggle Credit Card Fraud Detection Dataset

https://www.kaggle.com/datasets/mlg-ulb/creditcardfraud

imbalanced-learn documentation

https://imbalanced-learn.org/stable/

LightGBM Documentation

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0