-> 이를 해결하기 위해서 resampling을 통해 데이터의 불균형을 해결
🔴 출처
김성범[ 고려대 / 산업경영공학부 ] 교수님의 youtube 채널에서 보고 공부한 내용을 정리하였습니다.
채널명 : 김성범[ 교수 / 산업경영공학부 ]
채널주소 : https://www.youtube.com/@user-yu5qs4ct2b
✅ 영상 주소
[핵심 머신러닝] 불균형 데이터 분석을 위한 샘플링 기법
https://www.youtube.com/watch?v=Vhwz228VrIk&list=PLpIPLT0Pf7IoTxTCi2MEQ94MZnHaxrP0j&index=18
1) random oversampling - 적은 클래스의 데이터를 임의로 복제
-> 적은 클래스 분류시 overfitting 발생
2) SMOTE(Synthetic Minority Over-sampling Technique)
3) Borderline SMOTE
1) random undersampling - 많은 클래스의 데이터를 임의로 샘플링해서, 적은 클래스와 유사한 비율
-> 데이터 유실, 샘플로 인해 잘못된 bias 발생 가능성
2) tomek links -> 두 범주 사이를 탐지하고, 정리하여 부정확한 분류경계선 방지
3) CNN(Condensed Nearest neighbor)
4) One-Sided Selection (OSS)
✅ dataset - abalone
UC Irvine Machine Learning Repository
https://archive.ics.uci.edu/dataset/1/abalone
# data
raw_file = pd.read_table('./data/abalone.txt', sep=',', header=None)
# feature_names
abal_col = []
with open('./data/abalone_attributes.txt') as f:
for line in f:
abal_col.append(line.strip())
raw_file.columns = abal_col
abal = raw_file
X = abal.iloc[:, 1:]
y = abal['Sex']
np.unique(y, return_counts=True)
(array(['F', 'I', 'M'], dtype=object), array([1307, 1342, 1528], dtype=int64))
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler()
oversampled_data, oversampled_label = ros.fit_resample(X, y)
oversampled_data = pd.DataFrame(oversampled_data, columns=X.columns)
print(f'원본 데이터의 클래스 비율 {pd.get_dummies(y).sum())}')
print(f'oversampling의 클래스 비율 {pd.get_dummies(oversampled_label).sum())}')
원본 데이터의 클래스 비율
F 1307
I 1342
M 1528
dtype: int64
oversampling 샘플링 결과
F 1528
I 1528
M 1528
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler()
undersampled_data, undersampled_label = rus.fit_resample(X, y)
undersampled_data = pd.DataFrame(undersampled_data, columns=X.columns)
print(f'원본 데이터의 클래스 비율 {pd.get_dummies(y).sum())}')
print(f'undersampling의 클래스 비율 {pd.get_dummies(undersampled_label).sum())}')
Random Under 샘플링 결과
F 1307
I 1307
M 1307
✅
abalone 데이터는 class 분류가 균등하게 되어있다.
SOMTE를 연습하기 위해서 abalone dataset을 기반으로 임의의 데이터를 생성
from sklearn.datasets import make_classification
# 1000개의 데이터 샘플
# 5 : 15 : 80 비율
# 2차원 데이터
data, label = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=3,
n_clusters_per_class=1,
weights=[0.05, 0.15, 0.8],
class_sep=0.8, random_state=2019)
import matplotlib.pyplot as plt
fig = plt.Figure(figsize=(12,6))
plt.scatter(data[:, 0], data[:, 1], c=label, linewidth=1, edgecolor='black')
plt.show()
from imblearn.over_sampling import SMOTE
## k_neighbors - 측정 k의 갯수
smote = SMOTE(k_neighbors=5)
smoted_data, smoted_label = smote.fit_resample(data, label)
print(f'원본 데이터의 클래스 비율 {pd.get_dummies(label).sum())}')
print(f'undersampling의 클래스 비율 {pd.get_dummies(smote_label).sum())}')
원본 데이터의 클래스 비율
0 53
1 154
2 793
dtype: int64
SMOTE 결과
0 793
1 793
2 793
dtype: int64
✅ 가장 많은 클래스의 수를 기준으로 oversampling
fig = plt.Figure(figsize=(12,6))
plt.scatter(smoted_data[:, 0], smoted_data[:, 1], c=smoted_label, linewidth=1, edgecolor='black')
plt.show()
✅ KNN 방식으로 구하고, 그 선 사이위에서 샘플을 추가하는 경향
✅ 이에 따라 추가된 샘플이 선형을 나타내기도 한다.