Credit risk adalah risiko yang harus ditanggung oleh seorang individu atau lembaga ketika memberikan sebuah pinjaman – biasanya dalam bentuk uang – ke individu atau pihak lain. Risiko ini berupa pokok dan bunga pinjaman yang tidak dapat dibayarkan oleh peminjam, sehingga mengakibatkan kerugian berikut:
Untuk memperkecil risiko kredit ini, perlu dilakukan proses credit scoring atau credit rating terhadap pihak peminjam. Output proses ini akan menjadi basis untuk menentukan apakah aplikasi pengajuan pinjaman baru diterima atau ditolak.
Penentuan aplikasi pengajuan pinjaman baru diterima atau ditolak dapat dilakukan dengan cara klasifikasi data menggunakan metode Decision Tree. Algoritma Decision Tree yang digunakan pada penelitian ini adalah C5.0.
Dataset yang digunakan adalah data histori lamanya proses pengembalian pinjaman oleh nasabah pinjaman. Data ini berupa data sekunder yang diambil dari materi yang disediakan oleh DQLab.
Link Website DQLab: https://academy.dqlab.id/
Data ini berjumlah 900 data dengan 7 atribut sebagai berikut:
| Variabel | Keterangan |
|---|---|
| kode_kontrak | nomor kode kontrak |
| pendapatan_setahun_juta | pendapatan peminjam per tahun (juta) |
| durasi_pinjaman_bulan | durasi pinjaman (bulan) |
| jumlah_tanggungan | jumlah tanggungan |
| kpr_aktif | status kpr (aktif atau tidak) |
| rata_rata_overdue | rata-rata waktu keterlambatan pembayaran |
| risk_rating | tingkat risiko keterlambatan pembayaran (1-5) |
library("openxlsx")
library("C50")
library("reshape2")
# Mempersiapkan Data
dataCreditRating <- read.xlsx("credit_scoring.xlsx")
# Menampilkan 5 Data teratas
head(dataCreditRating)
## kode_kontrak pendapatan_setahun_juta kpr_aktif durasi_pinjaman_bulan
## 1 AGR-000001 295 YA 48
## 2 AGR-000011 271 YA 36
## 3 AGR-000030 159 TIDAK 12
## 4 AGR-000043 210 YA 12
## 5 AGR-000049 165 TIDAK 36
## 6 AGR-000063 220 TIDAK 24
## jumlah_tanggungan rata_rata_overdue risk_rating
## 1 5 61 - 90 days 4
## 2 5 61 - 90 days 4
## 3 0 0 - 30 days 1
## 4 3 46 - 60 days 3
## 5 0 31 - 45 days 2
## 6 5 0 - 30 days 1
str(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 ...
Berdasarkan hasil struktur data, variabel risk_rating
berupa data numerik. Namun dalam Algoritma C5.0, class variable
atau variabel yang ingin diteliti harus berupa faktor,
yang artinya variabel risk_rating tidak boleh berupa
numerik. Oleh karena itu, perlu dilakukan konversi pada data
risk_rating dari data numerik menjadi faktor.
Variabel kpr_aktif dan variabel
rata_rata_overdue juga perlu dikonversi dari string menjadi
faktor karena variabel tersebut berupa variabel kategorik.
dataCreditRating$risk_rating <- as.factor(dataCreditRating$risk_rating)
dataCreditRating$kpr_aktif <- as.factor(dataCreditRating$kpr_aktif)
dataCreditRating$rata_rata_overdue <- as.factor(dataCreditRating$rata_rata_overdue)
#Melihat struktur data setelah konversi
str(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 : Factor w/ 2 levels "TIDAK","YA": 2 2 1 2 1 1 1 1 1 1 ...
## $ 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 : Factor w/ 5 levels "> 90 days","0 - 30 days",..: 5 5 2 4 3 2 3 3 3 3 ...
## $ risk_rating : Factor w/ 5 levels "1","2","3","4",..: 4 4 1 3 2 1 2 2 2 2 ...
Feature selection adalah tahap untuk seleksi atau melakukan
filtering input variable yang akan digunakan.
Berdasarkan data, variabel rata_rata_overdue berkaitan erat
dengan risk_rating dimana variabel risk_rating ditentukan
berdasarkan rata_rata_overdue, sehingga variabel
rata_rata_overdue tidak digunakan. Variabel
kode_kontrak juga tidak digunakan karena tidak ada
hubungannya dengan penentuan nilairisk_rating.
Atribut yang akan digunakan sebagai input variable adalah
variabel durasi_pinjaman_bulan dan
jumlah_tanggungan. Hasil filtering tersebut akan
disimpan ke variabel baru dengan nama input_data.
input_columns <- c("durasi_pinjaman_bulan", "jumlah_tanggungan")
input_data <- dataCreditRating[,input_columns]
#Melihat struktur input_data
str(input_data)
## '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 ...
Sebelum melakukan pemodelan, dataset perlu dibagi menjadi dua, yaitu:
Training set: porsi dataset yang dijadikan sebagai input yang nantinya akan dianalisis oleh algoritma.
Testing set: porsi dataset yang digunakan untuk menguji model yang telah ditraining.
Data akan dibagi secara acak dimana dari 900 data, 800 data akan dijadikan sebagai training set dan 100 data sebagai testing set.
#Mempersiapkan indeks acak untuk training set dan testing set
set.seed(100) #Memastikan nilai acak yang diambil selalu sama
indeks_training_set <- sample(900,800)
#Membuat training set dan testing set
input_training_set <- input_data[indeks_training_set,]
class_training_set <- dataCreditRating[indeks_training_set,]$risk_rating
input_testing_set <-input_data[-indeks_training_set,]
#Menampilkan hasil training set dan testing set
str(input_training_set)
## 'data.frame': 800 obs. of 2 variables:
## $ durasi_pinjaman_bulan: num 36 24 36 36 36 24 12 48 48 12 ...
## $ jumlah_tanggungan : num 1 1 5 1 5 3 3 3 0 0 ...
str(class_training_set)
## Factor w/ 5 levels "1","2","3","4",..: 1 1 4 1 5 3 3 3 2 1 ...
length(class_training_set)
## [1] 800
str(input_testing_set)
## 'data.frame': 100 obs. of 2 variables:
## $ durasi_pinjaman_bulan: num 12 36 48 36 48 48 12 12 12 12 ...
## $ jumlah_tanggungan : num 0 0 3 3 6 5 0 0 0 4 ...
Berdasarkan hasil output, dapat dilihat bahwa pembagian data menjadi training set dan testing set telah berhasil dimana training set baik untuk input variable maupun class variable terdapat 800 baris data sedangkan testing set memuat 100 baris data.
model_C50 <- C5.0(input_training_set, class_training_set, control = C5.0Control(label="Risk Rating"))
summary(model_C50)
##
## Call:
## C5.0.default(x = input_training_set, y = class_training_set, control
## = C5.0Control(label = "Risk Rating"))
##
##
## C5.0 [Release 2.07 GPL Edition] Thu Oct 12 10:28:31 2023
## -------------------------------
##
## Class specified by attribute `Risk Rating'
##
## 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
Penjelasan dari hasil output pemodelan decision tree pada gambar di atas adalah sebagai berikut:
Berikut adalah interpretasi dari hasil pemodelan decision tree:
jumlah tanggungan > 4 dan
durasi pinjaman <= 24 bulan, maka
risk rating = 4.105 : 105 data diklasifikasikan nilai risk ratingnya
4.30 : 30 data dari 105 data salah klasifikasi.jumlah tanggungan > 4 dan
durasi pinjaman > 24 bulan, maka
risk rating = 5.120 : 120 data diklasifikasikan nilai risk ratingnya
5.51 : 51 data dari 120 data salah klasifikasi.jumlah tanggungan <= 4 dan
jumlah tanggungan > 2, maka
risk rating = 3.216 : 216 data diklasifikasikan nilai risk ratingnya
320 : 20 data dari 216 data salah klasifikasijumlah tanggungan <= 2, dan
durasi pinjaman <= 36 bulan, maka
risk rating = 1.264 : 264 data diklasifikasikan nilai risk ratingnya
1.80 : 80 data dari 264 data salah klasifikasi.jumlah tanggungan = 0 dan
durasi pinjaman > 36 bulan, maka
risk rating = 2.37 : 37 data diklasifikasikan nilai risk ratingnya
2.7 : 7 data dari 37 data salah klasifikasi.jumlah tanggungan <= 2,
durasi pinjaman > 36 bulan, dan
jumlah tanggungan > 0, maka
risk rating = 358 : 58 data diklasifikasikan nilai risk ratingnya
2.4 : 4 data dari 58 data salah klasifikasi.Hasil decision tree dapat divisualisasikan dalam bentuk plot sebagai berikut:
plot(model_C50)
Size = 6 = terdapat 6 leaf node pada decision
tree yang terbentuk.Errors = 192 (24.0%) = total jumlah kesalahan
klasifikasi ada 192 data atau 24% dari
keseluruhan data training set (800 data). Atau dalam kata lain, model
yang terbentuk menghasilkan output dengan akurasi 76%.Selain melihat persentase kesalahan klasifikasi, untuk mengukur akurasi dari model yang dibentuk dapat menggunakan confusion matrix.
risk_rating
yang diprediksi oleh model.risk_rating
pada data sebenarnya.Berikut adalah penjelasan dari output confusion matrix dari hasil pemodelan decision tree sebelumnya:
[1,1] dengan nilai 184 menunjukkan jumlah
data yang hasil prediksinya benar.
risk_rating hasil klasifikasi adalah 1.risk_rating data sebenarnya adalah 1.[1,2] dengan nilai 2 menunjukkan jumlah
data yang hasil prediksinya salah.
risk_rating hasil klasifikasi adalah 2.risk_rating data sebenarnya adalah 1.[1,3] dengan nilai 5 menunjukkan jumlah
data yang hasil prediksinya salah.
risk_rating hasil klasifikasi adalah 3.risk_rating data sebenarnya adalah 1.[1,4] dengan nilai 6 menunjukkan jumlah
data yang hasil prediksinya salah.
risk_rating hasil klasifikasi adalah 4.risk_rating data sebenarnya adalah 1.[1,5] dengan nilai 6 menunjukkan jumlah
data yang hasil prediksinya salah.
risk_rating hasil klasifikasi adalah 5.risk_rating data sebenarnya adalah 1.[2,1] dengan nilai 80 menunjukkan jumlah
data yang hasil prediksinya salah.
risk_rating hasil klasifikasi adalah 1.risk_rating data sebenarnya adalah 2.[2,2] dengan nilai 30 menunjukkan jumlah
data yang hasil prediksinya benar.
risk_rating hasil klasifikasi adalah 2.risk_rating data sebenarnya adalah 2.Berdasarkan hasil interpretasi tersebut, dapat disimpulkan bahwa
diagonal dari matriks tersebut
{[1,1],[2,2],[3,3],[4,4],
dan [5,5]}, menunjukkan jumlah hasil prediksi/klasifikasi
model yang benar.
Gambar berikut adalah hasil persentase penggunaan atribut untuk pemodelan:
jumlah_tanggungan digunakan untuk membentuk model.durasi_pinjaman_bulan digunakan untuk membentuk model.Selanjutnya dapat dilakukan evaluasi atau pengujian model terhadap data testing.
#Menyimpan data risk_rating sebenarnya pada testing set
input_testing_set$risk_rating <- dataCreditRating[-indeks_training_set,]$risk_rating
#Menyimpan hasil prediksi berdasarkan model yang telah dibuat terhadap testing set
input_testing_set$hasil_prediksi <- predict(model_C50, input_testing_set)
#Menyimpan keterangan perbandingan hasil prediksi dengan data sebenarnya
input_testing_set$compare <- input_testing_set$risk_rating == input_testing_set$hasil_prediksi
#Menampilkan 5 data teratas dari testing set
head(input_testing_set)
## durasi_pinjaman_bulan jumlah_tanggungan risk_rating hasil_prediksi compare
## 3 12 0 1 1 TRUE
## 5 36 0 2 1 FALSE
## 8 48 3 2 3 FALSE
## 40 36 3 2 3 FALSE
## 41 48 6 2 5 FALSE
## 44 48 5 2 5 FALSE
summary(input_testing_set$compare)
## Mode FALSE TRUE
## logical 13 87
Hasil summary menunjukkan bahwa model menghasilkan 87 prediksi benar dan 13 prediksi salah. Artinya, model dapat memprediksi klasifikasi risk rating dengan akurasi 87%.
Berikut adalah hasil confusion matrix dari hasil prediksi terhadap data testing:
dcast(hasil_prediksi ~ risk_rating, data=input_testing_set)
## Using compare as value column: use value.var to override.
## Aggregation function missing: defaulting to length
## 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
Hasil pemodelan jumlah tanggungan dan durasi pinjaman terhadap risk rating menghasilkan akurasi 76% pada data train dan akurasi 87% pada data test, sehingga dapat disimpulkan bahwa model yang dibuat cukup baik diterapkan untuk memprediksi risk rating dari calon peminjam.