신용카드 사기 거래 탐지 예측 모델 개발

신용카드 거래에서 사기를 탐지하는 것은 머신러닝의 중요한 응용 분야 중 하나 입니다. 이번 포스팅에서는 Kaggle의 신용카드 사기 거래 탐지 데이터 세트를 활용하여 신용카드 사기 거래 탐지 예측 모델 개발에 접근하는 방법에 대해서 알아 보겠습니다.

데이터 출처: 신용카드 사기 거래 탐지 데이터세트
https://www.kaggle.com/mlg-ulb/creditcardfraud

1단계: 데이터 전처리

필요한 라이브러리를 가져오고 데이터 세트를 Pandas DataFrame에 로드해야 합니다.

# 필요한 라이브러리 가져오기 
import pandas as pd

# 데이터를 Pandas 데이터프레임으로 로드하기
# 데이터를 D드라이브에 저장한 경우의 로드 방법
creditcardData = pd.read_csv('D:/creditcard.csv') 

# 데이터 탐색
creditcardData.head()
---------------------------------------------------------------
   Time        V1        V2        V3        V4        V5        V6        V7  \
0   0.0 -1.359807 -0.072781  2.536347  1.378155 -0.338321  0.462388  0.239599   
1   0.0  1.191857  0.266151  0.166480  0.448154  0.060018 -0.082361 -0.078803   
2   1.0 -1.358354 -1.340163  1.773209  0.379780 -0.503198  1.800499  0.791461   
3   1.0 -0.966272 -0.185226  1.792993 -0.863291 -0.010309  1.247203  0.237609   
4   2.0 -1.158233  0.877737  1.548718  0.403034 -0.407193  0.095921  0.592941   

         V8        V9  ...       V21       V22       V23       V24       V25  \
0  0.098698  0.363787  ... -0.018307  0.277838 -0.110474  0.066928  0.128539   
1  0.085102 -0.255425  ... -0.225775 -0.638672  0.101288 -0.339846  0.167170   
2  0.247676 -1.514654  ...  0.247998  0.771679  0.909412 -0.689281 -0.327642   
3  0.377436 -1.387024  ... -0.108300  0.005274 -0.190321 -1.175575  0.647376   
4 -0.270533  0.817739  ... -0.009431  0.798278 -0.137458  0.141267 -0.206010   

        V26       V27       V28  Amount  Class  
0 -0.189115  0.133558 -0.021053  149.62      0  
1  0.125895 -0.008983  0.014724    2.69      0  
2 -0.139097 -0.055353 -0.059752  378.66      0  
3 -0.221929  0.062723  0.061458  123.50      0  
4  0.502292  0.219422  0.215153   69.99      0  

[5 rows x 31 columns]


2단계: 데이터 탐색

데이터세트의 구조, 요약 통계, class 분포(사기성 신용카드거래와 비사기성 신용카드거래)를 확인하여 데이터세트를 이해합니다.

# 데이터 세트의 행과 열의 갯수 확인 
creditcardData.shape
--------------------------------------
(284807, 31)

데이터 세트는 284,807개의 행과 31개의 열로 구성되어 있습니다.

# 요약 통계량 확인
print(creditcardData.describe())
--------------------------------------
                Time            V1            V2            V3            V4  \
count  284807.000000  2.848070e+05  2.848070e+05  2.848070e+05  2.848070e+05   
mean    94813.859575  1.168375e-15  3.416908e-16 -1.379537e-15  2.074095e-15   
std     47488.145955  1.958696e+00  1.651309e+00  1.516255e+00  1.415869e+00   
min         0.000000 -5.640751e+01 -7.271573e+01 -4.832559e+01 -5.683171e+00   
25%     54201.500000 -9.203734e-01 -5.985499e-01 -8.903648e-01 -8.486401e-01   
50%     84692.000000  1.810880e-02  6.548556e-02  1.798463e-01 -1.984653e-02   
75%    139320.500000  1.315642e+00  8.037239e-01  1.027196e+00  7.433413e-01   
max    172792.000000  2.454930e+00  2.205773e+01  9.382558e+00  1.687534e+01   

                 V5            V6            V7            V8            V9  \
count  2.848070e+05  2.848070e+05  2.848070e+05  2.848070e+05  2.848070e+05   
mean   9.604066e-16  1.487313e-15 -5.556467e-16  1.213481e-16 -2.406331e-15   
std    1.380247e+00  1.332271e+00  1.237094e+00  1.194353e+00  1.098632e+00   
min   -1.137433e+02 -2.616051e+01 -4.355724e+01 -7.321672e+01 -1.343407e+01   
25%   -6.915971e-01 -7.682956e-01 -5.540759e-01 -2.086297e-01 -6.430976e-01   
50%   -5.433583e-02 -2.741871e-01  4.010308e-02  2.235804e-02 -5.142873e-02   
75%    6.119264e-01  3.985649e-01  5.704361e-01  3.273459e-01  5.971390e-01   
max    3.480167e+01  7.330163e+01  1.205895e+02  2.000721e+01  1.559499e+01   

       ...           V21           V22           V23           V24  \
count  ...  2.848070e+05  2.848070e+05  2.848070e+05  2.848070e+05   
mean   ...  1.654067e-16 -3.568593e-16  2.578648e-16  4.473266e-15   
std    ...  7.345240e-01  7.257016e-01  6.244603e-01  6.056471e-01   
min    ... -3.483038e+01 -1.093314e+01 -4.480774e+01 -2.836627e+00   
25%    ... -2.283949e-01 -5.423504e-01 -1.618463e-01 -3.545861e-01   
50%    ... -2.945017e-02  6.781943e-03 -1.119293e-02  4.097606e-02   
75%    ...  1.863772e-01  5.285536e-01  1.476421e-01  4.395266e-01   
max    ...  2.720284e+01  1.050309e+01  2.252841e+01  4.584549e+00   

                V25           V26           V27           V28         Amount  \
count  2.848070e+05  2.848070e+05  2.848070e+05  2.848070e+05  284807.000000   
mean   5.340915e-16  1.683437e-15 -3.660091e-16 -1.227390e-16      88.349619   
std    5.212781e-01  4.822270e-01  4.036325e-01  3.300833e-01     250.120109   
min   -1.029540e+01 -2.604551e+00 -2.256568e+01 -1.543008e+01       0.000000   
25%   -3.171451e-01 -3.269839e-01 -7.083953e-02 -5.295979e-02       5.600000   
50%    1.659350e-02 -5.213911e-02  1.342146e-03  1.124383e-02      22.000000   
75%    3.507156e-01  2.409522e-01  9.104512e-02  7.827995e-02      77.165000   
max    7.519589e+00  3.517346e+00  3.161220e+01  3.384781e+01   25691.160000   

               Class  
count  284807.000000  
mean        0.001727  
std         0.041527  
min         0.000000  
25%         0.000000  
50%         0.000000  
75%         0.000000  
max         1.000000  

[8 rows x 31 columns]

각 열에 대한 데이터 건수, 평균, 표준편차, 최소값, q1(하위 25%), median(중앙값), q3(상위 25%), 최대값을 확인합니다.

# class 칼럼 건수 확인
creditcardData['Class'].value_counts()
----------------------------------------------------------
0    284315
1       492
Name: Class, dtype: int64


# class 칼럼 비율 확인
creditcardData['Class'].value_counts(normalize = True)
----------------------------------------------------------
0    0.998273
1    0.001727
Name: Class, dtype: float64

class 칼럼 확인 결과, 사기성 신용카드거래는 492건(0.17%)이 존재하고, 비사기성 신용카드거래는 284,315건(99.83%)이 존재합니다.


3단계: 데이터 분할

먼저, 머신러닝 분야의 대표적인 라이브러리인 sklearn에서 필요 모듈을 로드합니다. 데이터 세트를 훈련 세트와 테스트 세트로 분할하여 훈련 세트로 모델을 개발하고, 테스트 세트로 모델의 성능을 평가합니다.

# 데이터 분할을 위한 필요 모듈 로드
from sklearn.model_selection import train_test_split

# 머신러닝 학습을 위한 열 (Features) 선택 
X = creditcardData.drop('Class', axis = 1)  

# 머신러닝 학습을 위한 Target 변수 선택
y = creditcardData['Class']  

# 데이터 분할 : 훈련 세트(80%)와 테스트 세트(20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)


4단계: 모델 훈련

훈련 데이터에 대해 머신러닝의 가장 기초적인 알고리즘인 로지스틱 회귀로 모델을 훈련합니다. 먼저, 로지스틱 회귀 모델을 학습하기 위해 필요한 모듈을 로드하는 것이 필요합니다.

# 로지스틱 회귀 모델을 훈련하기 위한 필요 모듈 로드
from sklearn.linear_model import LogisticRegression

# 로지스틱 회귀 모델 생성
logisticModel = LogisticRegression()

# 훈련 데이터에 대한 모델 적합
logisticModel.fit(X_train, y_train)
-------------------------------------------------
LogisticRegression()


5단계: 모델 평가

정확도, 정밀도, 재현율, F1-Score 등 적절한 측정 항목을 사용하여 테스트 데이터를 활용하여 모델 성능을 평가합니다. 먼저, 모델 성능 평가에 필요한 모듈을 로드합니다.

# 테스트 데이터를 활용하여 예측
y_pred = logisticModel.predict(X_test)

# 모델 평가 
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))

print("\nClassification Report:")
print(classification_report(y_test, y_pred))
------------------------------------------------------------
Confusion Matrix:
[[56829    35]
 [   43    55]]

Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00     56864
           1       0.61      0.56      0.59        98

    accuracy                           1.00     56962
   macro avg       0.81      0.78      0.79     56962
weighted avg       1.00      1.00      1.00     56962

결과로 나오는 Confusion Matrix, Classification Report의 지표에 대한 자세한 해석은 Confusion Matrix, Precision-Recall, F1-Score 이해하기를 참고하시면 됩니다.



6단계: 시각화

신용카드 사기 거래 탐지와 같은 이진 분류 예측 문제에 대한 예측 값과 실제 값을 시각적으로 비교하기 위해 Confusion Matrix Heatmap 또는 ROC 곡선을 만들 수 있습니다.


Confusion Matrix Heatmap

# 필요 라이브러리 로드
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix

# Confusion Matrix 생성
confusionMatrix = confusion_matrix(y_test, y_pred)

# Confusion Matrix를 위한 heatmap 생성
plt.figure(figsize = (8, 6))
sns.heatmap(confusionMatrix, annot = True, fmt = "d", cmap = "Blues", cbar = False,
            xticklabels = ["예측값 0", "예측값 1"],
            yticklabels = ["실제값 0", "실제값 1"])
plt.xlabel('예측값')
plt.ylabel('실제값')
plt.title('Confusion Matrix')
plt.show()

위의 코드와 산출된 Confusion Matrix Heatmap에 대한 설명은 아래와 같습니다.

  • y_test는 테스트 데이터세트의 실제 값(실제 실제값)을 나타냅니다.
  • y_pred는 모델의 예측 값을 나타냅니다.

이 코드는 x축이 예측 class(비사기 및 사기에 대해 각각 0과 1)를 나타내고, y축이 실제 class를 나타내는 히트맵을 생성합니다. 히트맵 셀 내부의 숫자는 각 범주에 속하는 관측치의 수를 나타냅니다.

이 시각화를 사용하면 예측 값과 실제 값을 쉽게 비교하여, 모델의 정확한 예측도와 오류 분류를 확인할 수 있습니다.


ROC curve

# 필요 라이브러리 로드
from sklearn.metrics import roc_curve, roc_auc_score, auc

# ROC 를 표시하기 위한 신용카드 사기 탐색 예측 확률값 산출
y_prob = logisticModel.predict_proba(X_test)[:, 1]

# ROC curve 계산
fpr, tpr, thresholds = roc_curve(y_test, y_prob)

# AUROC(Area Under the ROC Curve) 계산
rocAuc = auc(fpr, tpr)

# ROC curve 출력
plt.figure(figsize = (8, 6))
plt.plot(fpr, tpr, color = 'darkorange', lw = 2, label = f'ROC curve (AUC = {rocAuc:.2f})')
plt.plot([0, 1], [0, 1], color = 'navy', lw = 2, linestyle = '--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('거짓 양성률')
plt.ylabel('참 양성률')
plt.title('ROC Curve')
plt.legend(loc = 'lower right')
plt.show()

위의 코드에 대한 설명은 아래와 같습니다.

  • y_test는 테스트 데이터 세트의 실제 레이블(실제 정보)을 나타냅니다.
  • y_prob는 모델에서 예측된 class 1(사기) 확률을 나타냅니다.

코드는 ROC 곡선과 AUROC(곡선 아래 면적) 점수를 계산한 다음 ROC 곡선을 그립니다. ROC 곡선은 결정 임계값을 변경함에 따라 참양성률(TPR)과 거짓양성률(FPR) 간의 균형을 보여줍니다. AUC가 높을수록 모델 성능이 더 우수함을 나타냅니다.


Precision Recall Curve

# 필요 라이브러리 로드
from sklearn.metrics import precision_recall_curve, average_precision_score

# Precision-Recall curve 계산 
precision, recall, thresholds = precision_recall_curve(y_test, y_prob)

# 평균 정밀도 계산 
averagePrecision = average_precision_score(y_test, y_prob)

# Precision-Recall curve 출력 
plt.figure(figsize = (8, 6))
plt.plot(recall, precision, color = 'darkorange', lw = 2, label = f'Precision-Recall curve (AP = {averagePrecision:.2f})')
plt.xlabel('재현율')
plt.ylabel('정밀도')
plt.title('Precision-Recall Curve')
plt.legend(loc = 'best')
plt.show()

위의 코드에 대한 설명은 아래와 같습니다.

  • y_test는 테스트 데이터 세트의 실제 레이블(실제 정보)을 나타냅니다.
  • y_prob는 모델에서 예측된 clas 1(사기) 확률을 나타냅니다.

코드는 정밀도-재현율 곡선과 평균 정밀도(AP) 점수를 계산한 다음 곡선을 그립니다. 정밀도-재현율 곡선은 결정 임계값을 변경함에 따라 정밀도와 재현율 간의 균형을 보여줍니다. AP가 높을수록 모델 성능이 더 우수함을 나타냅니다.


8단계: 미세 조정 및 최적화

하이퍼파라미터를 미세 조정하고, 다양한 알고리즘(예: Random Forest, Gradient Boosting)을 시도하고, 오버샘플링 또는 언더샘플링과 같은 기술을 사용하여 class 불균형 문제를 처리하여 모델을 더욱 최적화할 수 있습니다.

성능이 좋은 모델이 있으면 실시간 사기 탐지를 위해 이를 운영 환경에 배포할 수 있습니다. 여기에는 API를 설정하거나 이를 승인 시스템에 통합하는 작업이 포함될 수 있습니다.

이상으로 신용 카드 사기 탐색 예측 모델을 산출하는 방법에 대해서 간단하게 알아 보았습니다. 다음 포스팅에서는 더 복잡한 머신러닝 기법을 활용한 모델 학습 방법에 대해서 알아 보겠습니다.

감사합니다.


답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다