728x90
imblearn라이브러리의 under_sampling 비교
- Import
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_classification
from imblearn.under_sampling import *
- Data 생성
X, y = make_classification(n_samples=5000, n_features=2, n_informative=2,
n_redundant=0, n_repeated=0, n_classes=3,
n_clusters_per_class=1,
weights=[0.2, 0.3, 0.5],
class_sep=0.8, random_state=0)
print(X.shape , y.shape)
(5000, 2) (5000,)
Data Frame으로 변경
df = pd.DataFrame(X, columns = ['f1', 'f2'])
df['target'] = y
print(df.target.value_counts())
df.head()
>>>
2 2497
1 1501
0 1002
f1 f2 target
0 -0.571967 1.247429 0
1 0.772671 0.395459 1
2 0.581133 0.420392 1
3 1.375456 0.974206 2
4 1.018848 1.119809 1
생성한 데이터의 분포
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df, x = 'f1', y = 'f2', hue = 'target')
- RandomUnderSampler
메이저 클래스 샘플을 랜덤으로 제거
- 'majority': resample only the majority class(메이저 클래스 샘플 리샘플링)
- 'not minority': resample all classes but the minority class(마이너 클래스를 제외한 클래스 리샘플링)
- 'not majority': resample all classes but the majority class(메이저 클래스를 제외한 클래스 리샘플링)
- 'all': resample all classes(모든 클래스 리샘플링)
- 'auto': equivalent to 'not minority'(마이너 클래스가 아닌 적절한 클래스 자동으로 선정)
rus = RandomUnderSampler(random_state = 10)
X_rus, y_rus = rus.fit_resample(X, y)
df1 = pd.DataFrame(X_rus, columns = ['rus1', 'rus2'])
df1['y_rus'] = y_rus
print(df1.y_rus.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df1, x = 'rus1', y = 'rus2', hue = 'y_rus')
0 1002
2 1002
1 1002
- ClusterCentroids
KMeans 알고리즘을 이용하여 메이저 클래스의 샘플을 클러스터 중심을 기반으로 제거
cc = ClusterCentroids(random_state = 10)
X_cc, y_cc = cc.fit_resample(X, y)
df2 = pd.DataFrame(X_cc, columns = ['cc1', 'cc2'])
df2['y_cc'] = y_cc
print(df2.y_cc.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df2, x = 'cc1', y = 'cc2', hue = 'y_cc')
0 1002
2 1002
1 1002
- CondensedNearestNeighbour
KNN 알고리즘을 사용하여 메이저 클래스의 샘플들 중 가까운 샘플들을 제거, 이상치에 민감
cnn = CondensedNearestNeighbour(random_state = 10)
X_cnn, y_cnn = cnn.fit_resample(X, y)
df3 = pd.DataFrame(X_cnn, columns = ['cnn1', 'cnn2'])
df3['y_cnn'] = y_cnn
print(df3.y_cnn.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df3, x = 'cnn1', y = 'cnn2', hue = 'y_cnn')
0 1002
2 64
1 63
- EditedNearestNeighbours
Nearest-neighbors 알고리즘을 이용하여 근접한 샘플들과 유사하지 않은 샘플 제거
enn = EditedNearestNeighbours()
X_enn, y_enn = enn.fit_resample(X, y)
df4 = pd.DataFrame(X_enn, columns = ['enn1', 'enn2'])
df4['y_enn'] = y_enn
print(df4.y_enn.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df4, x = 'enn1', y = 'enn2', hue = 'y_enn')
2 2389
1 1402
0 1002
- RepeatedEditedNearestNeighbours
ENN(EditedNearestNeighbours)알고리즘 여러 번 반복해서 진행하여 더 많은 샘플 제거
renn = RepeatedEditedNearestNeighbours()
X_renn, y_renn = renn.fit_resample(X, y)
df5 = pd.DataFrame(X_renn, columns = ['renn1', 'renn2'])
df5['y_renn'] = y_renn
print(df5.y_renn.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df5, x = 'renn1', y = 'renn2', hue = 'y_renn')
2 2382
1 1399
0 1002
- AllKNN
RENN과 유사하게 ENN을 반복하여 진행하지만, 고려해야할 근접 샘플의 수를 증가시키면서 반복
allknn = AllKNN()
X_allknn, y_allknn = allknn.fit_resample(X, y)
df6 = pd.DataFrame(X_allknn, columns = ['allknn1', 'allknn2'])
df6['y_allknn'] = y_allknn
print(df6.y_allknn.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df6, x = 'allknn1', y = 'allknn2', hue = 'y_allknn')
2 2422
1 1429
0 1002
- InstanceHardnessThreshold
classification 모델로 훈련하여 확률이 낮은 샘플을 제거하는 방법
sklearn 라이브러리의 classification model을 활용하여 predict probability를 측정한 후 낮은 확률의 샘플을 제거
iht = InstanceHardnessThreshold(random_state = 10)
X_iht, y_iht = iht.fit_resample(X, y)
df7 = pd.DataFrame(X_iht, columns = ['iht1', 'iht2'])
df7['y_iht'] = y_iht
print(df7.y_iht.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df7, x = 'iht1', y = 'iht2', hue = 'y_iht')
2 1580
1 1116
0 1002
- NearMiss
소수 클래스를 기준으로 메이저 클래스의 거리를 측정하여 제거할 샘플을 선택
nm = NearMiss()
X_nm, y_nm = nm.fit_resample(X, y)
df8 = pd.DataFrame(X_nm, columns = ['nm1', 'nm2'])
df8['y_nm'] = y_nm
print(df8.y_nm.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df8, x = 'nm1', y = 'nm2', hue = 'y_nm')
0 1002
2 1002
1 1002
- NeighbourhoodCleaningRule
ENN, KNN 알고리즘을 사용하여 이상치 데이터 제거
ncr = NeighbourhoodCleaningRule()
X_ncr, y_ncr = ncr.fit_resample(X, y)
df9 = pd.DataFrame(X_ncr, columns = ['ncr1', 'ncr2'])
df9['y_ncr'] = y_ncr
print(df9.y_ncr.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df9, x = 'ncr1', y = 'ncr2', hue = 'y_ncr')
2 2469
1 1473
0 1002
- OneSidedSelection
TomekLinks를 사용하여 이상치가 많은 샘플 제거
oss = OneSidedSelection(random_state = 10)
X_oss, y_oss = oss.fit_resample(X, y)
df10 = pd.DataFrame(X_oss, columns = ['oss1', 'oss2'])
df10['y_oss'] = y_oss
print(df10.y_oss.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df10, x = 'oss1', y = 'oss2', hue = 'y_oss')
2 1839
1 1386
0 1002
- TomekLinks
- 두 범주에서 하나씩 추출한 포인트를 각각 와 라 할 때, 또는 가 되는 관측치 가 없는 경우, 두 샘플 와 가 Tomek Link를 형성한다고 한다.
- Tomek link를 형성하는 두 샘플 중 하나는 노이즈이거나 둘 다 경계선 근처에 있다.
- Tomek link를 형성한 샘플 중 다수 범주에 속한 샘플을 제거한다.
- [그림 4]는 Tomek link의 예제를 보여준다. 좌측과 같은 데이터 세트에 대하여 Tomek link를 형성하면 가운데 그림과 같이 된다. Tomek link를 형성한 파란색 샘플들을 제외하면 우측 그림과 같이 되는데 샘플을 제외하기 이전보다 두 범주의 구분이 보다 명확히 됨을 알 수 있다. 따라서 두 범주 간의 분류 경계면을 찾는데 도움이 된다.
- Tomek link는 다수 범주의 데이터의 중심 분포는 거의 유지하면서 분류 경계를 조정하는 효과를 얻기 때문에 random undersampling에 비해 정보의 유실을 크게 줄일 수 있지만, 제거되는 샘플이 한정적이기 때문에 큰 언더 샘플링의 효과를 얻을 수는 없다.
tl = TomekLinks()
X_tl, y_tl = tl.fit_resample(X, y)
df11 = pd.DataFrame(X_tl, columns = ['tl1', 'tl2'])
df11['y_tl'] = y_tl
print(df11.y_tl.value_counts())
plt.figure(figsize = (12, 8))
sns.scatterplot(data = df11, x = 'tl1', y = 'tl2', hue = 'y_tl')
2 2470
1 1471
0 1002
- notebook ipynb file: https://github.com/heejvely/python-machine_learning-practice/blob/main/undersampling.ipynb
728x90
'Machine Learning' 카테고리의 다른 글
[Machine Learning] SMOTETomek (0) | 2022.11.23 |
---|---|
[Machine Learning] imblearn 라이브러리 oversampling (0) | 2022.11.18 |
[Machine Learning]PCA로 cluster 그래프 그리기 (0) | 2022.11.11 |
[Machin Learning]변수 중요도를 기준으로 Kfold 교차검증 진행하기 (0) | 2022.11.01 |
[Machine Learning]변수 중요도 출력(feature importance) (0) | 2022.11.01 |