1 Credit Risk dan Model Prediksi

1.1 Pendahuluan

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:

  • gangguan aliran kas (cash flow) sehingga modal kerja terganggu.
  • meningkatkan biaya operasional untuk mengejar pembayaran tersebut (collection).

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.

1.2 Credit Score

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.

1.3 Risk Rating

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.

  • Jika keterlambatan sampai dengan 30 hari (0 - 30 days) maka diberikan nilai 1.
  • keterlambatan 31 sampai dengan 45 hari (31 - 45 days) maka scoring diberikan nilai 2.
  • dan seterusnya

Dari sini juga beberapa kolom juga diambil oleh analis untuk mencari pola keterkaitannya terhadap rating ini, yaitu:

  • pendapatan dalam jutaan per tahun (pendapatan_setahun_juta).
  • durasi pinjaman dalam satuan bulan (durasi_pinjaman_bulan).
  • jumlah tanggungan (jumlah_tanggungan).
  • apakah ada KPR/Kredit Pemilikan Rumah aktif atau tidak (kpr_aktif).

Adapaun rekam jejak historis yang digunakan sebagai basis untuk perhitungan credit score dan risk rating yaitu keterlambatan pembyaran pinjaman.

1.4 Analisa dan Model Pengambilan Keputusan

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:

  • Jika jumlah tanggungan berjumlah lebih dari 4, kecenderungan resikonya sangat tinggi (rating 4 dan 5).
  • Jika durasi pinjaman semakin lama yaitu lebih dari 24 bulan, maka kecenderungan resiko juga meningkat (rating 4 dan 5).

Dari kedua temuan ini, analis akan membentuk aturan-aturan untuk menuntun pengambilan keputusan (decision making model) terhadap pengajuan pinjaman baru untuk sebagai berikut:

  • Jika jumlah tanggungan berjumlah kurang dari 5 orang, dan durasi pinjaman kurang dari 24 bulan maka rating diberikan nilai 2 dan pengajuan pinjaman diterima.
  • Jika jumlah tanggungan berjumlah lebih dari 4 orang dan durasi pinjaman lebih dari 24 bulan maka maka rating diberikan nilai 5 dan pengajuan pinjaman ditolak.
  • Jika jumlah tanggungan berjumlah kurang dari 5, dan durasi pinjaman kurang dari 36 bulan maka maka rating diberikan nilai 3 dan diberikan pinjaman.

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.

1.5 Kesimpulan

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:

  • gangguan aliran kas (cash flow) sehingga modal kerja terganggu.
  • meningkatkan biaya operasional untuk mengejar pembayaran tersebut (collection).

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.

2 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:

  • Jika jumlah tanggungan berjumlah kurang dari 2 orang , dan durasi pinjaman kurang dari 42 bulan maka rating diberikan nilai 1 dan pengajuan pinjaman diterima.
  • Jika jumlah tanggungan berjumlah lebih dari 4 orang dan durasi pinjaman lebih dari 30 bulan maka maka rating diberikan nilai 5 dan pengajuan pinjaman ditolak.
  • Jika jumlah tanggungan berjumlah kurang dari 5, dan durasi pinjaman kurang dari 30 bulan maka maka rating diberikan nilai 3 dan diberikan pinjaman.

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.

2.1 Komponen Decision Tree

Berikut adalah komponen dari decision tree:

  • Node: diwakili oleh 1, 3 dan 4.
  • Branch (cabang) atau split (pemisah): diwakili oleh 2.
  • Root node: atau node akar, diwakili oleh 3.
  • Leaf node: atau node daun, diwakili oleh 4.

Mengerti komponen-komponen ini sangat penting untuk nanti memahami output dari algoritma machine learning yang digunakan.

2.2 Pemodelan Decision Tree dengan Machine Learning

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.

2.3 Kesimpulan

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.

3 Algoritma C5.0

3.1 Apa Itu Algoritma 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.

3.2 Class dan Input Variables

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.

3.3 Data Preparation untuk Class Variable

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 ...

3.4 Data Preparation untuk Input Variables

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.

3.5 Traning Set dan Testing Set

Untuk proses pembentukan model machine learning dan melihat akurasinya, biasanya dataset perlu dibagi menjadi dua, yaitu:

  • Training set: adalah porsi dataset yang digunakan oleh algoritma untuk dianalisa dan menjadi input untuk pembentukan model.
  • Testing set: adalah porsi dataset yang tidak digunakan untuk membentuk model, tapi untuk menguji model yang telah dibentuk.

Pembentukan ini biasanya menggunakan metode pemilihan acak.

3.6 Mempersiapkan Traning dan Testing Set

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:

  • set.seed(100) adalah perintah untuk menyeragamkan pengambilan bilangan acak di seluruh aplikasi R.
  • sample(900, 800) adalah membuat urutan acak dengan rentang nilai 1 sampai dengan 900, tetapi diambil sebanyak 800 nilai.

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:

  • input_training_set akan diisi dari data frame datafeed dengan jumlah indeksnya yang terdapat pada variabel indeks_training_set.
  • class_training_set akan diisi dari data frame dataCreditRating dengan indeks yang isinya terdapat pada variabel indeks_training_set.
  • input_testing_set akan diisi datafeed dengan indeks yang isinya ‘tidak ada’ di indeks_training_set - perhatikan tanda minus yang ada di depan variabel indeks_training_set.

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)

3.7 Mengahasilkan Model dengan Fungsi C5.0

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:

  • x: sebuah data frame atau matiks untuk prediksi.
  • y: sebuah faktor yang memiliki 2 level atau lebih. Maksud level disini yaitu banyaknya jumlah data di dalam data frame atau kolom bertipe data factor. Sebagai contoh, lihat struktur kolom risk_rating yang sudah dikonversi pada bab Data Preparation untuk Class Variable.

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.

3.8 Visualisasi dari 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.

3.9 Kesimpulan

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:

  • Class variable, yaitu variabel yang berisi nilai yang ingin diklasifikasikan. Variabel ini harus berisi tipe factor.
  • Input variables, yaitu variabel-variabel yang berisi nilai input.

Dan untuk mengukur akurasi dari model yang dihasilkan, sebaiknya membagi dataset yang ada menjadi dua porsi secara random:

  • Training set, yang digunakan untuk memberikan input ke algoritma untuk membentuk model.
  • Testing set, yang akan digunakan untuk data pembanding untuk mengukur akurasi algoritma.

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.

4 Summary Model 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.

4.1 Memahami Output

4.1.1 Label dari Class

Mari perhatikan baris setelah karakter “———-” atau baris ke-9. Akan dijelaskan secara satu persatu setiap barisnya. output lainnya dijelaskan menyusul.

  • Class specified by attribute ‘outcome’: Ini artinya class variable dilabelkan atau dinamakan sebagai outcome. Jika ingin merubah label yang lebih mewakili, yaitu “Risk Rating”, maka bisa dilakukan dengan cara: menambahkan argumen control yang berisi fungsi C5.0Control* dengan isian argumen label**. Seperti berikut:
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'"

4.1.2 Jumlah Data dan Variable yang Digunakan

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.

  • … undefined.data: untuk ini bisa diabaikan saja, karena bagian ini harusnya berisi informasi file .data dari program C5.0 yang asli. Jika ingin mengetahui lebih lanjut mengenai hal ini bisa dilihat pada url https://www.rulequest.com/see5-unix.html dan fokus ke bagian preparing data.

4.1.3 Tampilan Teks dari Model Decision Tree

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:

  • Warna biru adalah node dan kondisi split nya. Hubungan antar node (connector) ditulis dengan karakter titik dua dan titik berulang (:…).
  • Warna merah adalah leaf node atau klasifikasinya.
  • Warna ungu adalah statistik kesalahannya dalam bentuk (jumlah_klasifikasi / jumlah_kesalahan).

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:

  1. Jika durasi pinjaman sampai dengan 24 bulan, maka klasifikasi risk rating nya adalah 4. Dari dataset training, alur ini mengklasifikasikan 98 data, namun 25 diantara 98 data ini salah klasifikasi. Berikut adalah tampilan data asal, terlihat beberapa kondisi yang terpenuhi namun bukan dengan nilai risk rating 4 (warna merah).

  1. Jika durasi pinjaman lebih dari 24 bulan, maka klasifikasi risk rating nya adalah 5. Dari dataset training, alur ini mengklasifikasikan 129 data, namun 49 diantara 129 data ini salah klasifikasi. Berikut adalah tampilan data asal, terlihat beberapa kondisi yang terpenuhi namun bukan dengan nilai risk rating 5 (warna merah).

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.

4.1.4 Persentase Kesalahan Model

Fokus baris berikutnya adalah potongan evaluasi model yang terlihat sebagai berikut.

Informasi yang terdapat pada output ini adalah:

  • 800 cases adalah jumlah baris data (case) yang diproses.
  • Size = 6 adalah jumlah leaf nodes (node ujung) dari decision tree.
  • Errors = 180(22.5%): 180 adalah jumlah record/baris yang salah klasifikasi, dan 22.5% adalah rasio dari seluruh populasi.

4.1.5 Confusion Matrix

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.

  • Header pada kolom (column headers) menunjukkan nilai class risk_rating yang diprediksi atau diklasifikasikan oleh model, dengan menggunakan label (a), (b), (c), dan seterusnya.
  • Header pada baris (row headers) menunjukkan nilai class risk_rating pada data sebenarnya. Masih direpresentasikan dengan (a), (b), (c), (d) dan (e). Namun disini sudah diberikan informasi label tersebut merepresentasikan nilai risk_rating yang mana. Terlihat kalau (a) merupakan representasi risk_rating dengan nilai 1, (b) merupakan representasi risk_rating dengan nilai 2, dan seterusnya.
  • Tiap perpotongan antara kolom dan baris merupakan informasi hasil prediksi dari class ada di nilai pada kolom dibandingkan data aktual class-nya berada pada nilai di baris.

Untuk lebih jelasnya, mari diskusikan arti dari nilai-nilai pada baris pertama dari matrix ini.

  • Angka 179 pada kolom pertama baris pertama menunjukkan jumlah data yang benar klasifikasi atau prediksinya, dimana:
    • klasifikasi model terhadap data mendapatkan risk_rating 1
    • pada data aktual juga nilai risk_rating-nya 1
  • Angka 1 pada kolom kedua baris pertama menunjukkan jumlah data yang salah prediksi, dimana:
    • klasifikasi model terhadap data mendapatkan risk_rating 2
    • pada data aktual ternyata nilai risk_rating nya 1
  • Angka 5 pada kolom ketiga baris pertama menunjukkan jumlah data yang salah prediksi, dimana:
    • klasifikasi model terhadap data mendapatkan risk_rating 3
    • pada data aktual ternyata nilai risk_rating nya 1
  • Angka 5 pada kolom keempat baris pertama menunjukkan jumlah data yang salah prediksi, dimana:
    • klasifikasi model terhadap data mendapatkan risk_rating 4
    • pada data aktual ternyata nilai risk_rating nya 1
  • Angka 6 pada kolom kelima baris pertama menunjukkan jumlah data yang salah prediksi, dimana:
    • klasifikasi model terhadap data mendapatkan risk_rating 5
    • pada data aktual ternyata nilai risk_rating nya 1

Mungkin akan sedikit kesulitan cara membaca data diatas diawal. Begini caranya:

  • Misal angka 179 baris 1 kolom 1.
    • klasifikasi model mendapat risk_rating 1 karena baris pertama termasuk ke kolom baris (a) yaitu class 1. Begitupun angka 1, 5, dst semua akan mendapat risk_rating 1 karena semua berada di baris ke-1 yang mana termasuk ke kolom baris (a) yang ada di sebelah kanan.
    • Nilai risk_rating nya 1 karena kolomn header nya adalah (a), dan kolom (a) tersebut termasuk di class 1. Begitu juga untuk angka 1 nilai risk_rating nya 2.

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:

  • Angka dengan prediksi benar: 620 (179 + 30 + 258 + 73 + 80)
  • Angka dengan prediksi salah: 180 (1 + 5 + 5 + 6 + 80 + 14 + 3 + 12 + 4 + 2 + 31 + 17)

Total adalah 800 data, sesuai dengan statistik sebenarnya. Angka 180 yang merupakan error juga konsisten dengan hasil output di subbab sebelumnya.

4.1.6 Merubah Label Class Variable

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:

  • dataCreditRating$risk_rating[…], artinya mengakses kolom risk_rating pada indeks ke-…
  • dataCreditRating$risk_rating == “1”, artinya mengambil indeks dimana nilai risk_rating bernilai “1”
  • <- “satu”, teks “satu” dimasukkan ke …

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)

4.1.7 Variabel-variabel Penentu

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).

4.1.8 Elemen dari Plot Decision Tree 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.

  • Warna merah menunjukkan node dan penomoran node nya
    • bulatan merah nomor 1 adalah node nomor 1 adalah root node dengan variabel penentu jumlah_tanggungan.
    • bulatan merah nomor 2 adalah node nomor 2 dengan variabel penentu jumlah_tanggungan.
    • bulatan merah nomor 3 adalah node nomor 7 adalah leaf node untuk klasifikasi risk_rating.
  • Warna biru menunjukkan kondisi split ke node-node berikutnya
    • bulatan biru nomor 4 menunjukkan kondisi split dimana durasi pinjaman kurang atau sama dengan 24 bulan.
    • bulatan biru nomor 5 menunjukkan kondisi split dimana durasi pinjaman lebih dari 24 bulan.
  • Warna hijau menunjukkan jumlah data yang telah diklasifikasi.
    • bulatan hijau nomor 6 menunjukkan hasil klasifikasi sebanyak 98 data.
    • bulatan hijau nomor 7 menunjukkan hasil klasifikasi sebanyak 129 data.
  • Warna ungu menunjukkan hasil klasifikasi dan distribusinya (dalam rentang rasio antara angka 0 dan 1).
    • bulatan ungu nomor 8 menunjukkan risk_rating pada node tersebut mayoritas adalah 4, dan dengan demikian model mengambil itu sebagai klasifikasinya. Selain itu risk_rating 5, 1, dan 2 adalah data yang juga sebenarnya jatuh ke dalam kondisi yang berakhir di node nomor 10 ini.
    • bulatan ungu nomor 9 menunjukkan risk_rating pada node tersebut mayoritas adalah 5, dan dengan demikian model mengambil itu sebagai klasifikasinya. Selain itu risk_rating 4, 2, dan 1 adalah data yang juga sebenarnya jatuh ke dalam kondisi yang berakhir di node nomor 11 ini.

4.2 Kesimpulan

Bab ini memfokuskan diri untuk memberi penjelasan output dari model yang meliputi aspek berikut:

  • Jumlah baris data yang diproses untuk menghasilkan model.
  • Jumlah variabel yang digunakan untuk menghasilkan model.
  • Tampilan decision tree.
  • Statistik error dari model ini.
  • Confusion matrix yang menampilkan detil dari hasil klasifikasi dan aktual.
  • Variabel-variabel yang digunakan dan tingkat pentingnya variabel tersebut.

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.

5 Evaluasi Model

5.1 Pendahuluan

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.

5.2 Menggunakan Fungsi Predict

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.

5.3 Menggabungkan Hasil Prediksi

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

5.4 Membuat Tabel Confusion Matrix

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.

5.5 Jumlah Data dengan Prediksi Benar

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.

5.6 Jumlah Data dengan Prediksi Salah

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.

5.7 Kesimpulan

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.

6 Menggunakan Model untuk Prediksi

6.1 Pendahuluan

Tahap terakhir setelah melakukan evaluasi dan yakin akan akurasinya, model akan digunakan dalam keseharian untuk melakukan prediksi risk rating dari data baru.

6.2 Mempersiapkan Data Pengajuan 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:

  • jumlah_tanggungan
  • durasi_pinjaman_bulan

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.

6.3 Melakukan Prediksi terhadap Data Pengajuan Baru

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.

6.4 Merubah Durasi Pinjaman

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.

6.5 Kesimpulan

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:

  • Input berupa data frame.
  • Kolom-kolom di dalam data frame harus sama dengan input yang digunakan untuk menghasilkan model.

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.

7 Kesimpulan

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:

  • Mengerti apa itu decision tree dan algoritma C5.0.
  • Melakukan data preparation untuk class variable dan input variable.
  • Melakukan data preparation untuk training dan testing set.
  • Menggunakan training set untuk menghasilkan model credit risk menggunakan algoritma C5.0.
  • Mengevaluasi akurasi decision credit risk.
  • Menggunakan model tersebut untuk memprediksi risk rating data pengajuan baru.

8 What’s Next?

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:

  • Pada kenyataannya, variabel yang terlibat jauh lebih banyak dan kadang masih dalam bentuk yang kosong, tidak lengkap atau tidak standar. Ini memerlukan teknik data cleansing.
  • Variabel yang sangat banyak ini perlu diambil yang korelasinya tinggi saja. Tidak keseluruhan karena akan mengakibatkan pembentukan model tidak optimal. Teknik ini disebut data reduction atau feature selection, atau kalau lebih luas ilmunya mencakup apa yang dinamakan feature engineering. InshaAllah akan dibahas selanjutnya.
  • Evaluasi model yang juga umum dan menjadi best practice adalah menggunakan visualisasi ROC Curve. Bisa baca di sini.
  • Terakhir, tentunya perlu lebih banyak latihan dan praktek menangani berbagai kasus mengenai pembentukan model decision tree terutama untuk credit risk ini.

Sekian dan terima kasih.