불균형한 데이터셋은 머신러닝 모델을 훈련시키는 데 있어 큰 도전 과제가 됩니다. 특정 클래스의 데이터가 과도하게 많고, 다른 클래스의 데이터가 상대적으로 적을 경우, 모델은 주로 다수 클래스에 대해 학습하게 되어 소수 클래스의 예측 성능이 떨어질 수 있습니다. 이러한 문제를 해결하기 위해 오버샘플링 기법이 주목받고 있습니다. 본 포스트에서는 오버샘플링 기법의 개념과 그 구현 방법, 그리고 몇 가지 예제를 살펴보겠습니다.

오버샘플링의 정의

오버샘플링은 소수 클래스의 데이터를 인위적으로 늘려서 데이터셋의 불균형을 줄이는 방법입니다. 이를 통해 머신러닝 모델이 더 균형 잡힌 데이터로 학습할 수 있도록 하여 성능을 개선할 수 있습니다. 오버샘플링 기법에는 여러 종류가 있으며, 대표적으로 SMOTE(Synthetic Minority Over-sampling Technique)와 ADASYN(Adaptive Synthetic Sampling) 등이 있습니다.

SMOTE 기법

SMOTE는 소수 클래스의 데이터 포인트 사이에 새로운 데이터 포인트를 생성하는 기법입니다. 이는 기존 데이터 포인트의 특성을 바탕으로 새로운 데이터를 생성하여 데이터의 다양성을 높이는 효과를 가져옵니다. SMOTE의 기본 원리는 임의로 선택된 소수 클래스 샘플과 그 이웃 샘플을 결합하여 새로운 샘플을 생성하는 것입니다.

SMOTE 구현 예제

아래는 Python의 imbalanced-learn 라이브러리를 사용하여 SMOTE를 적용하는 예제입니다.

import numpy as np
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt

X, y = make_classification(n_classes=2, class_sep=2,
                           weights=[0.9, 0.1], n_informative=3,
                           n_redundant=1, flip_y=0,
                           n_features=20, n_clusters_per_class=1,
                           n_samples=1000, random_state=10)

# SMOTE 적용 전 데이터 분포
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.title('Before SMOTE')
plt.scatter(X[y  0][:, 0], X[y  0][:, 1], label='Majority Class', alpha=0.5)
plt.scatter(X[y  1][:, 0], X[y  1][:, 1], label='Minority Class', alpha=0.5)
plt.legend()

# SMOTE 적용
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)

# SMOTE 적용 후 데이터 분포
plt.subplot(1, 2, 2)
plt.title('After SMOTE')
plt.scatter(X_res[y_res  0][:, 0], X_res[y_res  0][:, 1], label='Majority Class', alpha=0.5)
plt.scatter(X_res[y_res  1][:, 0], X_res[y_res  1][:, 1], label='Minority Class', alpha=0.5)
plt.legend()
plt.show()

위 코드는 불균형한 데이터셋을 생성하고, SMOTE를 적용한 후의 데이터 분포를 시각화합니다. 왼쪽 그래프는 SMOTE 적용 전, 오른쪽 그래프는 SMOTE 적용 후의 데이터 분포를 보여줍니다. SMOTE를 통해 소수 클래스 데이터가 증가한 것을 확인할 수 있습니다.

ADASYN 기법

ADASYN은 SMOTE의 변형으로, 소수 클래스의 데이터 포인트 주변에 생성할 샘플의 수를 조정하여 더 어려운 샘플에 더 많은 샘플을 생성하는 기법입니다. 이는 모델 학습 시 더 어려운 예제에 집중할 수 있게 도와줍니다.

ADASYN 구현 예제

다음은 imbalanced-learn 라이브러리에서 ADASYN을 사용하는 예제입니다.

from imblearn.over_sampling import ADASYN

# ADASYN 적용
adasyn = ADASYN(random_state=42)
X_res_adasyn, y_res_adasyn = adasyn.fit_resample(X, y)

# ADASYN 적용 후 데이터 분포
plt.figure(figsize=(12, 5))
plt.subplot(1, 1, 1)
plt.title('After ADASYN')
plt.scatter(X_res_adasyn[y_res_adasyn  0][:, 0], X_res_adasyn[y_res_adasyn  0][:, 1], label='Majority Class', alpha=0.5)
plt.scatter(X_res_adasyn[y_res_adasyn  1][:, 0], X_res_adasyn[y_res_adasyn  1][:, 1], label='Minority Class', alpha=0.5)
plt.legend()
plt.show()

ADASYN을 적용한 후 소수 클래스 데이터가 어떻게 증가했는지 확인할 수 있습니다. 이 기법은 특히 데이터가 매우 불균형할 때 효과적입니다.

마무리

불균형한 데이터셋 문제는 머신러닝 모델의 성능에 큰 영향을 미칠 수 있습니다. 오버샘플링 기법, 특히 SMOTE와 ADASYN은 이러한 문제를 극복하는 데 매우 유용하게 사용될 수 있습니다. 두 기법 모두 데이터의 다양성을 증가시켜 모델이 보다 균형 잡힌 데이터를 학습할 수 있도록 도와줍니다. 하지만 각 기법의 특성과 데이터셋의 성격에 따라 선택이 달라질 수 있으므로, 상황에 맞게 적절한 기법을 선택하는 것이 중요합니다. 데이터 기반의 머신러닝 모델을 구축하는 데 있어 오버샘플링 기법은 필수적인 도구가 될 것입니다.