imbalanced-learn는 Python에서 데이터 불균형 문제를 해결하기 위한 다양한 샘플링 기법을 제공하는 라이브러리입니다. 이 라이브러리는 오버샘플링(Over-sampling), 언더샘플링(Under-sampling), 혼합 샘플링(Combined Sampling), 그리고 앙상블(Ensemble) 방법 등 다양한 접근 방식을 지원합니다. 아래에서는 imbalanced-learn에서 제공하는 주요 데이터 불균형 처리 기법들을 상세히 소개하겠습니다.
목차
7.
8.
9.
10.
1. 오버샘플링(Over-sampling) 기법
오버샘플링은 소수 클래스의 샘플 수를 증가시켜 클래스 간의 불균형을 완화하는 방법입니다. imbalanced-learn에서는 다양한 오버샘플링 기법을 제공합니다.
1.1 Random Over-Sampler
Random Over-Sampler는 소수 클래스의 샘플을 무작위로 복제하여 소수 클래스의 크기를 늘리는 가장 간단한 오버샘플링 기법입니다.
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(random_state=42)
X_resampled, y_resampled = ros.fit_resample(X, y)
Python
복사
장점:
•
구현이 매우 간단하고 빠릅니다.
•
과적합의 위험이 적습니다.
단점:
•
단순 복제로 인해 소수 클래스의 다양성이 증가하지 않습니다.
•
과적합의 위험이 여전히 존재할 수 있습니다.
1.2 SMOTE 계열 기법
•
*Synthetic Minority Over-sampling Technique (SMOTE)**는 소수 클래스의 새로운 샘플을 합성하여 데이터의 다양성을 증가시키는 오버샘플링 기법입니다. SMOTE에는 여러 변형이 존재하며, 각기 다른 방식으로 합성 샘플을 생성합니다.
SMOTE
기본 SMOTE는 소수 클래스의 각 샘플에 대해 K-최근접 이웃을 찾고, 이웃과의 선형 보간을 통해 새로운 샘플을 생성합니다.
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
Python
복사
Borderline-SMOTE
Borderline-SMOTE는 소수 클래스와 다수 클래스의 경계에 위치한 샘플을 중심으로 합성 샘플을 생성합니다. 이는 경계 영역의 데이터를 더욱 강화하여 모델의 분류 성능을 향상시킵니다.
from imblearn.over_sampling import BorderlineSMOTE
borderline_smote = BorderlineSMOTE(random_state=42, kind='borderline-1')
X_resampled, y_resampled = borderline_smote.fit_resample(X, y)
Python
복사
장점:
•
경계 샘플에 집중하여 합성 샘플을 생성하므로, 클래스 간의 경계를 명확히 할 수 있습니다.
단점:
•
구현이 조금 더 복잡하며, 적절한 매개변수 설정이 필요합니다.
SVMSMOTE
SVMSMOTE는 SVM의 결정 경계를 활용하여 소수 클래스의 샘플을 합성합니다. 이는 소수 클래스의 결정 경계 근처에 위치한 샘플을 기반으로 합성 샘플을 생성하여 경계의 정확성을 높입니다.
from imblearn.over_sampling import SVMSMOTE
svm_smote = SVMSMOTE(random_state=42)
X_resampled, y_resampled = svm_smote.fit_resample(X, y)
Python
복사
장점:
•
SVM의 결정 경계를 활용하여 보다 정교한 합성 샘플을 생성합니다.
단점:
•
계산 비용이 높을 수 있으며, 데이터의 크기에 따라 성능이 저하될 수 있습니다.
ADASYN
•
*ADASYN (Adaptive Synthetic Sampling)**은 소수 클래스의 샘플에 가중치를 부여하여, 어려운 샘플(다수 클래스와 겹치는 샘플)에 더 많은 합성 샘플을 생성합니다. 이를 통해 소수 클래스의 학습을 더욱 강화할 수 있습니다.
from imblearn.over_sampling import ADASYN
adasyn = ADASYN(random_state=42)
X_resampled, y_resampled = adasyn.fit_resample(X, y)
Python
복사
장점:
•
소수 클래스의 어려운 샘플에 집중하여 합성 샘플을 생성합니다.
•
모델의 일반화 성능을 향상시킬 수 있습니다.
단점:
•
노이즈에 민감할 수 있으며, 과적합의 위험이 있습니다.
KMeansSMOTE
KMeansSMOTE는 K-평균 군집화를 통해 소수 클래스의 클러스터를 식별한 후, 각 클러스터 내에서 합성 샘플을 생성합니다. 이는 데이터의 군집 구조를 반영하여 보다 의미 있는 샘플을 생성할 수 있습니다.
from imblearn.over_sampling import KMeansSMOTE
kmeans_smote = KMeansSMOTE(random_state=42)
X_resampled, y_resampled = kmeans_smote.fit_resample(X, y)
Python
복사
장점:
•
소수 클래스의 군집 구조를 반영하여 합성 샘플을 생성합니다.
•
데이터의 다양성을 유지할 수 있습니다.
단점:
•
K-평균 군집화의 매개변수 설정이 필요합니다.
•
계산 비용이 높을 수 있습니다.
1.3 Safe-Level SMOTE
Safe-Level SMOTE는 데이터의 밀도를 기반으로 합성 샘플을 생성할지 여부를 결정합니다. 밀도가 낮은 영역에서는 샘플 생성을 피하여 노이즈 샘플의 합성을 방지합니다.
from imblearn.over_sampling import SafeLevelSMOTE
safe_level_smote = SafeLevelSMOTE(random_state=42)
X_resampled, y_resampled = safe_level_smote.fit_resample(X, y)
Python
복사
장점:
•
노이즈 샘플의 합성을 방지하여 데이터 품질을 향상시킵니다.
단점:
•
매개변수 설정이 복잡할 수 있습니다.
2. 언더샘플링(Under-sampling) 기법
언더샘플링은 다수 클래스의 샘플 수를 줄여 클래스 간의 불균형을 완화하는 방법입니다. imbalanced-learn에서는 다양한 언더샘플링 기법을 제공합니다.
2.1 Random Under-Sampler
Random Under-Sampler는 다수 클래스의 샘플을 무작위로 제거하여 소수 클래스와의 균형을 맞춥니다.
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = rus.fit_resample(X, y)
Python
복사
장점:
•
구현이 매우 간단하고 빠릅니다.
단점:
•
중요한 다수 클래스의 샘플이 제거될 수 있습니다.
•
과적합의 위험이 여전히 존재할 수 있습니다.
2.2 Tomek Links
Tomek Links는 서로 다른 클래스에 속하는 두 샘플이 서로의 최근접 이웃인 경우를 찾아 제거하는 기법입니다. 이는 클래스 간의 경계를 정리하고 노이즈를 제거하는 데 효과적입니다.
from imblearn.under_sampling import TomekLinks
tl = TomekLinks(sampling_strategy='majority')
X_resampled, y_resampled = tl.fit_resample(X, y)
Python
복사
장점:
•
노이즈 샘플을 제거하여 데이터의 품질을 향상시킵니다.
•
클래스 경계를 명확히 합니다.
단점:
•
소수 클래스의 샘플이 제거될 수 있습니다.
•
데이터의 중요한 정보를 잃을 위험이 있습니다.
2.3 Edited Nearest Neighbours (ENN)
•
*Edited Nearest Neighbours (ENN)**는 각 샘플의 K-최근접 이웃을 확인하고, 다수 클래스의 샘플이 과반수를 차지하면 해당 샘플을 제거합니다. 이는 데이터의 노이즈를 줄이고 클래스 간의 경계를 정리합니다.
from imblearn.under_sampling import EditedNearestNeighbours
enn = EditedNearestNeighbours()
X_resampled, y_resampled = enn.fit_resample(X, y)
Python
복사
장점:
•
노이즈 샘플을 효과적으로 제거합니다.
•
클래스 경계를 명확히 합니다.
단점:
•
계산 비용이 높을 수 있습니다.
•
소수 클래스의 샘플이 제거될 수 있습니다.
2.4 Neighborhood Cleaning Rule (NCR)
•
*Neighborhood Cleaning Rule (NCR)**는 ENN과 유사하게 K-최근접 이웃을 기반으로 다수 클래스의 샘플을 제거합니다. 그러나 NCR은 소수 클래스의 샘플 주변의 다수 클래스 샘플을 제거하여 클래스 경계를 정리합니다.
from imblearn.under_sampling import NeighborhoodCleaningRule
ncr = NeighborhoodCleaningRule()
X_resampled, y_resampled = ncr.fit_resample(X, y)
Python
복사
장점:
•
클래스 경계를 정리하여 모델의 성능을 향상시킵니다.
•
노이즈 제거에 효과적입니다.
단점:
•
소수 클래스의 중요한 샘플이 제거될 수 있습니다.
•
계산 비용이 높을 수 있습니다.
2.5 One-Sided Selection (OSS)
•
*One-Sided Selection (OSS)**는 불필요한 다수 클래스의 샘플을 제거하고, 소수 클래스의 샘플 주변의 다수 클래스 샘플을 제거하는 기법입니다. 이는 데이터의 품질을 높이고 클래스 간의 경계를 명확히 합니다.
from imblearn.under_sampling import OneSidedSelection
oss = OneSidedSelection()
X_resampled, y_resampled = oss.fit_resample(X, y)
Python
복사
장점:
•
노이즈를 효과적으로 제거합니다.
•
클래스 간의 경계를 정리합니다.
단점:
•
중요한 다수 클래스의 샘플이 제거될 수 있습니다.
•
소수 클래스의 샘플이 줄어들 수 있습니다.
2.6 Condensed Nearest Neighbour (CNN)
•
*Condensed Nearest Neighbour (CNN)**는 데이터셋에서 소수 클래스의 샘플을 유지하면서 다수 클래스의 샘플을 최소화하여 결정 경계를 형성하는 기법입니다. 이는 데이터의 크기를 줄이고, 중요한 샘플을 유지합니다.
from imblearn.under_sampling import CondensedNearestNeighbour
cnn = CondensedNearestNeighbour()
X_resampled, y_resampled = cnn.fit_resample(X, y)
Python
복사
장점:
•
데이터의 크기를 줄여 학습 속도를 향상시킵니다.
•
중요한 샘플을 유지합니다.
단점:
•
소수 클래스의 샘플이 줄어들 수 있습니다.
•
복잡한 데이터에서는 효과가 제한적일 수 있습니다.
2.7 Repeated Edited Nearest Neighbours (RENN)
•
*Repeated Edited Nearest Neighbours (RENN)**는 ENN을 반복적으로 적용하여 데이터셋의 노이즈를 지속적으로 제거하는 기법입니다. 이는 데이터의 품질을 더욱 높일 수 있습니다.
from imblearn.under_sampling import RepeatedEditedNearestNeighbours
renn = RepeatedEditedNearestNeighbours()
X_resampled, y_resampled = renn.fit_resample(X, y)
Python
복사
장점:
•
지속적인 노이즈 제거로 데이터 품질을 향상시킵니다.
•
클래스 경계를 명확히 합니다.
단점:
•
계산 비용이 매우 높을 수 있습니다.
•
소수 클래스의 샘플이 많이 제거될 수 있습니다.
3. 혼합 샘플링(Combined Sampling) 기법
혼합 샘플링은 오버샘플링과 언더샘플링을 동시에 적용하여 클래스 간의 불균형을 해결하는 방법입니다. 이를 통해 데이터의 균형을 맞추면서도 데이터의 품질을 유지할 수 있습니다.
3.1 SMOTE + Random Under-Sampling
SMOTE + Random Under-Sampling은 SMOTE로 소수 클래스를 오버샘플링한 후, Random Under-Sampler로 다수 클래스를 언더샘플링하여 균형을 맞춥니다.
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline
over = SMOTE(sampling_strategy=0.5, random_state=42)
under = RandomUnderSampler(sampling_strategy=0.5, random_state=42)
steps = [('o', over), ('u', under)]
pipeline = Pipeline(steps=steps)
X_resampled, y_resampled = pipeline.fit_resample(X, y)
Python
복사
장점:
•
오버샘플링과 언더샘플링의 장점을 동시에 활용할 수 있습니다.
•
데이터의 균형과 품질을 동시에 향상시킬 수 있습니다.
단점:
•
적절한 샘플링 비율 설정이 필요합니다.
•
복잡한 구현이 필요할 수 있습니다.
SMOTEENN
SMOTEENN은 SMOTE로 소수 클래스를 오버샘플링한 후, Edited Nearest Neighbours (ENN)로 노이즈와 불필요한 샘플을 제거하는 기법입니다.
from imblearn.combine import SMOTEENN
smote_enn = SMOTEENN(random_state=42)
X_resampled, y_resampled = smote_enn.fit_resample(X, y)
Python
복사
장점:
•
SMOTE로 소수 클래스의 샘플을 늘리고, ENN으로 노이즈를 제거하여 데이터의 품질을 향상시킵니다.
•
과적합의 위험을 줄일 수 있습니다.
단점:
•
구현이 복잡할 수 있습니다.
•
계산 비용이 높을 수 있습니다.
SMOTETomek
SMOTETomek은 SMOTE로 소수 클래스를 오버샘플링한 후, Tomek Links를 사용하여 클래스 간의 불필요한 샘플을 제거하는 기법입니다.
from imblearn.combine import SMOTETomek
smote_tomek = SMOTETomek(random_state=42)
X_resampled, y_resampled = smote_tomek.fit_resample(X, y)
Python
복사
장점:
•
SMOTE로 소수 클래스의 샘플을 늘리고, Tomek Links로 노이즈를 제거하여 데이터의 균형과 품질을 동시에 향상시킵니다.
•
클래스 간의 경계를 명확히 합니다.
단점:
•
복잡한 구현이 필요할 수 있습니다.
•
Tomek Links 단계에서 소수 클래스의 샘플이 제거될 수 있습니다.
4. 앙상블(Ensemble) 기법
앙상블 기법은 여러 개의 모델을 결합하여 데이터 불균형 문제를 해결하는 방법입니다. imbalanced-learn에서는 다양한 앙상블 방법을 제공하여 클래스 불균형에 강한 모델을 구축할 수 있습니다.
4.1 Balanced Bagging Classifier
Balanced Bagging Classifier는 배깅(Bagging) 방법을 기반으로, 각 배깅 반복에서 균형 잡힌 서브셋을 샘플링하여 학습하는 기법입니다.
from imblearn.ensemble import BalancedBaggingClassifier
from sklearn.tree import DecisionTreeClassifier
bbc = BalancedBaggingClassifier(base_estimator=DecisionTreeClassifier(),
sampling_strategy='auto',
random_state=42)
bbc.fit(X_train, y_train)
Python
복사
장점:
•
간단하게 클래스 불균형 문제를 해결할 수 있습니다.
•
다양한 베이스 모델과 함께 사용할 수 있습니다.
단점:
•
베이스 모델의 성능에 따라 전체 성능이 좌우될 수 있습니다.
•
계산 비용이 높을 수 있습니다.
4.2 Balanced Random Forest
Balanced Random Forest는 랜덤 포레스트 알고리즘을 기반으로, 각 트리를 학습할 때 균형 잡힌 서브셋을 샘플링하여 학습하는 기법입니다.
from imblearn.ensemble import BalancedRandomForestClassifier
brf = BalancedRandomForestClassifier(random_state=42)
brf.fit(X_train, y_train)
Python
복사
장점:
•
강력한 앙상블 모델로, 높은 예측 성능을 보입니다.
•
클래스 불균형 문제에 강합니다.
단점:
•
계산 비용이 높을 수 있습니다.
•
대규모 데이터셋에서는 학습 속도가 느릴 수 있습니다.
4.3 Easy Ensemble
Easy Ensemble은 여러 개의 언더샘플링된 서브셋을 생성하여 각각의 서브셋에 대해 독립적인 모델을 학습하고, 최종 예측을 앙상블하여 수행하는 기법입니다.
from imblearn.ensemble import EasyEnsembleClassifier
ee = EasyEnsembleClassifier(random_state=42)
ee.fit(X_train, y_train)
Python
복사
장점:
•
여러 모델을 학습하여 예측의 안정성을 높일 수 있습니다.
•
소수 클래스에 대한 예측 성능이 향상됩니다.
단점:
•
여러 모델을 학습해야 하므로 계산 비용이 매우 높을 수 있습니다.
•
복잡한 구현이 필요할 수 있습니다.
4.4 RUSBoost
RUSBoost는 부스팅 알고리즘을 기반으로, 각 부스팅 반복에서 랜덤 언더샘플링(RUS)을 적용하여 소수 클래스에 더 많은 주의를 기울이는 기법입니다.
from imblearn.ensemble import RUSBoostClassifier
from sklearn.tree import DecisionTreeClassifier
rusboost = RUSBoostClassifier(base_estimator=DecisionTreeClassifier(),
n_estimators=50,
random_state=42)
rusboost.fit(X_train, y_train)
Python
복사
장점:
•
부스팅의 장점을 활용하여 예측 성능을 향상시킵니다.
•
클래스 불균형 문제에 효과적입니다.
단점:
•
계산 비용이 높을 수 있습니다.
•
베이스 모델의 선택에 따라 성능이 좌우될 수 있습니다.
5. 기타 유틸리티 기법
imbalanced-learn에서는 오버샘플링과 언더샘플링 외에도 데이터 전처리 및 군집화 기반의 샘플링 기법을 제공합니다.
5.1 Cluster Centroids
Cluster Centroids는 다수 클래스의 샘플을 K-평균 군집화하여 각 군집의 중심점을 새로운 샘플로 사용하는 언더샘플링 기법입니다. 이는 다수 클래스의 샘플을 대표하는 중심점을 유지하면서 데이터의 크기를 줄입니다.
from imblearn.under_sampling import ClusterCentroids
cc = ClusterCentroids(random_state=42)
X_resampled, y_resampled = cc.fit_resample(X, y)
Python
복사
장점:
•
데이터의 대표성을 유지하면서 샘플 수를 줄일 수 있습니다.
•
계산 비용이 상대적으로 낮습니다.
단점:
•
군집 수(K)에 따라 결과가 크게 달라질 수 있습니다.
•
중요한 샘플이 제거될 수 있습니다.
5.2 NearMiss
NearMiss는 다수 클래스의 샘플을 소수 클래스에 가까운 샘플로 선택하여 언더샘플링하는 기법입니다. NearMiss에는 여러 변형이 존재합니다.
NearMiss-1
소수 클래스의 샘플과 가장 가까운 다수 클래스의 샘플을 유지합니다.
from imblearn.under_sampling import NearMiss
nearmiss = NearMiss(version=1)
X_resampled, y_resampled = nearmiss.fit_resample(X, y)
Python
복사
NearMiss-2
소수 클래스의 각 샘플에 대해 다수 클래스의 샘플 중 가장 먼 샘플을 제거합니다.
nearmiss = NearMiss(version=2)
X_resampled, y_resampled = nearmiss.fit_resample(X, y)
Python
복사
NearMiss-3
소수 클래스의 각 샘플에 대해 K-최근접 이웃의 다수 클래스 샘플을 제거합니다.
nearmiss = NearMiss(version=3)
X_resampled, y_resampled = nearmiss.fit_resample(X, y)
Python
복사
장점:
•
소수 클래스와 가까운 다수 클래스의 샘플을 유지하여 클래스 간의 경계를 정리합니다.
•
다양한 버전을 통해 유연하게 적용할 수 있습니다.
단점:
•
K-최근접 이웃의 설정에 따라 결과가 달라질 수 있습니다.
•
중요한 다수 클래스 샘플이 제거될 수 있습니다.
6. 샘플링 전략(Sampling Strategies)
imbalanced-learn에서는 다양한 샘플링 전략을 지원하여 각 기법이 어떻게 적용될지 정의할 수 있습니다. 주요 전략은 다음과 같습니다.
•
'auto' / 'not majority': 자동으로 다수 클래스를 제외한 모든 클래스를 대상으로 샘플링합니다.
•
'minority': 소수 클래스만을 대상으로 샘플링합니다.
•
'not minority': 소수 클래스를 제외한 모든 클래스를 대상으로 샘플링합니다.
•
'all': 모든 클래스를 대상으로 샘플링합니다.
•
비율 지정: 특정 클래스 비율을 직접 지정할 수 있습니다. 예를 들어, {'class_0': 100, 'class_1': 200}과 같이 설정할 수 있습니다.
from imblearn.over_sampling import SMOTE
smote = SMOTE(sampling_strategy={'class_0': 100, 'class_1': 200}, random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
Python
복사
장점:
•
유연한 샘플링 전략 설정이 가능합니다.
•
다양한 데이터 분포에 맞춰 기법을 적용할 수 있습니다.
단점:
•
적절한 샘플링 비율 설정이 필요합니다.
•
복잡한 설정은 이해와 구현을 어렵게 할 수 있습니다.
7. 종합 비교
아래 표는 imbalanced-learn에서 제공하는 주요 샘플링 기법들의 특징을 비교한 것입니다.
기법 종류 | 기법 이름 | 방법 | 장점 | 단점 |
오버샘플링 | Random Over-Sampler | 소수 클래스의 샘플을 무작위로 복제 | 간단하고 빠름 | 다양성 부족, 과적합 가능성 |
SMOTE | 소수 클래스의 샘플 간 선형 보간으로 합성 샘플 생성 | 데이터 다양성 증가 | 노이즈에 민감, 과적합 위험 | |
Borderline-SMOTE | 경계 샘플 중심 합성 샘플 생성 | 클래스 경계 명확화 | 복잡한 매개변수 설정 필요 | |
SVMSMOTE | SVM 결정 경계 기반 합성 샘플 생성 | 정교한 샘플 생성 | 높은 계산 비용 | |
ADASYN | 어려운 소수 클래스 샘플 중심 합성 샘플 생성 | 어려운 샘플 강화 | 노이즈에 민감, 과적합 위험 | |
KMeansSMOTE | K-평균 군집 기반 합성 샘플 생성 | 군집 구조 반영, 데이터 다양성 유지 | 군집 수 설정 필요, 높은 계산 비용 | |
Safe-Level SMOTE | 데이터 밀도 기반 합성 샘플 생성 | 노이즈 샘플 방지 | 복잡한 매개변수 설정 필요 | |
언더샘플링 | Random Under-Sampler | 다수 클래스의 샘플을 무작위로 제거 | 간단하고 빠름 | 중요한 샘플 제거 위험, 과적합 가능성 |
Tomek Links | 클래스 간 경계 샘플 제거 | 노이즈 제거, 클래스 경계 정리 | 소수 클래스 샘플 제거 위험 | |
Edited Nearest Neighbours (ENN) | K-최근접 이웃 기반 다수 클래스 샘플 제거 | 노이즈 제거, 클래스 경계 정리 | 소수 클래스 샘플 제거 위험, 높은 계산 비용 | |
Neighborhood Cleaning Rule (NCR) | 소수 클래스 주변 다수 클래스 샘플 제거 | 노이즈 제거, 클래스 경계 정리 | 소수 클래스 샘플 제거 위험, 높은 계산 비용 | |
One-Sided Selection (OSS) | 다수 클래스 샘플 제거 및 클래스 경계 정리 | 노이즈 제거, 클래스 경계 정리 | 중요한 샘플 제거 위험, 소수 클래스 샘플 감소 | |
Condensed Nearest Neighbour (CNN) | 다수 클래스 샘플을 줄이고 소수 클래스 유지 | 데이터 크기 감소, 중요한 샘플 유지 | 소수 클래스 샘플 감소, 복잡한 경계에서 비효율적 | |
Repeated Edited Nearest Neighbours (RENN) | ENN을 반복적으로 적용하여 노이즈 제거 | 데이터 품질 향상, 클래스 경계 정리 | 매우 높은 계산 비용, 소수 클래스 샘플 제거 위험 | |
혼합 샘플링 | SMOTE + Random Under-Sampling | SMOTE로 오버샘플링 후 Random Under-Sampling 적용 | 균형 잡힌 데이터셋 생성, 데이터 품질 향상 | 샘플링 비율 설정 필요, 복잡한 구현 |
SMOTEENN | SMOTE + ENN | 소수 클래스 샘플 증가 및 노이즈 제거 | 구현 복잡, 계산 비용 증가 | |
SMOTETomek | SMOTE + Tomek Links | 소수 클래스 샘플 증가 및 노이즈 제거 | 소수 클래스 샘플 제거 위험, 구현 복잡 | |
앙상블 기법 | Balanced Bagging Classifier | 배깅과 언더샘플링 결합 | 높은 예측 성능, 다양한 모델 사용 가능 | 계산 비용 높음, 베이스 모델 선택 중요 |
Balanced Random Forest | 랜덤 포레스트와 언더샘플링 결합 | 강력한 앙상블 모델, 높은 예측 성능 | 계산 비용 높음, 대규모 데이터셋에서 느릴 수 있음 | |
Easy Ensemble | 여러 언더샘플링 서브셋에 대해 독립적인 모델 학습 후 앙상블 | 높은 예측 성능, 소수 클래스 강화 | 매우 높은 계산 비용, 복잡한 구현 | |
RUSBoost | 부스팅과 랜덤 언더샘플링 결합 | 높은 예측 성능, 클래스 불균형에 강함 | 계산 비용 높음, 베이스 모델 선택 중요 | |
기타 유틸리티 기법 | Cluster Centroids | K-평균 군집 중심을 대표 샘플로 사용 | 데이터의 대표성 유지, 계산 비용 낮음 | 군집 수 설정 필요, 중요한 샘플 제거 위험 |
NearMiss | 다수 클래스의 소수 클래스 가까운 샘플만 유지 | 클래스 간 경계 정리, 노이즈 제거 | 중요한 샘플 제거 위험, K 설정 필요 |
8. 실제 적용 예제
아래는 imbalanced-learn에서 제공하는 다양한 샘플링 기법을 실제 데이터에 적용하는 예제입니다. 이 예제에서는 make_classification을 사용하여 불균형한 데이터를 생성하고, 다양한 샘플링 기법을 적용하여 모델의 성능을 비교합니다.
8.1 필요한 라이브러리 설치 및 불러오기
# 필요한 라이브러리 설치
!pip install imbalanced-learn matplotlib seaborn scikit-learn
# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from imblearn.over_sampling import SMOTE, ADASYN
from imblearn.under_sampling import TomekLinks, RandomUnderSampler
from imblearn.combine import SMOTETomek
Python
복사
8.2 예제 데이터 생성 및 시각화
# 랜덤 시드 설정
RANDOM_STATE = 42
# 불균형 데이터 생성
X, y = make_classification(n_samples=1000,
n_features=2,
n_informative=2,
n_redundant=0,
n_clusters_per_class=1,
weights=[0.9, 0.1],
flip_y=0,
random_state=RANDOM_STATE)
# 데이터프레임으로 변환
df = pd.DataFrame(X, columns=['Feature1', 'Feature2'])
df['Target'] = y
# 클래스 분포 확인
print("원본 데이터 클래스 분포:")
print(df['Target'].value_counts())
# 원본 데이터 시각화
plt.figure(figsize=(8,6))
sns.scatterplot(x='Feature1', y='Feature2', hue='Target', data=df, palette=['blue', 'red'], alpha=0.6)
plt.title('원본 데이터 클래스 분포')
plt.show()
Python
복사
출력:
원본 데이터 클래스 분포:
0 900
1 100
Name: Target, dtype: int64
Plain Text
복사
시각화:
<!-- 실제 이미지 링크로 교체 -->
(이미지 링크는 예시이며, 실제 실행 시 그래프가 출력됩니다.)
8.3 샘플링 기법 적용 및 모델 학습
8.3.1 기본 로지스틱 회귀 모델 학습 (샘플링 없이)
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.3,
stratify=y,
random_state=RANDOM_STATE)
# 로지스틱 회귀 모델 학습
clf = LogisticRegression(random_state=RANDOM_STATE, solver='liblinear')
clf.fit(X_train, y_train)
# 예측
y_pred = clf.predict(X_test)
# 성능 평가
print("기본 로지스틱 회귀 모델 성능:")
print(classification_report(y_test, y_pred))
Python
복사
출력 (예시):
기본 로지스틱 회귀 모델 성능:
precision recall f1-score support
0 0.90 1.00 0.95 270
1 0.00 0.00 0.00 30
accuracy 0.90 300
macro avg 0.45 0.50 0.47 300
weighted avg 0.81 0.90 0.85 300
Plain Text
복사
해석:
•
다수 클래스인 클래스 0에 대해 높은 성능을 보이지만, 소수 클래스인 클래스 1에 대해서는 전혀 예측하지 못하고 있습니다.
8.3.2 SMOTE 적용 후 로지스틱 회귀 모델 학습
# SMOTE 적용
smote = SMOTE(random_state=RANDOM_STATE)
X_res, y_res = smote.fit_resample(X_train, y_train)
print("SMOTE 적용 후 클래스 분포:")
print(pd.Series(y_res).value_counts())
# SMOTE 적용된 데이터 시각화
df_res = pd.DataFrame(X_res, columns=['Feature1', 'Feature2'])
df_res['Target'] = y_res
plt.figure(figsize=(8,6))
sns.scatterplot(x='Feature1', y='Feature2', hue='Target', data=df_res, palette=['blue', 'red'], alpha=0.6)
plt.title('SMOTE 적용 후 클래스 분포')
plt.show()
# 로지스틱 회귀 모델 학습
clf_smote = LogisticRegression(random_state=RANDOM_STATE, solver='liblinear')
clf_smote.fit(X_res, y_res)
# 예측
y_pred_smote = clf_smote.predict(X_test)
# 성능 평가
print("SMOTE 적용 후 로지스틱 회귀 모델 성능:")
print(classification_report(y_test, y_pred_smote))
Python
복사
출력 (예시):
SMOTE 적용 후 클래스 분포:
0 630
1 630
dtype: int64
Plain Text
복사
시각화:
<!-- 실제 이미지 링크로 교체 -->
성능 평가:
SMOTE 적용 후 로지스틱 회귀 모델 성능:
precision recall f1-score support
0 0.92 0.98 0.95 270
1 0.60 0.33 0.43 30
accuracy 0.90 300
macro avg 0.76 0.66 0.69 300
weighted avg 0.86 0.90 0.85 300
Plain Text
복사
해석:
•
SMOTE를 적용한 후, 소수 클래스인 클래스 1에 대한 예측이 개선되었습니다. 그러나 여전히 소수 클래스의 예측 성능이 낮습니다.
8.3.3 Tomek Links 적용 후 로지스틱 회귀 모델 학습
# Tomek Links 적용
tl = TomekLinks(sampling_strategy='majority')
X_res_tl, y_res_tl = tl.fit_resample(X_train, y_train)
print("Tomek Links 적용 후 클래스 분포:")
print(pd.Series(y_res_tl).value_counts())
# Tomek Links 적용된 데이터 시각화
df_res_tl = pd.DataFrame(X_res_tl, columns=['Feature1', 'Feature2'])
df_res_tl['Target'] = y_res_tl
plt.figure(figsize=(8,6))
sns.scatterplot(x='Feature1', y='Feature2', hue='Target', data=df_res_tl, palette=['blue', 'red'], alpha=0.6)
plt.title('Tomek Links 적용 후 클래스 분포')
plt.show()
# 로지스틱 회귀 모델 학습
clf_tl = LogisticRegression(random_state=RANDOM_STATE, solver='liblinear')
clf_tl.fit(X_res_tl, y_res_tl)
# 예측
y_pred_tl = clf_tl.predict(X_test)
# 성능 평가
print("Tomek Links 적용 후 로지스틱 회귀 모델 성능:")
print(classification_report(y_test, y_pred_tl))
Python
복사
출력 (예시):
Tomek Links 적용 후 클래스 분포:
0 870
1 100
dtype: int64
Plain Text
복사
시각화:
<!-- 실제 이미지 링크로 교체 -->
성능 평가:
Tomek Links 적용 후 로지스틱 회귀 모델 성능:
precision recall f1-score support
0 0.94 0.96 0.95 261
1 0.46 0.40 0.43 30
accuracy 0.92 291
macro avg 0.70 0.68 0.69 291
weighted avg 0.90 0.92 0.91 291
Plain Text
복사
해석:
•
Tomek Links를 적용한 후, 소수 클래스에 대한 예측이 더욱 개선되었습니다. 그러나 여전히 소수 클래스의 예측 성능은 낮습니다.
8.3.4 SMOTE + Tomek Links 적용 후 로지스틱 회귀 모델 학습
# SMOTE + Tomek Links 적용
smote_tomek = SMOTETomek(random_state=RANDOM_STATE)
X_res_smote_tomek, y_res_smote_tomek = smote_tomek.fit_resample(X_train, y_train)
print("SMOTE + Tomek Links 적용 후 클래스 분포:")
print(pd.Series(y_res_smote_tomek).value_counts())
# SMOTE + Tomek Links 적용된 데이터 시각화
df_res_smote_tomek = pd.DataFrame(X_res_smote_tomek, columns=['Feature1', 'Feature2'])
df_res_smote_tomek['Target'] = y_res_smote_tomek
plt.figure(figsize=(8,6))
sns.scatterplot(x='Feature1', y='Feature2', hue='Target', data=df_res_smote_tomek, palette=['blue', 'red'], alpha=0.6)
plt.title('SMOTE + Tomek Links 적용 후 클래스 분포')
plt.show()
# 로지스틱 회귀 모델 학습
clf_smote_tomek = LogisticRegression(random_state=RANDOM_STATE, solver='liblinear')
clf_smote_tomek.fit(X_res_smote_tomek, y_res_smote_tomek)
# 예측
y_pred_smote_tomek = clf_smote_tomek.predict(X_test)
# 성능 평가
print("SMOTE + Tomek Links 적용 후 로지스틱 회귀 모델 성능:")
print(classification_report(y_test, y_pred_smote_tomek))
Python
복사
출력 (예시):
SMOTE + Tomek Links 적용 후 클래스 분포:
0 870
1 100
dtype: int64
Plain Text
복사
시각화:
<!-- 실제 이미지 링크로 교체 -->
성능 평가:
SMOTE + Tomek Links 적용 후 로지스틱 회귀 모델 성능:
precision recall f1-score support
0 0.94 0.96 0.95 270
1 0.50 0.50 0.50 30
accuracy 0.92 300
macro avg 0.72 0.73 0.73 300
weighted avg 0.91 0.92 0.91 300
Plain Text
복사
해석:
•
SMOTE + Tomek Links를 적용한 모델은 소수 클래스에 대한 예측 성능이 더 향상되었습니다. 이는 SMOTE로 소수 클래스의 샘플을 늘리고, Tomek Links로 노이즈를 제거함으로써 데이터의 균형과 품질을 동시에 개선했기 때문입니다.
9. 결론
imbalanced-learn은 데이터 불균형 문제를 해결하기 위한 다양한 샘플링 기법을 제공합니다. 각 기법은 특정 상황에서 장단점이 있으며, 데이터의 특성과 문제의 요구사항에 따라 적절한 기법을 선택하는 것이 중요합니다. 아래는 주요 포인트입니다.
•
오버샘플링: 소수 클래스의 샘플을 증가시켜 데이터의 균형을 맞추며, SMOTE 계열 기법이 특히 효과적입니다.
•
언더샘플링: 다수 클래스의 샘플을 줄여 균형을 맞추며, Tomek Links나 ENN과 같은 기법은 데이터의 품질을 향상시킵니다.
•
혼합 샘플링: 오버샘플링과 언더샘플링을 결합하여 데이터의 균형과 품질을 동시에 개선합니다.
•
앙상블 기법: 여러 모델을 결합하여 클래스 불균형 문제를 효과적으로 해결합니다.
샘플링 기법을 적용할 때는 다음 사항을 고려해야 합니다.
1.
데이터의 특성: 데이터의 크기, 분포, 노이즈 수준 등을 고려하여 적절한 기법을 선택합니다.
2.
모델의 요구사항: 특정 모델은 특정 샘플링 기법과 더 잘 작동할 수 있습니다.
3.
평가 지표: 클래스 불균형을 고려한 평가 지표(예: F1-score, ROC-AUC)를 사용하여 모델의 성능을 평가합니다.
4.
과적합 방지: 오버샘플링 시 과적합의 위험이 있으므로, 교차 검증을 통해 모델의 일반화 성능을 확인합니다.
최적의 샘플링 기법을 찾기 위해서는 여러 기법을 실험하고, 모델의 성능을 비교 분석하는 과정이 필요합니다.
10. 참고 자료
이상으로 imbalanced-learn에서 제공하는 데이터 불균형 처리 기법들에 대해 자세히 살펴보았습니다. 각 기법의 특징과 장단점을 이해하고, 데이터와 문제의 특성에 맞게 적절한 기법을 선택하여 모델의 성능을 향상시키는 것이 중요합니다.