본문 바로가기
Machine Learning

[ML] Credit Card Fraud Detection

by ram_ 2023. 1. 10.

STEP 01. DATA INFO

신용카드 부정사용 검출에 관한 논문의 예

    - 신용카드와 같은 금융 데이터들은 구하기가 어렵다

    - 금융 데이터들의 데이터는 다루기 쉽지 않다

    - 그러나 지능화되어가는 현대 범죄에 맞춰 사전 이상 징후 검출 등 금융기관이 많은 노력을 기울이고 있다

    - 이 데이터 역시 센서를 이용한 사람의 행동 과정 유추처럼 머신러닝의 이용 분야 중 하나이다

 

데이터 다운로드

    - https://www.kaggle.com/datasets/mlg-ulb/creditcardfraud  

 

데이터 개요 

    - 신용카드 사기 검출 분류 실습용 데이터

    - 데이터에 class 컬럼이 사기유무를 의미한다

    - class 컬럼의 불균형이 극심해서 전체 데이터의 약 0.172%가 1(사기 Fraud)을 가진다

 

데이터 특성

    - 금융 데이터이고 기업의 기밀 보호를 위해 대다수 특성의 이름은 삭제되어 있다

    - Amount : 거래금액 , Class : Fraud 여유(1이면 Fraud)

 


STEP 02. READ DATA

import pandas as pd

data_path = './creditcard.csv'
raw_data =pd.read_csv(data_path)
frauds_rate = round(raw_data['Class'].value_counts()[1]/len(raw_data) * 100, 2)

아주 미세하게 1의 값이 보인다.

raw_data.columns

X = raw_data.iloc[:, 1:-1] #  맨 첫번째 Time 컬럼, 마지막 Class 컬럼 빼고 사용
y = raw_data.iloc[:, -1]

X.shape, y.shape
# ((284807, 29), (284807,))
from sklearn.model_selection import train_test_split

# 데이터의 불균형이 너무 심해서 stratify 꼭 잡아줘야 한다
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=13, stratify=y)

# 불균형 정도 확인
import numpy as np
print(np.unique(y_train, return_counts=True)[1][1] /len(y_train) * 100, '%')
# 0.17254870488152324%

 


STEP 03. TRIAL 1-1

# 분류기 성능 return 함수
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score

def get_clf_eval(y_test, pred):
    acc = accuracy_score(y_test, pred)
    pre = precision_score(y_test, pred)
    re = recall_score(y_test, pred)
    f1 = f1_score(y_test, pred)
    auc = roc_auc_score(y_test, pred)

    return acc, pre, re, f1, auc
# 성능 출력하는 함수 
from sklearn.metrics import confusion_matrix

def print_clf_eval(y_test, pred):
    confusion = confusion_matrix(y_test, pred)
    acc, pre, re, f1, auc = get_clf_eval(y_test, pred)

    print('=> confusion matrix')
    print(confusion)
    print('==========')
    print('Accuracy : {0:.4f}, Precision : {1:.4f}'.format(acc, pre))
    print('Recall : {0:.4f}, F1 : {1:.4f}, AUC : {2:.4f}'.format(re, f1, auc))

Accuracy가 99.9% ...? 상당히 높은 수치를 띈다.

하지만 Recall(참값 중 얼마나 맞췄나)은 59.4%인 것을 볼 수 있다.

DecisionTree를 사용해봤더니 Recall은 조금 높아졌다.

더 끌어 올릴 수 있는 여지가 있는지 더 고민해봤다.

Recall 74.32%로 좀 더 올라갔다.

오답수도 38개로 줄었다.

성능이 조금 더 좋아졌다. 

 

여기서, Recall과 Precision의 의미는?

- 은행 입장에서는 모든 fraud를 찾고 싶을테니 Recall이 좋을 것이다. 

- 사용자 입장에서는 Recall이 높아지면 정상 사용자가 fraud사용자로 오해받아 성가신 일이 생길 수 있으니 Precision이 좋겠다.