샘플링
데이터 증강
택일해야 한다면 오버샘플링(Oversampling) 을 선택한다.
-
선택 이유: 정보 손실 방지
-
언더샘플링의 치명적 단점: 언더샘플링은 다수 클래스의 데이터를 인위적으로 제거하므로, 모델 학습에 유의미한 정보(분산, 데이터 고유의 패턴 등)가 영구적으로 유실될 위험이 매우 크다. 이는 전체적인 모집단 분포를 왜곡하여 모델의 일반화(Generalization) 성능 저하로 이어진다.
-
오버샘플링의 강점: 오버샘플링은 기존 다수 클래스 데이터의 정보 손실을 발생시키지 않는다. 특히 SMOTE(Synthetic Minority Over-sampling Technique)와 같은 합성 기법을 사용하면, 소수 클래스의 특성을 반영한 새로운 데이터를 생성하여 분류기가 결정 경계(Decision Boundary)를 더 명확하고 넓게 학습하도록 돕는다.
실무적 한계 및 보완책
-
과적합(Overfitting) 리스크: 단순히 소수 클래스의 데이터를 복제하는 방식(Random Over-Sampling)은 과적합을 유발한다. 따라서 K-최근접 이웃(KNN) 기반으로 가상의 데이터를 생성하는 SMOTE, ADASYN 등의 알고리즘 사용이 필수적이다.
-
컴퓨팅 자원 제약: 원본 데이터셋이 수백만 건 이상으로 거대할 경우, 오버샘플링은 메모리 초과(Out Of Memory)나 학습 시간의 기하급수적인 증가를 초래할 수 있다. 오직 이러한 물리적 한계가 명확할 때만 언더샘플링을 차선책으로 고려한다.
오버샘플링
| 구분 (기법) | 작동 원리 | 장점 | 단점 |
|---|---|---|---|
| SMOTE | 소수 클래스 데이터와 그 k-최근접 이웃(k-NN) 사이에 가상의 선을 긋고, 그 선상에 임의의 비율을 곱해 새로운 데이터를 선형 보간(Interpolation) 방식으로 생성 | 랜덤 오버샘플링(단순 복제)에 비해 과적합 위험이 적고, 데이터의 정보량과 다양성을 효과적으로 확장 | 전체적인 데이터 분포 / 다수 클래스와의 겹침(Overlap)을 고려하지 않고 맹목적으로 생성하므로, 분류 경계면 근처에서 노이즈(Noise) 증가 위험 |
| ADASYN | 데이터의 ‘학습 난이도’를 기준으로 삼아 샘플링 가중치를 다르게 부여 (다수 클래스 데이터가 많이 분포하여 모델이 분류하기 어려운 소수 클래스 샘플 주변에 더 많은 합성 데이터를 집중적으로 생성, SMOTE와 어느정도 유사) | 분류 경계면을 학습하기 어려운 방향(Minority class 쪽)으로 밀어내어 복잡한 분포에서 모델 일반화 성능 향상 | 다수 클래스 영역 깊숙이 위치한 소수 클래스 이상치(Outlier)를 어려운 샘플로 착각, 그 주변에 과도한 노이즈 생성 우려 |
| SMOTENC | 범주형/연속형 혼합 데이터 전용 (연속형은 SMOTE처럼 보간, 범주형은 최근접 이웃들의 최빈값 채택하여 합성), 거리 계산 시 범주형 변수의 차이에 페널티를 부여한다. | 범주형 변수의 원-핫 인코딩 시 발생하는 희소성(Sparsity) 문제나 연속형 공간으로의 억지스러운 매핑 없이, 원형 그대로 자연스러운 오버샘플링이 가능 | 이웃을 찾기 위한 거리 계산(VDM 등) 복잡도로 인한, 기본 SMOTE에 비해 연산 비용 및 시간 급증 |
| SVMSMOTE | 저차원 분류기인 SVM(Support Vector Machine)을 선행 학습시켜 지지 벡터(Support Vector)를 추출, 이후 다수 클래스와 맞닿아 있는 경계면의 지지 벡터(소수 클래스)를 중심으로만 합성 샘플 생성 | 불필요 영역 (노이즈 영역이나 너무 안전한 (안쪽))에서의 무의미한 샘플 생성을 억제, 실제 분류를 결정짓는 결정 경계(Decision Boundary) 학습 정교화 | 오버샘플링 수행 전에 매번 SVM 모델을 학습시켜야 하므로 대용량 데이터셋 적용 시 연산 병목 현상이 발생 |
- SMOTE (Synthetic Minority Over-sampling Technique)
ValueError: could not convert string to float: '2015-02-02 14:19:59' 에러가 발생하는 이유는 SMOTE 알고리즘이 내부적으로 수학적 연산(거리 계산 등)을 수행하기 때문이다.
SMOTE는 새로운 데이터를 생성하기 위해 데이터 간의 거리를 계산하는데, 날짜/시간(Datetime) 데이터가 문자열(String) 형태로 남아 있으면 계산이 불가능하다.
이 문제를 해결하려면 날짜 컬럼을 수치형으로 변환하거나, 학습 데이터에서 제외해야 한다.
날짜 정보가 중요하다면, 이를 정수 또는 실수 형태인 타임스탬프로 변환하여 계산 가능하게 만들어야 한다.
단순 날짜 문자열보다는 시간대, 요일 등 수치화된 정보를 추출하는 것이 성능에 유리하다.
- ADASYN (Adaptive Synthetic Sampling)
- SMOTENC (SMOTE for Nominal Continuous)
- SVMSMOTE (SMOTE variant by Support Vectors)
import os; os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
import pandas as pd
from imblearn.over_sampling import SMOTE
import statsmodels.api as sm
# fair 데이터셋 로드 (Pandas DataFrame 형태로 반환)
df = sm.datasets.fair.load_pandas().data
# df.info()
y = df['occupation_husb']; X = df.drop('occupation_husb', axis=1)
display(y.value_counts())
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
# print(pd.DataFrame(X_resampled, columns=X.columns)['occupation_husb'].value_counts())
display(pd.Series(y_resampled).value_counts())
4.0 2030
5.0 1779
2.0 1308
6.0 530
3.0 490
1.0 229
Name: occupation_husb, dtype: int64
1.0 2030
6.0 2030
2.0 2030
3.0 2030
4.0 2030
5.0 2030
dtype: int64
언더샘플링
| 기법명 | 핵심 원리 | 주요 장점 | 주요 단점 |
|---|---|---|---|
| RandomUnderSampler | 다수 클래스 데이터 무작위 제거 | 연산 속도 최상, 베이스라인 시점에 활용도 높음 | 유의미한 정보 패턴 및 분포 유실 위험 |
| TomekLinks | 서로 다른 클래스의 인접 데이터 쌍 (Tomek Link) 탐색 후, 그 중 다수 클래스 제거 | 클래스 간 겹치거나 혼재된 영역을 정리하여 결정 경계(Decision Boundary) 명확화 | 경계면 근처의 데이터만 부분적으로 제거하므로 클래스 간 비율을 딱 맞추기 어려움, 거리 계산으로 인한 연산 비용 |
| NearMiss | KNN 기반 거리 계산을 통해 다수 클래스 데이터 선택적 추출, 소수 클래스 데이터와의 거리 계산 후 기준에 맞는 다수 클래스 샘플만 남김 | 무작위 샘플링의 정보 유실 문제를 보완하여, 분류 경계 형성에 핵심적인 다수 클래스 데이터를 체계적으로 보존 | 소수 클래스의 이상치 및 노이즈에 민감, 전체 데이터 간 거리 계산이 필요해 연산 속도가 매우 저하 |
import os; os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
import imblearn
# dir(imblearn.under_sampling)
rus = imblearn.under_sampling.RandomUnderSampler()
X_resampled, y_resampled = rus.fit_resample(X, y)