Day 7 Algorit.ma : Capstone Project
Fraud Prediction
Problem Statement
💼 Fraud merupakan suatu tindakan penipuan pada transaksi keuangan. Transaksi ini bertujuan untuk memperoleh keuntungan dari suatu entitas lain dengan cara ilegal sehingga dapat menyebabkan kerugian.
Transaksi fraud sering terjadi di industri perbankan. Beberapa contoh transaksi fraud pada industri perbankan antara lain adalah pishing, skimming, penipuan kartu kredit, penipuan pinjaman, dll.
Efek negatif dari transaksi fraud adalah adanya kerugian finansial di kedua belah pihak baik customer maupun industri perbankan. Oleh karena itu diperlukan tindakan pencegahan dengan deteksi lebih dini terhadap potensi transaksi fraud.
Transaksi fraud dapat dideteksi lebih awal dengan cara membangun model machine learning dengan metode klasifikasi. Tugas kita pada project kali ini adalah membuat model klasifikasi untuk mendeteksi transaksi fraud agar dapat dilakukan action plan berikutnya
Rubrics Penilaian
Untuk menyelesaikan project ini, silahkan mengacu pada rubrics di bawah ini serta memberikan deskripsi dari proses yang Anda kerjakan untuk setiap bagian.
Data Preparation
(1 poin) Bagaimana melakukan persiapan data sebelum dilakukan pemodelan.
- Metode apa saja yang yang dilakukan dalam proses persiapan data?
- Apakah terdapat data yang missing atau duplicate, bagaimana cara mengatasi data tersebut? Referensi: dokumentasi pandas atau FAQ
(4 poin) Bagaimana cara untuk melakukan feature engineering ataupun pemilihan variabel dari data yang tersedia.
- Apakah terdapat variable yang dihilangkan? Jika iya, kenapa?
- Apakah terdapat variable yang ditambahkan? Jika iya, kenapa?
Exploratory Data Analysis
(2 poin) Exploratory Data Analysis
- Berikan penjelasan informatif dari visualisasi dan/atau segala jenis hasil eksplorasi Anda.
- Bagaimana distribusi data pada setiap variabel?
- Apakah terdapat informasi menarik antara variable predictor dengan variable target?
Data Pre-processing and Model Fitting
(2 poin) Data Pre-processing
- Apakah terdapat variabel yang harus di-encoding? Kalau ada, apa saja dan kenapa?
- Bagaimana pembagian proporsi Data Train & Test?
(4 poin) Membuat model, pilih model berdasarkan model yang sudah diajarkan dikelas (logistic regression / knn)
- Buatlah model yang dapat menjawab pertanyaan bisnis di atas.
- Variable apa yang dirasa cukup penting dalam pembuatan model? Sertakan alasannya.
- Metode evaluasi apa yang cocok digunakan untuk kasus ini? Jelaskan.
Prediction Performance
(1 poin) Metrics yang dipilih mencapai 60% pada data train (2 poin) Metrics yang dipilih mencapai 60% pada data test
Conclusion
(2 poin) Tuliskan kesimpulan dari project yang anda kerjakan.
- Apakah model sudah dapat melakukan prediksi dengan baik? Jelaskan.
- Apakah model sudah dapat menjawab pertanyaan bisnis yang ada? Jelaskan.
- Action plan apa yang dapat dilakukan untuk tindakan preventif transaksi fraud?
Total Poin Capstone Project : 18
NOTE:
Apabila Anda sudah berhasil mendapatkan model yang baik dan berhasil menjawab seluruh rubric di atas, Anda diperkenankan untuk melakukan eksplorasi model menggunakan metode lain di luar yang diajarkan di kelas. Hasil model yang mendapatkan metrics pengukuran paling baik akan mendapatkan bonus nilai (di luar nilai capstone).
Penjelasan Dataset
Berikut adalah penjelasan setiap kolom yang terdapat pada dataset yang akan digunakan:
X
: ID kartuid_tanggal_transaksi_awal
: ID tanggal transaksi dilakukantanggal_transaksi_awal
: tanggal dilakukan transaksi (POSIX format)tipe_kartu
: tipe kartu yang bertransaksiid_merchant
: ID merchant kartu tersebut bertransaksinama_merchant
: nama merchant kartu tersebut bertransaksitipe_mesin
: tipe mesin yang digunakan untuk bertransaksi (ATM, EDC, dll)tipe_transaksi
: jenis transaksinama_transaksi
: nama jenis transaksinilai_transaksi
: nilai uang yang tercatat saat transaksiid_negara
: ID negara tempat terjadi transaksinama_negara
: nama negara tempat terjadi transaksinama_kota
: nama kota tempat terjadi transaksilokasi_mesin
: lokasi mesinpemilik_mesin
: pemilik mesinwaktu_transaksi
: waktu transaksi berlangsungkuartal_transaksi
: kuartal waktu transaksi berlangsungkepemilikan_kartu
: kepemilikan kartunama_channel
: nama channel kartu tersebut bertransaksiid_channel
: ID channel kartu tersebut bertransaksiflag_transaksi_finansial
: jenis transaksistatus_transaksi
: keberhasilan atau kegagalan transaksibank_pemilik_kartu
: kepemilikan kartu yang dimiliki suatu bankrata_rata_nilai_transaksi
: rata - rata nilai transaksimaksimum_nilai_transaksi
: nilai maksimum transaksiminimum_nilai_transaksi
: nilai minimum transaksirata_rata_jumlah_transaksi
: rata - rata jumlah transaksiflag_transaksi_fraud
: transaksi fraud (1) atau tidak fraud (0)
Data Preparation
(1 poin) Bagaimana melakukan persiapan data sebelum dilakukan pemodelan.
- Metode apa saja yang yang dilakukan dalam proses persiapan data?
- Apakah terdapat data yang missing atau duplicate, bagaimana cara mengatasi data tersebut? Referensi: dokumentasi pandas atau FAQu FAQ
Import Library yang dibutuhkan
import pandas as pd
import numpy as np
from datetime import datetime
import seaborn as sns
import matplotlib
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import statsmodels.api as sm
from sklearn.metrics import recall_score, precision_score, accuracy_score
from sklearn.preprocessing import StandardScaler
Read Data
fraud = pd.read_csv('transaksi_fraud.csv')
fraud.head().T
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
X | 4676 | 788 | 1520 | 9346 | 2914 |
id_tanggal_transaksi_awal | 2457646 | 2457419 | 2457521 | 2457659 | 2457311 |
tanggal_transaksi_awal | 2457726 | 2457507 | 2457612 | 2457746 | 2457385 |
tipe_kartu | 111 | 111 | 2 | 103 | 0 |
id_merchant | -2 | -2 | -2 | 75336 | -2 |
nama_merchant | 1798 | 1798 | 1798 | 249 | 1798 |
tipe_mesin | 2605127 | -3 | -3 | 2806174 | 2334932 |
tipe_transaksi | 26 | 156 | 156 | 58 | 26 |
nama_transaksi | 10 | 12 | 12 | 6 | 10 |
nilai_transaksi | 2200000.0 | 2500000.0 | 1200000.0 | 320000.0 | 150000.0 |
id_negara | 96 | 96 | 96 | 96 | 96 |
nama_negara | 5 | 5 | 5 | 5 | 5 |
nama_kota | 265 | 121 | 101 | 239 | 69 |
lokasi_mesin | 4137 | 1264 | 1283 | 7049 | 3425 |
pemilik_mesin | 613 | 2196 | 2049 | 588 | 613 |
waktu_transaksi | 193955 | 73140 | 140216 | 155117 | 143339 |
kuartal_transaksi | 4 | 2 | 3 | 3 | 3 |
kepemilikan_kartu | 2 | 1 | 1 | 2 | 2 |
nama_channel | 1 | 5 | 5 | 2 | 1 |
id_channel | 9 | 8 | 8 | 4 | 9 |
flag_transaksi_finansial | False | False | False | False | False |
status_transaksi | 3 | 3 | 3 | 3 | 3 |
bank_pemilik_kartu | 999 | 999 | 999 | 999 | 999 |
rata_rata_nilai_transaksi | 1332292.784 | 1369047.619 | 15523460.4 | 711764.7059 | 617968.254 |
maksimum_nilai_transaksi | 9750000.0 | 10000000.0 | 100000000.0 | 6884408.0 | 2500000.0 |
minimum_nilai_transaksi | 10000.0 | 30000.0 | 41804.0 | 10000.0 | 100000.0 |
rata_rata_jumlah_transaksi | 2.73 | 2.33 | 2.4 | 1.98 | 1.46 |
flag_transaksi_fraud | 0 | 1 | 0 | 0 | 0 |
Cek keseimbangan fraudnya
fraud_asli = fraud.copy()
fraud_asli['flag_transaksi_fraud'].value_counts()
flag_transaksi_fraud
0 12215
1 910
Name: count, dtype: int64
Cek informasi sekilas dan tipe data
fraud.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13125 entries, 0 to 13124
Data columns (total 28 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 X 13125 non-null int64
1 id_tanggal_transaksi_awal 13125 non-null int64
2 tanggal_transaksi_awal 13125 non-null int64
3 tipe_kartu 13125 non-null int64
4 id_merchant 13125 non-null int64
5 nama_merchant 13125 non-null int64
6 tipe_mesin 13125 non-null int64
7 tipe_transaksi 13125 non-null int64
8 nama_transaksi 13125 non-null int64
9 nilai_transaksi 13125 non-null float64
10 id_negara 13125 non-null int64
11 nama_negara 13125 non-null int64
12 nama_kota 13125 non-null int64
13 lokasi_mesin 13125 non-null int64
14 pemilik_mesin 13125 non-null int64
15 waktu_transaksi 13125 non-null int64
16 kuartal_transaksi 13125 non-null int64
17 kepemilikan_kartu 13125 non-null int64
18 nama_channel 13125 non-null int64
19 id_channel 13125 non-null int64
20 flag_transaksi_finansial 13125 non-null bool
21 status_transaksi 13125 non-null int64
22 bank_pemilik_kartu 13125 non-null int64
23 rata_rata_nilai_transaksi 13104 non-null float64
24 maksimum_nilai_transaksi 13104 non-null float64
25 minimum_nilai_transaksi 13104 non-null float64
26 rata_rata_jumlah_transaksi 13104 non-null float64
27 flag_transaksi_fraud 13125 non-null int64
dtypes: bool(1), float64(5), int64(22)
memory usage: 2.7 MB
Berdasarkan deskripsi data sebelumnya dan fraud.info()
maka beberapa kolom akan diubah ke tipe data lain.
object
= [‘X’, ‘id_tanggal_transaksi_awal’, ‘nama_channel’, ‘id_channel’, ‘bank_pemilik_kartu’, ‘id_merchant’, ‘nama_merchant’, ‘nama_transaksi’]category
= [‘tipe_kartu’, ‘tipe_mesin’, ‘tipe_transaksi’, ‘id_negara’, ‘nama_negara’, ‘nama_kota’, ‘lokasi_mesin’, ‘pemilik_mesin’, ‘kepemilikan_kartu’, ‘status_transaksi’]datetime
= [‘tanggal_transaksi_awal’, ‘waktu_transaksi’]
Ubah datatype
obj_kolom = ['X', 'id_tanggal_transaksi_awal', 'nama_channel', 'id_channel', 'bank_pemilik_kartu', 'id_merchant', 'nama_merchant', 'nama_transaksi']
cat_kolom = ['kuartal_transaksi', 'tipe_kartu', 'tipe_mesin', 'tipe_transaksi', 'id_negara', 'nama_negara', 'nama_kota', 'lokasi_mesin', 'pemilik_mesin', 'kepemilikan_kartu', 'status_transaksi']
dt_kolom = ['tanggal_transaksi_awal', 'waktu_transaksi']
# -> object
fraud[obj_kolom] = fraud[obj_kolom].astype('object')
# -> category
fraud[cat_kolom] = fraud[cat_kolom].astype('category')
# -> datetime
fraud['tanggal_transaksi_awal'] = fraud['tanggal_transaksi_awal'].apply(lambda x : datetime.fromtimestamp(x))
fraud['waktu_transaksi'] = fraud['waktu_transaksi'].apply(lambda x : datetime.fromtimestamp(x))
fraud.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13125 entries, 0 to 13124
Data columns (total 28 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 X 13125 non-null object
1 id_tanggal_transaksi_awal 13125 non-null object
2 tanggal_transaksi_awal 13125 non-null datetime64[ns]
3 tipe_kartu 13125 non-null category
4 id_merchant 13125 non-null object
5 nama_merchant 13125 non-null object
6 tipe_mesin 13125 non-null category
7 tipe_transaksi 13125 non-null category
8 nama_transaksi 13125 non-null object
9 nilai_transaksi 13125 non-null float64
10 id_negara 13125 non-null category
11 nama_negara 13125 non-null category
12 nama_kota 13125 non-null category
13 lokasi_mesin 13125 non-null category
14 pemilik_mesin 13125 non-null category
15 waktu_transaksi 13125 non-null datetime64[ns]
16 kuartal_transaksi 13125 non-null category
17 kepemilikan_kartu 13125 non-null category
18 nama_channel 13125 non-null object
19 id_channel 13125 non-null object
20 flag_transaksi_finansial 13125 non-null bool
21 status_transaksi 13125 non-null category
22 bank_pemilik_kartu 13125 non-null object
23 rata_rata_nilai_transaksi 13104 non-null float64
24 maksimum_nilai_transaksi 13104 non-null float64
25 minimum_nilai_transaksi 13104 non-null float64
26 rata_rata_jumlah_transaksi 13104 non-null float64
27 flag_transaksi_fraud 13125 non-null int64
dtypes: bool(1), category(11), datetime64[ns](2), float64(5), int64(1), object(8)
memory usage: 2.2+ MB
Cek deskripsi data numerik dan kategorik
# numerik
fraud.describe().T
count | mean | min | 25% | 50% | 75% | max | std | |
---|---|---|---|---|---|---|---|---|
tanggal_transaksi_awal | 13125 | 1970-01-29 17:39:00.576761904 | 1970-01-29 17:35:03 | 1970-01-29 17:37:31 | 1970-01-29 17:39:03 | 1970-01-29 17:40:32 | 1970-01-29 17:42:34 | NaN |
nilai_transaksi | 13125.0 | 1315218.824267 | 1.0 | 200000.0 | 570000.0 | 1250000.0 | 75000000.0 | 2838050.053336 |
waktu_transaksi | 13125 | 1970-01-02 21:34:55.669638095 | 1970-01-01 07:00:47 | 1970-01-02 11:30:22 | 1970-01-02 22:05:07 | 1970-01-03 07:43:40 | 1970-01-04 00:31:54 | NaN |
rata_rata_nilai_transaksi | 13104.0 | 1364131.826769 | 50000.0 | 568563.3893 | 1024239.017 | 1679777.627 | 24666666.67 | 1448583.095472 |
maksimum_nilai_transaksi | 13104.0 | 12287602.944063 | 38000.0 | 2500000.0 | 6000000.0 | 15000000.0 | 100000000.0 | 16459046.159531 |
minimum_nilai_transaksi | 13104.0 | 76519.328602 | 1.0 | 25000.0 | 36964.0 | 63200.0 | 75000000.0 | 676539.058057 |
rata_rata_jumlah_transaksi | 13104.0 | 2.436182 | 1.0 | 1.68 | 2.1 | 2.79 | 19.78 | 1.389367 |
flag_transaksi_fraud | 13125.0 | 0.069333 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.25403 |
# numerik
fraud.select_dtypes(include=['object', 'category']).describe().T
count | unique | top | freq | |
---|---|---|---|---|
X | 13125 | 8793 | 2925 | 6 |
id_tanggal_transaksi_awal | 13125 | 360 | 2457509 | 169 |
tipe_kartu | 13125 | 14 | 111 | 4846 |
id_merchant | 13125 | 1122 | -2 | 11307 |
nama_merchant | 13125 | 1105 | 1798 | 11307 |
tipe_mesin | 13125 | 5341 | -3 | 883 |
tipe_transaksi | 13125 | 20 | 26 | 3575 |
nama_transaksi | 13125 | 20 | 10 | 3575 |
id_negara | 13125 | 13 | 96 | 13081 |
nama_negara | 13125 | 12 | 5 | 13080 |
nama_kota | 13125 | 229 | 128 | 5404 |
lokasi_mesin | 13125 | 5814 | 600 | 21 |
pemilik_mesin | 13125 | 1666 | 613 | 10418 |
kuartal_transaksi | 13125 | 4 | 3 | 5224 |
kepemilikan_kartu | 13125 | 2 | 2 | 12236 |
nama_channel | 13125 | 5 | 1 | 10418 |
id_channel | 13125 | 4 | 9 | 10418 |
status_transaksi | 13125 | 1 | 3 | 13125 |
bank_pemilik_kartu | 13125 | 1 | 999 | 13125 |
Cek missing atau duplicated
fraud.isna().sum()
X 0
id_tanggal_transaksi_awal 0
tanggal_transaksi_awal 0
tipe_kartu 0
id_merchant 0
nama_merchant 0
tipe_mesin 0
tipe_transaksi 0
nama_transaksi 0
nilai_transaksi 0
id_negara 0
nama_negara 0
nama_kota 0
lokasi_mesin 0
pemilik_mesin 0
waktu_transaksi 0
kuartal_transaksi 0
kepemilikan_kartu 0
nama_channel 0
id_channel 0
flag_transaksi_finansial 0
status_transaksi 0
bank_pemilik_kartu 0
rata_rata_nilai_transaksi 21
maksimum_nilai_transaksi 21
minimum_nilai_transaksi 21
rata_rata_jumlah_transaksi 21
flag_transaksi_fraud 0
dtype: int64
fraud[fraud['rata_rata_nilai_transaksi'].isna()].T
610 | 1489 | 1829 | 3069 | 3752 | 3781 | 6185 | 6501 | 7655 | 7660 | ... | 7777 | 8719 | 8758 | 9147 | 10006 | 10374 | 10401 | 11142 | 11520 | 11797 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
X | 1039 | 4020 | 14080 | 1335 | 8871 | 12852 | 8659 | 7518 | 2557 | 1813 | ... | 4192 | 2465 | 9504 | 342 | 5102 | 9641 | 14239 | 6907 | 8832 | 2409 |
id_tanggal_transaksi_awal | 2457561 | 2457655 | 2457510 | 2457514 | 2457531 | 2457368 | 2457603 | 2457620 | 2457558 | 2457385 | ... | 2457331 | 2457592 | 2457524 | 2457526 | 2457517 | 2457593 | 2457429 | 2457308 | 2457468 | 2457536 |
tanggal_transaksi_awal | 1970-01-29 17:40:07 | 1970-01-29 17:40:58 | 1970-01-29 17:38:41 | 1970-01-29 17:39:33 | 1970-01-29 17:40:10 | 1970-01-29 17:36:52 | 1970-01-29 17:40:43 | 1970-01-29 17:41:37 | 1970-01-29 17:39:26 | 1970-01-29 17:37:43 | ... | 1970-01-29 17:36:13 | 1970-01-29 17:40:45 | 1970-01-29 17:38:45 | 1970-01-29 17:40:21 | 1970-01-29 17:39:25 | 1970-01-29 17:40:16 | 1970-01-29 17:37:11 | 1970-01-29 17:35:48 | 1970-01-29 17:39:13 | 1970-01-29 17:39:51 |
tipe_kartu | 93 | 103 | 93 | 111 | 111 | 111 | 93 | 111 | 93 | 111 | ... | 111 | 111 | 111 | 104 | 93 | 111 | 93 | 103 | 111 | 93 |
id_merchant | -2 | -2 | -2 | -2 | -2 | -2 | -2 | -2 | -2 | -2 | ... | -2 | -2 | -2 | -2 | 388748 | -2 | -2 | -2 | -2 | -2 |
nama_merchant | 1798 | 1798 | 1798 | 1798 | 1798 | 1798 | 1798 | 1798 | 1798 | 1798 | ... | 1798 | 1798 | 1798 | 1798 | 1574 | 1798 | 1798 | 1798 | 1798 | 1798 |
tipe_mesin | -3 | 2330 | 185678 | 2344943 | 2805857 | 2337114 | 288963 | -3 | 3186008 | 2393471 | ... | 1906758 | 2331560 | 181 | -3 | 2383750 | 1752625 | 2489227 | 1478519 | 3166779 | 1180307 |
tipe_transaksi | 156 | 147 | 159 | 26 | 26 | 148 | 26 | 156 | 238 | 26 | ... | 159 | 26 | 147 | 156 | 58 | 385 | 26 | 385 | 26 | 159 |
nama_transaksi | 12 | 3 | 19 | 10 | 10 | 5 | 10 | 12 | 9 | 10 | ... | 19 | 10 | 3 | 12 | 6 | 11 | 10 | 11 | 10 | 19 |
nilai_transaksi | 100000.0 | 1000000.0 | 6000000.0 | 500000.0 | 2500000.0 | 25000.0 | 600000.0 | 1200000.0 | 2150000.0 | 200000.0 | ... | 25000.0 | 400000.0 | 500000.0 | 200000.0 | 220130.0 | 1200000.0 | 350000.0 | 100000.0 | 200000.0 | 13918500.0 |
id_negara | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 | ... | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 | 96 |
nama_negara | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | ... | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
nama_kota | 128 | 128 | 101 | 141 | 128 | 265 | 57 | 101 | 128 | 128 | ... | 128 | 70 | 128 | 3 | 251 | 60 | 128 | 128 | 259 | 128 |
lokasi_mesin | 1360 | 374 | 3988 | 3442 | 7852 | 3674 | 4759 | 7791 | 8414 | 3763 | ... | 2540 | 3489 | 2979 | 1213 | 7314 | 2162 | 8212 | 1486 | 8422 | 503 |
pemilik_mesin | 1637 | 613 | 613 | 613 | 613 | 613 | 613 | 496 | 613 | 613 | ... | 613 | 613 | 613 | 1616 | 2309 | 613 | 613 | 613 | 613 | 613 |
waktu_transaksi | 1970-01-02 17:28:42 | 1970-01-03 10:20:58 | 1970-01-02 22:08:43 | 1970-01-03 05:00:42 | 1970-01-03 07:10:21 | 1970-01-02 19:46:51 | 1970-01-03 04:43:42 | 1970-01-03 07:02:13 | 1970-01-02 11:36:56 | 1970-01-03 04:32:37 | ... | 1970-01-02 11:00:30 | 1970-01-02 01:12:28 | 1970-01-03 07:44:12 | 1970-01-02 05:20:54 | 1970-01-02 23:02:10 | 1970-01-02 17:51:54 | 1970-01-02 23:25:27 | 1970-01-02 00:59:10 | 1970-01-03 04:17:08 | 1970-01-02 12:20:14 |
kuartal_transaksi | 3 | 4 | 3 | 3 | 3 | 3 | 3 | 3 | 2 | 3 | ... | 2 | 2 | 3 | 2 | 3 | 3 | 3 | 2 | 3 | 2 |
kepemilikan_kartu | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 2 | ... | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 |
nama_channel | 5 | 1 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 1 | ... | 1 | 1 | 1 | 5 | 2 | 1 | 1 | 1 | 1 | 1 |
id_channel | 8 | 9 | 9 | 9 | 9 | 9 | 9 | 8 | 9 | 9 | ... | 9 | 9 | 9 | 8 | 4 | 9 | 9 | 9 | 9 | 9 |
flag_transaksi_finansial | False | False | False | False | False | False | False | False | False | False | ... | False | False | False | False | False | False | False | False | False | False |
status_transaksi | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | ... | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
bank_pemilik_kartu | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | ... | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 |
rata_rata_nilai_transaksi | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
maksimum_nilai_transaksi | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
minimum_nilai_transaksi | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
rata_rata_jumlah_transaksi | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
flag_transaksi_fraud | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | ... | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
28 rows × 21 columns
Saya akan coba menggunakan 2 metode dalam mengatasi missing value.
- Drop missing value karena missing value hanya 21 dan secara kumulatif hanya 0.16 % saja kehilangan data (prioritas karena mudah)
- Menggunakan imputasi (singular (
mean
,median
) atau flexible imputation (KNNImputer
atauIterativeImputer
))
fraud = fraud.dropna()
fraud.isna().sum()
X 0
id_tanggal_transaksi_awal 0
tanggal_transaksi_awal 0
tipe_kartu 0
id_merchant 0
nama_merchant 0
tipe_mesin 0
tipe_transaksi 0
nama_transaksi 0
nilai_transaksi 0
id_negara 0
nama_negara 0
nama_kota 0
lokasi_mesin 0
pemilik_mesin 0
waktu_transaksi 0
kuartal_transaksi 0
kepemilikan_kartu 0
nama_channel 0
id_channel 0
flag_transaksi_finansial 0
status_transaksi 0
bank_pemilik_kartu 0
rata_rata_nilai_transaksi 0
maksimum_nilai_transaksi 0
minimum_nilai_transaksi 0
rata_rata_jumlah_transaksi 0
flag_transaksi_fraud 0
dtype: int64
Cek duplikat
fraud.duplicated().any()
False
Alhamdulillah tidak ada duplikat wkwkwkwkwk
(4 poin) Bagaimana cara untuk melakukan feature engineering ataupun pemilihan variabel dari data yang tersedia.
- Apakah terdapat variable yang dihilangkan? Jika iya, kenapa?
- Apakah terdapat variable yang ditambahkan? Jika iya, kenapa?
# numerik
fraud.select_dtypes(include=['object', 'category']).describe().T
count | unique | top | freq | |
---|---|---|---|---|
X | 13104 | 8780 | 2925 | 6 |
id_tanggal_transaksi_awal | 13104 | 360 | 2457509 | 169 |
tipe_kartu | 13104 | 14 | 111 | 4835 |
id_merchant | 13104 | 1121 | -2 | 11287 |
nama_merchant | 13104 | 1105 | 1798 | 11287 |
tipe_mesin | 13104 | 5338 | -3 | 880 |
tipe_transaksi | 13104 | 20 | 26 | 3568 |
nama_transaksi | 13104 | 20 | 10 | 3568 |
id_negara | 13104 | 13 | 96 | 13060 |
nama_negara | 13104 | 12 | 5 | 13059 |
nama_kota | 13104 | 229 | 128 | 5394 |
lokasi_mesin | 13104 | 5810 | 600 | 21 |
pemilik_mesin | 13104 | 1665 | 613 | 10401 |
kuartal_transaksi | 13104 | 4 | 3 | 5211 |
kepemilikan_kartu | 13104 | 2 | 2 | 12218 |
nama_channel | 13104 | 5 | 1 | 10401 |
id_channel | 13104 | 4 | 9 | 10401 |
status_transaksi | 13104 | 1 | 3 | 13104 |
bank_pemilik_kartu | 13104 | 1 | 999 | 13104 |
Apakah terdapat variable yang dihilangkan? Jika iya, kenapa?
Iya, terutama variabel yang hanya menyangkut ID dan Nama yang memiliki nilai unik terlalu banyak akan dihilangkan seperti X
, id_tanggal_transaksi_awal
, id_merchant
, nama_merchant
, tipe_mesin
, tipe_transaksi
, nama_transaksi
, id_negara
, nama_negara
,tipe_kartu
, nama_kota
, lokasi_mesin
, pemilik_mesin
lalu untuk status_transaksi
dan bank_pemilik_kartu
juga dihapus karena kategori yang tidak punya unique value
fraud[['nama_channel', 'id_channel']].corr()
nama_channel | id_channel | |
---|---|---|
nama_channel | 1.000000 | -0.376658 |
id_channel | -0.376658 | 1.000000 |
Karena nama_channel
dan id_channel
tidak berkorelasi cukup kuat seperti asumsi saya diawal jadi dibiarkan saja
fraud_clean = fraud.drop(columns=['X', 'id_tanggal_transaksi_awal', 'id_merchant', 'nama_merchant', 'tipe_mesin', 'tipe_transaksi', 'nama_transaksi', 'id_negara','tipe_kartu', 'nama_negara', 'nama_kota', 'lokasi_mesin', 'pemilik_mesin', 'status_transaksi', 'bank_pemilik_kartu'])
fraud_clean.head().T
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
tanggal_transaksi_awal | 1970-01-29 17:42:06 | 1970-01-29 17:38:27 | 1970-01-29 17:40:12 | 1970-01-29 17:42:26 | 1970-01-29 17:36:25 |
nilai_transaksi | 2200000.0 | 2500000.0 | 1200000.0 | 320000.0 | 150000.0 |
waktu_transaksi | 1970-01-03 12:52:35 | 1970-01-02 03:19:00 | 1970-01-02 21:56:56 | 1970-01-03 02:05:17 | 1970-01-02 22:48:59 |
kuartal_transaksi | 4 | 2 | 3 | 3 | 3 |
kepemilikan_kartu | 2 | 1 | 1 | 2 | 2 |
nama_channel | 1 | 5 | 5 | 2 | 1 |
id_channel | 9 | 8 | 8 | 4 | 9 |
flag_transaksi_finansial | False | False | False | False | False |
rata_rata_nilai_transaksi | 1332292.784 | 1369047.619 | 15523460.4 | 711764.7059 | 617968.254 |
maksimum_nilai_transaksi | 9750000.0 | 10000000.0 | 100000000.0 | 6884408.0 | 2500000.0 |
minimum_nilai_transaksi | 10000.0 | 30000.0 | 41804.0 | 10000.0 | 100000.0 |
rata_rata_jumlah_transaksi | 2.73 | 2.33 | 2.4 | 1.98 | 1.46 |
flag_transaksi_fraud | 0 | 1 | 0 | 0 | 0 |
Apakah terdapat variable yang ditambahkan? Jika iya, kenapa?
Sepertinya belum ada variable yang perlu ditambahkan dikarenakan belum diperlukannya. Namun ada kemungkinan penambahan variabel berdasarkan waktu seperti jam, hari, tanggal dan sebagainya. Beberapa dari variabel kategori atau objek akan ditambahkan untuk keperluan encoding agar input dapat dibaca oleh model. Namun akan dilakukan di cell lain. Lalu untuk variabel tanggal (tanggal_transaksi_awal
, waktu_transaksi
) akan diubah ke dalam bentuk timestamp
agar dapat diproses model juga
Untuk analisis saya akan fokus menggunakan fraud_clean
sedangkan untuk modelling akan menggunakan fraud_clean_enc
Exploratory Data Analysis
(2 poin) Exploratory Data Analyss-
Berikan penjelasan informatif dari visualisasi dan/atau segala jenis hasil eksplorasi An- da. Bagaimana distribusi data pada setiap varia- bel? Apakah terdapat informasi menarik antara variable predictor dengan variable target?
Multivariate analysis
matplotlib.rc('figure', figsize=(10, 5)) # Buat melebarkan gambar
sns.heatmap(fraud_clean.select_dtypes(include=['int64', 'float64']).corr(), # nilai korelasi
annot=True, # anotasi angka di dalam kotak heatmap
fmt=".3f", # format 3 angka dibelakang koma
cmap='Blues'); # warna heatmap
Terlihat insight menarik bahwa korelasi antar prediktor nilai_transaksi
, rata_rata_nilai_transaksi
, dan maksimum_nilai_transaksi
cukup tinggi. Ini akan cukup mempengaruhi model karena redundansi yang tinggi. Mari kita lihat distribusi ketiga variabel tersebut
Distribusi nilai_transaksi
terhadap flag_transaksi_fraud
sns.histplot(data=fraud_clean, x='nilai_transaksi', log_scale=True, kde=True, hue='flag_transaksi_fraud')
<Axes: xlabel='nilai_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='nilai_transaksi', log_scale=True, hue='flag_transaksi_fraud')
<Axes: xlabel='nilai_transaksi'>
Distribusi rata_rata_nilai_transaksi
terhadap flag_transaksi_fraud
sns.histplot(data=fraud_clean, x='rata_rata_nilai_transaksi', log_scale=True, kde=True, hue='flag_transaksi_fraud')
<Axes: xlabel='rata_rata_nilai_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='rata_rata_nilai_transaksi', log_scale=True, hue='flag_transaksi_fraud')
<Axes: xlabel='rata_rata_nilai_transaksi'>
Distribusi maksimum_nilai_transaksi
terhadap flag_transaksi_fraud
sns.histplot(data=fraud_clean, x='maksimum_nilai_transaksi', log_scale=True, kde=True, hue='flag_transaksi_fraud')
<Axes: xlabel='maksimum_nilai_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='maksimum_nilai_transaksi', log_scale=True, hue='flag_transaksi_fraud')
<Axes: xlabel='maksimum_nilai_transaksi'>
Distribusi minimum_nilai_transaksi
terhadap flag_transaksi_fraud
sns.histplot(data=fraud_clean, x='minimum_nilai_transaksi', log_scale=True, kde=True, hue='flag_transaksi_fraud')
<Axes: xlabel='minimum_nilai_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='minimum_nilai_transaksi', log_scale=True, hue='flag_transaksi_fraud')
<Axes: xlabel='minimum_nilai_transaksi'>
Distribusi rata_rata_jumlah_transaksi
terhadap flag_transaksi_fraud
sns.histplot(data=fraud_clean, x='rata_rata_jumlah_transaksi', log_scale=True, kde=True, hue='flag_transaksi_fraud')
<Axes: xlabel='rata_rata_jumlah_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='rata_rata_jumlah_transaksi', log_scale=True, hue='flag_transaksi_fraud')
<Axes: xlabel='rata_rata_jumlah_transaksi'>
Kesimpulan yang didapat pada data kontinu
- Terdapat persebaran yang sangat luas pada
nilai_transaksi
danminimum_nilai_transaksi
. - Untuk
rata_rata_nilai_transaksi
distribusinya cukup normal - Untuk
maksimum_jumlah_transaksi
danrata_rata_jumlah_transaksi
mempunyai skewness yang berlawanan - Untuk
rata_rata_jumlah_transaksi
mempunyai skala yang berbeda dengan yang lain (karena hanya menghitung banyaknya transaksi jadi tidak banyak nilainya dibanding yang lain - Melihat dari boxplot, sepertinya
rata_rata_jumlah_transaksi
dannilai_transaksi
bisa menjadi prediktor yang baik untuk memprediksi target
Analysis tanggal dan transaksi fraud
sns.histplot(data=fraud_clean, x='tanggal_transaksi_awal', hue='flag_transaksi_fraud')
<Axes: xlabel='tanggal_transaksi_awal', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='tanggal_transaksi_awal', hue='flag_transaksi_fraud')
<Axes: xlabel='tanggal_transaksi_awal'>
Kesimpulan dari sini fraud lebih banyak terjadi waktu di waktu yang lebih sore/malam
sns.histplot(data=fraud_clean, x='waktu_transaksi', hue='flag_transaksi_fraud')
<Axes: xlabel='waktu_transaksi', ylabel='Count'>
sns.boxplot(data=fraud_clean, x='waktu_transaksi', hue='flag_transaksi_fraud')
<Axes: xlabel='waktu_transaksi'>
Analysis kategorikal data dengan target
non_num_kolom
['kuartal_transaksi', 'kepemilikan_kartu', 'nama_channel', 'id_channel']
sns.barplot(data=fraud_clean, x='kuartal_transaksi', y='flag_transaksi_fraud' )
<Axes: xlabel='kuartal_transaksi', ylabel='flag_transaksi_fraud'>
Dapat dilihat bahwa transaksi fraud lebih condong ke awal awal kuartal transaksi
sns.barplot(data=fraud_clean, x='kepemilikan_kartu', y='flag_transaksi_fraud' )
<Axes: xlabel='kepemilikan_kartu', ylabel='flag_transaksi_fraud'>
Lalu untuk kepemilikan_kartu
= 1 lebih condong melakukan fraud
sns.barplot(data=fraud_clean, x='nama_channel', y='flag_transaksi_fraud' )
<Axes: xlabel='nama_channel', ylabel='flag_transaksi_fraud'>
Lalu untuk nama_channel
3 dan 5 lebih condong fraud dibanding yang lain
sns.barplot(data=fraud_clean, x='id_channel', y='flag_transaksi_fraud' )
<Axes: xlabel='id_channel', ylabel='flag_transaksi_fraud'>
Lalu untuk id_channel
8 lebih condong fraud dibanding yang lain
Data Pre-processing and Model Fitting
(2 poin) Data Pre-processing
- Apakah terdapat variabel yang harus di-encoding? Kalau ada, apa saja dan kenapa?
Ada yaitu data-data yang masih bersifat kategorikal dan boolean. Alasannya adalah karena model tidak dapat membaca data yang bersifat object
atau categorical
(untuk boolean
masih diperdebatkan karena terkadang ada beberapa model yang bisa membaca boolean
sebagai 1 atau 0).
Untuk kolom yang perlu di encoding adalah kuartal_transaksi
, kepemilikan_kartu
, nama_channel
, id_channel
, flag_transaksi_finansial
Oh iya jangan lupa datetimens[64]
juga terkadang tidak bisa dibaca mode makanya sebaiknya diubah lagi dalam bentuk timestamp
fraud_asli['flag_transaksi_finansial'].value_counts()
flag_transaksi_finansial
False 13125
Name: count, dtype: int64
# Ternyata False semua WKWKWKWKWKWWKK
fraud_clean = fraud_clean.drop(columns='flag_transaksi_finansial')
Dikarenakan variabel nama_channel
dan id_channel
nilai encoding nya punya korelasi tinggi maka salah satu kolom dihapus dan diambillah id_channel
.
Lalu untuk tanggal_transaksi_awal
karena banyak sekali keanehan saat dalam bentuk datettimens(64)
(cuma 1 hari) maka di drop untuk menghindari kesalahan data
non_num_kolom = ['kuartal_transaksi', 'kepemilikan_kartu', 'id_channel']
fraud_clean_enc = pd.get_dummies(fraud_clean,columns=non_num_kolom,drop_first=True,dtype='int')
fraud_clean_enc[dt_kolom] = fraud_asli[dt_kolom]
fraud_clean_enc = fraud_clean_enc.drop(columns=['tanggal_transaksi_awal', 'nama_channel'])
fraud_clean_enc.head().T
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
nilai_transaksi | 2200000.000 | 2.500000e+06 | 1200000.0 | 3.200000e+05 | 150000.000 |
waktu_transaksi | 193955.000 | 7.314000e+04 | 140216.0 | 1.551170e+05 | 143339.000 |
rata_rata_nilai_transaksi | 1332292.784 | 1.369048e+06 | 15523460.4 | 7.117647e+05 | 617968.254 |
maksimum_nilai_transaksi | 9750000.000 | 1.000000e+07 | 100000000.0 | 6.884408e+06 | 2500000.000 |
minimum_nilai_transaksi | 10000.000 | 3.000000e+04 | 41804.0 | 1.000000e+04 | 100000.000 |
rata_rata_jumlah_transaksi | 2.730 | 2.330000e+00 | 2.4 | 1.980000e+00 | 1.460 |
flag_transaksi_fraud | 0.000 | 1.000000e+00 | 0.0 | 0.000000e+00 | 0.000 |
kuartal_transaksi_2 | 0.000 | 1.000000e+00 | 0.0 | 0.000000e+00 | 0.000 |
kuartal_transaksi_3 | 0.000 | 0.000000e+00 | 1.0 | 1.000000e+00 | 1.000 |
kuartal_transaksi_4 | 1.000 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.000 |
kepemilikan_kartu_2 | 1.000 | 0.000000e+00 | 0.0 | 1.000000e+00 | 1.000 |
id_channel_4 | 0.000 | 0.000000e+00 | 0.0 | 1.000000e+00 | 0.000 |
id_channel_8 | 0.000 | 1.000000e+00 | 1.0 | 0.000000e+00 | 0.000 |
id_channel_9 | 1.000 | 0.000000e+00 | 0.0 | 0.000000e+00 | 1.000 |
(4 poin) Membuat model, pilih model berdasarkan model yang sudah diajarkan dikelas (logistic regression / knn)
-
Buatlah model yang dapat menjawab pertanyaan bisnis di atas. : Untuk Capstone, saya akan mencoba menggunakan kedua model
Logit()
danKNN
-
Variable apa yang dirasa cukup penting dalam pembuatan model? Sertakan alasannya. : Untuk model
Logit()
saya akan mencoba menggunakan semua data yang ada, namun ada beberapa prediktor kategorikal akan dihapus karena memiliki korelasi tinggi. Lalu untukKNN
, saya mencoba menggunakan semua nilai numerik yang ada dan melakukan scaling -
Metode evaluasi apa yang cocok digunakan untuk kasus ini? Jelaskan. : Evaluasi yang digunakan adalah
precision
karena target tidak seimbang dan dalam business case ini difokuskan untuk mencari True Positive dengan menurunkan dan menghindari False Positive sebanyak mungkin
Uji coba menggunakan Logistic Regression
Train Test split
X = sm.add_constant(fraud_clean_enc.drop(columns='flag_transaksi_fraud'))
y = fraud_clean_enc['flag_transaksi_fraud']
X.info()
<class 'pandas.core.frame.DataFrame'>
Index: 13104 entries, 0 to 13124
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 const 13104 non-null float64
1 nilai_transaksi 13104 non-null float64
2 waktu_transaksi 13104 non-null int64
3 rata_rata_nilai_transaksi 13104 non-null float64
4 maksimum_nilai_transaksi 13104 non-null float64
5 minimum_nilai_transaksi 13104 non-null float64
6 rata_rata_jumlah_transaksi 13104 non-null float64
7 kuartal_transaksi_2 13104 non-null int32
8 kuartal_transaksi_3 13104 non-null int32
9 kuartal_transaksi_4 13104 non-null int32
10 kepemilikan_kartu_2 13104 non-null int32
11 id_channel_4 13104 non-null int32
12 id_channel_8 13104 non-null int32
13 id_channel_9 13104 non-null int32
dtypes: float64(6), int32(7), int64(1)
memory usage: 1.1 MB
# X = X.iloc[:, :12]
X.corr()
const | nilai_transaksi | waktu_transaksi | rata_rata_nilai_transaksi | maksimum_nilai_transaksi | minimum_nilai_transaksi | rata_rata_jumlah_transaksi | kuartal_transaksi_2 | kuartal_transaksi_3 | kuartal_transaksi_4 | kepemilikan_kartu_2 | id_channel_4 | id_channel_8 | id_channel_9 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
const | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
nilai_transaksi | NaN | 1.000000 | -0.019857 | 0.419086 | 0.219751 | 0.025245 | 0.092394 | 0.018400 | 0.002426 | -0.022916 | -0.019989 | -0.095767 | 0.020400 | 0.069391 |
waktu_transaksi | NaN | -0.019857 | 1.000000 | -0.026441 | -0.019929 | -0.004055 | 0.000056 | -0.661371 | 0.152606 | 0.725364 | 0.028756 | 0.081363 | -0.027334 | -0.051648 |
rata_rata_nilai_transaksi | NaN | 0.419086 | -0.026441 | 1.000000 | 0.674542 | 0.183931 | 0.223442 | 0.021902 | -0.003942 | -0.021849 | -0.015058 | -0.052375 | 0.015319 | 0.035389 |
maksimum_nilai_transaksi | NaN | 0.219751 | -0.019929 | 0.674542 | 1.000000 | 0.045452 | 0.309681 | 0.016373 | -0.008148 | -0.009549 | 0.005384 | -0.015978 | -0.004986 | 0.016988 |
minimum_nilai_transaksi | NaN | 0.025245 | -0.004055 | 0.183931 | 0.045452 | 1.000000 | -0.003797 | -0.001714 | 0.007160 | -0.006077 | -0.008944 | -0.010199 | 0.008779 | 0.003161 |
rata_rata_jumlah_transaksi | NaN | 0.092394 | 0.000056 | 0.223442 | 0.309681 | -0.003797 | 1.000000 | -0.005349 | 0.002426 | 0.002915 | 0.012259 | -0.024747 | -0.011278 | 0.028744 |
kuartal_transaksi_2 | NaN | 0.018400 | -0.661371 | 0.021902 | 0.016373 | -0.001714 | -0.005349 | 1.000000 | -0.561865 | -0.394363 | -0.013247 | -0.081556 | 0.012598 | 0.061437 |
kuartal_transaksi_3 | NaN | 0.002426 | 0.152606 | -0.003942 | -0.008148 | 0.007160 | 0.002426 | -0.561865 | 1.000000 | -0.463386 | 0.002069 | 0.037197 | -0.001212 | -0.030486 |
kuartal_transaksi_4 | NaN | -0.022916 | 0.725364 | -0.021849 | -0.009549 | -0.006077 | 0.002915 | -0.394363 | -0.463386 | 1.000000 | 0.022208 | 0.050322 | -0.021943 | -0.029200 |
kepemilikan_kartu_2 | NaN | -0.019989 | 0.028756 | -0.015058 | 0.005384 | -0.008944 | 0.012259 | -0.013247 | 0.002069 | 0.022208 | 1.000000 | 0.108045 | -0.996364 | 0.528240 |
id_channel_4 | NaN | -0.095767 | 0.081363 | -0.052375 | -0.015978 | -0.010199 | -0.024747 | -0.081556 | 0.037197 | 0.050322 | 0.108045 | 1.000000 | -0.107652 | -0.787051 |
id_channel_8 | NaN | 0.020400 | -0.027334 | 0.015319 | -0.004986 | 0.008779 | -0.011278 | 0.012598 | -0.001212 | -0.021943 | -0.996364 | -0.107652 | 1.000000 | -0.526319 |
id_channel_9 | NaN | 0.069391 | -0.051648 | 0.035389 | 0.016988 | 0.003161 | 0.028744 | 0.061437 | -0.030486 | -0.029200 | 0.528240 | -0.787051 | -0.526319 | 1.000000 |
Membuat kolom dengan korelasi tinggi
X.head()
const | nilai_transaksi | waktu_transaksi | rata_rata_nilai_transaksi | maksimum_nilai_transaksi | minimum_nilai_transaksi | rata_rata_jumlah_transaksi | kuartal_transaksi_2 | kuartal_transaksi_3 | kuartal_transaksi_4 | kepemilikan_kartu_2 | id_channel_4 | id_channel_8 | id_channel_9 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1.0 | 2200000.0 | 193955 | 1.332293e+06 | 9750000.0 | 10000.0 | 2.73 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
1 | 1.0 | 2500000.0 | 73140 | 1.369048e+06 | 10000000.0 | 30000.0 | 2.33 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
2 | 1.0 | 1200000.0 | 140216 | 1.552346e+07 | 100000000.0 | 41804.0 | 2.40 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
3 | 1.0 | 320000.0 | 155117 | 7.117647e+05 | 6884408.0 | 10000.0 | 1.98 | 0 | 1 | 0 | 1 | 1 | 0 | 0 |
4 | 1.0 | 150000.0 | 143339 | 6.179683e+05 | 2500000.0 | 100000.0 | 1.46 | 0 | 1 | 0 | 1 | 0 | 0 | 1 |
fraud_clean_enc.describe().T
count | mean | std | min | 25% | 50% | 75% | max | |
---|---|---|---|---|---|---|---|---|
nilai_transaksi | 13104.0 | 1.314923e+06 | 2.837644e+06 | 1.0 | 2.000000e+05 | 572575.000 | 1.251524e+06 | 7.500000e+07 |
waktu_transaksi | 13104.0 | 1.389062e+05 | 4.788674e+04 | 47.0 | 1.026220e+05 | 140707.000 | 1.754315e+05 | 2.359140e+05 |
rata_rata_nilai_transaksi | 13104.0 | 1.364132e+06 | 1.448583e+06 | 50000.0 | 5.685634e+05 | 1024239.017 | 1.679778e+06 | 2.466667e+07 |
maksimum_nilai_transaksi | 13104.0 | 1.228760e+07 | 1.645905e+07 | 38000.0 | 2.500000e+06 | 6000000.000 | 1.500000e+07 | 1.000000e+08 |
minimum_nilai_transaksi | 13104.0 | 7.651933e+04 | 6.765391e+05 | 1.0 | 2.500000e+04 | 36964.000 | 6.320000e+04 | 7.500000e+07 |
rata_rata_jumlah_transaksi | 13104.0 | 2.436182e+00 | 1.389367e+00 | 1.0 | 1.680000e+00 | 2.100 | 2.790000e+00 | 1.978000e+01 |
flag_transaksi_fraud | 13104.0 | 6.822344e-02 | 2.521386e-01 | 0.0 | 0.000000e+00 | 0.000 | 0.000000e+00 | 1.000000e+00 |
kuartal_transaksi_2 | 13104.0 | 3.234890e-01 | 4.678254e-01 | 0.0 | 0.000000e+00 | 0.000 | 1.000000e+00 | 1.000000e+00 |
kuartal_transaksi_3 | 13104.0 | 3.976648e-01 | 4.894342e-01 | 0.0 | 0.000000e+00 | 0.000 | 1.000000e+00 | 1.000000e+00 |
kuartal_transaksi_4 | 13104.0 | 2.454212e-01 | 4.303531e-01 | 0.0 | 0.000000e+00 | 0.000 | 0.000000e+00 | 1.000000e+00 |
kepemilikan_kartu_2 | 13104.0 | 9.323871e-01 | 2.510901e-01 | 0.0 | 1.000000e+00 | 1.000 | 1.000000e+00 | 1.000000e+00 |
id_channel_4 | 13104.0 | 1.386600e-01 | 3.456045e-01 | 0.0 | 0.000000e+00 | 0.000 | 0.000000e+00 | 1.000000e+00 |
id_channel_8 | 13104.0 | 6.715507e-02 | 2.502999e-01 | 0.0 | 0.000000e+00 | 0.000 | 0.000000e+00 | 1.000000e+00 |
id_channel_9 | 13104.0 | 7.937271e-01 | 4.046441e-01 | 0.0 | 1.000000e+00 | 1.000 | 1.000000e+00 | 1.000000e+00 |
X_train, X_test, y_train, y_test = train_test_split(X,
y, # kolom target
test_size = 0.2, # 80% training and 20% test
random_state = 10,
stratify=y)
X_train.dtypes
const float64
nilai_transaksi float64
waktu_transaksi int64
rata_rata_nilai_transaksi float64
maksimum_nilai_transaksi float64
minimum_nilai_transaksi float64
rata_rata_jumlah_transaksi float64
kuartal_transaksi_2 int32
kuartal_transaksi_3 int32
kuartal_transaksi_4 int32
kepemilikan_kartu_2 int32
id_channel_4 int32
id_channel_8 int32
id_channel_9 int32
dtype: object
Modelling menggunakan Logistic Regression
model_logit = sm.Logit(y_train, X_train)
model_logit.fit().summary()
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.209745
Iterations: 35
C:\Users\SaltFarmer\miniconda3\envs\algoritma\lib\site-packages\statsmodels\base\model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
warnings.warn("Maximum Likelihood optimization failed to "
Dep. Variable: | flag_transaksi_fraud | No. Observations: | 10483 |
---|---|---|---|
Model: | Logit | Df Residuals: | 10469 |
Method: | MLE | Df Model: | 13 |
Date: | Thu, 11 Jan 2024 | Pseudo R-squ.: | 0.1576 |
Time: | 15:02:23 | Log-Likelihood: | -2198.8 |
converged: | False | LL-Null: | -2610.0 |
Covariance Type: | nonrobust | LLR p-value: | 2.158e-167 |
coef | std err | z | P>|z| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
const | -19.0997 | 8660.347 | -0.002 | 0.998 | -1.7e+04 | 1.7e+04 |
nilai_transaksi | 8.383e-08 | 1.15e-08 | 7.266 | 0.000 | 6.12e-08 | 1.06e-07 |
waktu_transaksi | -1.875e-06 | 2.53e-06 | -0.741 | 0.459 | -6.83e-06 | 3.08e-06 |
rata_rata_nilai_transaksi | -1.908e-08 | 3.87e-08 | -0.492 | 0.622 | -9.5e-08 | 5.69e-08 |
maksimum_nilai_transaksi | -1.298e-09 | 3.82e-09 | -0.340 | 0.734 | -8.79e-09 | 6.19e-09 |
minimum_nilai_transaksi | 1.112e-06 | 2.02e-07 | 5.505 | 0.000 | 7.16e-07 | 1.51e-06 |
rata_rata_jumlah_transaksi | -0.2769 | 0.050 | -5.553 | 0.000 | -0.375 | -0.179 |
kuartal_transaksi_2 | -0.4941 | 0.250 | -1.974 | 0.048 | -0.985 | -0.004 |
kuartal_transaksi_3 | -0.4149 | 0.356 | -1.166 | 0.244 | -1.112 | 0.283 |
kuartal_transaksi_4 | -0.5087 | 0.475 | -1.071 | 0.284 | -1.440 | 0.422 |
kepemilikan_kartu_2 | 11.3593 | nan | nan | nan | nan | nan |
id_channel_4 | 5.4534 | nan | nan | nan | nan | nan |
id_channel_8 | 19.7843 | 8660.347 | 0.002 | 0.998 | -1.7e+04 | 1.7e+04 |
id_channel_9 | 5.9059 | nan | nan | nan | nan | nan |
Prediction Performance
- (1 poin) Metrics yang dipilih mencapai 60% pada data train (2 poin) Metrics yang dipilih mencapai 60% pada data test
Hasil metric data train
logit_pred_tr = model_logit.fit().predict(X_train)
logit_pred_tr
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.209745
Iterations: 35
C:\Users\SaltFarmer\miniconda3\envs\algoritma\lib\site-packages\statsmodels\base\model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
warnings.warn("Maximum Likelihood optimization failed to "
11191 0.037380
1027 0.056526
10908 0.057065
4404 0.057710
5958 0.027605
...
3071 0.380087
4977 0.050986
574 0.048985
1717 0.049682
203 0.048698
Length: 10483, dtype: float64
pred_label_tr = logit_pred_tr.apply(lambda x: 1 if x > 0.5 else 0)
pred_label_tr.value_counts()
0 10416
1 67
Name: count, dtype: int64
print(f'Accuracy score: {accuracy_score(y_train, pred_label_tr)}')
print(f'Recall score: {recall_score(y_train, pred_label_tr)}')
print(f'Precision score: {precision_score(y_train, pred_label_tr)}')
Accuracy score: 0.9311265859009825
Recall score: 0.04195804195804196
Precision score: 0.44776119402985076
Karena Precision belum lebih dari 60% maka saya atur lagi thresholdnya
pred_label_tr = logit_pred_tr.apply(lambda x: 1 if x > 0.8 else 0)
pred_label_tr.value_counts()
0 10470
1 13
Name: count, dtype: int64
print(f'Accuracy score: {accuracy_score(y_train, pred_label_tr)}')
print(f'Recall score: {recall_score(y_train, pred_label_tr)}')
print(f'Precision score: {precision_score(y_train, pred_label_tr)}')
Accuracy score: 0.9322712963846227
Recall score: 0.012587412587412588
Precision score: 0.6923076923076923
Sudah ditemukan threshold yang tepat untuk Data Train melebihi nilai threshold 60%
Hasil metric data Test
logit_pred = model_logit.fit().predict(X_test)
logit_pred
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.209745
Iterations: 35
C:\Users\SaltFarmer\miniconda3\envs\algoritma\lib\site-packages\statsmodels\base\model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
warnings.warn("Maximum Likelihood optimization failed to "
12431 0.057628
4523 0.049031
8211 0.011157
4172 0.048879
5746 0.389036
...
11842 0.048245
9454 0.046732
2449 0.055409
3865 0.036163
5465 0.051302
Length: 2621, dtype: float64
pred_label = logit_pred.apply(lambda x: 1 if x > 0.5 else 0)
pred_label.value_counts()
0 2602
1 19
Name: count, dtype: int64
print(f'Accuracy score: {accuracy_score(y_test, pred_label)}')
print(f'Recall score: {recall_score(y_test, pred_label)}')
print(f'Precision score: {precision_score(y_test, pred_label)}')
Accuracy score: 0.9320869896985883
Recall score: 0.055865921787709494
Precision score: 0.5263157894736842
Saya coba atur sedikit threshold nya agar mendapatkan nilai presisi yang diinginkan
pred_label = logit_pred.apply(lambda x: 1 if x > 0.8 else 0)
pred_label.value_counts()
0 2619
1 2
Name: count, dtype: int64
print(f'Accuracy score: {accuracy_score(y_test, pred_label)}')
print(f'Recall score: {recall_score(y_test, pred_label)}')
print(f'Precision score: {precision_score(y_test, pred_label)}')
Accuracy score: 0.9324685234643266
Recall score: 0.0111731843575419
Precision score: 1.0
Melihat hasil metric dari data train dan data test maka model bisa dianggap undefitting (hasil train < hasil test)
Angka Haram
Hasil dengan presisi 1 dan terbaik
# fraud_asli = fraud_asli.dropna()
# X = sm.add_constant(fraud_asli.drop(columns='flag_transaksi_fraud')[['nilai_transaksi', 'waktu_transaksi', 'rata_rata_nilai_transaksi', 'maksimum_nilai_transaksi', 'minimum_nilai_transaksi', 'rata_rata_jumlah_transaksi']])
# y = fraud_asli['flag_transaksi_fraud']
# X_train, X_test, y_train, y_test = train_test_split(X,
# y, # kolom target
# test_size = 0.2, # 80% training and 20% test
# random_state = 10,
# stratify=y)
# X_train
const | nilai_transaksi | waktu_transaksi | rata_rata_nilai_transaksi | maksimum_nilai_transaksi | minimum_nilai_transaksi | rata_rata_jumlah_transaksi | |
---|---|---|---|---|---|---|---|
11191 | 1.0 | 1250000.0 | 155818 | 5.527200e+06 | 75000000.0 | 50000.0 | 2.40 |
1027 | 1.0 | 2500000.0 | 142017 | 1.303347e+06 | 9000000.0 | 33500.0 | 1.84 |
10908 | 1.0 | 100000.0 | 102021 | 3.992588e+05 | 2500000.0 | 22400.0 | 1.11 |
4404 | 1.0 | 2500000.0 | 172626 | 8.525882e+05 | 7000000.0 | 50000.0 | 1.66 |
5958 | 1.0 | 498813.0 | 154446 | 5.185913e+05 | 4318765.0 | 21200.0 | 2.24 |
... | ... | ... | ... | ... | ... | ... | ... |
3071 | 1.0 | 1300000.0 | 151541 | 1.184368e+06 | 10000000.0 | 25000.0 | 2.08 |
4977 | 1.0 | 1250000.0 | 171957 | 1.275961e+06 | 7000000.0 | 50000.0 | 1.73 |
574 | 1.0 | 2499000.0 | 102907 | 2.917987e+06 | 7328969.0 | 500000.0 | 2.50 |
1717 | 1.0 | 1000000.0 | 133843 | 6.063348e+05 | 3500000.0 | 31700.0 | 2.00 |
203 | 1.0 | 300000.0 | 195601 | 5.033857e+05 | 1000000.0 | 100000.0 | 1.40 |
10483 rows × 7 columns
# model_logit2 = sm.Logit(y_train, X_train)
# model_logit2.fit().summary()
Optimization terminated successfully.
Current function value: 0.240125
Iterations 7
Dep. Variable: | flag_transaksi_fraud | No. Observations: | 10483 |
---|---|---|---|
Model: | Logit | Df Residuals: | 10476 |
Method: | MLE | Df Model: | 6 |
Date: | Thu, 11 Jan 2024 | Pseudo R-squ.: | 0.03554 |
Time: | 12:11:09 | Log-Likelihood: | -2517.2 |
converged: | True | LL-Null: | -2610.0 |
Covariance Type: | nonrobust | LLR p-value: | 2.302e-37 |
coef | std err | z | P>|z| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
const | -1.7497 | 0.153 | -11.472 | 0.000 | -2.049 | -1.451 |
nilai_transaksi | 7.637e-08 | 1.05e-08 | 7.274 | 0.000 | 5.58e-08 | 9.7e-08 |
waktu_transaksi | -3.296e-06 | 8.14e-07 | -4.047 | 0.000 | -4.89e-06 | -1.7e-06 |
rata_rata_nilai_transaksi | -3.895e-10 | 3.67e-08 | -0.011 | 0.992 | -7.24e-08 | 7.16e-08 |
maksimum_nilai_transaksi | -2.108e-09 | 3.59e-09 | -0.588 | 0.557 | -9.14e-09 | 4.92e-09 |
minimum_nilai_transaksi | 1.101e-06 | 2.02e-07 | 5.447 | 0.000 | 7.05e-07 | 1.5e-06 |
rata_rata_jumlah_transaksi | -0.2684 | 0.047 | -5.669 | 0.000 | -0.361 | -0.176 |
# logit_pred2 = model_logit2.fit().predict(X_test)
# logit_pred2
Optimization terminated successfully.
Current function value: 0.240125
Iterations 7
12431 0.075937
4523 0.082749
8211 0.015727
4172 0.065997
5746 0.081120
...
11842 0.062634
9454 0.071733
2449 0.072522
3865 0.049655
5465 0.078226
Length: 2621, dtype: float64
# pred_label2 = logit_pred2.apply(lambda x: 1 if x > 0.5 else 0)
# pred_label2.value_counts()
0 2618
1 3
Name: count, dtype: int64
# print(f'Accuracy score: {accuracy_score(y_test, pred_label2)}')
# print(f'Recall score: {recall_score(y_test, pred_label2)}')
# print(f'Precision score: {precision_score(y_test, pred_label2)}')
Accuracy score: 0.9320869896985883
Recall score: 0.0111731843575419
Precision score: 0.6666666666666666
Coba KNN
KNN_model = KNeighborsClassifier(n_neighbors=10)
scaler = StandardScaler()
KNN_model
KNeighborsClassifier(n_neighbors=10)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
KNeighborsClassifier(n_neighbors=10)
fraud_clean_num = fraud_clean_enc.iloc[:, :6]
fraud_clean_num
nilai_transaksi | waktu_transaksi | rata_rata_nilai_transaksi | maksimum_nilai_transaksi | minimum_nilai_transaksi | rata_rata_jumlah_transaksi | |
---|---|---|---|---|---|---|
0 | 2200000.0 | 193955 | 1.332293e+06 | 9750000.0 | 10000.0 | 2.73 |
1 | 2500000.0 | 73140 | 1.369048e+06 | 10000000.0 | 30000.0 | 2.33 |
2 | 1200000.0 | 140216 | 1.552346e+07 | 100000000.0 | 41804.0 | 2.40 |
3 | 320000.0 | 155117 | 7.117647e+05 | 6884408.0 | 10000.0 | 1.98 |
4 | 150000.0 | 143339 | 6.179683e+05 | 2500000.0 | 100000.0 | 1.46 |
... | ... | ... | ... | ... | ... | ... |
13120 | 100000.0 | 140547 | 2.917987e+06 | 7400000.0 | 26500.0 | 2.57 |
13121 | 2500000.0 | 172446 | 1.914437e+06 | 20000000.0 | 100000.0 | 2.73 |
13122 | 1250000.0 | 141836 | 3.417045e+05 | 1000000.0 | 100000.0 | 1.33 |
13123 | 500000.0 | 71451 | 7.644508e+05 | 3000000.0 | 25000.0 | 1.62 |
13124 | 300000.0 | 175350 | 8.483696e+05 | 6375000.0 | 25000.0 | 1.79 |
13104 rows × 6 columns
# prediktor
X = fraud_clean_num
# target
y = fraud_clean_enc['flag_transaksi_fraud']
# Split dataset
X_train, X_test, y_train, y_test = train_test_split(X, # kolom prediktor
y, # kolom target
test_size = 0.2, # 80% training and 20% test
random_state = 10,
stratify = y)
Scaling
cols = X_train.columns
scaler.fit(X_train)
X_train_scale = scaler.transform(X_train)
X_test_scale = scaler.transform(X_test)
KNN_model.fit(X_train_scale, y_train)
pred_knn_tr = KNN_model.predict(X_train_scale)
print(f'Accuracy score: {accuracy_score(y_train, pred_knn_tr)}')
print(f'Recall score: {recall_score(y_train, pred_knn_tr)}')
print(f'Precision score: {precision_score(y_train, pred_knn_tr)}')
Accuracy score: 0.9324620814652295
Recall score: 0.013986013986013986
Precision score: 0.7692307692307693
Precision score dari KNN sudah cukup memuaskan karena sudah diatas 60%
KNN_model.fit(X_train_scale, y_train)
pred_knn_label = KNN_model.predict(X_test_scale)
print(f'Accuracy score: {accuracy_score(y_test, pred_knn_label)}')
print(f'Recall score: {recall_score(y_test, pred_knn_label)}')
print(f'Precision score: {precision_score(y_test, pred_knn_label)}')
Accuracy score: 0.9328500572300649
Recall score: 0.01675977653631285
Precision score: 1.0
Didapatkan score precisision dari Data Test yang lebih tinggi lagi sehingga dianggap modelnya underfitting (hasil train < hasil test)
Conclusion
(2 poin) Tuliskan kesimpulan dari project yang anda kerjakan.
- Apakah model sudah dapat melakukan prediksi dengan baik? Jelaskan
Sudah cukup baik karena memenuhi pertanyaan bisnis untuk metric precision
diatas 60%. Untuk kedua model Logit()
dan KNN()
sudah cukup memuaskan dengan hasil KNN()
yang lebih baik pada Data Test. Kedua model tersebut juga perlu dilakukan tuning parameter seperti threshold
di logit dan n_neighbor
di KNN agar mendapatkan hasil yang diinginkan
- Apakah model sudah dapat menjawab pertanyaan bisnis yang ada? Jelaskan.
Sudah, karena pertanyaan bisnisnya mendeteksi fraud sebaik mungkin. Dikarenakan ketidakseimbangan jumlah target, maka metric yang digunakan pun harus tepat untuk fokus melihat True Positive sebaik mungkin dan melihat False Negative sesedikit mungkin. Dari hasil diatas, model Logit dan KNN sudah bekerja dengan baik sudah memenuhi standar presisi yang diinginkan.
- Action plan apa yang dapat dilakukan untuk tindakan preventif transaksi fraud?
Berdasarkan hasil dari model Logit, maka perlu diwaspadai saat ada momen nilai_transaksi
, minimum_nilai_transaksi
, tinggi serta mempunyai kepemilikan_kartu
2 dan melakukan id_channel
selain 3 dikarenakan variabel - variabel ber koefisiensi positive terhadap model dalam memberikan peluang positif Fraud
Freestyle SMOTE dan XGBoost
fraud_clean_enc
Index(['nilai_transaksi', 'waktu_transaksi', 'rata_rata_nilai_transaksi',
'maksimum_nilai_transaksi', 'minimum_nilai_transaksi',
'rata_rata_jumlah_transaksi', 'flag_transaksi_fraud',
'kuartal_transaksi_2', 'kuartal_transaksi_3', 'kuartal_transaksi_4',
'kepemilikan_kartu_2', 'id_channel_4', 'id_channel_8', 'id_channel_9'],
dtype='object')
from imblearn.combine import SMOTEENN
sme = SMOTEENN(random_state=10)
X_0 = fraud_clean_enc.drop(columns='flag_transaksi_fraud')
y_0 = fraud_clean_enc['flag_transaksi_fraud']
X_res, y_res = sme.fit_resample(X_0, y_0)
y_res.value_counts()
flag_transaksi_fraud
1 10106
0 8553
Name: count, dtype: int64
X_res.shape
(18659, 13)
fraud_clean_enc['flag_transaksi_fraud'].value_counts()
flag_transaksi_fraud
0 12210
1 894
Name: count, dtype: int64
from xgboost import XGBClassifier
xgb = XGBClassifier(random_state=10)
X_train, X_test, y_train, y_test = train_test_split(X_res, # kolom prediktor
y_res, # kolom target
test_size = 0.2, # 80% training and 20% test
random_state = 10,
stratify = y_res)
xgb.fit(X_train, y_train)
XGBClassifier(base_score=None, booster=None, callbacks=None, colsample_bylevel=None, colsample_bynode=None, colsample_bytree=None, device=None, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, feature_types=None, gamma=None, grow_policy=None, importance_type=None, interaction_constraints=None, learning_rate=None, max_bin=None, max_cat_threshold=None, max_cat_to_onehot=None, max_delta_step=None, max_depth=None, max_leaves=None, min_child_weight=None, missing=nan, monotone_constraints=None, multi_strategy=None, n_estimators=None, n_jobs=None, num_parallel_tree=None, random_state=10, ...)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
XGBClassifier(base_score=None, booster=None, callbacks=None, colsample_bylevel=None, colsample_bynode=None, colsample_bytree=None, device=None, early_stopping_rounds=None, enable_categorical=False, eval_metric=None, feature_types=None, gamma=None, grow_policy=None, importance_type=None, interaction_constraints=None, learning_rate=None, max_bin=None, max_cat_threshold=None, max_cat_to_onehot=None, max_delta_step=None, max_depth=None, max_leaves=None, min_child_weight=None, missing=nan, monotone_constraints=None, multi_strategy=None, n_estimators=None, n_jobs=None, num_parallel_tree=None, random_state=10, ...)
pred_tr = xgb.predict(X_train)
pred_tr
array([0, 1, 0, ..., 1, 1, 0])
print(f'Accuracy score: {accuracy_score(y_train, pred_tr)}')
print(f'Recall score: {recall_score(y_train, pred_tr)}')
print(f'Precision score: {precision_score(y_train, pred_tr)}')
Accuracy score: 0.9952435184564883
Recall score: 0.9922077922077922
Precision score: 0.9990037359900373
pred_ts = xgb.predict(X_test)
pred_ts
array([1, 1, 1, ..., 0, 0, 1])
print(f'Accuracy score: {accuracy_score(y_test, pred_ts)}')
print(f'Recall score: {recall_score(y_test, pred_ts)}')
print(f'Precision score: {precision_score(y_test, pred_ts)}')
Accuracy score: 0.964898177920686
Recall score: 0.9609104403760514
Precision score: 0.9739217652958877
model_logit3 = sm.Logit(y_train, X_train)
model_logit3.fit().summary()
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.290377
Iterations: 35
C:\Users\SaltFarmer\miniconda3\envs\algoritma\lib\site-packages\statsmodels\base\model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
warnings.warn("Maximum Likelihood optimization failed to "
Dep. Variable: | flag_transaksi_fraud | No. Observations: | 14927 |
---|---|---|---|
Model: | Logit | Df Residuals: | 14914 |
Method: | MLE | Df Model: | 12 |
Date: | Thu, 11 Jan 2024 | Pseudo R-squ.: | 0.5790 |
Time: | 14:25:01 | Log-Likelihood: | -4334.5 |
converged: | False | LL-Null: | -10295. |
Covariance Type: | nonrobust | LLR p-value: | 0.000 |
coef | std err | z | P>|z| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
nilai_transaksi | 2.549e-07 | 1.37e-08 | 18.650 | 0.000 | 2.28e-07 | 2.82e-07 |
waktu_transaksi | 4.549e-05 | 1.14e-06 | 39.752 | 0.000 | 4.32e-05 | 4.77e-05 |
rata_rata_nilai_transaksi | 6.933e-08 | 3.18e-08 | 2.182 | 0.029 | 7.07e-09 | 1.32e-07 |
maksimum_nilai_transaksi | -1.684e-08 | 2.85e-09 | -5.909 | 0.000 | -2.24e-08 | -1.13e-08 |
minimum_nilai_transaksi | 2.725e-06 | 2.21e-07 | 12.346 | 0.000 | 2.29e-06 | 3.16e-06 |
rata_rata_jumlah_transaksi | -0.0988 | 0.024 | -4.099 | 0.000 | -0.146 | -0.052 |
kuartal_transaksi_2 | -2.9516 | 0.095 | -31.185 | 0.000 | -3.137 | -2.766 |
kuartal_transaksi_3 | -5.2644 | 0.138 | -38.187 | 0.000 | -5.535 | -4.994 |
kuartal_transaksi_4 | -8.5689 | 0.202 | -42.511 | 0.000 | -8.964 | -8.174 |
kepemilikan_kartu_2 | 19.4428 | 2287.246 | 0.009 | 0.993 | -4463.477 | 4502.362 |
id_channel_4 | -23.9954 | 2287.246 | -0.010 | 0.992 | -4506.915 | 4458.924 |
id_channel_8 | -0.3650 | 0.106 | -3.455 | 0.001 | -0.572 | -0.158 |
id_channel_9 | -22.4858 | 2287.246 | -0.010 | 0.992 | -4505.405 | 4460.434 |
logit_pred_tr2 = model_logit3.fit().predict(X_train)
logit_pred_tr2
Warning: Maximum number of iterations has been exceeded.
Current function value: 0.290377
Iterations: 35
C:\Users\SaltFarmer\miniconda3\envs\algoritma\lib\site-packages\statsmodels\base\model.py:607: ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
warnings.warn("Maximum Likelihood optimization failed to "
4595 0.475110
15122 0.978847
5773 0.342949
10132 0.853132
18484 0.757783
...
2803 0.415036
14465 0.998638
12002 0.999722
12342 0.887879
3115 0.110515
Length: 14927, dtype: float64
pred_label = logit_pred_tr2.apply(lambda x: 1 if x > 0.5 else 0)
pred_label.value_counts()
0 7604
1 7323
Name: count, dtype: int64
print(f'Accuracy score: {accuracy_score(y_train, pred_label)}')
print(f'Recall score: {recall_score(y_train, pred_label)}')
print(f'Precision score: {precision_score(y_train, pred_label)}')
Accuracy score: 0.8929456689220875
Recall score: 0.8540507111935683
Precision score: 0.9429195684828622
Leave a comment