Credit risk adalah resiko yang harus ditanggung oleh seorang individu atau lembaga ketika memberikan pinjaman - biasanya dalam bentuk uang - ke individu atau pihak lain.
Resiko ini berupa tidak bisa dibayarkannya pokok dan bunga pinjaman, sehingga mengakibatkan kerugian berikut:
Untuk memperkecil resiko kredit ini, biasanya dilakukan proses yang disebut dengan credit scoring dan credit rating terhadap pihak peminjam. Hasil proses ini akan menjadi basis untuk menentukan apakah aplikasi pengajuan pinjaman baru diterima atau ditolak.
Credit score adalah nilai resiko yang diberikan kepada seorang individu atau organisasi yang mengajukan pinjaman berdasarkan rekam jejak pinjaman dan pembayaran yang dilakukan. Proses pemberian credit score ini biasanya disebut sebagai credit scoring.
Perhitungan credit score biasanya dibuat berdasarkan data riwayat lamanya keterlambatan pembayaran dan yang tidak bayar sama sekali (bad debt). Bad debt biasanya mengakibatkan lembaga pemberian kredit harus menyita aset atau melakukan write off. Nilai credit score biasanya bervariasi antar lembaga. Namun banyak yang kemudian mengadopsi model FICO Score yang memiliki rentang nilai 300 - 850. Semakin tinggi nilai yang didapatkan, maka semakin baik tingkat kemampuan seseorang atau sebuah lembaga untuk membayar pinjaman.
Jadi, credit score adalah nilai kemampuan seorang individu atau organisasi untuk melunasi pembayaran berdasarkan rekam jejak historisnya.
Kadang banyak lembaga yang menggunakan risk rating atau tingkat resiko. Terbalik dengan credit score, semakin tinggi rating ini menunjukkan resiko yang semakin meningkat.
Selain itu kodifikasi juga dibuat lebih sederhana dibandingkan rentang nilai sehingga keputusan yang bisa diambil lebih cepat. Contoh, misalkan penggunaan kombinasi seperti huruf AAA, AA+, P-1, dan seterusnya. Atau untuk banyak internal lembaga peminjam, kategorisasi hanya menggunakan rentang angka yang kecil misalkan 1 sampai dengan 5.
Mari lihat contoh data risk rating dengan pendekatan terakhir ini pada contoh tabel dibawah.
Contoh data risk rating yang dihasilkan berdasarkan data historis lamanya proses pengembalian pinjaman. Perhatikan kolom risk_rating dimana terdapat angka 1 sampai dengan 5 - yang menunjukkan resiko terendah sampai tertinggi.
Dataset dapat diunduh di sini.
Kolom risk_rating ini berelasi langsung dengan kolom overdue_average, atau kolom keterlambatan pembayaran.
Dari sini juga beberapa kolom juga diambil oleh analis untuk mencari pola keterkaitannya terhadap rating ini, yaitu:
Adapaun rekam jejak historis yang digunakan sebagai basis untuk perhitungan credit score dan risk rating yaitu keterlambatan pembyaran pinjaman.
Masih terkait dengan contoh data sebelumnya, dibawah ini diberikan ilustrasi aktivitas tindak lanjut terhadap data dengan contoh skenario berikut.
Seorang analis akan melakukan penelusuran terhadap data sebelumnya untuk mencari pola. Berikut adalah temuannya:
Dari kedua temuan ini, analis akan membentuk aturan-aturan untuk menuntun pengambilan keputusan (decision making model) terhadap pengajuan pinjaman baru untuk sebagai berikut:
Nah, tiga aturan itu akan disebut sebagai model untuk memprediksi nilai risk rating dan menjadi basis pengambilan keputusan terhadap aplikasi pinjaman baru.
Dengan model ini, lembaga pinjaman akan semakin cepat mengambil keputusan dan dengan tingkat kesalahan pengambilan keputusan yang lebih minim.
Adapun yang dilakukan oleh analyst dari skenario diatas adalah mencari pola antara credit score dengan variabel lain dan membuat model pengambilan keputusan untuk apliaksi pinjaman baru.
Credit risk adalah resiko yang harus ditanggung oleh seorang individu atau lembaga ketika memberikan pinjaman - biasanya dalam bentuk uang - ke individu atau pihak lain.
Resiko ini berupa tidak bisa dibayarkannya pokok dan bunga pinjaman, sehingga mengakibatkan kerugian berikut:
Credit score dan risk rating adalah dua penilaian yang dilakukan meminimalkan resiko dari pihak pemberi kredit. Karena berdasarkan kedua model penilaian tersebut, akan diputuskan apakah aplikasi peminjaman seseorang disetujui atau ditolak.
Pada bab setelah ini, akan dilihat bagaimana model penilaian ini distrukturkan dalam bentuk decision tree.
Pada bab sebelumnya telah disebutkan sedikit mengenai proses pengambilan keputusan dengan konstruksi rangkaian logika; “Jika kondisi x maka … selain itu …” atau dikenal dengan “IF … ELSE …”.
Dari contoh bab satu, rangkaiannya terlihat sebagai berikut:
Rangkaian ini sebenarnya bisa dimodelkan kembali dengan apa yang dinamakan struktur pohon keputusan atau decision tree, seperti ditampilkan secara visual sebagai berikut.
Disini, proses pengambilan keputusan adalah melihat dari kondisi paling atas, yaitu berapa jumlah tanggungan. Jika tanggungannya berjumlah 3 atau 4 maka akan langsung ke kotak bawah paling kanan yang menunjukkan rating 3.
Untuk jumlah tanggungan 5 dan durasi pinjaman kurang dari 30 maka akan masuk ke rating nilai 4.
Berikut adalah komponen dari decision tree:
Mengerti komponen-komponen ini sangat penting untuk nanti memahami output dari algoritma machine learning yang digunakan.
Dibawah adalah contoh otomatisasi model decision tree dengan menggunakan salah satu algoritma populer di R, yaitu C5.0. Package C5.0 digunakan untuk pengenolan pola dengan pemodelan decision tree dan rule-based. Selengkapnya di sini.
Bagian ini hanya untuk mendemostrasikan baris kode dan output nya. Untuk penjelasan akan diterangkan nantinya.
library("openxlsx")
library("C50")
# Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "credit_scoring_dqlab.xlsx")
dataCreditRating$risk_rating <- as.factor(dataCreditRating$risk_rating)
# Menggunakan C5.0
drop_columns <- c("kpr_aktif", "pendapatan_setahun_juta", "risk_rating", "rata_rata_overdue")
datafeed <- dataCreditRating[ , !(names(dataCreditRating) %in% drop_columns)]
modelKu <- C5.0(datafeed, as.factor(dataCreditRating$risk_rating))
summary(modelKu)
##
## Call:
## C5.0.default(x = datafeed, y = as.factor(dataCreditRating$risk_rating))
##
##
## C5.0 [Release 2.07 GPL Edition] Fri Mar 12 13:00:32 2021
## -------------------------------
##
## Class specified by attribute `outcome'
##
## Read 900 cases (4 attributes) from undefined.data
##
## Decision tree:
##
## jumlah_tanggungan > 4:
## :...durasi_pinjaman_bulan <= 24: 4 (112/30)
## : durasi_pinjaman_bulan > 24: 5 (140/55)
## jumlah_tanggungan <= 4:
## :...jumlah_tanggungan > 2: 3 (246/22)
## jumlah_tanggungan <= 2:
## :...durasi_pinjaman_bulan <= 36: 1 (294/86)
## durasi_pinjaman_bulan > 36:
## :...jumlah_tanggungan <= 0: 2 (41/8)
## jumlah_tanggungan > 0: 3 (67/4)
##
##
## Evaluation on training data (900 cases):
##
## Decision Tree
## ----------------
## Size Errors
##
## 6 205(22.8%) <<
##
##
## (a) (b) (c) (d) (e) <-classified as
## ---- ---- ---- ---- ----
## 208 2 5 6 6 (a): class 1
## 86 33 21 6 13 (b): class 2
## 4 287 (c): class 3
## 2 82 36 (d): class 4
## 18 85 (e): class 5
##
##
## Attribute usage:
##
## 100.00% jumlah_tanggungan
## 72.67% durasi_pinjaman_bulan
##
##
## Time: 0.0 secs
Hasil diatas adalah bentuk representasi tree/pohon dalam bentuk teks. Dimana pengecekan akan dimulai dari variabel jumlah_tanggungan. Sebagai contoh, jika jumlah tanggungan lebih dari 4 dan durasi pinjaman sampai dengan maksimal 24 bulan maka rating diberikan nilai 4.
Decision tree adalah struktur model untuk pengambilan keputusan dimana mengikuti alur dari suatu titik awal (yang disebut root node), kondisi-kondisi berikutnya, sampai mencapai kesimpulan.
Komponen-komponen dari decision tree ini yaitu root node, branch atau split, node, dan leaf node.
Ini adalah model output yang cocok dihasilkan para analis untuk membantu mengidentifikasi risk rating. Dan beruntungnya, model ini bisa otomatis dihasilkan dari algoritma machine learning dengan input data historis credit. Dan ini telah ditunjukkan dengan contoh menggunakan algoritma bernama C5.0.
C5.0 adalah kode penamaan suatu algoritma untuk decision tree. Banyak algoritma lain seperti random forest, CART, CHAID, MARS, dan lain-lain. Namun C5.0 adalah algoritma yang sangat populer karena memiliki performa yang sangat baik dari sisi kecepatan maupun akurasi.
Algoritma ini sering dikategorikan sebagai classification, dimana tujuannya adalah untuk mengkategorikan atau mengklasifikan sesuatu - pada contoh risk rating - berdasarkan input dari data-data lain.
Mari lihat contoh data dari gambar berikut ini dimana tiap header kolom diberi bulatan merah dengan penomoran.
Tujuan dari pelajaran ini adalah memprediksi nilai pada kolom risk rating (7) berdasarkan data-data lain yang menyertai (1 s/d 6). Dengan demikian, risk rating disebut sebagai class variable. Kolom-kolom lainnya disebut sebagai input variables. Input variables bisa digunakan sebagian saja, namun class variable harus selalu digunakan untuk membentuk model.
Dan pada algoritma C5.0 di R, class variable harus selalu berupa factor. Jadi jika dibaca sebagai tipe data lain, maka harus dikonversi terlebih dahulu menjadi factor.
Satu class varible diperlukan untuk membentuk model decision tree.
Coba lihat tipe data setiap kolom dari dataset atau varibel dataCreditRating.
## 'data.frame': 900 obs. of 7 variables:
## $ kode_kontrak : chr "AGR-000001" "AGR-000011" "AGR-000030" "AGR-000043" ...
## $ pendapatan_setahun_juta: num 295 271 159 210 165 220 70 88 163 100 ...
## $ kpr_aktif : chr "YA" "YA" "TIDAK" "YA" ...
## $ durasi_pinjaman_bulan : num 48 36 12 12 36 24 36 48 48 36 ...
## $ jumlah_tanggungan : num 5 5 0 3 0 5 3 3 5 6 ...
## $ rata_rata_overdue : chr "61 - 90 days" "61 - 90 days" "0 - 30 days" "46 - 60 days" ...
## $ risk_rating : num 4 4 1 3 2 1 2 2 2 2 ...
Untuk class variable, yaitu kolom risk_rating ternyata masih dibaca dalam bentuk numerik. Untuk menjadi class variable yang digunakan pada algoritma C5.0, maka perlu dikonversi menjadi factor. Ini bisa dilakukan dengan menggunakan fungsi as.factor() yang disimpan ke dalam variabel yang sudah mengarah ke kolom yang ingin dikonversi.
dataCreditRating$risk_rating <- as.factor(dataCreditRating$risk_rating)
Maka kolom risk_rating sudah bertipe data factor dan class variabel sudah terbentuk.
## 'data.frame': 900 obs. of 7 variables:
## $ kode_kontrak : chr "AGR-000001" "AGR-000011" "AGR-000030" "AGR-000043" ...
## $ pendapatan_setahun_juta: num 295 271 159 210 165 220 70 88 163 100 ...
## $ kpr_aktif : chr "YA" "YA" "TIDAK" "YA" ...
## $ durasi_pinjaman_bulan : num 48 36 12 12 36 24 36 48 48 36 ...
## $ jumlah_tanggungan : num 5 5 0 3 0 5 3 3 5 6 ...
## $ rata_rata_overdue : chr "61 - 90 days" "61 - 90 days" "0 - 30 days" "46 - 60 days" ...
## $ risk_rating : Factor w/ 5 levels "1","2","3","4",..: 4 4 1 3 2 1 2 2 2 2 ...
Tidak semua input variabel yang perlu akan gunakan, apalagi yang sangat berkaitan sangat erat dengan risk_rating, yaitu rata_rata_overdue. Input variabel ini akan dibuang. Proses ini disebut sebagai feature selection.
Karena menggunakan data frame sebagai tipe data input untuk C5.0, maka fields/kolom-kolom yang ingin digunakan bisa dimasukkan sebagai vector sebagai filter.
Berikut adalah perintah untuk membuat vektor nama kolom yang dibutuhkan saat ini, yaitu durasi_pinjaman_bulan dan jumlah_tanggungan. Hasil filtering ini disimpan ke variabel baru bernama datafeed, dan perintah terakhir yang digunakan melihat struktur variabel ini.
# Menghilangkan beberapa variable input dari dataset
input_columns <- c("durasi_pinjaman_bulan", "jumlah_tanggungan")
datafeed <- dataCreditRating[ , input_columns ]
str(datafeed)
## 'data.frame': 900 obs. of 2 variables:
## $ durasi_pinjaman_bulan: num 48 36 12 12 36 24 36 48 48 36 ...
## $ jumlah_tanggungan : num 5 5 0 3 0 5 3 3 5 6 ...
Catatan: kode_kontrak harusnya tidak dipilih karena unik untuk keseluruhan data, dan tidak menjadi penentu untuk membentuk pola. Tetapi ini dimasukkan dengan tujuan untuk menunjukkan C5.0 memiliki kemampuan untuk membuang variabel input yang tidak relevan secara otomatis.
Untuk proses pembentukan model machine learning dan melihat akurasinya, biasanya dataset perlu dibagi menjadi dua, yaitu:
Pembentukan ini biasanya menggunakan metode pemilihan acak.
Training dan testing set akan mengambil dari variabel data frame bernama datafeed yang telah dipersiapkan sebelumnya. Jumlah baris dataset adalah 900, dimana akan mengambil 800 baris secara acak sebagai training set dan sisa 100 sebagai testing set.
Langkah pertama adalah menyusun index untuk training set, caranya adalah menggunakan kedua perintah berikut.
# Mempersiapkan porsi index acak untuk training dan testing set
set.seed(100)
indeks_training_set <- sample(900, 800)
Dimana:
Langkah kedua adalah membuat variabel untuk training set (input dan class variable) dan testing set (input variable saja) berdasarkan indeks di atas.
Ingat, dalam kasus ini; training = pembentukan model, dan testing = pengujian model.
Perintahnya sebagai berikut.
# Membuat dan menampilkan training set dan testing set
input_training_set <- datafeed[indeks_training_set,]
class_training_set <- dataCreditRating[indeks_training_set,]$risk_rating
input_testing_set <- datafeed[-indeks_training_set,]
Dimana:
Jika dijalankan akan tampil dua struktur dataset dimana satunya berjumlah 800 baris dan satunya berjumlah 100.
str(input_training_set)
str(class_training_set)
str(input_testing_set)
Dengan persiapan sebelumnya, sekarang saatnya menggunakan algoritma C5.0 untuk menghasilkan model decision tree dengan menggunakan fungsi yang juga bernama C5.0. Function ini juga memerlukan package R yang bernama “C50”.
Fungsi C5.0 mengambil beberapa argumen didalamnya. Contohnya C5.0(x, y, trials = …, …). Baca selengkapnya di sini. Namun tidak semua argumen akan digunakan. Atau agar lebih mudah rumus fungsi C5.0 dalam kasus ini yaitu C5.0(input_variables, class_variables).
Dari variabel sebelumnya, hanya butuh argumen x dan y.
Dimana x dan y di fungsi C5.0:
Dengan menggunakan dataset yang sudah disiapkan maka perintah untuk membentuk model dengan fungsi C5.0 dan sekaligus menyimpannya dalam satu variabel bernama risk_rating_model adalah sebagai berikut:
risk_rating_model <- C5.0(input_training_set, class_training_set)
# Melihat overview dari model diatas
summary(risk_rating_model)
##
## Call:
## C5.0.default(x = input_training_set, y = class_training_set)
##
##
## C5.0 [Release 2.07 GPL Edition] Fri Mar 12 13:00:33 2021
## -------------------------------
##
## Class specified by attribute `outcome'
##
## Read 800 cases (3 attributes) from undefined.data
##
## Decision tree:
##
## jumlah_tanggungan > 4:
## :...durasi_pinjaman_bulan <= 24: 4 (105/30)
## : durasi_pinjaman_bulan > 24: 5 (120/51)
## jumlah_tanggungan <= 4:
## :...jumlah_tanggungan > 2: 3 (216/20)
## jumlah_tanggungan <= 2:
## :...durasi_pinjaman_bulan <= 36: 1 (264/80)
## durasi_pinjaman_bulan > 36:
## :...jumlah_tanggungan <= 0: 2 (37/7)
## jumlah_tanggungan > 0: 3 (58/4)
##
##
## Evaluation on training data (800 cases):
##
## Decision Tree
## ----------------
## Size Errors
##
## 6 192(24.0%) <<
##
##
## (a) (b) (c) (d) (e) <-classified as
## ---- ---- ---- ---- ----
## 184 2 5 6 6 (a): class 1
## 80 30 19 6 11 (b): class 2
## 3 250 (c): class 3
## 2 75 34 (d): class 4
## 18 69 (e): class 5
##
##
## Attribute usage:
##
## 100.00% jumlah_tanggungan
## 73.00% durasi_pinjaman_bulan
##
##
## Time: 0.0 secs
Detail output akan dijelaskan berikutnya.
Ingat, training set untuk input variables dan traning set untuk class variables adalah yang diperlukan untuk menghasilkan model C5.0.
Selain model teks dari output sebelumnya, bisa juga menghasilkan decision tree dalam bentuk grafik. Dan hanya butuh satu perintah untuk melakukan hal ini, yaitu:
risk_rating_model <- C5.0(input_training_set, class_training_set)
# Visualisasi model
plot(risk_rating_model)
Dari perintah diatas akan mendapatkan diagram decision tree sebagai berikut.
Ingat-ingat kembali mana yang disebut node, leaf node, dll agar dapat menjelaskan grafik dengan baik.
Algoritma C5.0 adalah algoritma machine learning yang digunakan untuk membentuk model pohon keputusan (decision tree) secara otomatis, dan cocok untuk memodelkan dan sebagi alat prediksi credit rating.
Karena algoritma ini masuk ke dalam kategori classification, variabel yang diperlukan oleh algoritma ini ada dua macam:
Dan untuk mengukur akurasi dari model yang dihasilkan, sebaiknya membagi dataset yang ada menjadi dua porsi secara random:
Setelah semua persiapan dataset ini selesai, lalu menggunakan fungsi C5.0 untuk membentuk model risk rating. Dan untuk mencetak hasil yang bisa dibaca atas model ini, digunakan fungsi summary(). Sedangkan untuk menghasilkan diagram decision tree maka gunakan perintah plot. Semua function ini dari package C5.0.
Sebelumnya pada bab Mengahasilkan Model dengan Fungsi C5.0, terdapat output/overview dari summary fungsi C5.0. Yang mana output nya sebagai berikut.
##
## Call:
## C5.0.default(x = input_training_set, y = class_training_set)
##
##
## C5.0 [Release 2.07 GPL Edition] Fri Mar 12 13:00:33 2021
## -------------------------------
##
## Class specified by attribute `outcome'
##
## Read 800 cases (3 attributes) from undefined.data
##
## Decision tree:
##
## jumlah_tanggungan > 4:
## :...durasi_pinjaman_bulan <= 24: 4 (105/30)
## : durasi_pinjaman_bulan > 24: 5 (120/51)
## jumlah_tanggungan <= 4:
## :...jumlah_tanggungan > 2: 3 (216/20)
## jumlah_tanggungan <= 2:
## :...durasi_pinjaman_bulan <= 36: 1 (264/80)
## durasi_pinjaman_bulan > 36:
## :...jumlah_tanggungan <= 0: 2 (37/7)
## jumlah_tanggungan > 0: 3 (58/4)
##
##
## Evaluation on training data (800 cases):
##
## Decision Tree
## ----------------
## Size Errors
##
## 6 192(24.0%) <<
##
##
## (a) (b) (c) (d) (e) <-classified as
## ---- ---- ---- ---- ----
## 184 2 5 6 6 (a): class 1
## 80 30 19 6 11 (b): class 2
## 3 250 (c): class 3
## 2 75 34 (d): class 4
## 18 69 (e): class 5
##
##
## Attribute usage:
##
## 100.00% jumlah_tanggungan
## 73.00% durasi_pinjaman_bulan
##
##
## Time: 0.0 secs
Pada bab ini akan dijelaskan lebih lanjut output tersebut.
Mari perhatikan baris setelah karakter “———-” atau baris ke-9. Akan dijelaskan secara satu persatu setiap barisnya. output lainnya dijelaskan menyusul.
control = C5.0(label = "Risk Rating")
Secara default dalam function C5.0, control memang menggunakan fungsi C5.0Control. Baca selengkapnya tentang fungsi C5.0 dan fungsi C5.0Control.
Berikut contoh bagian baris kode diatas yang sudah disisipkan ke dalam fungsi C5.0:
# Mengganti nama/label class variable
risk_rating_model <- C5.0(
input_training_set,
class_training_set,
control = C5.0Control(label="Risk Rating")
)
summary(risk_rating_model)
Maka terlihat, class variable sudah diberi label “Risk Rating”.
## [1] "Class specified by attribute `Risk Rating'"
Lanjut fokus ke baris berikut dari summary C5.0.
Read 800 cases (3 attributes) from undefined.data: Hasil ini artinya C5.0 membaca 800 baris data. Ini karena tadi mengambil 800 dari 900 data menggunakan fungsi sample(); lihat baris kode bagian kesatu di bab Mempersiapkan Traning dan Testing Set
… (3 attributes) ….: ini artinya ada memiliki tiga variabel, yaitu:
input variables: durasi_pinjaman dan jumlah_tanggungan. Dua variable ini didapatkan dari hasil baris kode dibawah:
class variable: risk_rating
Berikut adalah gambar tampilan dari tiga variabel tersebut di Excel.
Saatnya fokus ke baris yang paling menarik, yaitu tampilan model decision tree itu sendiri.
Baris yang akan dijelaskan dimulai dari baris seteleh tulisan “Decision tree:” atau baris ke-13 dari bab Summary Model C5.0.
Untuk membantu penjelasan, dilakukan format ulang hasil tersebut dengan memberikan pewarnaan.
Dimana arti perwanaan tersebut adalah:
Mari coba ambil contoh satu alur yang sudah diwarnai seperti berikut:
Dari sini alur pengambilan keputusan untuk menentukan risk rating adalah: Jika jumlah tanggungan >lebih dari 4 maka perlu dilihat kondisi berikutnya yaitu:
Dengan demikian, model yang dibentuk untuk melakukan otomatisasi untuk klasifikasi atau prediksi ini tetap memiliki tingkat resiko kesalahan.Pada bab berikutnya, akan dilakukan evaluasi apakah dengan persentase kesalahan ini masih dalam toleransi yang baik, sehingga model layak digunakan.
Fokus baris berikutnya adalah potongan evaluasi model yang terlihat sebagai berikut.
Informasi yang terdapat pada output ini adalah:
Tampilan output berikutnya adalah semacam tabel yang disebut dengan confusion matrix dengan ukuran 5 x 5.
Confusion matrix atau error matrix adalah tabel yang menunjukkan hasil dari klasifikasi yang dilakukan model versus (dibandingkan) dengan data klasifikasi sebenarnya, dengan demikian menunjukkan seberapa akurat model melakukan klasifikasi atau prediksi.
Confusion matrix ini terdiri dari jumlah kolom dan baris yang sama. Dimana header dari baris dan kolom adalah merupakan representasi dari nilai class variable - untuk contoh ini adalah representasi risk_rating. Untuk kasus ini dimana class variable ada 5, maka tabelnya berukuran 5 x 5 seperti terlihat di atas.
Untuk lebih jelasnya, mari diskusikan arti dari nilai-nilai pada baris pertama dari matrix ini.
Mungkin akan sedikit kesulitan cara membaca data diatas diawal. Begini caranya:
Disini bisa diambil kesimpulan dari penjelasan di atas, jika perpotongan kolom dan baris jatuh pada label yang sama maka klasifikasi dari model itu benar. Sedangkan jika beda label maka salah.
Dari kesimpulan di atas juga, maka mampu untuk mengambil keseimpulan lanjutan kalau diagonal ke kanan bawah di confusion matrix menunjukkan seluruh prediksi yang benar dari model, karena berpotongan di label yang sama, seperti terlihat pada angka-angka yang diwarnai biru sebagai berikut. Untuk angka yang berwarna merah merupakan representasi jumlah data yang salah prediksi.
Terakhir, coba jumlahkan seluruh angka ini:
Total adalah 800 data, sesuai dengan statistik sebenarnya. Angka 180 yang merupakan error juga konsisten dengan hasil output di subbab sebelumnya.
Label risk rating pada confusion matrix saat ini adalah 1 sampai dengan 5. Ini karena kebetulan contoh class variable nya adalah angka terurut seperti itu.
Agar tidak bingung mari ubah isi dari variabel risk_rating dari 1, 2, 3, 4, dan 5 menjadi “satu”, “dua”, “tiga”, “empat” dan “lima” dengan perintah-perintah berikut.
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "1"] <- "satu"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "2"] <- "dua"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "3"] <- "tiga"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "4"] <- "empat"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "5"] <- "lima"
Tiap perintah ini memiliki tiga bagian, contohnya pada perintah pertama:
Dengan demikian, arti dari perintah pertama adalah memasukkan teks “satu” ke variabel risk_rating dengan indeks dimana nilai risk_rating yang bernilai “1”.
Dijalankan maka mendapat hasil seperi berikut.
Terlihat kolom baris (a) sampai (e) labelnya sudah berubah.
Catatan: jika baris kode diatas tidak dapat dijalankan, kemungkinan besar karena penempatan baris kodenya tidak sesuai. Di bahasa R dan mayoritas bahasa lainnya, setiap baris kode dijankan secara increment atau bertahap per barisnya. Jika baris kode diatas dijalan setelah fungsi summary data risk_rating_model maka kemungkinan tidak jalan karena class variable sudah terbentuk. Contoh penempatan yang dianjurkan adalah seperti di bawah ini:
library("openxlsx")
library("C50")
# Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx?fbclid=lwAR0lKFz3A8HH61fjD6QgBET7nqPwYoT2VxvMKN6jgUeZaLyQV5_XXJF75Wk")
# Mempersiapkan class dan input variables
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "1"] <- "satu"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "2"] <- "dua"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "3"] <- "tiga"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "4"] <- "empat"
dataCreditRating$risk_rating[dataCreditRating$risk_rating == "5"] <- "lima"
dataCreditRating$risk_rating <- as.factor(dataCreditRating$risk_rating)
input_columns <- c("durasi_pinjaman_bulan", "jumlah_tanggungan")
datafeed <- dataCreditRating[ , input_columns ]
# Mempersiapkan training dan testing set
set.seed(100) #untuk menyeragamkan hasil random antar tiap komputer
indeks_training_set <- sample(900, 800)
# Membuat dan menampilkan training set dan testing set
input_training_set <- datafeed[indeks_training_set,]
class_training_set <- dataCreditRating[indeks_training_set,]$risk_rating
input_testing_set <- datafeed[-indeks_training_set,]
# Menghasilkan model
risk_rating_model <- C5.0(input_training_set, class_training_set, control = C5.0Control(label="Risk Rating"))
summary(risk_rating_model)
Output terakhir adalah daftar variabel-variabel yang digunakan oleh model decision tree.
Output tersebut menceritakan tingkat pentingnya penggunaan tiap variabel. Disini jumlah_tanggungan menempati urutan pertama dengan nilai 100% dan durasi_pinjaman dengan 72.62%.
Ini juga yang menjelaskan kenapa jumlah_tanggungan menempati root node di model yang telah dibuat dan pada diagram decision tree (Lihat bab Visualisasi dari Model C5.0).
Pada bab Visualisasi dari Model C5.0 telah dibuat visualisasi bentuk decision tree dari data atau model risk_rating_model. Pada bagian ini akan dijelaskan tentang bagian-bagian atau setiap elemen yang terdapat dalam plot tersebut.
Bab ini memfokuskan diri untuk memberi penjelasan output dari model yang meliputi aspek berikut:
Dengan tingkat error 22.5 persen, model ini harusnya cukup layak digunakan. Dari confusion matrix juga terlihat banyak sekali yang diprediksi dengan benar, terutama untuk nilai risk_rating 4 dan 5. Pada bab berikutnya, akan mengevaluasi model ini dengan memprediksi nilai dari testing set.
Confusion Matrix yang terdapat pada output model sebelumnya adalah evaluasi model menggunakan training set. Namun, perlu mengevaluasi model ini terhadap testing set yang telah disiapkan.
Bab ini akan fokus ke melakukan hal ini dengan cara menggunakan model ini untuk prediksi class variable dari data test yang ada dan kemudian membandingkan dengan nilai sebenarnya.
Package C50 memiliki fungsi bernama predict, yang bisa digunakan untuk melakukan prediksi berdasarkan input model dan data test. Fungsi lengkapnya terlihat sebagai berikut.
predict(model, test_set)
dan untuk implementasi nyatanya, maka tampilan lengkapnya adalah sebagai berikut.
predict(risk_rating_model, input_testing_set)
Hasil dari baris kode diatas adalah sebagai berikut.
## [1] 1 1 3 3 5 5 1 1 1 3 1 2 1 1 3 3 1 3 3 3 3 3 1 5 1 1 3 1 3 5 1 1 2 1 5 1 1
## [38] 5 3 3 3 3 4 3 3 1 3 5 2 3 2 5 3 5 1 5 4 5 3 4 1 3 4 4 3 5 5 5 3 1 1 1 1 3
## [75] 5 1 4 5 3 1 3 3 3 3 3 1 3 3 5 4 5 3 3 3 1 1 5 5 3 3
## Levels: 1 2 3 4 5
Terlihat hasil prediksi semua sesuai dengan posisi baris data dari testing set. Dan ini juga sesuai dengan rentang nilai risk_rating, yaitu 1 sampai dengan 5.
Model dan data frame dengan input variables adalah yang diperlukan oleh fungsi predict.
Catatan: terkadang output hasil prediksi masih dengan label “satu” sampai “lima” yang dibuat pada subbab sebelumnya. Untuk hasil prediksi menjadi angka 1 sampai 5, cukup hapus semua baris kode yang merubah label class variable di bab [Merubah Label Class Variable.
Seperti diinformasikan pada subbab sebelumnya, bagaimana cara menyimpan risk_rating dari dataset awal dan hasil prediksi ini ke dalam dua kolom nama yang lain di data frame input_testing_set. Mari namakan kolom tersebut dengan risk_rating dan hasil_prediksi.
Gunakan perintah pertama untuk menyimpan nilai asli risk_rating ke dalam kolom risk_rating.
input_testing_set$risk_rating <- dataCreditRating[-indeks_training_set, ]$risk_rating
Catatan: Ingat jika -index_training_set (dengan tanda minus di depan) menunjukkan angka-angka indeks untuk testing set.
Kemudian gunakan perintah kedua untuk menyimpan nilai prediksi ke dalam kolom hasil_prediksi.
input_testing_set$hasil_prediksi <- predict(risk_rating_model, input_testing_set)
Jika semua berjalan lancar maka akan tampil output sebagai berikut. Dengan kolom risk_rating dan hasil_prediksi bersampingan, disini bisa langsung bandingkan data awal dengan hasil prediksi. Terlihat ada rating yang sama (prediksi benar) dan berbeda (prediksi salah). Lau selanjunya akan dievaluasi tingkat akurasi dari kedua kolom ini dengan menghasilkan confusion matrix pada bagian selanjutnya.
## durasi_pinjaman_bulan jumlah_tanggungan risk_rating hasil_prediksi
## 3 12 0 1 1
## 5 36 0 2 1
## 8 48 3 2 3
## 40 36 3 2 3
## 41 48 6 2 5
## 44 48 5 2 5
## 58 12 0 1 1
## 70 12 0 1 1
## 109 12 0 1 1
## 110 12 4 3 3
Setelah hasil prediksi terhadap testing set selesai, langkah berikutnya coba lihat distribusi mana yang terprediksi dengan benar dan salah. Ini dilakukan dengan confusion matrix.
Untuk menghasilkan ini dapat menggunakan fungsi dcast dari package reshape2, caranya adalah sebagai berikut.
dcast(kolom ~ baris, dataframe)
Dan untuk kasus ini, maka perintahnya adalah sebagai berikut.
dcast(hasil_prediksi ~ risk_rating, data=input_testing_set)
Hasil dari fungsi dcast dengan argumen diatas adalah sebagai berikut.
## hasil_prediksi 1 2 3 4 5
## 1 1 24 6 0 0 0
## 2 2 0 3 1 0 0
## 3 3 0 2 37 0 0
## 4 4 0 0 0 7 0
## 5 5 0 2 0 2 16
Diagonal yang angka 24, 3, 37, 7, dan 16 menunjukkan jumlah data yang terprediksi dengan benar, dan sisa angka lainnya menunjukkan data yang salah terprediksi.
Sekilas terlihat jumlah yang terprediksi dengan benar jauh lebih besar porsinya dibandingkan yang salah. Namun untuk yang 4 dan 5 ada sedikit catatan dimana prediksi 5 itu kadang jatuh ke 4. Namun ini bisa diabaikan, karena 4 dan 5 memang beresiko tinggi.
Untuk rasio persentase kebenaran dan kesalahan prediksi lebih detil akan dihitung pada bagian berikutnya.
Untuk menghitung persentase error, bisa menghitung terlebih dahulu jumlah data dengan prediksi yang benar. Hasil dikatakan benar jika data risk_rating sama dengan hasil_prediksi. Ini jiak dituliskan dengan baris kode adalah sebagai berikut.
input_testing_set$risk_rating == input_testing_set$hasil_prediksi
Disini digunakan operator == untuk membandingkan. Jika dijalankan akan mendapat hasil seperti berikut.
## [1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [13] TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## [25] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [37] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [49] TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [61] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE
## [73] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [85] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## [97] TRUE TRUE TRUE TRUE
Ini artinya kalau TRUE maka data pada posisi tersebut prediksinya benar dan FALSE untuk sebaliknya. Namun ini masih belum dalam bentuk yang diinginkan. Masih perlu beberapa tambahan perintah tersebut untuk mengeluarkan persentase prediksi yang tepat.
Langkah berikutnya, adalah filtering/menyaring data frame tersebut dengan hasil tadi dengan perintah berikut.
input_testing_set[input_testing_set$risk_rating == input_testing_set$hasil_prediksi, ]
Jika dijalankan dan berhasil dengan baik, maka akan muncul sebagian hasil output berikut.
## durasi_pinjaman_bulan jumlah_tanggungan risk_rating hasil_prediksi
## 3 12 0 1 1
## 58 12 0 1 1
## 70 12 0 1 1
## 109 12 0 1 1
## 110 12 4 3 3
## 122 12 0 1 1
## 151 48 0 2 2
## 179 36 1 1 1
## 182 24 4 3 3
## 195 48 3 3 3
Terlihat semua hasil filtering memiliki nilai yang sama untuk kolom risk_rating dan hasil_prediksi. Kemudian akan dihitung jumlah baris filtering ini dengan menambahkan fungsi nrow terhadap perintah di atas, sebagai berikut.
nrow(input_testing_set[input_testing_set$risk_rating == input_testing_set$hasil_prediksi, ])
Jika berjalan dengan lancar, maka hasil output nya adalah sebagai berikut.
## [1] 87
Angka 87 ini menunjukkan jumlah data dengan prediksi yang benar terhadap testing set. Karena testing set berjumlah 100, maka persentase prediksi yang benar adalah 87%, dan error rate atau persentase yang salah adalah 13%.
Mari cek kembali hasil tersebut dengan menjumlahkan posisi diagonal pada confusion matrix yang telah dibuat sebelumnya.
## hasil_prediksi 1 2 3 4 5
## 1 1 24 6 0 0 0
## 2 2 0 3 1 0 0
## 3 3 0 2 37 0 0
## 4 4 0 0 0 7 0
## 5 5 0 2 0 2 16
Hasilnya juga 87 yang merupakan hasil dari operasi penjumlah 24 + 3 + 37 + 7 + 16.
Pada bagian sebelumnya, digunakan operator == untuk membandingkan kesamaan antara kolom risk_rating dengan hasil_prediksi. Bagaimana kalau hanya ingin mencari yang tidak sama, dengan kata lain mencari yang salah prediksinya?
Untuk ini cukup mudah, cukup menggunakan operator != sehingga kondisi pengecekan sebelumnya menjadi seperti berikut.
nrow(input_testing_set[input_testing_set$risk_rating != input_testing_set$hasil_prediksi,])
## [1] 13
Terlihat bahwa jumlah prediksi error ada 13. Hasil ini konsisten jika dibandingkan dengan jumlah 87 dari prediksi yang benar, dimana total keduanya adalah 100 - yang merupakan jumlah data untuk testing set.
Bab ini berisi bahasan yang cukup singkat, namun menjadi bagian yang sangat penting yaitu untuk pertama kalinya melakukan prediksi dengan function predict terhadap porsi data testing set.
Tujuannya adalah mengukur akurasi dari hasil prediksi dengan data awal. Ini digunakan dengan menggunakan confusion matrix juga dan menghitung jumlah prediksi data yang benar dan salah secara agak “manual”. Pendekatan terakhir adalah membandingkan data awal dan hasil prediksi di data frame dengan operator ==, !=, dan nrow.
Dengan tingkat error 13%, dan walaupun ada catatan untuk klasifikasi 4 dan 5, namun secara garis besar bisa anggap model ini cukup baik. Dan dengan keputusan ini, saatnya mengadopsi model ini untuk melakukan prediksi per data aplikasi kredit baru yang masuk.
Tahap terakhir setelah melakukan evaluasi dan yakin akan akurasinya, model akan digunakan dalam keseharian untuk melakukan prediksi risk rating dari data baru.
Data pengajuan baru perlu dibentuk sebagai satu data frame dengan input dimana nama-nama variabel yang digunakan harus sama persis. Dari awal pemodelan, sudah menggunakan dua variabel yakni:
Keduanya dalam bentuk numerik (angka). Dan berikut adalah contoh membentuk data frame dengan dua variabel tersebut.
aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 12)
print(aplikasi_baru)
## jumlah_tanggungan durasi_pinjaman_bulan
## 1 6 12
Data frame ini akan digunakan sebagai input untuk prediksi di bagian berikutnya.
Data aplikasi baru yang telah dibuat sebelumnya akan diprediksi nilai risk_rating nya dengan fungsi predict, dimana cara penggunaannya masih sama dengan cara yang ditunjukkan pada bab Evaluasi Model.
Maka penyesuaian perintah di atas dengan nama model dan variabel yang digunakan, adalah variabel risk_rating_model sebagai model dan aplikasi_baru sebagai data frame yang akan di prediksi.
# Membuat data frame aplikasi baru
aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 12)
# Melakukan prediksi
predict(risk_rating_model, aplikasi_baru)
## [1] 4
## Levels: 1 2 3 4 5
Ini artinya hasil prediksi risk_rating untuk aplikasi baru ini adalah 4, dari kemungkinan 1, 2, 3, 4 dan 5. Nilai 4 ini adalah nilai resiko yang cukup tinggi, jadi bisa saja aplikasi baru ini ditolak sesuai dengan kebijakan lembaga peminjam.
Pada bahasan sebelumnya sudah mempelajari cara memprediksi dari data frame berdasarkan model yang telah dibuat. Sekarang dicoba memprediksi dari data yang tidak ada dari data set yang dijadikan model.
Mari coba ganti durasi pinjaman selama 64 bulan.
# Membuat data frame aplikasi baru
aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 64)
# Melakukan prediksi
predict(risk_rating_model, aplikasi_baru)
## [1] 5
## Levels: 1 2 3 4 5
Ini artinya hasil prediksi risk_rating untuk aplikasi baru ini adalah 5, dari kemungkinan 1, 2, 3, 4 dan 5. Nilai 5 ini adalah nilai resiko yang sangat tinggi dikarenakan durasi peminjaman tidak termasuk dalam data yang di lakukan model.
Bab ini telah menunjukkan bagaimana melakukan prediksi nilai resiko kredit (risk_rating) terhadap data aplikasi baru.
Fungsi yang digunakna sangat sederhana, tetapi tetap perlu ketat dengan syarat ketika menyiapkan input:
Jika syarat tidak terpenuhi, misalkan memiliki kelebihan satu kolom data frame yang tidak digunakan pada saat memberikan input ke model akan berakibat error pada saat melakukan prediksi.
Sudah sampai di akhir bahasan ini. Pada seluruh bab ini, telah mempelajari mengenai kasus bisnis resiko kredit pada dunia finance. Dengan mengerti apa pengertian credit risk, credit scoring, risk rating dan masalah-masalah yang dihadapi dimana dapat maju ke pencarian solusi yang tepat.
Problem yang dihadapi adalah lambatnya analisa resiko sehingga lembaga kredit bisa kehilangan kesempatan (lost opportunity) ketika calon peminjam tidak jadi bertransaksi.
Solusi machine learning denga algoritma decision tree sangat cocok diterapkan untuk membantu memprediksi credit risk dengan cepat. Konkritnya adalah penggunaan algoritma C5.0 di R.
Adapun dalam keselurujan bab ini sudah banyak menerapkan solusi seperti:
Walaupun cukup banyak konsep dan implementasi dari semua bahasan bab ini yang bisa langsung diterapkan untuk kasus credit rating di lapangan. Namun ada banyak catatan agar lebih baik menggunakan model ini, yaitu:
Sekian dan terima kasih.