Mendeteksi Transaksi Kartu Kredit Fraud Menggunakan Neural Network
Machine learning merupakan teknologi dimana sebuah mesin bisa mempelajari sesuatu dari data yang diberikan, sehingga mesin bisa menemukan suatu pola dari data tersebut. Pola inilah yang digunakan mesin untuk memprediksi suatu data.Dalam tutorial kali ini, aku akan mencoba salah satu algoritma supervised learning yaitu Neural Network untuk mengklasifikasi apakah suatu transaksi fraud atau tidak fraud.
Dataset Kartu Kredit
Aku dan beberapa temanku membuat dataset kartu kredit ini dengan beberapa asumsi. Asumsi ini kami dapatkan dari beberapa literatur dan juga wawancara. Asumsi jika transaksi dilabeli fraud adalah :
- Transaksi yang menggunakan verifikasi tanda tangan di atas kertas lebih rentan dilabeli fraud karena bisa saja tanda tangan tersebut palsu atau tidak sesuai dengan aslinya.
- Apabila saat melakukan transaksi terdapat percobaan menekan PIN lebih dari 3 kali, maka dapat dilabeli fraud, karena bisa saja fraudster tidak tahu PIN dari kartu kredit tersebut.
- Jumlah transaksi yang melebihi limit yang merupakan salah satu anomali yang disebut di atas.
- Waktu transaksi yang tidak wajar, transaksi yang dilakukan saat dini hari, bisa saja transaksi dilakukan di tempat yang memiliki zona waktu yang sangat jauh. Contoh bisa saja fraudster melakukan transaksi di AS saat pagi hari, dimana di Indonesia saat malam hari.
- Transaksi yang dilakukan di tempat yang sangat jauh yang merupakan salah satu anomali yang disebut di atas
- Transaksi yang dilakukan oleh e-mail yang tidak sesuai dengan e-mail pemilik.
Pembuatan dataset dengan constraint berikut :
- Amount : Nominal transaksi yang dilakukan.
- Pin_attempt : Percobaan menekan PIN
- Is_signature : 0 = tidak ditandatangani / 1 = ditandatangani
- Cc_limit (limit kartu kredit) : 5000000 / 15000000 / 20000000 / 50000000 / 450000000
- Last_use_accum : Jumlah penggunaan terakhir menggunakan kartu kredit
- Hour : Dari 0 - 23
- Most_place_zipcode : Dilihat dari link ini
- Transaction_place_zipcode : Dilihat dari link ini
- Domain : 1 = gmail.com / 2 = yahoo.com / 3 = hotmail.com / 4 = aol.com / 5 = live.com / 6 = ymail.com / 7 = outlook.com / 8 = yahoo.co.id
- Class : 0 = tidak fraud / 1 = fraud
Dataset berisi total data 368 data dengan 203 data tidak fraud (class 0) dan 165 data fraud (class 1). Kemudian penulis melakukan encode atribut-atribut tersebut menjadi A1-A9 agar lebih mudah dibaca. Berikut nama atribut sebelum perubahan dengan perubahannya :
- Amount menjadi A1
- Pin_attempt menjadi A2
- Is_signature menjadi A3
- Cc_limit menjadi A4
- Last_use_accum menjadi A5
- Hour menjadi A6
- Most_place_zipcode menjadi A7
- Transaction_place_zipcode menjadi A8
- Domain menjadi A9
Langkah-langkah
Langkah-langkah ini dilakukan di Jupyter Notebook :
Mengimpor library yang digunakan untuk klasifikasi.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Impor Library | |
import pandas as pd | |
from sklearn.preprocessing import StandardScaler | |
from sklearn.model_selection import train_test_split | |
import keras | |
from keras.models import Sequential | |
from keras.layers import Dense | |
from sklearn.metrics import classification_report | |
from sklearn.metrics import confusion_matrix | |
import matplotlib.pyplot as plt | |
import seaborn as sn | |
from sklearn.metrics import accuracy_score | |
import numpy as np |
Mengimpor dataset yang akan diklasifikasi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Impor dataset | |
data = pd.read_csv('datasetmikir6.csv') | |
data.describe() |
Mengecek apakah ada data yang kosong pada setiap atributnya
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Cek apakah ada kolom yang kosong | |
data.isnull().sum() |
Melakukan normalisasi pada semua atribut. Atribut dinormalisasi dengan tujuan agar bisa dipelajari oleh model dengan mudah. Dinormalisasi menggunakan rumus standardization yaitu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Feature Scaling | |
data['normalizedA1'] = StandardScaler().fit_transform(data['A1'].values.reshape(-1,1)) | |
data['normalizedA2'] = StandardScaler().fit_transform(data['A2'].values.reshape(-1,1)) | |
data['normalizedA3'] = StandardScaler().fit_transform(data['A3'].values.reshape(-1,1)) | |
data['normalizedA4'] = StandardScaler().fit_transform(data['A4'].values.reshape(-1,1)) | |
data['normalizedA5'] = StandardScaler().fit_transform(data['A5'].values.reshape(-1,1)) | |
data['normalizedA6'] = StandardScaler().fit_transform(data['A6'].values.reshape(-1,1)) | |
data['normalizedA7'] = StandardScaler().fit_transform(data['A7'].values.reshape(-1,1)) | |
data['normalizedA8'] = StandardScaler().fit_transform(data['A8'].values.reshape(-1,1)) | |
data['normalizedA9'] = StandardScaler().fit_transform(data['A9'].values.reshape(-1,1)) | |
data = data.drop(['A1'],axis=1) | |
data = data.drop(['A2'],axis=1) | |
data = data.drop(['A3'],axis=1) | |
data = data.drop(['A4'],axis=1) | |
data = data.drop(['A5'],axis=1) | |
data = data.drop(['A6'],axis=1) | |
data = data.drop(['A7'],axis=1) | |
data = data.drop(['A8'],axis=1) | |
data = data.drop(['A9'],axis=1) | |
data.head() |
Pembagian Train Sample dan Test Sample
Membagi dataset menjadi dua bagian yaitu train untuk dipelajari model dan test untuk diprediksi oleh model. Jumlah untuk data test sebesar 30% dari seluruh data. Sehingga 111 data digunakan untuk test.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Pembagian Train dan Test | |
X = data.iloc[:, data.columns != 'class'] | |
y = data.iloc[:, data.columns == 'class'] | |
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.3, random_state=0) |
Pembuatan Neural Network
Pembuatan Neural Network dengan 9 neuron (9 atribut data) dalam input layer kemudian diikuti 2 hidden layer yang masing-masingnya 15 neuron, kemudian diikuti output layer yang masing-masingnya 1 neuron. Masing-masing neuron dalam hidden layer menggunakan ReLU activation function. Sedangkan neuron dalam output layer menggunakan Sigmoid activation function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Buat ANN | |
classifier = Sequential() | |
# Input Layer dan Hidden Layer Pertama | |
classifier.add(Dense(units = 15, kernel_initializer = 'uniform', activation = 'relu', input_dim = 9)) | |
# Hidden Layer Kedua | |
classifier.add(Dense(units = 15, kernel_initializer = 'uniform', activation = 'relu')) | |
# Output Layer | |
classifier.add(Dense(units = 1, kernel_initializer = 'uniform', activation = 'sigmoid')) | |
# ANN Compile | |
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy']) | |
# Fitting the ANN to the Training set | |
history = classifier.fit(X_train, y_train, batch_size = 32, epochs = 100, validation_split=0.33) |
Menampilkan kurva akurasi dan loss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# list all data in history | |
print(history.history.keys()) | |
# summarize history for accuracy | |
plt.plot(history.history['acc']) | |
plt.plot(history.history['val_acc']) | |
plt.title('model accuracy') | |
plt.ylabel('accuracy') | |
plt.xlabel('epoch') | |
plt.legend(['train', 'test'], loc='upper left') | |
plt.show() | |
# summarize history for loss | |
plt.plot(history.history['loss']) | |
plt.plot(history.history['val_loss']) | |
plt.title('model loss') | |
plt.ylabel('loss') | |
plt.xlabel('epoch') | |
plt.legend(['train', 'test'], loc='upper left') | |
plt.show() |
Menampilkan nilai akurasi dan loss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Predict | |
y_pred = classifier.predict(X_test) | |
y_pred = (y_pred > 0.5) | |
score = classifier.evaluate(X_test, y_test) | |
print("Score test", score) | |
y_pred_train = classifier.predict(X_train) | |
y_pred_train = (y_pred_train > 0.5) | |
score_pred_train = classifier.evaluate(X_train, y_train) | |
print("Score train", score_pred_train) |
Nilai loss test adalah 0,35
Nilai akurasi test adalah 0,85
Nilai loss train adalah 0,34
Nilai akurasi train adalah 0,85
Nilai akurasi test adalah 0,85
Nilai loss train adalah 0,34
Nilai akurasi train adalah 0,85
Menampilkan classification report
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Let's see how our model performed | |
print("Hasil Test") | |
print(classification_report(y_test, y_pred)) |
Menampilkan Confusion Matrix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## EXTRA: Confusion Matrix | |
cm = confusion_matrix(y_test, y_pred) # rows = truth, cols = prediction | |
cm_train = confusion_matrix(y_train, y_pred_train) | |
print("Test Data Accuracy: %0.4f" % accuracy_score(y_test, y_pred)) | |
print(cm) | |
print("Train Data Accuracy: %0.4f" % accuracy_score(y_train, y_pred_train)) | |
print(cm_train) |
Kesimpulan
Hasilnya terbilang cukup bagus dapat dilihat dari akurasinya sebesar 0.87 dan dari confusion matrix, hampir sebagian besar klasifikasi benar. Akan lebih bagus lagi, jika jumlah data diperbanyak. Tutorial ini terinspirasi dari https://blog.usejournal.com/credit-card-fraud-detection-by-neural-network-in-keras-4bd81cc9e7fe
Gan mau nanya kalo untuk proses praprocessing data y gimana ya langkah2 y. Sampe terbentuk dataset yg siap di olah ke data mining. Misal saya dapet data mentah data transaksi penjualan, nah agar bisa di olah kan perlu pra processing data dulu.
BalasHapusSaya masih miss di pra processing data y.
Terima kasih gan
Tergantung sih, ada beberapa metode kayak scaling untuk numerik, label encoding kalau kategorikal. Bisa dilihat di https://hackernoon.com/what-steps-should-one-take-while-doing-data-preprocessing-502c993e1caa untuk lengkapnya
Hapus