Gaegul's devlog

[데이터 분석] 라벨 불균형 처리 본문

Data Analysis

[데이터 분석] 라벨 불균형 처리

부지런깨꾹이 2022. 10. 28. 02:12
728x90
반응형

라벨의 불균형을 확인하고 불균형을 처리하는 방법은 다음과 같습니다!

print(train['Class'].value_counts())
print(train['Class'].value_counts() / train['Class'].value_counts().sum() * 100)

 

방법은 크게 두가지가 있는데요! 샘플링 방법과 StratifiedKFold를 통해 라벨을 균일하게 한 뒤 학습을 시키는 방법입니다. 

1. Sampling 방법

그중에 Oversampling 방법인 SMOTE 와 hybrid 방법인 SMOTE+ENN 방법이 있습니다. 저는 SMOTE+ENN 방법을 택하였습니다.

  • 선택 이유: 데이터 클래스 비율이 너무 차이가 나면(highly-imbalanced data) 단순히 우세한 클래스를 택하는 모형의 정확도가 높아지므로 모형의 성능 판별이 어려워진다. 이를 위해 ‘환자‘ 데이터는 늘리고, 클래스 주변의 ‘환자 아님’ 데이터는 모두 삭제하여 분류의 기준선을 명확하게 해주는 SMOTE (Synthetic Minority Over-sampling Technique) + ENN (Edited Nearest Neighbours) 방법을 선택
# Oversampling
from imblearn.over_sampling import SMOTE
from imblearn.combine import SMOTEENN

# smote = SMOTE(random_state=777)
smoteenn = SMOTEENN(random_state=777)
# X_train_over, y_train_over = smote.fit_resample(X_train, y_train)
X_train_hybrid, y_train_hybrid = smoteenn.fit_resample(X_train, y_train)

print('Original : ', X_train.shape, y_train.shape) 
# print('SMOTE : ', X_train_over.shape, y_train_over.shape)
print('SMOTEENN : ', X_train_hybrid.shape, y_train_hybrid.shape)

 

2. Stratified Kfold 방법

# xgboost 모델
from xgboost.sklearn import XGBClassifier

def train_xgb_model(x_data, y_data, k=5):
    models = []
    sk_fold = StratifiedKFold(n_splits=k, random_state=777, shuffle=True)
    loss = 0
    accuracy = 0
    precision = 0
    recall = 0
    f1 = 0
    roc_auc_score = 0 #시험 평가 지표
    metric_list = []

    for train_idx, val_idx in sk_fold.split(x_data, y_data):
        x_train, y_train = x_data.iloc[train_idx], y_data.iloc[train_idx]
        x_val, y_val = x_data.iloc[val_idx], y_data.iloc[val_idx]        
        
        params = {            
            'n_estimators'  : 1000, 
            'learning_rate' : 0.05,             
            'objective'     :'binary:logistic',
            'reg_alpha' : 0.,           # L1 regularization
            'reg_lambda': 0.1,           # L2 regularization
            'colsample_bytree': 0.6,
            'bagging_fraction': 0.5,
            'bagging_freq': 5,
            'random_state': 777,    
                          
        }
        
        model = XGBClassifier(**params)
        model.fit(x_train, y_train, eval_set=[(x_val, y_val)], verbose=100, early_stopping_rounds=15)
        pred_prob = model.predict_proba(x_val)[:, 1]
        pred = model.predict(x_val)

        #binary values로 
        # for i in range(len(pred)):
        #     if pred[i]>=.5:  
        #         pred[i]=1
        #     else:  
        #         pred[i]=0  

        loss += log_loss(y_val, pred_prob)/k
        roc_auc_score += roc_auc_score(y_val, pred_prob)/k

        # 추가 metric
        accuracy += accuracy_score(y_val, pred)/k
        precision += precision_score(y_val, pred)/k 
        recall += recall_score(y_val, pred)/k
        f1 += f1_score(y_val, pred)/k

        models.append(model)
    metric_list.append({'accuracy:{0:.4f}, precision:{1:.4f}, recall:{2:.4f}, f1_score:{3:.4f}'.format(accuracy, precision, recall, f1)})
    return (models, model, metric_list, pred)
xgb_models = {}
xgb_eval = {}

xgb_models, xgb_model, xgb_eval, pred = train_xgb_model(X_train_hybrid, y_train_hybrid)
print(xgb_eval)
728x90
반응형
Comments