1 . Pendahuluan

Credit scoring menjadi salah satu cara untuk melakukan prediksi apakah pengajuan kredit dari seseorang akan memberikan hasil profit dan loss pada lembaga yang memberikan pinjaman. Credit scoring atau penilaian kredit adalah suatu sistem yang diterapkan oleh suatu lembaga pembiayaan seperti bank, fintech, p2p lending atau pihak pemberi pinjaman lainnya untuk menilai profil risiko peminjam terkait kelayakannya mendapat pendanaan atau tidak. Informasi nasabah yang mengajukan pinjaman akan dilengkapi dengan sejumlah persyaratan dokumen yang wajib dilampirkan oleh calon peminjam untuk kemudian diverifikasi keabsahannya oleh lembaga jasa keuangan. Informasi inilah yang kemudian akan menjadi data input untuk dihitung nilai score-nya dan menjadi dasar untuk menentukan pemberian kreditnya.

Hal-hal yang akan dilakukan pada project analisis ini adalah:

  • Melakukan preprocessing data sebelum dilakukan cross validation dan juga tahapan initial characteristic analysis

  • Membuat data scaling dengan WOE, melakukan variable selection dengan IV, serta melakukan coarse classing

  • Mengimplementasikan pemodelan machine learning untuk prediksi scorecard

  • Membuat penilaian dalam bentuk score point untuk setiap bin yang diakumulasikan menjadi scorecard

  • Melakukan evaluasi pembentukan scorecard dan prediksi pada data baru.

Pada proyek kali ini, data Source diambil dai kaggle dengan link berikut: https://www.kaggle.com/datasets/atulmittal199174/credit-risk-analysis-for-extending-bank-loans. Dimana jenis Scoring yang akan dilakukan adalah Credit Application, yakni: untuk modeling credit granting decision untuk kasus-kasus pengajuan aplikasi pertama kali.

2 . Import dan Eksplorasi Data

#import dataset
kredit <- read.csv("data_project/bankloans.csv")
head(kredit,5)
##   age ed employ address income debtinc  creddebt  othdebt default
## 1  41  3     17      12    176     9.3 11.359392 5.008608       1
## 2  27  1     10       6     31    17.3  1.362202 4.000798       0
## 3  40  1     15      14     55     5.5  0.856075 2.168925       0
## 4  41  1     15      14    120     2.9  2.658720 0.821280       0
## 5  24  2      2       0     28    17.3  1.787436 3.056564       1
#cek tipe data
glimpse(kredit)
## Rows: 1,150
## Columns: 9
## $ age      <int> 41, 27, 40, 41, 24, 41, 39, 43, 24, 36, 27, 25, 52, 37, 48, 3…
## $ ed       <int> 3, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 1…
## $ employ   <int> 17, 10, 15, 15, 2, 5, 20, 12, 3, 0, 0, 4, 24, 6, 22, 9, 13, 2…
## $ address  <int> 12, 6, 14, 14, 0, 5, 9, 11, 4, 13, 1, 0, 14, 9, 15, 6, 6, 19,…
## $ income   <int> 176, 31, 55, 120, 28, 25, 67, 38, 19, 25, 16, 23, 64, 29, 100…
## $ debtinc  <dbl> 9.3, 17.3, 5.5, 2.9, 17.3, 10.2, 30.6, 3.6, 24.4, 19.7, 1.7, …
## $ creddebt <dbl> 11.359392, 1.362202, 0.856075, 2.658720, 1.787436, 0.392700, …
## $ othdebt  <dbl> 5.008608, 4.000798, 2.168925, 0.821280, 3.056564, 2.157300, 1…
## $ default  <int> 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0…

Keterangan kolom data adalah sebagai berikut:

Variabel Prediktor

  • age: Age of the Customers

  • ed: Education Level

  • employ: Work Experience

  • addres: Address of the Customer

  • income: Yearly Income of the customer

  • debtinc: Debt to Income ratio

  • creddebt: Credit to Debt ratio

  • othdebt: Other debts

Variabel Target:

  • default: Customer defaulted in the past (1= defaulted, 0=Never defaulted)
#cek missing value pada variabel target
sum(is.na(kredit$default))
## [1] 450

Dari hasil di atas diketahui bahwa sebanyak 450 data pada variabel target memiliki missing value sehingga terpaksa harus dibuang. Setelah itu, proses dilanjutkan dengan mengubah kelas data untuk variabel ed dan address menjadi factor.

#membuang row dengan missing value pada variabel target
#perubahan tipe data

kredit <- kredit %>%
  drop_na() %>% 
  mutate(ed = as.factor(ed),
         address = as.factor(address))
glimpse(kredit)
## Rows: 700
## Columns: 9
## $ age      <int> 41, 27, 40, 41, 24, 41, 39, 43, 24, 36, 27, 25, 52, 37, 48, 3…
## $ ed       <fct> 3, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 1…
## $ employ   <int> 17, 10, 15, 15, 2, 5, 20, 12, 3, 0, 0, 4, 24, 6, 22, 9, 13, 2…
## $ address  <fct> 12, 6, 14, 14, 0, 5, 9, 11, 4, 13, 1, 0, 14, 9, 15, 6, 6, 19,…
## $ income   <int> 176, 31, 55, 120, 28, 25, 67, 38, 19, 25, 16, 23, 64, 29, 100…
## $ debtinc  <dbl> 9.3, 17.3, 5.5, 2.9, 17.3, 10.2, 30.6, 3.6, 24.4, 19.7, 1.7, …
## $ creddebt <dbl> 11.359392, 1.362202, 0.856075, 2.658720, 1.787436, 0.392700, …
## $ othdebt  <dbl> 5.008608, 4.000798, 2.168925, 0.821280, 3.056564, 2.157300, 1…
## $ default  <int> 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0…
sum(is.na(kredit$default))
## [1] 0

Dari proses di atas terlihat data yang tersisa seluruhnya sudah memiliki variable target. Proses dilanjutkan dengan mengecek distribusi data pada variabel target.

#Mengecek Distribusi Variabel Target
table(kredit$default) %>% 
  prop.table()
## 
##         0         1 
## 0.7385714 0.2614286

Walaupun proporsi dari variabel target agak tidak seimbang, namun untuk tahapan ini akan dibiarkan terlebih dahulu karena akan diproses saat sudah menjadi data train.

#pengecekan distribusi data
describe(kredit)
##    variable   class count missing_rate unique_count identical_rate       min
##      <char>  <char> <int>        <num>        <int>          <num>     <num>
## 1:      age integer   700            0           37         0.0629 20.000000
## 2:       ed  factor   700            0            5         0.5314        NA
## 3:   employ integer   700            0           32         0.0886  0.000000
## 4:  address  factor   700            0           31         0.0843        NA
## 5:   income integer   700            0          114         0.0343 14.000000
## 6:  debtinc numeric   700            0          231         0.0143  0.400000
## 7: creddebt numeric   700            0          695         0.0029  0.011696
## 8:  othdebt numeric   700            0          699         0.0029  0.045584
## 9:  default integer   700            0            2         0.7386  0.000000
##           p25        p50       p75       max    mean      sd     cv
##         <num>      <num>     <num>     <num>   <num>   <num>  <num>
## 1: 29.0000000 34.0000000 40.000000  56.00000 34.8600  7.9973 0.2294
## 2:         NA         NA        NA        NA      NA      NA     NA
## 3:  3.0000000  7.0000000 12.000000  31.00000  8.3886  6.6580 0.7937
## 4:         NA         NA        NA        NA      NA      NA     NA
## 5: 24.0000000 34.0000000 55.000000 446.00000 45.6014 36.8142 0.8073
## 6:  5.0000000  8.6000000 14.125000  41.30000 10.2606  6.8272 0.6654
## 7:  0.3690593  0.8548695  1.901955  20.56131  1.5536  2.1172 1.3628
## 8:  1.0441782  1.9875675  3.923065  27.03360  3.0582  3.2876 1.0750
## 9:  0.0000000  0.0000000  1.000000   1.00000  0.2614  0.4397 1.6820

3 . Cross Validation

Dataset keseluruhan akan dibagi menjadi data Train dan Data Test. Hal ini dilakukan dengan menggunakan fungsi Splitter.

RNGkind(sample.kind= "Rounding")
set.seed(123) # mengunci kerandoman data

#membuat binary split data menjadi set data training dan testing dengan proporsi 80:20
splitter <- initial_split(data = kredit,
                          prop = 0.8) # data train

# splitting
train <- training(splitter)
test <- testing(splitter)

Data Train dicek keseimbangan data dari variabel targetnya.

table(train$default) %>% 
  prop.table()
## 
##      0      1 
## 0.7375 0.2625

Jika datanya dirasa belum seimbang, maka dapat dilakukan adjustment data train dengan teknik SMOTE agar proporsi variabel targetnya menjadi lebih baik

# train <- SmoteClassif(form = default ~ .,
#                                 dat = train,
#                                 C.perc = "balance",
#                                 dist = "HVDM")

Melakukan pengecekan keseimbangan data variabel target dari data train yang baru

# table(train$default) %>%
#   prop.table()

Namun kali ini data yang digunakan tetap data awal, dimana proposi 73:26 pada variabel target dianggap masih masuk dalam kategori seimbang.

4 . Weight of Evidence (WoE) or Fine Classing

Membuat Data Binning

binning <- woebin(dt = train,
                  y = "default",
                  positive = 0)
## ℹ Creating woe binning ...
## ✔ Binning on 560 rows and 9 columns in 00:00:03

Mengubah Dataframe ke dalam WOE

# data train
train_woe <- woebin_ply(dt = train,
                        bins = binning)
## ℹ Converting into woe values ...
## ✔ Woe transformating on 560 rows and 8 columns in 00:00:01
# data test
test_woe <- woebin_ply(dt = test,
                        bins = binning)
## ℹ Converting into woe values ...
## ✔ Woe transformating on 140 rows and 8 columns in 00:00:01

Information Value (IV)

iv(dt = train_woe,
   y ='default',
   positive = 0)
##        variable info_value
##          <char>      <num>
## 1:  debtinc_woe 0.81304157
## 2:   employ_woe 0.71084053
## 3:  address_woe 0.35987867
## 4: creddebt_woe 0.35331456
## 5:      age_woe 0.29780930
## 6:  othdebt_woe 0.29680119
## 7:   income_woe 0.19543587
## 8:       ed_woe 0.06896655

Menurut (Siddiqi, Naeem), skor IV dapat dikategorikan menjadi nilai berikut:

  • IV dibawah 0.02 -> unpredictive
  • IV diantara 0.02 - 0.1 -> ‘weak’
  • IV diantara 0.1 sampai 0.3 dikategorikan sebagai ‘medium’
  • IV diatas 0.3 dikategorikan sebagai ‘strong’

Berdasarkan value IV yang dihasilkan diperoleh kesimpulan bahwa semua variabel dapat digunakan karena memiliki IV > 0.02

Logical Trend and Business Consideration / Coarse Classing

plot <- woebin_plot(bins = binning)
plot
## $age

## 
## $ed

## 
## $employ

## 
## $address

## 
## $income

## 
## $debtinc

## 
## $creddebt

## 
## $othdebt

5 . Modeling - Logistic Regression

Model akan dibuat dengan memasukkan keseluruhan variabel predictor

model <- glm(formula = default ~ .,
             data = train_woe,
             family = "binomial")

summary(model) 
## 
## Call:
## glm(formula = default ~ ., family = "binomial", data = train_woe)
## 
## Coefficients:
##              Estimate Std. Error z value      Pr(>|z|)    
## (Intercept)   -1.0671     0.1283  -8.314       < 2e-16 ***
## age_woe       -0.3365     0.2675  -1.258      0.208319    
## ed_woe        -0.4813     0.5040  -0.955      0.339633    
## employ_woe    -1.1533     0.2012  -5.731 0.00000000996 ***
## address_woe   -1.0684     0.2330  -4.586 0.00000451558 ***
## income_woe    -0.3806     0.3430  -1.110      0.267142    
## debtinc_woe   -0.5873     0.1605  -3.660      0.000252 ***
## creddebt_woe  -1.3889     0.2681  -5.181 0.00000022070 ***
## othdebt_woe   -0.9225     0.2822  -3.269      0.001078 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 644.73  on 559  degrees of freedom
## Residual deviance: 421.27  on 551  degrees of freedom
## AIC: 439.27
## 
## Number of Fisher Scoring iterations: 6

Model kedua akan dibuat hanya menggunakan prediktor dengan signifikasi

model_2 <- glm(formula = default ~ employ_woe + address_woe + debtinc_woe + debtinc_woe + creddebt_woe + othdebt_woe,
             data = train_woe,
             family = "binomial")

summary(model_2) 
## 
## Call:
## glm(formula = default ~ employ_woe + address_woe + debtinc_woe + 
##     debtinc_woe + creddebt_woe + othdebt_woe, family = "binomial", 
##     data = train_woe)
## 
## Coefficients:
##              Estimate Std. Error z value           Pr(>|z|)    
## (Intercept)   -1.0743     0.1280  -8.393            < 2e-16 ***
## employ_woe    -1.3492     0.1802  -7.486 0.0000000000000708 ***
## address_woe   -1.1753     0.2175  -5.403 0.0000000656086478 ***
## debtinc_woe   -0.6050     0.1558  -3.883           0.000103 ***
## creddebt_woe  -1.3604     0.2533  -5.372 0.0000000779960706 ***
## othdebt_woe   -0.8587     0.2736  -3.139           0.001698 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 644.73  on 559  degrees of freedom
## Residual deviance: 425.46  on 554  degrees of freedom
## AIC: 437.46
## 
## Number of Fisher Scoring iterations: 6

Model Asumsi - Multikolinearitas

Model yang akan digunakan akan dilakukan uji asumsi dengan menggunakan Uji VIF

vif(model_2)
##   employ_woe  address_woe  debtinc_woe creddebt_woe  othdebt_woe 
##     1.275469     1.098485     1.252619     1.435451     1.209899

Dari hasil uji VIF ditemukan nilai dari setiap variabel < 10 sehingga dapat dikatakan variabel prediktor tidak memiliki multikolinearitas.

Prediction

# Melakukan prediksi pada data test
test_woe$pred_risk <- predict(object = model_2,
                              newdata = test_woe,
                              type = "response")
test_woe
##      default      age_woe     ed_woe   employ_woe address_woe  income_woe
##        <int>        <num>      <num>        <num>       <num>       <num>
##   1:       0 -0.297903627  0.2691962  0.605271061  -0.4650310  0.45336281
##   2:       0  0.562034169  0.2691962 -0.958907034   0.4186621  0.47106239
##   3:       0  0.562034169  0.2691962  0.001881468   0.4186621  0.07456595
##   4:       0  0.562034169 -0.2979036 -0.958907034   1.0082053 -0.36396538
##   5:       0  0.562034169  0.2691962  2.704654612  -0.4650310  0.07456595
##  ---                                                                     
## 136:       0  0.562034169  0.2691962  0.605271061   0.4186621 -0.36396538
## 137:       0 -1.033015006 -0.2265391 -0.958907034  -0.4650310  0.47106239
## 138:       0  0.003076926  0.2691962  2.704654612   0.4186621  0.65646561
## 139:       0  0.562034169  0.2691962  0.605271061   0.4186621  0.07456595
## 140:       0 -1.033015006  0.2691962 -0.958907034   0.2066759 -0.55344193
##      debtinc_woe creddebt_woe othdebt_woe    pred_risk
##            <num>        <num>       <num>        <num>
##   1:  -0.8932531   -0.3070780 -0.30259643 0.4684547929
##   2:  -0.8932531   -0.3070780  0.82328298 0.4946529678
##   3:   1.0157896    0.3757522 -0.30259643 0.0805516049
##   4:   1.0157896    1.1154194  0.39410135 0.0311890696
##   5:   1.0157896    0.3757522  2.40097220 0.0006330753
##  ---                                                  
## 136:   1.0157896   -0.1857171  0.54252135 0.0387608309
## 137:   1.0157896    0.3757522 -0.02621027 0.4164655579
## 138:   1.0157896   -0.3070780 -0.30259643 0.0057518111
## 139:  -0.1350734    0.3757522 -0.30259643 0.0722494001
## 140:   1.0157896    1.1154194 -0.02621027 0.1059277000

Evaluation Model

  1. Membuat list untuk hasil prediksi resiko dari masing-masing data train dan test
list_pred <- list(test = test_woe$pred_risk)
  1. Membuat list label pada data train dan test
list_label <- list(test = test_woe$default)
  1. Menggunakan function perf_eva untuk melakukan evaluasi
perf_eva(pred = list_pred,
         label = list_label,
         confusion_matrix = TRUE,
         threshold = 0.5,
         show_plot = c("ks", "roc"))
## ℹ The threshold of confusion matrix is 0.5000.

## $binomial_metric
## $binomial_metric$test
##          MSE      RMSE  LogLoss        R2        KS       AUC      Gini
##        <num>     <num>    <num>     <num>     <num>     <num>     <num>
## 1: 0.1716665 0.4143265 0.520948 0.1138592 0.4590209 0.7724147 0.5448295
## 
## 
## $confusion_matrix
## $confusion_matrix$test
##     label pred_0 pred_1      error
##    <char>  <num>  <num>      <num>
## 1:      0     92      9 0.08910891
## 2:      1     26     10 0.72222222
## 3:  total    118     19 0.25547445
## 
## 
## $pic
## TableGrob (1 x 2) "arrange": 2 grobs
##   z     cells    name           grob
## 1 1 (1-1,1-1) arrange gtable[layout]
## 2 2 (1-1,2-2) arrange gtable[layout]

KS Statistics

KS (Kolmogorov-Smirnov) Statistics adalah metode statistik yang digunakan untuk mengukur perbedaan antara dua distribusi kumulatif empiris, sering digunakan untuk membandingkan distribusi skor antara dua kelompok, misalnya dalam analisis kinerja credit model (membedakan antara good dan bad customers).

Nilai KS yang tinggi menunjukkan model yang baik dalam membedakan antara kedua kelompok (misalnya, good vs bad customers). Biasanya, nilai KS > 0.4 dianggap baik dalam kredit scoring.

Pada model_2terlihat dari hasil analisis nilai KS berada pada angka 0.459 sehingga dapat disimpulkan bahwa model diaanggap baik dalam kredit scoring.

6 . Scorecard Creation

# membentuk scorecard
score_card <- scorecard(bins = binning, 
                        model = model_2,
                        odds0 = 1/19,
                        points0 = 600,
                        pdo = 20)

Mengubah Karakteristik menjadi Score

score_train <- scorecard_ply(dt = train,
                       card = score_card,
                       only_total_score = F)
score_train %>% head()
##    employ_points address_points debtinc_points creddebt_points othdebt_points
##            <num>          <num>          <num>           <num>          <num>
## 1:            24             14             18              -7             -7
## 2:           -37              7             -2              15             20
## 3:            24             34             18              15             -8
## 4:           105             14             18              15             20
## 5:            24            -16            -39             -12             -7
## 6:           -37             14             -2              15             13
##    score
##    <num>
## 1:   588
## 2:   549
## 3:   629
## 4:   718
## 5:   496
## 6:   549
score_test <- scorecard_ply(dt = test,
                       card = score_card,
                       only_total_score = F)
score_test %>% head()
##    employ_points address_points debtinc_points creddebt_points othdebt_points
##            <num>          <num>          <num>           <num>          <num>
## 1:            24            -16            -16             -12             -7
## 2:           -37             14            -16             -12             20
## 3:             0             14             18              15             -7
## 4:           -37             34             18              44             10
## 5:           105            -16             18              15             59
## 6:            24            -16             -2              15             -7
##    score
##    <num>
## 1:   519
## 2:   515
## 3:   586
## 4:   615
## 5:   727
## 6:   560

Dapat dilihat dari setiap karakteristik asli debitur diubah menjadi bentuk points dan setiap points tersebut dijumlahkan ke dalam kolom score yang menyatakan total points dari debitur tersebut.

7 . Performance Evaluation Scorecard

Population Stability Index (PSI) adalah suatu metrik yang digunakan dalam analisis kredit dan risiko kredit untuk mengevaluasi stabilitas atau perubahan dalam distribusi poin atau skor kredit dari suatu populasi dari waktu ke waktu.

  • Sebuah PSI yang tinggi dapat mengindikasikan bahwa ada perubahan substansial dalam distribusi skor kredit, yang dapat berarti peningkatan risiko kredit atau perlu pemantauan lebih lanjut.
  • Sebaliknya, PSI yang rendah menunjukkan stabilitas dalam populasi skor kredit.
  • Metrik ini berguna untuk validasi manajemen risiko dan analisis portofolio kredit setelah scorecard dihasilkan

Langkah-langkah:

  1. Menyiapkan list score untuk data train dan juga test.

Membuat list dengan function list()

score_list <- list(train = score_train$score, 
                   test = score_test$score)
  1. Menyiapkan list label untuk data train dan juga test
label_list <- list(train = train_woe$default, 
                   test = test_woe$default)
  1. Menghitung score psi dengan function perf_psi()

Parameter:

  • score : list berisikan score antara data train dan test
  • label : list berisikan label antara data train dan test (tidak wajib)
  • positive : kelas positive
psi <- perf_psi(score = score_list, 
                label = label_list, 
                positive = 0)
psi$psi # psi data frame
##    variable    dataset   psi
##      <char>     <char> <num>
## 1:     pred train_test   Inf

Menurut Siddqi Naeem, index PSI memiliki rentang:

  • PSI < 0.10: Biasanya dianggap sebagai tanda bahwa tidak ada perubahan yang signifikan dalam distribusi skor kredit, dan populasi skor cenderung stabil.

  • PSI 0.10 s.d 0.25: Menunjukkan perubahan yang relatif kecil yang mungkin memerlukan penyelidikan lebih lanjut. Meskipun tidak menciptakan alarm besar, tetapi tetap penting untuk memahami faktor-faktor apa yang mungkin menyebabkan perubahan tersebut.

  • PSI > 0.25: Menandakan pergeseran yang signifikan dalam distribusi scorecard dan dapat dianggap sebagai sinyal bahwa ada perubahan yang patut diperhatikan dalam profil risiko kredit. Ini mungkin memerlukan analisis mendalam dan tindakan lebih lanjut.

8 . Cutoff

Penentuan seorang debitur termasuk dalam “GOOD” atau “BAD” debitur, harus ditetapkan nilai cutoff (batas) dari total score debitur. Untuk menentukan nilai cutoff dibutuhkan informasi approval rate dan juga bad rate sehingga dapat menentukan persentase debitur yang dianggap GOOD dan juga tingkat risiko dari debitur yang dianggap GOOD.

Untuk mendapatkan nilai approval rate dan bad rate kita membutuhkan function approval_rate().

approval_rate() akan menampilkan tabel berupa pilihan nilai cutoff, approval rate, negative rate (bad rate) beserta detail lainnya. Adapun parameter approval_rate() antara lain:

  • score: Kolom score total dari data debitur.
  • label: Kolom label yang menyatakan apakah debitur default/not default.
  • positive: Kelas positif dari kolom label.
# using score test
approval_rate(score = score_test$score,
              label = test_woe$default,
              positive = 0)
## Key: <datset>
##            bin approval_rate neg_rate count_approved neg_approved count   neg
##         <fctr>         <num>    <num>          <int>        <int> <int> <int>
##  1: [-Inf,503)        0.9051   0.2258            124           28    13     8
##  2:  [503,529)        0.8029   0.2091            110           23    14     5
##  3:  [529,549)        0.7153   0.1633             98           16    12     7
##  4:  [549,562)        0.6131   0.1429             84           12    14     4
##  5:  [562,580)        0.5036   0.1014             69            7    15     5
##  6:  [580,586)        0.4234   0.0690             58            4    11     3
##  7:  [586,600)        0.3285   0.0444             45            2    13     2
##  8:  [600,626)        0.2044   0.0357             28            1    17     1
##  9:  [626,650)        0.1168   0.0625             16            1    12     0
## 10: [650, Inf)        0.0000   0.0000              0            0    16     1
##       pos
##     <int>
##  1:     5
##  2:     9
##  3:     5
##  4:    10
##  5:    10
##  6:     8
##  7:    11
##  8:    16
##  9:    12
## 10:    15

9 . Predict Score

Penentuan nilai cutoff dapat digunakan sebagai acuan apakah seorang debitur dianggap “GOOD” behaviour ketika total points scorecard di atas nilai cutoff, begitupun akan mendapatkan “BAD” behaviour jika total points di bawah nilai cutoff.

Kasus: semisal kita mempunyai debitur dengan karakteristik nilai asli sebagai berikut. Bagaimana keputusan scorenya?

new_data <- data.frame(list(
  employ = 40,
  address = 4,
  debtinc = 12,
  creddebt = 0.856075,
  othdebt = 3.277652))

new_data
##   employ address debtinc creddebt  othdebt
## 1     40       4      12 0.856075 3.277652

Untuk mengubah karakteristik nilai asli hingga menjadi total points dan penentuan behaviour, maka perlu dilakukan tahapan sebagai berikut:

  • Mengubah data asli menjadi bentuk points menggunakan scorecard_ply()
  • Menentukan behaviour dengan aturan:
    • “GOOD”: ketika score > cutoff
    • “BAD”: ketika score < cutoff

Beberapa tahapan ini akan sering digunakan, maka dari itu sebaiknya dibuatkan sebuah fungsi sehingga dapat digunakan berulang kali dengan mudah.

Fungsi yang dibuat bernama predict_behaviour() dengan parameter berikut:

  • data: Data karakteristik nilai asli debitur yang akan diprediksi skor dan behaviour.
  • score_card: Objek pembentukan score_card hasil dari fungsi scorecard()
  • cutoff: Nilai cutoff ditentukan user

Selanjutnya tinggal memanggil fungsi predict_behaviour() dengan memasukkan data debitur beserta objek score_card.

# predict behaviour
result <- predict_behaviour(data = new_data, 
                  score_card = score_card, 
                  cutoff = 539)
result
##    score recommendation
##    <num>         <char>
## 1:   641           GOOD

Untuk menggabungkan data asli / karakteristik debitur dengan hasil score dan rekomendasi menggunakan fuction cbind()

# column bind
cbind(new_data, result)
##   employ address debtinc creddebt  othdebt score recommendation
## 1     40       4      12 0.856075 3.277652   641           GOOD