레이블이 불균형한 분포를 가진 데이터 세트를 학습시킬 때 예측 성능의 문제가 발생할 수 있음

이상 레이블을 가지는 데이터 건수는 매우 적기 때문에 제대로 다양한 유형을 학습하지 못하기 때문에 일방적으로 정상 레이블에 치우친 학습을 수행해 제대로 된 이상 데이터 검출이 어려워진다

 

오버샘플링과 언더샘플링 중에서는 오버 샘플링 방식이 예측 성능상 조금 유리한 경우가 많아 상대적으로 더 많이 사용됨

 

- 언더 샘플링 : 많은 데이터 세트를 적은 데이터 세트를 적은 데이터 세트 수준으로 감소시키는 방식

- 오버 샘플링 : 이상 데이터와 같이 적은 데이터 세트를 증식하여 학습을 위한 충분한 데이터를 확보하는 방법

  동일한 데이터를 단순히 증식하는 방법은 과적합이 되기 때문에 원본 데이터의 피처 값들을 약간만 변경하여 증식

  대표적인 방법 : SMOTE(Synthetic Minority Over-sampling Technique)

  SMOTE는 적은 데이터 세트에 있는 개별 데이터들의 k 최근접 이웃을 찾아서 이 데이터와 k개 이웃들의 차이를 일정 값으로 만들어서 기존 데이터와 약간 차이가 나는 새로운 데이터들을 생성하는 방식

 

import pandas as pd
import nupy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline

card_df = pd.read_csv('')
card_df.head(3)

 

from sklearn.model_selection import train_test_split

def get_processed_df(df=None):
    df_copy = df.copy()
    df_copy.drop('Time', axis=1, inplace=True)
    return df_copy
#사전 데이터 가공 후 학습과 테스트 세트를 반환하는 함수
def get_train_test_dataset(df=None):
    df_copy = get_preprocessed_df(df)
    X_features = df_copy.iloc[:,:-1]
    y_target = df_copy.iloc[:,-1]
    X_train, X_test, y_train, y_test =
    train_test_split(X_features, y_target, test_size=0.3, random_state=0, stratify=y_traget)
    return X_train, X_test, y_train, y_test
    
X_train, X_test, y_train, y_test = get_train_test_dataset(card_df)

 

로지스틱 회귀 이용해 신용 카드 사기 여부 예측

from sklearn.linear_model import LogisticRegression

lr_clf = LogisticRegression(max_iter=1000)
lr_clf.fit(X_train, y_train)
lr_pred = lr_clf.predict(X_test)
lr_pred_proba = lr_clf.predict_proba(X_test)[:,1]

 

LightGBM 이용한 모델

*LightGBM이 버전업되면서 boost_from_average 파라미터의 디폴트 값이 False에서 True로 변경

레이블 값이 불균형한 분포를 이루는 경우 boost_from_average=True 설정은 재현률 및 ROC-AUC 성능을 매우 크게 저하시킨다

from lightgbm import LGBMClassifier

lgbm_clf = LGBMClassifier(n_estimator=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)
get_model_train_eval(lgbm_clf, ftr_train=X_train, ftr_test=X_test, tgt_train=y_train, tgt_test=y_test)

 

데이터의 분포도가 심하게 왜곡되어 있을 경우 적용하는 중요 기법

: 로그변환(log1p()), 정규분포 형태로 변환(StandardScaler)

 

이상치 데이터 제거 후 모델 학습/예측/평가

이상치 데이터(Outlier)는 전체 데이터의 패턴에서 벗어난 이상 값을 가진 데이터, 아웃라이어

 

사분위 : 전체 데이터를 값이 높은 순으로 정렬하고 이를 1/4씩으로 구간 분할

 

먼저 어떤 피처의 이상치 데이터를 검출할지 결정, 많은 피처가 있을 경우 결정값 즉 레이블과 가장 상관성이 높은 피처들을 위주로 이상치를 검출하는 것이 좋음

DataFrame의 corr()을 이용해 각 피처별로 상관도를 구한 뒤 시본의 heatmap을 통해 시각화

import seaborn as sns

plt.figure(figsize=(9,9))
corr = card_df.corr()
sns.heatmap(corr, cmap='RdBu')

 

import numpy as np

def get_outlier(df=None, column=None, weight=1.5):
    fraud = df[df['Class']==1][column]
    quantile_25 = np.percentile(fraud.values,25)
    quantile_75 = np.percentile(fraud.values,75)
    iqr = qunatile_75 - quanitle_25
    iqr_weight = iqr*weight
    lowest_val = quantile_25 - iqr_weight
    highest_val = quantile_75 + iqr_weight
    outlier_index = fraud[(fraud<lowest_val)|(fraud>highest_val)].index
    return outlier_index
    
outlier_index = get_outlier(df=card_df, column='V14', weight=1.5)
print('이상치 데이터 인덱스:', outlier_index)

 

 

SMOTE 오버 샘플링 적용 후 모델 학습/예측/평가

SMOTE를 적용할 때는 반드시 학습 데이터 세트만 오버 샘플링을 해야 함

from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state=0)
X_train_over, y_train_over = smote.fit_resample(X_train, y_train)

 

정밀도 지표보다는 재현율 지표를 높이는 것이 머신러닝 모델의 주요한 목표인 경우 SMOTE를 적용하면 좋다

 

 

 

'ML' 카테고리의 다른 글

회귀  (0) 2022.11.18
스태킹  (0) 2022.11.15
앙상블 학습  (0) 2022.11.14
사용자 행동 인식 데이터 세트  (0) 2022.11.11
분류 Classification  (0) 2022.11.08

+ Recent posts