1. SMOTE란
SMOTE의 동작 방식은 데이터의 개수가 적은 클래스의 표본을 가져온 뒤 임의의 값을 추가하여 새로운 샘플을 만들어 데이터에 추가하는 오버샘플링 방식이다.
2. 파이썬 예제 코드
데이터는 캐글의 Credit Card Fraud Detection의 creditcard.csv 을 활용했다.
import pandas as pd df = pd.read_csv('/Users/dreamus/Downloads/creditcard.csv')
df.Class.value_counts(normalize=True).plot(kind='bar')
print(df.Class.value_counts(normalize=True)*100)
보다시피 불균형하게 데이터가 분포되어 있는 것을 확인할 수 있고, 우선 현재 상태에서 아무 전처리 없이 모델링을 진행해보고자 한다.
from sklearn.model_selection import train_test_splitX = df.iloc[:,:-1]
y = df.iloc[:,-1]X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.25,random_state=10)#모델링
def modeling(model,x_train,x_test,y_train,y_test):
model.fit(x_train,y_train)
pred = model.predict(x_test)
metrics(y_test,pred)#평가 지표
def metrics(y_test,pred):
accuracy = accuracy_score(y_test,pred)
precision = precision_score(y_test,pred)
recall = recall_score(y_test,pred)
f1 = f1_score(y_test,pred)
roc_score = roc_auc_score(y_test,pred,average='macro')
print('정확도 : {0:.2f}, 정밀도 : {1:.2f}, 재현율 : {2:.2f}'.format(accuracy,precision,recall))
print('f1-score : {0:.2f}, auc : {1:.2f}'.format(f1,roc_score,recall))
(1) 전처리 전 데이터로 모델 성능 평가
- 로지스틱
from sklearn.linear_model import LogisticRegressionlr = LogisticRegression()
modeling(lr,X_train,X_test,y_train,y_test)
- lightgbm
from lightgbm import LGBMClassifierlgb = LGBMClassifier(n_estimators=1000,num_leaves=64,n_jobs=-1,boost_from_average=False)
modeling(lgb,X_train,X_test,y_train,y_test)
SMOTE를 적용시키기 전, 모델링을 한 결과 다음과 같이 모델의 성능을 볼 수 있다.
기본적인 데이터로 모델 성능을 확인했으니 이제 데이터 정규화와 outlier를 제거하는 과정(본문 생략)을 거친 후 모델의 성능을 확인해보자.
(2) 전처리 후 모델 성능 평가
- 로지스틱
lr = LogisticRegression()
modeling(lr,X_train,X_test,y_train,y_test)
- lightgbm
-> 위에 제시한 파라미터와 다르게 is_unblance 파라미터를 True로 설정하여 진행했다.
lgb = LGBMClassifier(n_estimators=1000,num_leaves=64,n_jobs=-1,
is_unbalance = True,boost_from_average=False)
modeling(lgb,X_train,X_test,y_train,y_test)
전처리(정규화,아웃라이어 제거)만 해도 굉장히 성능이 좋아지는 것을 확인할 수 있다. 그럼 이 상태에서 imbalanced data의 문제를 해결할 수 있는 SMOTE 기법을 적용시켜보도록 한다.
(3) SMOTE 적용
from imblearn.over_sampling import SMOTEsmote = SMOTE(random_state=0)
X_train_over,y_train_over = smote.fit_sample(X_train,y_train)print('SMOTE 적용 전 학습용 피처/레이블 데이터 세트: ', X_train.shape, y_train.shape)
print('SMOTE 적용 후 학습용 피처/레이블 데이터 세트: ', X_train_over.shape, y_train_over.shape)
print('SMOTE 적용 후 레이블 값 분포: \n', pd.Series(y_train_over).value_counts())
- 로지스틱
lr = LogisticRegression()
modeling(lr,X_train_over,X_test,y_train_over,y_test)
- lightgbm
lgb = LGBMClassifier(n_estimators=1000,num_leaves=64,n_jobs=-1,boost_from_average=False)
modeling(lgb,X_train_over,X_test,y_train_over,y_test)
결론
로지스틱 회귀 모델 같은 경우는 전처리 후에 비하여 정확도,정밀도,f1-score가 급감한 반면에,
lightgbm같은 경우는 정밀도가 살짝 감소한 것을 제외하면 재현율과 AUC가 증가하는 것을 볼 수 있다.
물론 lightgbm 같은 경우는 “scale_pos_weight”과 “is_unbalance”의 파라미터 튜닝을 통해 어느 정도 성능을 높일 수 있으나 해당 데이터 셋으로 테스트 해본 결과 SMOTE를 통해 오버 샘플링한 모델의 성능이 가장 좋은 것을 확인할 수 있었다.