데이터 전처리 : resample로 소수 클래스 샘플 늘리기
April 6, 2022, 11:58 p.m.
분류 문제에서 클래스 레이블의 불균형은 흔히 있는 일입니다. 클래스가 불균형 하면 모델도 그것에 영향을 받아 다수 클래스 쪽으로 편향이 되어버립니다.
이럴때 널리 사용하는 방법은 샘플링을 통해 훈련 데이터를 인공적으로 생성해서 클래스의 불균형을 줄이는 것입니다.
이번 포스트에서는 사이킷런에서 resampling을 통해 소수의 클래스를 추출해서 클래스 비율을 맞추어 보겠습니다.
사이킷런의 resample은 데이터셋에서 중복을 허용해서 샘플을 추출합니다. 아래와 같이 사용할 수 있는데요.
X, y = resample(샘플링할 X, 샘플링할 y, replace=True, n_samples=100)
샘플링할 X와 y를 얻고 최종 개수를 넣어주면 그 개수가 될때까지 무작위로 샘플링하여 반환합니다.
클래스가 불균형한 데이터를 가져와 두 클래스의 비율을 1:1로 맞추는 예시를 보여드리겠습니다.
import pandas as pd
import numpy as np
df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)
X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
print(X[y==2].shape[0])
print(X[y==3].shape[0])
71
48
예시로 데이터를 가져오고 클래스 2와 클래스 3의 수를 비교해 봤는데 3에 비해 2가 월등히 많은 것을 볼 수 있습니다. resample을 이용해 클래스 개수가 같도록 샘플링 해보겠습니다.
from sklearn.utils import resample
X_sampled, y_sampled = resample(X[y==3], y[y==3], replace=True, n_samples=X[y==2].shape[0])
클래스 레이블이 3인 데이터를 클래스 레이블이 2인 데이터의 수(n_samples)와 맞도록 resampling 하였습니다. 여기서 replace 옵션은 이전의 클래스 레이블이 3인 데이터는 사라지고 샘플링한 데이터로 교체한다는 뜻입니다.
잘 되었는지 확인해 볼까요?
X_sampled.shape[0]
71
샘플링한 데이터는 개수가 71로 클래스 2 데이터의 수와 일치합니다. 이 데이터를 본래 다른 클래스 데이터들과 합치면 샘플링이 완료됩니다.
X_new = np.vstack((X[(y==1) | (y==2)], X_sampled))
y_new = np.hstack((y[(y==1) | (y==2)], y_sampled))