본문 바로가기
머신러닝 with Python

[머신러닝 with Python] Light GBM 실습 / 신용카드 사기 검출 데이터(Credit Card Fraud) 활용

by CodeCrafter 2023. 9. 15.
반응형

이번 포스팅에서는 지난번에 알아봤던 Light GBM을 활용해서 실습을 진행해보겠습니다.

 

지난 포스팅에서는 작은 수의 데이터를 활용했기에 Light GBM의 성능향상을 크게 확인하지는 못했는데요. 이번에는 좀 더 큰 데이터를 활용해서 알아보겠습니다. 

 

이번에 사용할 데이터는 Credit Card Fraud Detection (신용카드 사기 검출) 데이터 셋입니다.

 

1. Credit Card Fraud Detection 데이터 설명

 

- 해당 데이터는 2013년 9월 유럽 카드 소지자가 신용 카드로 거래한 내역을 포함한 데이터 입니다.

- 이 데이터세트는 이틀 동안 발생한 거래를 보여주며, 총 284,807건의 거래 중 492건의 사기 사건 발생을 포함하고 있습니다.

 * 이는 전체 거래 중 0.172%의 사기 발생 확률을 가지고 있습니다. 

 * 해당 데이터로 학습을 진행할 경우,  예측률이 좋은 모델을 찾기는 쉽지 않습니다. 그 이유는, 모델이 거래 건이 무조건 사기가 아니다라고만 해도 무려 99.828%의 예측 정확도를 가진 모델이기 때문입니다. 

 * 그렇기에, 이러한 불균형한 데이터(Imbalanced data)를 가지고 학습을 하는 방법에 대해서도 알아보겠습니다.

- 해당 데이터의 구성은 아래 표와 같습니다.

 * 분석을 위해 공개된 데이터이기에 직접적으로 변수를 공개하기에는 제한되는것 같습니다.

 * 또한, 많은 변수들이 있기에 변수의 수를 줄이기 위해, PCA를 통해 차원을 축소한 변수들이 V1부터 V28까지 있습니다. PCA로 축소 및 변환되지 않은 변수는 Time과 Amount, 둘 뿐입니다. 

 * 추가적으로, Class라는 변수를 가지고 있으며 이는 0일 경우 사기가 아님을 / 1일 경우 사기임을 알리고 있습니다. 

 

 

2. 파이썬 코딩을 통해 알아보는 Credit Card Fraud Detection 문제 해결 - Light GBM 활용

 

1) 먼저 openml 사이트에서 데이터를 가져오고, 필요한 라이브러리들을 임포트 합니다.

이후, 데이터를 df라는 변수로 저장합니다.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml

# Credit Card Fraud 데이터 불러오기
data = fetch_openml(data_id=44235)  # 사이킷런에서 Titanic 데이터 불러오기
df = pd.DataFrame(data.data, columns=data.feature_names)

 

2) 데이터 중 사기 여부를 나타내는 'Class'를 df에 추가해주고 구축된 데이터의 최종형태는 아래와 같습니다.

df['Class'] = data.target
df.head()

 

3) 추후 데이터 구조의 변형을 위해 데이터의 카피버전인 df_copy를 만드는 함수를 def_preprocessed_df로 정의합니다.. 이때, Time 컬럼은 삭제합니다.

from sklearn.model_selection import train_test_split

# 인자로 입력받은 DataFrame을 복사 한 뒤 Time 컬럼만 삭제하고 복사된 DataFrame 반환
def get_preprocessed_df(df=None):
    df_copy = df.copy()
    df_copy.drop('Time', axis=1, inplace=True)
    return df_copy

 

4) 기본 데이터를 train데이터와 test 데이터로 분할하는 함수를 get_train_test_dataset으로 정의합니다. 

* 먼저, 본 데이터인 df를 카피하고

* 이후, features들의 집합인 X행렬을 만들고, 예측하고자하는 class(사기여부)는 y_target 으로 저장합니다.

* 다음으로, 해당 데이터(X 와 y)를 학습용과 테스트용으로 분할합니다. 이때, class(사기여부)의 비율에 맞춰서 train과 test용 데이터를 분할하기 위해 startified 분할을 실시해줍니다.

# 사전 데이터 가공 후 학습과 테스트 데이터 세트를 반환하는 함수.
def get_train_test_dataset(df=None):
    # 인자로 입력된 DataFrame의 사전 데이터 가공이 완료된 복사 DataFrame 반환
    df_copy = get_preprocessed_df(df)
    # DataFrame의 맨 마지막 컬럼이 레이블, 나머지는 피처들
    X_features = df_copy.iloc[:, :-1]
    y_target = df_copy.iloc[:, -1]
    # train_test_split( )으로 학습과 테스트 데이터 분할. stratify=y_target으로 Stratified 기반 분할
    X_train, X_test, y_train, y_test = \
    train_test_split(X_features, y_target, test_size=0.3, random_state=0, stratify=y_target)
    # 학습과 테스트 데이터 세트 반환
    return X_train, X_test, y_train, y_test

X_train, X_test, y_train, y_test = get_train_test_dataset(df)

 

5) 분할된 결과를 확인하면 아래와 같습니다.

print('학습 데이터 레이블 값 비율')
print(y_train.value_counts()/y_train.shape[0] * 100)
print('테스트 데이터 레이블 값 비율')
print(y_test.value_counts()/y_test.shape[0] * 100)

 

6) 우리가 만들 분류 모델의 결과를 정리하기 위한 함수를 만들어줍니다. 함수의 이름은 get_clf_eval로 정의합니다.

* 해당 함수가 도출하는 평가지표는 Confusion Matrix / Accuracy / Precision / Recall / f1_score / ROC-AUC score 입니다.

* 위 평가지표들에 대해서는 코드 아래 포스팅을 참조해주시면 되겠습니다.

from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
from sklearn.metrics import roc_auc_score

def get_clf_eval(y_test, pred=None, pred_proba=None):
    confusion = confusion_matrix( 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-AUC 추가
    roc_auc = roc_auc_score(y_test, pred_proba)
    print('오차 행렬')
    print(confusion)
    # ROC-AUC print 추가
    print('정확도: {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f},\
    F1: {3:.4f}, AUC:{4:.4f}'.format(accuracy, precision, recall, f1, roc_auc))

[머신러닝 with Python] 오차행렬 or 혼동행렬(Confusion Matrix) / 유방암 데이터(Breast Cancer Data) 활용하여 알아보기

 

[머신러닝 with Python] 오차행렬 or 혼동행렬(Confusion Matrix) / 유방암 데이터(Breast Cancer Data) 활용하여

이번에 알아볼 것은 지난 시간에 알아본 정확도 및 기타 분류평가지표를 도출할 수 있는 오차행렬 또는 혼동행렬이라 불리는 Confusion Matrix에 대해서 알아보겠습니다. 1. 오차행렬 / 혼동행렬 (Conf

jaylala.tistory.com

 

7) 먼저, Light GBM 결과와의 비교 모델을 선정해보았습니다. 비교 모델은 Logistic Regression 입니다.

* Logistic Regression을 활용해 train 데이터로 모델을 학습시키고, test 데이터로 모델을 테스트하고, 위에서 만든 평가지표 함수로 분류 결과를 평가해봅니다.

from sklearn.linear_model import LogisticRegression

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

# get_clf_eval() 함수를 이용하여 평가 수행.
get_clf_eval(y_test, lr_pred, lr_pred_proba)

* 정확도는 99.92%가 나왔습니다.  정상 데이터의 비율이 99.82%임을 감안하면 괜찮은 결과라 생각할 수도 있지만, 재현율(Recall)이 너무 낮습니다. 이를 향상 시키는 것이 사기를 예방하는데 더 도움이 될 것이라고 보입니다.

* 재현율(Recall)은 실제 사기데이터를 모델이 사기데이터라고 얼마나 예측했는지를 나타내는 지표 입니다.

   Recall = (모델이 분류한 실제 사기데이터) / (모델이 분류한 실제 사기데이터 + 모델이 분류하지 못한 실제 사기데이터) 

 

 

8) 이번에는 Light GBM을 활용해보겠습니다. 지난 시간에 알아본 것처럼 해당 데이터는 10,000건이 넘기에 Light GBM이 학습속도와 성능적인 측면에서 효과를 발휘할 것으로 기대가 됩니다.

* 먼저, Light GBM 모델을 학습 및 테스트 하기위해서 아래와 같은 함수를 정의힙니다. 따로 진행해도 상관은 없으나, 함수를 만들어놓으면 추후의 사용이 편하기에 모델을 만들어 보았습니다.

# 인자로 사이킷런의 Estimator객체와, 학습/테스트 데이터 세트를 입력 받아서 학습/예측/평가 수행.
def get_model_train_eval(model, ftr_train=None, ftr_test=None, tgt_train=None, tgt_test=None):
    model.fit(ftr_train, tgt_train)
    pred = model.predict(ftr_test)
    pred_proba = model.predict_proba(ftr_test)[:, 1]
    get_clf_eval(tgt_test, pred, pred_proba)

 

 

9) 다음은 lightgbm의 분류모델인 LGBMClassifier를 불러옵니다.

* 이후 하이퍼 파라미터 중 n_estimators를 1,000으로, num_leaves를 64로, n_jobs는 -1로, boost_from_average는 false로 선정해줍니다. 파라미터에 대한 설명은 코드 및 결과 다음의 포스팅을 참조해주시면 되겠습니다.

from lightgbm import LGBMClassifier

lgbm_clf = LGBMClassifier(n_estimators=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)

[머신러닝 with Python] 앙상블(Ensemble) 학습 (5) / LightGBM / 유방암(Breast Cancer) 데이터 활용

 

[머신러닝 with Python] 앙상블(Ensemble) 학습 (5) / LightGBM / 유방암(Breast Cancer) 데이터 활용

이번에 알아볼 앙상블 모델은 Light GBM입니다. Light GBM은 XGBoost가 나온 후 등장한 모델로, XGBoost의 장점은 살리고 단점은 보완된 모습이라고 볼 수 있는데요. 그렇지만, 무조건 XGBoost보다 좋다고 할

jaylala.tistory.com

 

* 결과를 확인해보니,

 a) 정확도가 99.92%(Logistic Regression)에서 99.95%(Light GBM)으로 향상되었으며

 b) 재현율도 59.46%(Logistic Regression)에서 75.68%(Light GBM)으로 향상되었음을 확인할 수 있습니다.

 

 

다음 포스팅에서는 이번 포스팅 결과에 이어서, 

1) 불균형 데이터의 정규화 후 재학습

2) 이상치(Outlier) 제거 후 재학습

3) 불균형 데이터 중 숫자가 적은 Class를 OverSampling 기법으로 향상 시킨 후 재학습

 

하는 방법에 대해서 알아보겠습니다.

반응형

댓글