[Sampling] Mixed sampling
이번 시간에는 Sampling의 마지막 포스트인 Mixed Sampling에 대해 알아보겠습니다. 즉, 앞서 설명드린 UnderSampling과 OverSampling을 모두 이용하는 Sampling 기법입니다. 간단히 2가지 정도를 소개하고 Sampling Chapter를 마무리 짓도록 하겠습니다.
개요
OverSampling 기법 중 SMOTE는 소수 집단 데이터를 늘리는 Sampling 기법으로 일반적인 UnderSampling 기법보다 통계적으로 유의하여 일반적으로 많이 사용되는 기법입니다. 그러나 해당 데이터의 분포에 대한 지식은 가지고 있지 않습니다. 따라서, 데이터의 경향성과 동떨어진 일명 Noise라고 불리는 이상치 데이터가 많은 Sample이 만들어 질 수 있습니다. 이런 데이터들이 많아지면 과대적합 문제가 발생할 수 있기 때문에 Noise 데이터를 청소하는 작업을 해준다면 더 좋은 Sample을 만들 수 있습니다. 즉, UnderSampling을 통해 불필요한 데이터를 제거한다면 더 좋은 Sample을 만들 수 있을 것입니다. 이렇듯, OverSampling과 UnderSampling을 모두 이용하여 과대표집된 데이터 중 Noise 데이터를 제거하는 Sampling 기법을 Mixed Sampling(혼합 샘플링) 기법이라고 합니다. Mixed Sampling은 다양한 방법을 이용하여 Customized 할 수 있으나, 이번 포스팅에서는 imblearn 패키지 내의 있는 SMOTETomek과 SMOTEENN에 대해 소개드리도록 하겠습니다.
실습
0. DataSet 소개
데이터는 지난 포스트인 OverSampling, UnderSampling에서 사용한 make_classification에서 가져왔습니다. 10개의 특성변수 중 0번째와 1번째 특성변수를 그래프로 나타내보았습니다. 이 때, class 데이터 당 weights를 [0.1, 0.2, 0.7]로 조금 조정하여 데이터를 만들어 보았습니다.
- 데이터 특징
- Shape : $(2000, 10)$
- class : {$0$(파랑 점)$: 203, ~~$$1$(흰 점)$: 401, ~~$$2$(빨강 점)$: 1396$}
from collections import Counter
from sklearn.datasets import make_classification # dataset -> sklearn에 내장되어 있는 데이터 셋
import matplotlib.pyplot as plt
X, y = make_classification(n_classes = 3, weights = [0.1, 0.2, 0.7], n_features = 10,
n_clusters_per_class = 1, n_samples = 2000, random_state = 10) # 특성변수 10개, 클래스 3개
yy = Counter(y)
tmp = sorted(yy.items(), key = lambda k : k[0])
print('Original dataset shape %s' % tmp)
plt.scatter(X[:, 0], X[:, 1], marker = 'o', c = y,
edgecolor = 'k', cmap = plt.cm.coolwarm)
plt.title("Original Data")
plt.show()
--------------------------------------------------------------------------------------------------------------------------------
Original dataset shape [(0, 203), (1, 401), (2, 1396)]
1. SMOTETomek
먼저 SMOTE + Tomik Links 혼합 기법인 SMOTETomek 입니다. SMOTE를 통해 데이터를 OverSampling한 후, Tomek links인 데이터 쌍을 모두 제거하여 UnderSampling 하는 기법입니다. Tomek Links 쌍의 데이터 중 다수 클래스 데이터만 삭제했던 기존의 Tomek Links 기법과 달리 한 쌍 모두 제거한다는 점이 특징입니다. 실제 데이터에 바로 적용해서 설명드리겠습니다.
우선 데이터가 생성된 것을 보면 빨강 점인 다수 클래스 데이터의 수는 1,393개로 3개 줄었고, 소수 클래스였던 파랑 점과 흰 점 데이터는 각각 1,393개, 1,396개로 과대표집된 것을 확인할 수 있습니다. 세 클래스가 모두 1,396개로 맞춰지지 않은 것으로 볼 때, 빨강 점과 파랑 점 사이에 Tomek Links가 세 쌍이 만들어져 제거된 것으로 추측해 볼 수 있습니다.
from imblearn.combine import SMOTETomek
X_smto, y_smto = SMOTETomek(random_state = 2024).fit_resample(X, y)
yy = Counter(y_smto)
tmp = sorted(yy.items(), key = lambda k : k[0])
print('Resampled dataset shape %s' % tmp)
plt.scatter(X_smto[:, 0], X_smto[:, 1], marker = 'o', c = y_smto,
edgecolor = 'k', cmap = plt.cm.coolwarm)
plt.show()
--------------------------------------------------------------------------------------------------------------------------------
Resampled dataset shape [(0, 1393), (1, 1396), (2, 1393)]
2. SMOTEENN
SMOTEENN는 SMOTE + ENN의 혼합 기법이며 SMOTE를 통해 데이터를 OverSampling한 후, ENN UnderSampling 하는 기법입니다. 일반적으로 SMOTETomek 기법보다 더 많은 Noise 데이터를 제거하는 것으로 알려져 있습니다.
아래 예시를 보면 SMOTETomik와 달리 다수 클래스 데이터의 수가 1,396개에서 1,223개로 크게 감소한 것을 확인할 수 있습니다.
from imblearn.combine import SMOTEENN
X_smenn, y_smenn = SMOTEENN(random_state = 2024).fit_resample(X, y)
yy = Counter(y_smenn)
tmp = sorted(yy.items(), key = lambda k : k[0])
print('Resampled dataset shape %s' % tmp)
plt.scatter(X_smenn[:, 0], X_smenn[:, 1], marker = 'o', c = y_smenn,
edgecolor = 'k', cmap = plt.cm.coolwarm)
plt.show()
--------------------------------------------------------------------------------------------------------------------------------
Resampled dataset shape [(0, 1346), (1, 1340), (2, 1223)]
실제로 위 두 개의 Mixed Sampling 기법들은 일반적인 SMOTE 기법보다 더 좋은 성능의 Model을 만들 수 있는 Sample을 제공해 주는 것으로 알려져 있습니다. 다음 시간부터는 또 다른 주제로 포스팅 해보도록 하겠습니다.
댓글남기기