Data Science in Finance: Credit Risk Analysis – R

Credit Risk dan Model Prediksi

Pengenalan terhadap mengenai credit risk dan credit rating prediction dan apa manfaatnya untuk industri finansial pemberi pinjaman seperti bank, multi finance, asuransi, dan lain-lain.

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

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

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 aktif atau tidak (kpr_aktif).

Analisa dan Model Pengambilan Keputusan

Masih terkait dengan contoh data sebelumnya, namun dengan contoh data utuh – WCLab akan memberikan ilustrasi aktivitas tindak lanjut terhadap data dengan contoh skenario berikut.

Seorang analis akan melakukan penelusuran terhadap data kita 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 kita sebut 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.

Decission Tree

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. 

Nah, 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. Dan kalau kita telusuri lagi, untuk jumlah tanggungan 5 dan durasi pinjaman kurang dari 30 maka akan masuk ke rating nilai 4. Lebih mudah dan cepat dimengerti, bukan?

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

Contoh Pemodelan Decision Tree dengan Machine Learning

Mari sekarang kita lihat contoh otomatisasi model decision tree dengan menggunakan salah satu algoritma populer di R, yaitu C5.0. Praktek kali ini kita hanya bertujuan untuk melihat contoh output, detilnya akan dibahas pada bab-bab selanjutnya.

Pada code editor telah diberikan contoh code untuk membaca dan menganalisa data credit rating dari file Excel, membentuk model decision tree, dan menampilkan hasilnya dalam bentuk output. Untuk itu kita perlu gunakan package C50 yang akan kita gunakan sepanjang course ini. Cobalah jalankan code tersebut dengan tombol Run, dan jika berjalan dengan lancar maka akan mendapatkan potongan hasil berikut.

Source Code

Result

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)

Ini adalah bentuk representasi tree dalam bentuk teks. Dimana pengecekan akan dimulai dari variable jumlah_tanggungan. Sebagai contoh, jika jumlah tanggungan lebih dari 4 dan durasi pinjaman sampai dengan maksimal 24 bulan maka rating diberikan nilai 4.

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 kita risk rating – berdasarkan input dari data-data lain.

Class and Input Variables

Mari kita kembali melihat contoh data kita dari gambar berikut ini dimana tiap header kolom diberi bulatan merah dengan penomoran.

.

Tujuan kita sepanjang course 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.

Kita akan membaca dataset dan melakukan proses konversi ini pada praktek berikutnya.

Data Preparation untuk Class Variable

Source Code

library("openxlsx")

#Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx")
str(dataCreditRating)

#Melakukan konversi kolom risk_rating menjadi factor
#[...]

#Melihat struktur setelah konversi
str(dataCreditRating)

.

Hasilnya

'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 kita, yaitu risk_rating ternyata masih dibaca dalam bentuk numerik. Untuk menjadi class variable yang digunakan pada algoritma C5.0, maka in perlu dikonversi menjadi factor. Ini bisa dilakukan dengan menggunakan perintah berikut.

dataCreditRating$risk_rating <- as.factor(dataCreditRating$risk_rating) 

.

Cobalah masukkan perintah ini untuk menggantikan bagian #[…] pada code editor dan klik tombol Run. Jika berjalan dengan lancar, maka outputnya akan terlihat seperti berikut.

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

.

Data Preparation untuk Input Variables

Tidak semua input variable yang perlu kita gunakan, apalagi yang sangat berkaitan sangat erat dengan risk_rating, yaitu rata_rata_overdue. Input variable ini akan kita buang. Proses ini disebut sebagai feature selection.

Karena kita gunakan data frame sebagai tipe data input kita untuk C5.0, maka field-field yang ingin kita gunakan bisa kita kita masukkan sebagai vector sebagai filter. Berikut adalah perintah untuk membuat vector nama kolom yang kita butuhkan saat ini, yaitu durasi_pinjaman_bulan dan jumlah_tanggungan. Hasil filtering ini kita simpan ke variable baru bernama datafeed, dan perintah terakhir kita gunakan melihat struktur variable ini.

input_columns <- c("durasi_pinjaman_bulan", "jumlah_tanggungan")
datafeed <- dataCreditRating[ , input_columns ]
str(datafeed)

.

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 variable input yang tidak relevan secara otomatis. 

Tambahkan ketiga perintah tersebut untuk menggantikan #[…] pada code editor. Dan jalankan code ini, jika berhasil maka akan muncul tampilan berikut.

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

.

Training Set dan Testing Set

Untuk proses pembentukan model machine learning dan melihat akurasinya, biasanya dataset kita 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. Untuk praktek selanjutnya, kita akan membagi dataset kita menjadi 800 baris data untuk training set dan 100 baris data untuk testing set.

Mempersiapkan Training dan Testing Set

Training dan testing set kita akan mengambil dari variable data frame bernama datafeed yang telah kita persiapkan pada praktek sebelumnya. Jumlah baris dataset kita adalah 900, dimana kita 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.

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.

Masukkan kedua perintah di atas untuk menggantikan bagian #[…1…] pada code editor.

Langkah kedua adalah membuat variable untuk training set (input dan class variable) dan testing set (input variable saja) berdasarkan index di atas dengan perintah berikut.

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 index yang isinya terdapat pada variable indeks_training_set.
  • class_training_set akan diisi dari data frame dataCreditRating dengan index yang isinya terdapat pada variable indeks_training_set.
  • input_testing_set akan diisi datafeed dengan index yang isinya tidak ada di indeks_training_set – perhatikan tanda minus yang ada di depan variable indeks_training_set.

Masukkan kedua perintah tersebut ke dalam code editor untuk menggantikan bagian #[…2…]. Jalankan dan lihat hasilnya, jika berjalan dengan lancar maka akan tampil dua struktur dataset dimana satunya berjumlah 800 row dan satunya berjumlah 100.

> str(input_training_set)
'data.frame':	800 obs. of  2 variables:
 $ durasi_pinjaman_bulan: num  36 24 12 36 48 24 24 36 24 12 ...
 $ jumlah_tanggungan    : num  2 0 3 4 6 4 3 2 1 4 ...

> str(class_training_set)
 Factor w/ 5 levels "1","2","3","4",..: 2 1 3 2 5 3 3 2 2 3 ...

> str(input_testing_set)
'data.frame':	100 obs. of  2 variables:
 $ durasi_pinjaman_bulan: num  12 48 24 12 36 24 24 48 36 12 ...
 $ jumlah_tanggungan    : num  0 3 5 0 5 5 5 0 2 4 ...

.

Menghasilkan Model dengan Fungsi C5.0

Dengan persiapan sebelumnya, sekarang saatnya kita akan 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”.

Syntax penggunaan fungsi C5.0 adalah sebagai berikut:

C5.0(input_variables, class_variables)

.

Dengan menggunakan dataset yang sudah kita siapkan maka perintah untuk membentuk model dan sekaligus menyimpannya dalam satu variable bernama risk_rating_model adalah sebagai berikut:

risk_rating_model <- C5.0(input_training_set, class_training_set)

.

Sederhana sekali bukan?

Namun kita belum selesai, setelah pembentukan model coba tampilkan overview model tersebut dengan perintah summary.

summary(risk_rating_model)

.

Masukkan kedua code yang telah dicontohkan ke dalam code editor untuk menggantikan bagian #[…1…] dan jalankan. Jika semua berjalan dengan lancar, maka output yang dihasilkan adalah sebagai berikut. Detil output ini akan kita bahas pada bab berikutnya.

Source Code

library("openxlsx")
library("C50")

#Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx")

#Mempersiapkan class dan input variables 
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 dan menampilkan summary model
risk_rating_model <- C5.0(input_training_set, class_training_set)
summary(risk_rating_model)

.

Hasilnya adalah sebagai berikut

Class specified by attribute `outcome'

Read 800 cases (3 attributes) from undefined.data

Decision tree:

jumlah_tanggungan > 4:
:...durasi_pinjaman_bulan <= 24: 4 (98/25)
:   durasi_pinjaman_bulan > 24: 5 (129/49)
jumlah_tanggungan <= 4:
:...jumlah_tanggungan > 2: 3 (219/17)
    jumlah_tanggungan <= 2:
    :...durasi_pinjaman_bulan <= 36: 1 (259/80)
        durasi_pinjaman_bulan > 36:
        :...jumlah_tanggungan <= 0: 2 (37/7)
            jumlah_tanggungan > 0: 3 (58/2)


Evaluation on training data (800 cases):

	    Decision Tree   
	  ----------------  
	  Size      Errors  

	     6  180(22.5%)   <<


	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 5


	Attribute usage:

	100.00%	jumlah_tanggungan
	 72.62%	durasi_pinjaman_bulan


Time: 0.0 secs

.

Menghasilkan Plot dari Model C5.0

Selain model teks dari praktek sebelumnya, kita juga bisa menghasilkan decision tree dalam bentuk grafik. Dan cuma butuh satu perintah untuk melakukan hal ini, yaitu:

plot(model)

Dengan code praktek yang telah kita lakukan – dimana model kita namakan risk_rating_model – maka perintah tersebut kita sesuaikan menjadi.

plot(risk_rating_model)

Ketikkan perintah tersebut untuk menggantikan bagian #[…1…] dari code editor. Jalankan, dan jika berhasil Anda akan mendapatkan diagram decision tree sebagai berikut.

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, variable yang diperlukan oleh algoritma ini ada dua macam:

  • Class variable, yaitu variable yang berisi nilai yang ingin kita klasifikasikan. Variable ini harus berisi tipe factor.
  • Input variables, yaitu variable-variable yang berisi nilai input.

Dan untuk mengukur akurasi dari model yang kita hasilkan, kita 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, pada penutup bab dataset ini kita menggunakan fungsi C5.0 untuk membentuk model risk rating. Dan untuk mencetak hasil yang bisa dibaca atas model ini, kita gunakan fungsi  summary. Sedangkan untuk menghasilkan diagram decision tree kita gunakan perintah plot. Semua function ini dari package C50.

Bab berikutnya akan kita fokuskan untuk membahas kedua output dari model ini. Klik tombol Next untuk melanjutkan.

.

Summary Model C5.0

Berikut adalah tampilan summary dari model decision tree yang dihasilkan dari fungsi C5.0 di bab sebelumnya. Terlihat cukup banyak informasi disini, akan kita lihat satu per satu pada bab ini.

Result

Class specified by attribute `outcome'

Read 800 cases (3 attributes) from undefined.data

Decision tree:

jumlah_tanggungan > 4:
:...durasi_pinjaman_bulan <= 24: 4 (98/25)
:   durasi_pinjaman_bulan > 24: 5 (129/49)
jumlah_tanggungan <= 4:
:...jumlah_tanggungan > 2: 3 (219/17)
    jumlah_tanggungan <= 2:
    :...durasi_pinjaman_bulan <= 36: 1 (259/80)
        durasi_pinjaman_bulan > 36:
        :...jumlah_tanggungan <= 0: 2 (37/7)
            jumlah_tanggungan > 0: 3 (58/2)


Evaluation on training data (800 cases):

	    Decision Tree   
	  ----------------  
	  Size      Errors  

	     6  180(22.5%)   <<


	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 5


	Attribute usage:

	100.00%	jumlah_tanggungan
	 72.62%	durasi_pinjaman_bulan

.

Label dari Class

Mari kita perhatikan baris pertama potongan output yang kita warnai biru sebagai berikut, output lainnya kita hilangkan.

Class specified by attribute `outcome'

Read 800 ....

Ini artinya class variable kita dilabelkan atau dinamakan sebagai outcome. Jika kita kita ingin merubah label yang lebih mewakili, yaitu “Risk Rating”, maka bisa kita tambahkan parameter control dengan input berupa fungsi C5.0Control dan parameter label sebagai berikut.

control = C5.0Control(label="Risk Rating")

Tambahkan code ini ke bagian […1…] dari code editor, dimana sudah dimasukkan seluruh code dari bab sebelumnya – dan jalankan. Jika berjalan dengan baik, maka akan muncul bagian output class label sebagai berikut.

Class specified by attribute `Risk Rating'

Read 800 ....

Terlihat label class kita sudah berubah menjadi “Risk Rating”.

Jumlah Data dan Variable yang Digunakan

Kita fokus ke bagian berikutnya dari output – yang diwarnai biru sebagai berikut.

Class specified by attribute `Risk Rating'

Read 800 cases (3 attributes) from undefined.data 

Kemudian untuk bagian 3 attributes, ini artinya kita memiliki tiga variable, yaitu:

  • input variables: durasi_pinjaman dan jumlah_tanggungan. Dua variable ini didapatkan dari hasil perintah berikut.
  • class variable: risk_rating
input_columns <- c("durasi_pinjaman_bulan", "jumlah_tanggungan")
datafeed <- dataCreditRating[ , input_columns ]

Berikut adalah gambar tampilan dari tiga variable tersebut di Excel.

Cobalah Anda ganti dua hal berikut pada code editor:

  • input_columns <- c(“durasi_pinjaman_bulan”, “jumlah_tanggungan”)
    menjadi
    input_columns <- c(“durasi_pinjaman_bulan”, “jumlah_tanggungan”, “kpr_aktif”)
  • sample(900, 800) menjadi sample(900, 780)

Cobalah jalankan dan harusnya Anda akan mendapatkan output baru sebagai berikut. Perhatikan jumlah cases dan attributes sudah berubah.

Class specified by attribute `Risk Rating'

Read 780 cases (4 attributes) from undefined.data

Decision tree:

kpr_aktif = TIDAK:
:...durasi_pinjaman_bulan <= 24: 1 (189/45)
:   durasi_pinjaman_bulan > 24: 2 (136/47)
kpr_aktif = YA:
:...jumlah_tanggungan <= 4: 3 (259/4)
    jumlah_tanggungan > 4:
    :...durasi_pinjaman_bulan <= 24: 4 (87/15)
        durasi_pinjaman_bulan > 24: 5 (109/31)

Tampilan Teks dari Model Decision Tree

Decision tree:

jumlah_tanggungan > 4:
:...durasi_pinjaman_bulan <= 24: 4 (98/25)
:   durasi_pinjaman_bulan > 24: 5 (129/49)
jumlah_tanggungan <= 4:
:...jumlah_tanggungan > 2: 3 (219/17)
    jumlah_tanggungan <= 2:
    :...durasi_pinjaman_bulan <= 36: 1 (259/80)
        durasi_pinjaman_bulan > 36:
        :...jumlah_tanggungan <= 0: 2 (37/7)
            jumlah_tanggungan > 0: 3 (58/2)

erikut adalah arti pewarnaan tersebut:

  • Warna biru adalah node dan kondisi splitnya. 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 kita ambil contoh satu alur yang telah diwarnai berikut.

jumlah_tanggungan > 4:
:...durasi_pinjaman_bulan <= 24: 4 (98/25)
: durasi_pinjaman_bulan > 24: 5 (129/49)

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 ratingnya adalah 4.
    Dari dataset training, alur ini mengklasifikasikan 98 data, namun 25 diantara 98 data ini salah klasifikasi. Berikut adalah tampilan data asal kita, terlihat beberapa kondisi yang terpenuhi namun bukan dengan nilai risk rating 4 (warna merah).

2. Jika durasi pinjaman lebih dari 24 bulan, maka klasifikasi risk ratingnya adalah 5.
Dari dataset training, alur ini mengklasifikasikan 129 data, namun 49 diantara 129 data ini salah klasifikasi. Berikut adalah tampilan data asal kita, 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 kita akan melakukan evaluasi apakah dengan persentase kesalahan ini masih dalam toleransi yang baik, sehingga model layak digunakan.

Persentase Kesalahan Model

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

Evaluation on training data (800 cases):

	    Decision Tree   
	  ----------------  
	  Size      Errors  

	     6  180(22.5%)   <<

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 yang salah klasifikasi, dan 22.5% adalah rasio dari seluruh populasi.

Confusion Matrix

Tampilan output berikutnya adalah semacam tabel yang disebut dengan confusion matrix dengan ukuran 5 x 5.

	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 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 row yang sama. Dimana header dari row dan kolom adalah merupakan representasi dari nilai class variable – untuk contoh kita adalah representasi risk_rating.  Untuk kasus kita 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 kita diskusikan arti dari nilai-nilai pada baris pertama dari matrix ini.

	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 5
  • 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

Kita bisa ambil 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 kita bisa ambil 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.

	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 5

Terakhir, kita 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.

Merubah Label Class Variable

Label risk rating pada confusion matrix kita saat ini adalah 1 sampai dengan 5. Ini karena kebetulan contoh class variable kita adalah angka terurut seperti itu.

Agar tidak bingung mari kita ubah isi dari variable 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, kita akan ambil contoh untuk perintah pertama:

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

Dengan demikian, arti dari perintah pertama adalah memasukkan teks “satu” ke variable risk_rating dengan indeks dimana nilai risk_rating bernilai “1”.

Masukkan kelimat perintah tersebut untuk menggantikan #[…1…] pada code editor kita dan jalankan. Jika berhasil, perhatikan output confusion matrix dimana labelnya – ditandai dengan warna biru – sudah berubah menjadi teks “dua”, “empat”, “lima”, “satu”, dan “tiga” (diurutkan berdasarkan alfabet).

	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	    30     3    12    80    14    (a): class dua
	     2    73    31                (b): class empat
	          17    80                (c): class lima
	     1     5     6   179     5    (d): class satu
	     4                     258    (e): class tiga

Bandingkan dengan confusion matrix sebelumnya, dimana semua hasilnya tetap konsisten. Hanya saja urutannya berubah.

	   (a)   (b)   (c)   (d)   (e)    <-classified as
	  ----  ----  ----  ----  ----
	   179     1     5     5     6    (a): class 1
	    80    30    14     3    12    (b): class 2
	           4   258                (c): class 3
	           2          73    31    (d): class 4
	                      17    80    (e): class 5

Demikian praktek kita kali ini, yang bertujuan untuk memperjelas output confusion matrix dari summary C5.0. Label “satu”, “dua”, dstnya hanya untuk menunjukkan, tapi tidak akan digunakan di content berikutnya.

Output terakhir adalah daftar variable-variable yang digunakan oleh model decision tree.

	Attribute usage:

	100.00%	jumlah_tanggungan
	 72.62%	durasi_pinjaman_bulan

Output tersebut menceritakan tingkat pentingnya penggunaan tiap variable. 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 kita.

Diagram Decision Tree C5.0

Elemen dari Plot Decision Tree C5.0

  • Warna merah menunjukkan node dan penomoran nodenya
    • bulatan merah nomor 1 adalah node nomor 1 adalah root node dengan variable penentu jumlah_tanggungan.
    • bulatan merah nomor 2 adalah node nomor 2 dengan variable 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.

Kesimpulan

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

  • Jumlah baris data yang diproses untuk menghasilkan model.
  • Jumlah variable yang digunakan untuk menghasilkan model.
  • Tampilan decision tree.
  • Statistik error dari model ini.
  • Confusion matrix yang menampilkan detil dari hasil klasifikasi dan aktual.
  • Variable-variable yang digunakan dan tingkat pentingnya variable 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, kita akan evaluasi model ini dengan memprediksi nilai dari testing set. 

EVALUASI MODEL

Confusion Matrix yang terdapat pada output model kita sebelumnya adalah evaluasi model menggunakan training set. Namun, kita perlu evaluasi model ini terhadap testing set yang telah kita siapkan.

Code

library("openxlsx")
library("C50")

#Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx")

#Mempersiapkan class dan input variables 
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"))

#menggunakan model untuk prediksi testing set
#[...1...]
predict(risk_rating_model, input_testing_set)

Result

> library("openxlsx")

> library("C50")

> #Mempersiapkan data
> dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx")

> #Mempersiapkan class dan input variables 
> 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"))

> #menggunakan model untuk prediksi testing set
> #[...1...]
> predict(risk_rating_model, input_testing_set)
  [1] 1 3 4 1 5 4 4 2 1 3 3 1 3 3 3 4 3 1 1 3 5 3 5 1 4 4 1 3 3 1 2 3 3 1 3 5 3
 [38] 3 3 1 3 3 5 1 5 1 5 1 3 3 4 1 3 1 1 3 1 1 1 5 1 1 3 3 3 1 3 4 1 3 3 3 1 3
 [75] 4 3 2 1 3 1 5 5 1 1 4 4 3 2 4 1 1 4 1 3 1 1 1 5 4 3
Levels: 1 2 3 4 5

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 contoh kita, maka tampilan lengkapnya adalah sebagai berikut.

predict(risk_rating_model, input_testing_set)

Gantilah bagian #[…1…] pada code editor dengan perintah di atas dan jalankan. Jika berjalan dengan baik, maka tampilan hasilnya adalah sebagai berikut.

> predict(risk_rating_model, input_testing_set)
  [1] 1 3 4 1 5 4 4 2 1 3 3 1 3 3 3 4 3 1 1 3 5 3 5 1 4 4 1 3 3 1 2 3 3 1 3 5 3
 [38] 3 3 1 3 3 5 1 5 1 5 1 3 3 4 1 3 1 1 3 1 1 1 5 1 1 3 3 3 1 3 4 1 3 3 3 1 3
 [75] 4 3 2 1 3 1 5 5 1 1 4 4 3 2 4 1 1 4 1 3 1 1 1 5 4 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.

Menggabungkan Hasil Prediksi

Seperti diinformasikan pada subbab sebelumnya, kita akan menyimpan risk_rating dari dataset awal dan hasil prediksi ini ke dalam dua kolom nama yang lain di data frame input_testing_set. Mari kita namakan kolom tersebut dengan risk_rating dan  hasil_prediksi.

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

Masukkan perintah tersebut untuk menggantikan bagian #[…1…] pada code editor. Setelah itu coba ganti bagian […2…] dengan perintah untuk menampilkan seluruh isi variable input_testing_set dengan perintah berikut.

print(input_testing_set)

Jika semua berjalan lancar maka akan tampil output sebagai berikut. Dengan kolom risk_rating dan hasil_prediksi bersampingan, kita bisa langsung bandingkan data awal dengan hasil prediksi. Terlihat ada rating yang sama (prediksi benar) dan berbeda (prediksi salah). Kita akan evaluasi 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
8                      48                 3           2              3
21                     24                 5           2              4
26                     12                 0           1              1
28                     36                 5           2              5
37                     24                 5           2              4
39                     24                 5           1              4
45                     48                 0           1              2
49                     36                 2           1              1
53                     12                 4           2              3
54                     48                 1           2              3
58                     12                 0           1              1
60                     48                 3           2              3
61                     48                 2           2              3
62                     24                 4           2              3
65                     24                 5           2              4
75                     24                 3           2              3
97                     12                 0           1              1
112                    12                 0           1              1
117                    24                 3           3              3
123                    36                 6           4              5
125                    36                 4           3              3
128                    36                 6           4              5
162                    12                 0           1              1
166                    24                 6           4              4
187                    12                 6           5              4
192                    36                 1           1              1
198                    12                 3           3              3
219                    48                 2           3              3
221                    36                 1           1              1
239                    48                 0           2              2
250                    24                 4           3              3
255                    48                 1           3              3
276                    36                 1           1              1
284                    24                 4           3              3
287                    36                 6           5              5
291                    24                 4           3              3
323                    48                 4           3              3
329                    48                 1           3              3
335                    24                 0           1              1
336                    48                 2           3              3
338                    36                 3           3              3
345                    36                 5           4              5
348                    24                 0           1              1
350                    48                 6           5              5
356                    36                 2           2              1
386                    48                 5           4              5
398                    12                 1           1              1
406                    36                 4           3              3
416                    24                 3           3              3
434                    12                 6           4              4
460                    12                 1           1              1
466                    48                 1           3              3
514                    36                 2           1              1
520                    24                 1           2              1
526                    24                 3           3              3
532                    36                 1           1              1
539                    36                 2           2              1
541                    24                 1           1              1
548                    48                 6           5              5
560                    24                 1           1              1
564                    24                 1           1              1
568                    48                 3           3              3
570                    48                 4           3              3
572                    24                 4           3              3
584                    36                 2           1              1
585                    36                 4           3              3
587                    12                 6           4              4
588                    12                 2           1              1
646                    48                 1           3              3
660                    36                 4           3              3
665                    12                 4           3              3
666                    36                 0           2              1
673                    48                 3           3              3
677                    24                 5           4              4
678                    48                 4           3              3
679                    48                 0           2              2
681                    36                 1           1              1
684                    48                 2           3              3
687                    12                 2           1              1
701                    48                 5           4              5
704                    48                 6           5              5
707                    12                 2           1              1
708                    12                 2           1              1
716                    12                 5           4              4
732                    24                 6           4              4
734                    24                 3           3              3
767                    48                 0           2              2
776                    12                 6           4              4
781                    24                 2           1              1
782                    24                 2           1              1
790                    12                 6           4              4
813                    24                 2           1              1
839                    24                 4           3              3
842                    36                 0           2              1
845                    24                 2           2              1
853                    24                 2           1              1
861                    48                 5           5              5
862                    12                 6           4              4
870                    48                 3           3              3

Membuat Table Confusion Matrix

Setelah hasil prediksi terhadap testing set selesai, langkah berikutnya kita coba lihat distribusi mana yang terprediksi dengan benar dan salah. Ini kita lakukan dengan confusion matrix.

Untuk menghasilkan ini kita bisa gunakan fungsi dcast dari package reshape2, caranya adalah sebagai berikut.

dcast(kolom ~ baris, dataframe)

Dan untuk kasus kita, maka modifikasi perintahnya adalah sebagai berikut.

dcast(hasil_prediksi ~ risk_rating, data=input_testing_set)

Gunakan perintah tersebut untuk menggantikan bagian #[…1…] – setelah perintah penggabungan input variables dan hasil prediksi.

  hasil_prediksi  1 2  3 4 5
1              1 29 6  0 0 0
2              2  1 3  0 0 0
3              3  0 7 29 0 0
4              4  1 3  0 9 1
5              5  0 1  0 5 5 

Yang kita perhatikan adalah bagian berwarna berikut:

   hasil_prediksi  1 2  3 4 5
1               1 29 6  0 0 0
2               2  1 3  0 0 0
3               3  0 7 29 0 0
4               4  1 3  0 9 1
5               5  0 1  0 5 5

Header kolom yang berwarna ungu menunjukkan risk_rating hasil prediksi, sedangkan header baris warna ungu menunjukkan data risk_rating sebenarnya. Diagonal warna biru menunjukkan jumlah data yang terprediksi dengan benar, dan warna merah 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 diman prediksi 5 itu kadang jatuh ke 4. Namun ini bisa kita abaikan, karena 4 dan 5 memang beresiko tinggi.

Jumlah Data dengan Prediksi Benar

Untuk menghitung persentase error, kita bisa menghitung terlebih dahulu jumlah data dengan prediksi yang benar. Hasil dikatakan benar jika data risk_rating sama dengan hasil_prediksi. Ini kalau kita tuliskan dengan code adalah sebagai berikut.

input_testing_set$risk_rating==input_testing_set$hasil_prediksi

Disini kita gunakan operator == untuk membandingkan. Cobalah ketik perintah tersebut  untuk menggantikan bagian […1…] dan jalankan. Jika berhasil maka akan keluar input tersebut.

> input_testing_set$risk_rating==input_testing_set$hasil_prediksi
  [1]  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
 [13] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE
 [25]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE
 [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
 [61]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [73] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
 [85]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
 [97]  TRUE  TRUE  TRUE  TRUE

Ini artinya kalau TRUE maka data pada posisi tersebut prediksinya benar dan FALSE untuk sebaliknya, data pada posisi tersebut salah prediksinya. Namun ini masih belum dalam bentuk yang kita inginkan. Kita masih perlu beberapa tambahan perintah tersebut untuk mengeluarkan persentase prediksi yang tepat.

Langkah berikutnya, adalah 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
26                     12                 0           1              1
49                     36                 2           1              1
58                     12                 0           1              1
97                     12                 0           1              1
112                    12                 0           1              1
117                    24                 3           3              3
125                    36                 4           3              3
162                    12                 0           1              1
...


Terlihat semua hasil filtering memiliki nilai yang sama untuk kolom risk_rating dan hasil_prediksi. Kita kemudian akan menghitung 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 outputnya adalah sebagai berikut.

> nrow(input_testing_set[input_testing_set$risk_rating==input_testing_set$hasil_prediksi,])
[1] 75

Angka 75 ini menunjukkan jumlah data dengan prediksi yang benar terhadap testing set. Karena testing set berjumlah 100, maka persentase prediksi yang benar adalah 75%, dan error rate atau persentase yang salah adalah 25%.

Mari kita cek hasil tersebut dengan menjumlahkan posisi diagonal pada confusion matrix kita sebelumnya.

   hasil_prediksi  1 2  3 4 5
1               1 29 6  0 0 0
2               2  1 3  0 0 0
3               3  0 7 29 0 0
4               4  1 3  0 9 1
5               5  0 1  0 5 5

Hasilnya juga 75 yang merupakan hasil dari operasi penjumlah 29 + 3 + 29 + 9 + 5. 

Jumlah Data dengan Prediksi Salah

Pada praktek sebelumnya, kita menggunakan operator == untuk membandingkan kesamaan antara kolom risk_rating dengan hasil_prediksi. Bagaimana kalau kita hanya ingin mencari yang tidak sama, dengan kata lain mencari yang salah prediksinya?

Untuk ini cukup simpel, kita bisa menggunakan operator != sehingga kondisi pengecekan sebelumnya menjadi seperti berikut.

nrow(input_testing_set[input_testing_set$risk_rating!=input_testing_set$hasil_prediksi,])

Cari dan gantilah operator == pada perbandingan hasil ini dengan !=. Jika berjalan dengan lancar maka akan mengeluarkan hasil berikut.

> nrow(input_testing_set[input_testing_set$risk_rating!=input_testing_set$hasil_prediksi,])
[1] 25


Terlihat bahwa jumlah prediksi error ada 25. Hasil ini konsisten jika dibandingkan dengan jumlah 75 dari prediksi yang benar, dimana total keduanya adalah 100 – yang merupakan jumlah data untuk testing set. Klik tombol Submit Code untuk melanjutkan ke bagian berikutnya. 

Kesimpulan

Bab ini berisi praktek yang cukup singkat, namun menjadi bagian yang sangat penting yaitu untuk pertama kalinya kita 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 25%, dan walaupun ada catatan untuk klasifikasi 4 dan 5, namun secara garis besar kita anggap model ini cukup baik. Dan dengan keputusan ini, saatnya kita mengadopsi model ini untuk melakukan prediksi per data aplikasi kredit baru yang masuk.

MENGGUNAKAN MODEL UNTUK PREDIKSI

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

Mempersiapkan Data Pengajuan Baru

Data pengajuan baru perlu dibentuk sebagai satu data frame dengan input dimana nama-nama variable yang digunakan harus sama persis. Dari awal pemodelan, kita menggunakan dua variable yakni:

  • jumlah_tanggungan
  • durasi_pinjaman_bulan

Keduanya dalam bentuk numerik (angka). Dan berikut adalah contoh membentuk data frame dengan dua variable tersebut.

aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 12)

Code tersebut sudah terdapat pada code editor. Namun, Anda perlu tampilkan variable tersebut dengan perintah print. Jika berhasil jalankan dengan lancar maka akan muncul hasil sebagai berikut.

  jumlah_tanggungan durasi_pinjaman_bulan
1                 6                    12

Kita akan gunakan data frame ini sebagai input untuk prediksi di bagian berikutnya.

CODE PROGRAM

#Membuat data frame aplikasi baru
aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 12)
print(aplikasi_baru)

Melakukan Prediksi terhadap Data Pengajuan Baru

Data aplikasi baru yang telah kita buat sebelumnya akan diprediksi nilai risk_rating-nya dengan fungsi predict, dimana cara penggunaannya masih sama dengan cara yang ditunjukkan pada bab evaluasi model, yaitu dengan syntax berikut.

predict(model, dataframe)

Code editor telah terisi code-code yang digunakan untuk membentuk model dan data frame aplikasi baru. Gantilah bagian […1…] dengan code untuk melakukan prediksi. Sesuaikan perintah di atas dengan nama model dan variable yang digunakan. Variable risk_rating_model sebagai model dan aplikasi_baru sebagai data frame yang akan di prediksi.

Jika berjalan dengan lancar maka output dari perintah tersebut akan muncul sebagai berikut.

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

Merubah Durasi Pinjaman

Source Code

library("openxlsx")
library("C50")

#Mempersiapkan data
dataCreditRating <- read.xlsx(xlsxFile = "https://storage.googleapis.com/dqlab-dataset/credit_scoring_dqlab.xlsx")

#Mempersiapkan class dan input variables 
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 dan menampilkan summary model
risk_rating_model <- C5.0(input_training_set, class_training_set)

#Membuat data frame aplikasi baru
aplikasi_baru <- data.frame(jumlah_tanggungan = 6, durasi_pinjaman_bulan = 12)

#melakukan prediksi
predict(risk_rating_model, aplikasi_baru)

Pada pelajaran sebelumnya kita sudah mempelajari cara memprediksi dari data frame berdasarkan model yang telah dibuat. Sekarang kita mencoba memprediksi dari data yang tidak ada dari data set yang dijadikan model.

Pada console gantilah pada […1…] yang menunjukan durasi pinjaman selama 64 bulan.

Jika berjalan dengan lancar maka output dari perintah tersebut akan muncul sebagai berikut.

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

KESIMPULAN

Bab ini telah menunjukkan bagaimana kita melakukan prediksi nilai resiko kredit (risk_rating) terhadap data aplikasi baru.

Fungsi yang digunakna sangat sederhana, tetapi kita 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 kita memiliki kelebihan satu kolom data frame yang tidak digunakan pada saat memberikan input ke model akan berakibat error pada saat melakukan prediksi.

Selamat, Anda sudah berhasil menyelesaikan seluruh content ini. Pada saat ini telah mempelajari mengenai kasus bisnis resiko kredit pada dunia finance. Dengan mengerti apa pengertian credit risk, credit scoring, risk rating dan problem-problem yang dihadapi kita 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.

Terkait hal tersebut, sepanjang bab ini Anda telah menempuh perjalanan sebagai seorang data scientist yang menerapkan solusi tersebut:

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

Walaupun cukup banyak konsep dan implementasi dari penelitian ini yang bisa langsung Anda terapkan untuk kasus credit rating di tempat Anda. Namun ada banyak catatan bagi Anda agar lebih baik menggunakan model ini, yaitu:

  • Pada kenyataannya, variable yang terlibat jauh lebih banyak dan kadang masih dalam bentuk yang kosong, tidak lengkap atau tidak standar. Ini memerlukan teknik data cleansing yang juga telah tersedia di Whitecyber.
  • Variable 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. Ini akan dibahas pada course lain.
  • Evaluasi model yang juga umum dan menjadi best practice adalah menggunakan visualisasi ROC Curve. Ini kami putuskan untuk dijadikan short course lanjutan setelah decision tree ini.
  • Terakhir, Anda perlu lebih banyak latihan dan praktek menangani berbagai kasus mengenai pembentukan model decision tree terutama untuk credit risk ini.  Ini akan secara regular kami berikan dalam bentuk project atau data challenge dari partner kami.

Leave a Reply

Your email address will not be published. Required fields are marked *