1 Pendahuluan

Laporan ini menganalisis risiko kredit menggunakan empat dataset sekunder yang berbeda. Semua model berada dalam tema yang sama, yaitu risiko ketika peminjam tidak mampu membayar kewajibannya sesuai perjanjian. Setiap dataset dipakai untuk satu jenis model karena bentuk variabel responnya berbeda.

Empat model yang digunakan adalah:

  1. Regresi logistik biner untuk menganalisis apakah nasabah kartu kredit mengalami gagal bayar atau tidak.
  2. Regresi logistik ordinal untuk menganalisis tingkat risiko pinjaman dari grade A sampai G.
  3. Regresi logistik multinomial untuk menganalisis status pinjaman Prosper.
  4. Regresi Poisson untuk menganalisis jumlah pinjaman SBA 7(a) yang bermasalah.

1.1 Istilah Penting dalam Bahasa Sederhana

Istilah dalam laporan ini
Risiko kredit Risiko bahwa peminjam tidak membayar pinjaman sesuai jadwal atau perjanjian.
Default / gagal bayar Kondisi ketika nasabah atau peminjam tidak memenuhi kewajiban pembayaran. Dalam data biner, 1 berarti default dan 0 berarti tidak default.
Charged-off / CHGOFF Pinjaman yang sudah dianggap macet atau rugi oleh lembaga pemberi pinjaman. Dalam laporan ini, istilah ini disebut sebagai pinjaman bermasalah.
PIF / Paid in Full Pinjaman sudah lunas dibayar. Dalam analisis SBA, ini dipakai sebagai kondisi tidak bermasalah.
Grade pinjaman Tingkat risiko pinjaman. Grade A dianggap risiko lebih rendah, sedangkan grade G dianggap risiko lebih tinggi.
Odds ratio / OR Ukuran untuk membaca pengaruh prediktor pada model logistik. Untuk model ordinal dengan MASS::polr, OR = exp(beta) dibaca sebagai perubahan odds untuk berada pada kategori yang lebih tinggi, karena spesifikasi modelnya adalah logit(P(Y <= j)) = alpha_j - x beta.
Relative risk ratio / RRR Ukuran untuk membaca pengaruh prediktor pada regresi multinomial. RRR membandingkan satu kategori respon terhadap kategori acuan.
Incidence rate ratio / IRR Ukuran untuk membaca pengaruh prediktor pada regresi Poisson. IRR lebih dari 1 berarti rate/jumlah kejadian per exposure lebih tinggi.
Data leakage Kondisi ketika model diberi variabel yang sebenarnya sudah mengandung jawaban. Variabel seperti ini harus dihindari agar model tidak terlihat bagus secara palsu.

2 Sumber Data dan Rancangan Analisis

Dataset yang digunakan bersumber dari repositori publik/sekunder: UCI Machine Learning Repository untuk data default kartu kredit, OpenIntro untuk Lending Club loan data, Prosper/Udacity public loan data untuk data Prosper, dan SBA Open Data untuk FOIA 7(a) loan data.

Model Dataset Variabel respon Bentuk respon Tujuan analisis
Logistik biner Default of Credit Card Clients Y 0/1 Menjelaskan peluang gagal bayar kartu kredit
Ordinal Lending Club loans_full_schema grade A < B < C < D < E < F < G Menjelaskan tingkat risiko pinjaman
Multinomial Prosper Loan Data LoanStatus_recode Banyak kategori tanpa urutan Menjelaskan status pinjaman
Poisson SBA 7(a) FOIA Jumlah_ChargedOff Hitungan/count Menjelaskan jumlah pinjaman bermasalah

3 Konsep Singkat Model

3.1 Regresi Logistik Biner

Regresi logistik biner dipakai ketika respon hanya memiliki dua kategori. Dalam laporan ini, responnya adalah gagal bayar atau tidak gagal bayar.

\[ \log\left(\frac{P(Y=1)}{P(Y=0)}\right) = \beta_0 + \beta_1X_1 + \cdots + \beta_pX_p \]

3.2 Regresi Logistik Ordinal

Regresi ordinal dipakai ketika respon memiliki urutan. Dalam laporan ini, responnya adalah grade pinjaman A sampai G.

Pada analisis ini model diestimasi menggunakan fungsi MASS::polr. Spesifikasi model polr adalah:

\[ \log\left(\frac{P(Y \leq j)}{P(Y > j)}\right) = \alpha_j - x\beta \]

Artinya, tanda koefisien harus dibaca dengan hati-hati. Jika koefisien beta bernilai positif, maka nilai alpha_j - x beta menjadi lebih kecil. Akibatnya, peluang kumulatif untuk berada pada kategori rendah P(Y <= j) menurun, sehingga peluang berada pada kategori yang lebih tinggi meningkat. Dengan urutan grade $A < B < C < D < E < F < G$, koefisien positif berarti kecenderungan pinjaman bergeser ke grade yang lebih buruk atau lebih berisiko.

3.3 Regresi Logistik Multinomial

Regresi multinomial dipakai ketika respon memiliki lebih dari dua kategori dan kategorinya tidak diperlakukan sebagai urutan. Dalam laporan ini, status pinjaman dibandingkan terhadap kategori acuan Completed.

3.4 Regresi Poisson

Regresi Poisson dipakai ketika respon berupa jumlah kejadian. Dalam laporan ini, responnya adalah jumlah pinjaman bermasalah (CHGOFF) pada setiap kelompok pinjaman SBA.

\[ Y_i \sim Poisson(\mu_i) \]

\[ \log(\mu_i) = \beta_0 + \beta_1X_1 + \cdots + \log(Total\_Loan_i) \]

Total_Loan digunakan sebagai offset, supaya model menganalisis rate pinjaman bermasalah, bukan hanya jumlah mentah.

4 Persiapan Package

required_packages <- c(
  "readxl", "readr", "dplyr", "tidyr", "ggplot2",
  "MASS", "nnet", "broom", "knitr", "scales", "stringr", "forcats", "tibble", "purrr",
  "pROC", "ordinal"
)

missing_packages <- required_packages[!(required_packages %in% rownames(installed.packages()))]
if (length(missing_packages) > 0) {
  install.packages(missing_packages, repos = "https://cloud.r-project.org")
}

invisible(lapply(required_packages, library, character.only = TRUE))

5 Import Data

data_dir <- "."
file_biner <- file.path(data_dir, "default of credit card clients.xls")
file_ordinal <- file.path(data_dir, "loans_full_schema.csv")
file_multinom <- file.path(data_dir, "prosperLoanData.csv")
file_poisson <- file.path(data_dir, "foia-7a-fy2010-fy2019-asof-260331.csv")

check_file <- function(path) {
  if (!file.exists(path)) {
    stop(paste("File tidak ditemukan:", path, "\nPastikan file Rmd dan dataset berada di folder yang sama atau ubah data_dir."))
  }
}

invisible(lapply(c(file_biner, file_ordinal, file_multinom, file_poisson), check_file))

data_biner_raw <- readxl::read_excel(file_biner, skip = 1)
data_ordinal_raw <- readr::read_csv(file_ordinal, show_col_types = FALSE)
data_multinom_raw <- readr::read_csv(file_multinom, show_col_types = FALSE)
data_poisson_raw <- readr::read_csv(file_poisson, show_col_types = FALSE)
dimensi_data <- tibble::tibble(
  Dataset = c("Default Credit Card", "Lending Club", "Prosper Loan", "SBA 7(a) FOIA"),
  Jumlah_Baris = c(nrow(data_biner_raw), nrow(data_ordinal_raw), nrow(data_multinom_raw), nrow(data_poisson_raw)),
  Jumlah_Kolom = c(ncol(data_biner_raw), ncol(data_ordinal_raw), ncol(data_multinom_raw), ncol(data_poisson_raw))
)
knitr::kable(dimensi_data, caption = "Dimensi Data Awal")
Dimensi Data Awal
Dataset Jumlah_Baris Jumlah_Kolom
Default Credit Card 30000 25
Lending Club 10000 55
Prosper Loan 113937 81
SBA 7(a) FOIA 545751 43

6 Bagian I — Regresi Logistik Biner

6.1 Tujuan Analisis

Tujuan analisis ini adalah mengetahui faktor-faktor yang berhubungan dengan peluang nasabah kartu kredit mengalami gagal bayar pada bulan berikutnya. Gagal bayar berarti nasabah tidak membayar sesuai kewajiban pada periode yang diamati.

6.2 Variabel yang Digunakan

Variabel respon adalah Y:

Nilai Y Arti sederhana
0 Nasabah tidak gagal bayar
1 Nasabah gagal bayar

Prediktor yang digunakan adalah X1 sampai X23. Seluruh prediktor ini digunakan karena dataset memang dirancang dengan 23 variabel penjelas untuk menganalisis default pembayaran kartu kredit.

Variabel yang Dipakai pada Model Biner
Variabel Makna Alasan_dipakai
X1 Jumlah kredit yang diberikan Menggambarkan kapasitas/limit kredit nasabah
X2 Gender Karakteristik demografi nasabah
X3 Pendidikan Karakteristik sosial ekonomi nasabah
X4 Status perkawinan Karakteristik demografi nasabah
X5 Umur Umur dapat berkaitan dengan perilaku pembayaran
X6-X11 Riwayat status pembayaran April-September 2005 Riwayat keterlambatan adalah indikator penting risiko gagal bayar
X12-X17 Jumlah tagihan April-September 2005 Tagihan menggambarkan beban kewajiban nasabah
X18-X23 Jumlah pembayaran sebelumnya April-September 2005 Pembayaran sebelumnya menggambarkan kemampuan dan kemauan bayar

6.3 Cleaning Data Biner

# Setelah skip = 1, kolom pertama sampai ke-25 adalah ID, X1-X23, dan Y.
names(data_biner_raw)[1:25] <- c("ID", paste0("X", 1:23), "Y")

money_vars_biner <- c("X1", paste0("X", 12:23))

data_biner <- data_biner_raw %>%
  dplyr::select(ID, dplyr::all_of(paste0("X", 1:23)), Y) %>%
  dplyr::mutate(dplyr::across(dplyr::everything(), as.numeric)) %>%
  tidyr::drop_na() %>%
  dplyr::mutate(
    Y_num = Y,
    Y_label = factor(Y, levels = c(0, 1), labels = c("Tidak gagal bayar", "Gagal bayar")),
    X2 = factor(dplyr::case_when(
      X2 == 1 ~ "Male",
      X2 == 2 ~ "Female",
      TRUE ~ "Other"
    )),
    X3 = factor(dplyr::case_when(
      X3 == 1 ~ "Graduate school",
      X3 == 2 ~ "University",
      X3 == 3 ~ "High school",
      TRUE ~ "Others"
    )),
    X4 = factor(dplyr::case_when(
      X4 == 1 ~ "Married",
      X4 == 2 ~ "Single",
      TRUE ~ "Others"
    ))
  ) %>%
  dplyr::mutate(dplyr::across(dplyr::all_of(money_vars_biner), ~ .x / 1000, .names = "{.col}_k"))

knitr::kable(head(data_biner, 6), caption = "Cuplikan Data Biner Setelah Cleaning")
Cuplikan Data Biner Setelah Cleaning
ID X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 Y Y_num Y_label X1_k X12_k X13_k X14_k X15_k X16_k X17_k X18_k X19_k X20_k X21_k X22_k X23_k
1 20000 Female University Married 24 2 2 -1 -1 -2 -2 3913 3102 689 0 0 0 0 689 0 0 0 0 1 1 Gagal bayar 20 3.913 3.102 0.689 0.000 0.000 0.000 0.000 0.689 0.000 0.0 0.000 0.000
2 120000 Female University Single 26 -1 2 0 0 0 2 2682 1725 2682 3272 3455 3261 0 1000 1000 1000 0 2000 1 1 Gagal bayar 120 2.682 1.725 2.682 3.272 3.455 3.261 0.000 1.000 1.000 1.0 0.000 2.000
3 90000 Female University Single 34 0 0 0 0 0 0 29239 14027 13559 14331 14948 15549 1518 1500 1000 1000 1000 5000 0 0 Tidak gagal bayar 90 29.239 14.027 13.559 14.331 14.948 15.549 1.518 1.500 1.000 1.0 1.000 5.000
4 50000 Female University Married 37 0 0 0 0 0 0 46990 48233 49291 28314 28959 29547 2000 2019 1200 1100 1069 1000 0 0 Tidak gagal bayar 50 46.990 48.233 49.291 28.314 28.959 29.547 2.000 2.019 1.200 1.1 1.069 1.000
5 50000 Male University Married 57 -1 0 -1 0 0 0 8617 5670 35835 20940 19146 19131 2000 36681 10000 9000 689 679 0 0 Tidak gagal bayar 50 8.617 5.670 35.835 20.940 19.146 19.131 2.000 36.681 10.000 9.0 0.689 0.679
6 50000 Male Graduate school Single 37 0 0 0 0 0 0 64400 57069 57608 19394 19619 20024 2500 1815 657 1000 1000 800 0 0 Tidak gagal bayar 50 64.400 57.069 57.608 19.394 19.619 20.024 2.500 1.815 0.657 1.0 1.000 0.800

Variabel uang seperti X1, X12 sampai X23 diskalakan dalam ribuan agar interpretasi lebih mudah. X1_k berarti limit kredit dalam ribuan NT dollar.

6.4 Analisis Deskriptif Data Biner

dist_biner <- data_biner %>%
  dplyr::count(Y_label) %>%
  dplyr::mutate(Persen = scales::percent(n / sum(n)))
knitr::kable(dist_biner, caption = "Distribusi Status Gagal Bayar")
Distribusi Status Gagal Bayar
Y_label n Persen
Tidak gagal bayar 23364 78%
Gagal bayar 6636 22%
summary_biner <- data_biner %>%
  dplyr::summarise(
    Rata_rata_limit_k = mean(X1_k),
    Median_limit_k = median(X1_k),
    Rata_rata_umur = mean(X5),
    Median_umur = median(X5)
  )
knitr::kable(summary_biner, caption = "Ringkasan Prediktor Utama Data Biner")
Ringkasan Prediktor Utama Data Biner
Rata_rata_limit_k Median_limit_k Rata_rata_umur Median_umur
167.4843 140 35.4855 34
ggplot(data_biner, aes(x = Y_label)) +
  geom_bar() +
  labs(
    title = "Distribusi Gagal Bayar Kartu Kredit",
    x = "Status nasabah",
    y = "Jumlah nasabah"
  ) +
  theme_minimal()

6.5 Pembentukan Model Regresi Logistik Biner

Model biner dibentuk untuk menjelaskan peluang Y = 1, yaitu nasabah gagal bayar.

\[ \log\left(\frac{P(Y=1)}{P(Y=0)}\right) = \beta_0 + \beta_1X_1 + \cdots + \beta_{23}X_{23} \]

formula_biner <- as.formula(paste(
  "Y_num ~ X1_k + X2 + X3 + X4 + X5 +",
  paste(paste0("X", 6:11), collapse = " + "), "+",
  paste(paste0("X", 12:23, "_k"), collapse = " + ")
))

model_biner <- glm(
  formula_biner,
  data = data_biner,
  family = binomial(link = "logit")
)

summary(model_biner)
## 
## Call:
## glm(formula = formula_biner, family = binomial(link = "logit"), 
##     data = data_biner)
## 
## Coefficients:
##                 Estimate Std. Error z value             Pr(>|z|)    
## (Intercept)   -1.1074252  0.0821938 -13.473 < 0.0000000000000002 ***
## X1_k          -0.0007133  0.0001577  -4.522       0.000006114973 ***
## X2Male         0.1129693  0.0307258   3.677             0.000236 ***
## X3High school -0.1130401  0.0475987  -2.375             0.017556 *  
## X3Others      -1.1624892  0.1884460  -6.169       0.000000000688 ***
## X3University  -0.0845189  0.0355734  -2.376             0.017506 *  
## X4Others      -0.1932064  0.1319446  -1.464             0.143112    
## X4Single      -0.1877621  0.0346303  -5.422       0.000000058970 ***
## X5             0.0056350  0.0018594   3.031             0.002441 ** 
## X6             0.5774743  0.0177087  32.610 < 0.0000000000000002 ***
## X7             0.0811208  0.0201961   4.017       0.000059030160 ***
## X8             0.0710667  0.0226075   3.143             0.001669 ** 
## X9             0.0228907  0.0250040   0.915             0.359938    
## X10            0.0341754  0.0268869   1.271             0.203700    
## X11            0.0071786  0.0221513   0.324             0.745886    
## X12_k         -0.0054952  0.0011374  -4.831       0.000001355474 ***
## X13_k          0.0023935  0.0015047   1.591             0.111683    
## X14_k          0.0013958  0.0013238   1.054             0.291694    
## X15_k         -0.0001765  0.0013519  -0.131             0.896140    
## X16_k          0.0007716  0.0015225   0.507             0.612305    
## X17_k          0.0001770  0.0011977   0.148             0.882525    
## X18_k         -0.0136808  0.0023079  -5.928       0.000000003069 ***
## X19_k         -0.0095322  0.0020889  -4.563       0.000005034879 ***
## X20_k         -0.0026224  0.0017191  -1.525             0.127151    
## X21_k         -0.0040673  0.0017859  -2.278             0.022756 *  
## X22_k         -0.0031418  0.0017786  -1.766             0.077325 .  
## X23_k         -0.0020692  0.0012966  -1.596             0.110534    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 31705  on 29999  degrees of freedom
## Residual deviance: 27840  on 29973  degrees of freedom
## AIC: 27894
## 
## Number of Fisher Scoring iterations: 6

6.6 Persamaan Model Hasil Estimasi Biner

Chunk model-biner di atas sudah membangun model regresi logistik biner menggunakan fungsi glm() dengan family = binomial(link = "logit"). Model yang diestimasi adalah model peluang gagal bayar, yaitu peluang ketika Y_num = 1.

Persamaan umumnya adalah:

\[ \widehat{\eta_i} = \log\left(\frac{\widehat{P}(Y_i=1)}{\widehat{P}(Y_i=0)}\right) = \hat{\beta}_0 + \hat{\beta}_1X_{1i} + \cdots + \hat{\beta}_{23}X_{23i} \]

Persamaan hasil estimasi model biner dapat ditulis sebagai berikut:

\[ \widehat{\eta_i} = -1.1074 - 0.0007\,X_{1k} + 0.113\,X_{2Male} - 0.113\,X_{3HighSchool} - 1.1625\,X_{3Others} - 0.0845\,X_{3University} - 0.1932\,X_{4Others} - 0.1878\,X_{4Single} + 0.0056\,X_5 + 0.5775\,X_6 + 0.0811\,X_7 + 0.0711\,X_8 + 0.0229\,X_9 + 0.0342\,X_{10} + 0.0072\,X_{11} - 0.0055\,X_{12k} + 0.0024\,X_{13k} + 0.0014\,X_{14k} - 0.0002\,X_{15k} + 0.0008\,X_{16k} + 0.0002\,X_{17k} - 0.0137\,X_{18k} - 0.0095\,X_{19k} - 0.0026\,X_{20k} - 0.0041\,X_{21k} - 0.0031\,X_{22k} - 0.0021\,X_{23k} \]

\[ \widehat{\eta_i} = \log\left(\frac{\widehat{P}(Y_i=1)}{\widehat{P}(Y_i=0)}\right) \]

Dengan:

\[ \widehat{P}(Y_i=1) = \frac{\exp(\widehat{\eta_i})}{1+\exp(\widehat{\eta_i})} \]

Persamaan tersebut menunjukkan bahwa setiap koefisien masuk ke dalam log-odds gagal bayar. Koefisien positif meningkatkan log-odds gagal bayar, sedangkan koefisien negatif menurunkan log-odds gagal bayar.

Parameter yang Membentuk Persamaan Regresi Logistik Biner
Variabel_Mudah term estimate Odds_Ratio
(Intercept) (Intercept) -1.1074 0.3304
jumlah limit kredit (per 1.000 NT dollar) X1_k -0.0007 0.9993
jenis kelamin: Male dibanding kategori acuan X2Male 0.1130 1.1196
pendidikan: High school dibanding kategori acuan X3High school -0.1130 0.8931
pendidikan: Others dibanding kategori acuan X3Others -1.1625 0.3127
pendidikan: University dibanding kategori acuan X3University -0.0845 0.9190
status perkawinan: Others dibanding kategori acuan X4Others -0.1932 0.8243
status perkawinan: Single dibanding kategori acuan X4Single -0.1878 0.8288
umur nasabah X5 0.0056 1.0057
status pembayaran September 2005 X6 0.5775 1.7815
status pembayaran Agustus 2005 X7 0.0811 1.0845
status pembayaran Juli 2005 X8 0.0711 1.0737
status pembayaran Juni 2005 X9 0.0229 1.0232
status pembayaran Mei 2005 X10 0.0342 1.0348
status pembayaran April 2005 X11 0.0072 1.0072
tagihan September 2005 (per 1.000 NT dollar) X12_k -0.0055 0.9945
tagihan Agustus 2005 (per 1.000 NT dollar) X13_k 0.0024 1.0024
tagihan Juli 2005 (per 1.000 NT dollar) X14_k 0.0014 1.0014
tagihan Juni 2005 (per 1.000 NT dollar) X15_k -0.0002 0.9998
tagihan Mei 2005 (per 1.000 NT dollar) X16_k 0.0008 1.0008
tagihan April 2005 (per 1.000 NT dollar) X17_k 0.0002 1.0002
pembayaran September 2005 (per 1.000 NT dollar) X18_k -0.0137 0.9864
pembayaran Agustus 2005 (per 1.000 NT dollar) X19_k -0.0095 0.9905
pembayaran Juli 2005 (per 1.000 NT dollar) X20_k -0.0026 0.9974
pembayaran Juni 2005 (per 1.000 NT dollar) X21_k -0.0041 0.9959
pembayaran Mei 2005 (per 1.000 NT dollar) X22_k -0.0031 0.9969
pembayaran April 2005 (per 1.000 NT dollar) X23_k -0.0021 0.9979

6.7 Koefisien dan Odds Ratio Model Biner

tabel_biner <- broom::tidy(model_biner) %>%
  dplyr::mutate(
    Odds_Ratio = exp(estimate),
    Variabel_Mudah = purrr::map_chr(term, label_biner),
    Keputusan_5persen = ifelse(p.value < 0.05, "Signifikan", "Tidak signifikan")
  ) %>%
  dplyr::arrange(p.value)

knitr::kable(
  tabel_biner %>% dplyr::select(Variabel_Mudah, term, estimate, std.error, statistic, p.value, Odds_Ratio, Keputusan_5persen) %>% head(25),
  digits = 4,
  caption = "Koefisien dan Odds Ratio Regresi Logistik Biner"
)
Koefisien dan Odds Ratio Regresi Logistik Biner
Variabel_Mudah term estimate std.error statistic p.value Odds_Ratio Keputusan_5persen
status pembayaran September 2005 X6 0.5775 0.0177 32.6097 0.0000 1.7815 Signifikan
(Intercept) (Intercept) -1.1074 0.0822 -13.4733 0.0000 0.3304 Signifikan
pendidikan: Others dibanding kategori acuan X3Others -1.1625 0.1884 -6.1688 0.0000 0.3127 Signifikan
pembayaran September 2005 (per 1.000 NT dollar) X18_k -0.0137 0.0023 -5.9279 0.0000 0.9864 Signifikan
status perkawinan: Single dibanding kategori acuan X4Single -0.1878 0.0346 -5.4219 0.0000 0.8288 Signifikan
tagihan September 2005 (per 1.000 NT dollar) X12_k -0.0055 0.0011 -4.8314 0.0000 0.9945 Signifikan
pembayaran Agustus 2005 (per 1.000 NT dollar) X19_k -0.0095 0.0021 -4.5633 0.0000 0.9905 Signifikan
jumlah limit kredit (per 1.000 NT dollar) X1_k -0.0007 0.0002 -4.5224 0.0000 0.9993 Signifikan
status pembayaran Agustus 2005 X7 0.0811 0.0202 4.0167 0.0001 1.0845 Signifikan
jenis kelamin: Male dibanding kategori acuan X2Male 0.1130 0.0307 3.6767 0.0002 1.1196 Signifikan
status pembayaran Juli 2005 X8 0.0711 0.0226 3.1435 0.0017 1.0737 Signifikan
umur nasabah X5 0.0056 0.0019 3.0305 0.0024 1.0057 Signifikan
pendidikan: University dibanding kategori acuan X3University -0.0845 0.0356 -2.3759 0.0175 0.9190 Signifikan
pendidikan: High school dibanding kategori acuan X3High school -0.1130 0.0476 -2.3749 0.0176 0.8931 Signifikan
pembayaran Juni 2005 (per 1.000 NT dollar) X21_k -0.0041 0.0018 -2.2775 0.0228 0.9959 Signifikan
pembayaran Mei 2005 (per 1.000 NT dollar) X22_k -0.0031 0.0018 -1.7664 0.0773 0.9969 Tidak signifikan
pembayaran April 2005 (per 1.000 NT dollar) X23_k -0.0021 0.0013 -1.5958 0.1105 0.9979 Tidak signifikan
tagihan Agustus 2005 (per 1.000 NT dollar) X13_k 0.0024 0.0015 1.5907 0.1117 1.0024 Tidak signifikan
pembayaran Juli 2005 (per 1.000 NT dollar) X20_k -0.0026 0.0017 -1.5254 0.1272 0.9974 Tidak signifikan
status perkawinan: Others dibanding kategori acuan X4Others -0.1932 0.1319 -1.4643 0.1431 0.8243 Tidak signifikan
status pembayaran Mei 2005 X10 0.0342 0.0269 1.2711 0.2037 1.0348 Tidak signifikan
tagihan Juli 2005 (per 1.000 NT dollar) X14_k 0.0014 0.0013 1.0544 0.2917 1.0014 Tidak signifikan
status pembayaran Juni 2005 X9 0.0229 0.0250 0.9155 0.3599 1.0232 Tidak signifikan
tagihan Mei 2005 (per 1.000 NT dollar) X16_k 0.0008 0.0015 0.5068 0.6123 1.0008 Tidak signifikan
status pembayaran April 2005 X11 0.0072 0.0222 0.3241 0.7459 1.0072 Tidak signifikan

6.8 Evaluasi Model Biner

data_biner$prob_default <- predict(model_biner, type = "response")
data_biner$pred_default <- ifelse(data_biner$prob_default >= 0.5, 1, 0)

tabel_klasifikasi_biner <- table(
  Prediksi = factor(data_biner$pred_default, levels = c(0, 1), labels = c("Tidak gagal bayar", "Gagal bayar")),
  Aktual = data_biner$Y_label
)
tabel_klasifikasi_biner
##                    Aktual
## Prediksi            Tidak gagal bayar Gagal bayar
##   Tidak gagal bayar             22729        5034
##   Gagal bayar                     635        1602
akurasi_biner <- mean(data_biner$pred_default == data_biner$Y_num)
akurasi_biner
## [1] 0.8110333
AIC_biner <- AIC(model_biner)
AIC_biner
## [1] 27894.21

6.9 Visualisasi Probabilitas Prediksi Model Biner

Visualisasi ini digunakan untuk melihat sebaran probabilitas gagal bayar yang dihasilkan oleh model. Probabilitas yang lebih tinggi menunjukkan nasabah yang diprediksi memiliki risiko gagal bayar lebih besar.

ggplot(data_biner, aes(x = prob_default)) +
  geom_histogram(bins = 40) +
  labs(
    title = "Distribusi Probabilitas Prediksi Gagal Bayar",
    x = "Probabilitas prediksi gagal bayar",
    y = "Jumlah nasabah"
  ) +
  theme_minimal()

ggplot(data_biner, aes(x = Y_label, y = prob_default)) +
  geom_boxplot() +
  labs(
    title = "Probabilitas Prediksi Gagal Bayar menurut Status Aktual",
    x = "Status aktual",
    y = "Probabilitas prediksi gagal bayar"
  ) +
  theme_minimal()

Grafik pertama menunjukkan sebaran probabilitas gagal bayar hasil model. Grafik kedua membandingkan probabilitas prediksi antara nasabah yang benar-benar gagal bayar dan tidak gagal bayar. Jika model cukup membedakan risiko, maka kelompok yang aktual gagal bayar seharusnya memiliki probabilitas prediksi yang lebih tinggi.

6.10 Evaluasi Tambahan: ROC Curve dan AUC

ROC Curve digunakan untuk melihat kemampuan model membedakan nasabah gagal bayar dan tidak gagal bayar pada berbagai threshold. AUC mendekati 1 menunjukkan kemampuan pemisahan yang lebih baik, sedangkan AUC mendekati 0,5 menunjukkan kemampuan model mendekati tebakan acak.

roc_biner <- pROC::roc(
  response = data_biner$Y_num,
  predictor = data_biner$prob_default,
  quiet = TRUE
)

auc_biner <- pROC::auc(roc_biner)
auc_biner
## Area under the curve: 0.7259
plot(
  roc_biner,
  main = paste("ROC Curve Model Biner | AUC =", round(as.numeric(auc_biner), 3))
)

AUC menunjukkan kemampuan model membedakan nasabah yang gagal bayar dan tidak gagal bayar. Semakin besar AUC, semakin baik kemampuan diskriminasi model. Namun AUC tidak menjelaskan arah pengaruh variabel; arah pengaruh tetap dibaca melalui koefisien dan odds ratio.

6.11 Catatan Asumsi Regresi Logistik Biner

Regresi logistik biner digunakan karena variabel respon hanya memiliki dua kategori, yaitu gagal bayar dan tidak gagal bayar. Model ini mengasumsikan bahwa observasi bersifat independen, tidak terdapat multikolinearitas berat antar prediktor, tidak terjadi perfect separation, dan prediktor numerik memiliki hubungan yang cukup linear terhadap log-odds gagal bayar.

Pada analisis credit risk, jumlah nasabah gagal bayar sering kali lebih kecil daripada nasabah tidak gagal bayar. Oleh karena itu, akurasi tidak boleh menjadi satu-satunya ukuran evaluasi. Confusion matrix, probabilitas prediksi, dan AUC perlu dibaca bersama dengan interpretasi odds ratio.

6.12 Interpretasi dan Kesimpulan Model Biner

sig_biner <- tabel_biner %>%
  dplyr::filter(term != "(Intercept)", p.value < 0.05) %>%
  dplyr::arrange(p.value)

cat("Pada taraf signifikansi 5%, model biner menemukan ", nrow(sig_biner),
    " prediktor yang berhubungan signifikan dengan peluang gagal bayar.\n\n", sep = "")

Pada taraf signifikansi 5%, model biner menemukan 14 prediktor yang berhubungan signifikan dengan peluang gagal bayar.

if (nrow(sig_biner) > 0) {
  cat("Prediktor paling penting berdasarkan p-value terkecil adalah:\n\n")
  top_biner <- head(sig_biner, 8)
  for (i in seq_len(nrow(top_biner))) {
    row <- top_biner[i, ]
    arah <- ifelse(row$Odds_Ratio > 1,
                   "meningkatkan odds gagal bayar",
                   "menurunkan odds gagal bayar")
    cat("- **", row$Variabel_Mudah, "** memiliki OR = ", fmt_num(row$Odds_Ratio, 3),
        " dan p-value = ", fmt_p(row$p.value), ", sehingga variabel ini ", arah,
        ", dengan asumsi variabel lain tetap.\n", sep = "")
  }
  cat("\n")
}

Prediktor paling penting berdasarkan p-value terkecil adalah:

  • status pembayaran September 2005 memiliki OR = 1.782 dan p-value = < 0.001, sehingga variabel ini meningkatkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • pendidikan: Others dibanding kategori acuan memiliki OR = 0.313 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • pembayaran September 2005 (per 1.000 NT dollar) memiliki OR = 0.986 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • status perkawinan: Single dibanding kategori acuan memiliki OR = 0.829 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • tagihan September 2005 (per 1.000 NT dollar) memiliki OR = 0.995 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • pembayaran Agustus 2005 (per 1.000 NT dollar) memiliki OR = 0.991 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • jumlah limit kredit (per 1.000 NT dollar) memiliki OR = 0.999 dan p-value = < 0.001, sehingga variabel ini menurunkan odds gagal bayar, dengan asumsi variabel lain tetap.
  • status pembayaran Agustus 2005 memiliki OR = 1.085 dan p-value = < 0.001, sehingga variabel ini meningkatkan odds gagal bayar, dengan asumsi variabel lain tetap.
cat("Akurasi klasifikasi model biner adalah **", scales::percent(akurasi_biner),
    "**. AIC model adalah **", fmt_num(AIC_biner, 2), "**.\n\n", sep = "")

Akurasi klasifikasi model biner adalah 81%. AIC model adalah 27,894.21.

if (any(sig_biner$term %in% paste0("X", 6:11))) {
  cat("**Kesimpulan substantif:** riwayat pembayaran sebelumnya menjadi faktor penting dalam menjelaskan gagal bayar. Dalam konteks risiko kredit, nasabah yang memiliki riwayat keterlambatan pembayaran cenderung lebih berisiko mengalami gagal bayar pada periode berikutnya.\n")
} else {
  cat("**Kesimpulan substantif:** model menunjukkan bahwa risiko gagal bayar dapat dijelaskan oleh kombinasi limit kredit, karakteristik demografi, tagihan, dan pembayaran sebelumnya. Variabel signifikan pada tabel di atas menjadi faktor utama yang perlu diperhatikan dalam penilaian risiko kartu kredit.\n")
}

Kesimpulan substantif: riwayat pembayaran sebelumnya menjadi faktor penting dalam menjelaskan gagal bayar. Dalam konteks risiko kredit, nasabah yang memiliki riwayat keterlambatan pembayaran cenderung lebih berisiko mengalami gagal bayar pada periode berikutnya.

7 Bagian II — Regresi Logistik Ordinal

7.1 Tujuan Analisis

Tujuan analisis ini adalah mengetahui faktor-faktor yang berhubungan dengan tingkat risiko pinjaman pada data Lending Club. Tingkat risiko diwakili oleh grade, dari A sampai G.

7.2 Variabel yang Digunakan

Variabel respon adalah grade dengan urutan:

\[ A < B < C < D < E < F < G \]

Dalam bahasa sederhana, A adalah risiko lebih rendah dan G adalah risiko lebih tinggi.

Variabel yang Dipakai pada Model Ordinal
Variabel Peran Alasan_dipakai
grade Respon Mewakili tingkat risiko pinjaman dari A sampai G
annual_income Prediktor Menggambarkan kemampuan pendapatan peminjam
debt_to_income Prediktor Mengukur beban utang dibanding pendapatan
delinq_2y Prediktor Riwayat keterlambatan kredit 2 tahun terakhir
inquiries_last_12m Prediktor Banyaknya pemeriksaan kredit terbaru
total_credit_lines Prediktor Menggambarkan pengalaman kredit peminjam
open_credit_lines Prediktor Menggambarkan kredit aktif
total_credit_limit Prediktor Menggambarkan total fasilitas kredit
total_credit_utilized Prediktor Menggambarkan total kredit yang sedang digunakan
num_historical_failed_to_pay Prediktor Riwayat gagal bayar sebelumnya
public_record_bankrupt Prediktor Riwayat kebangkrutan
loan_amount Prediktor Besar pinjaman yang diterima
term Prediktor Tenor atau lama pinjaman
homeownership Prediktor Status tempat tinggal peminjam
verified_income Prediktor Status verifikasi pendapatan
loan_purpose Prediktor Tujuan penggunaan pinjaman
application_type Prediktor Aplikasi individu atau joint

Variabel sub_grade, interest_rate, loan_status, balance, paid_total, paid_principal, paid_interest, dan paid_late_fees tidak digunakan. Alasannya, variabel-variabel tersebut terlalu dekat dengan hasil penilaian grade atau muncul setelah pinjaman berjalan. Jika dipakai, model berisiko mengalami data leakage.

7.3 Cleaning Data Ordinal

prediktor_ordinal <- c(
  "annual_income", "debt_to_income", "delinq_2y", "inquiries_last_12m",
  "total_credit_lines", "open_credit_lines", "total_credit_limit", "total_credit_utilized",
  "num_historical_failed_to_pay", "public_record_bankrupt", "loan_amount", "term",
  "homeownership", "verified_income", "loan_purpose", "application_type"
)

data_ordinal <- data_ordinal_raw %>%
  dplyr::select(grade, dplyr::all_of(prediktor_ordinal)) %>%
  tidyr::drop_na() %>%
  dplyr::mutate(
    grade = ordered(grade, levels = c("A", "B", "C", "D", "E", "F", "G")),
    homeownership = factor(homeownership),
    verified_income = factor(verified_income),
    loan_purpose = factor(loan_purpose),
    application_type = factor(application_type),
    term = factor(term),
    annual_income_k = annual_income / 1000,
    total_credit_limit_k = total_credit_limit / 1000,
    total_credit_utilized_k = total_credit_utilized / 1000,
    loan_amount_k = loan_amount / 1000
  )

knitr::kable(head(data_ordinal, 6), caption = "Cuplikan Data Ordinal Setelah Cleaning")
Cuplikan Data Ordinal Setelah Cleaning
grade annual_income debt_to_income delinq_2y inquiries_last_12m total_credit_lines open_credit_lines total_credit_limit total_credit_utilized num_historical_failed_to_pay public_record_bankrupt loan_amount term homeownership verified_income loan_purpose application_type annual_income_k total_credit_limit_k total_credit_utilized_k loan_amount_k
C 90000 18.01 0 6 28 10 70795 38767 0 0 28000 60 MORTGAGE Verified moving individual 90 70.795 38.767 28.0
C 40000 5.04 0 1 30 14 28800 4321 1 1 5000 36 RENT Not Verified debt_consolidation individual 40 28.800 4.321 5.0
D 40000 21.15 0 4 31 10 24193 16000 0 0 2000 36 RENT Source Verified other individual 40 24.193 16.000 2.0
A 30000 10.16 0 0 4 4 25400 4997 1 0 21600 36 RENT Not Verified debt_consolidation individual 30 25.400 4.997 21.6
C 35000 57.96 0 7 22 16 69839 52722 0 0 23000 36 RENT Verified credit_card joint 35 69.839 52.722 23.0
A 34000 6.46 1 6 32 12 42100 3898 0 0 5000 36 OWN Not Verified other individual 34 42.100 3.898 5.0

7.4 Analisis Deskriptif Data Ordinal

dist_ordinal <- data_ordinal %>%
  dplyr::count(grade) %>%
  dplyr::mutate(Persen = scales::percent(n / sum(n)))
knitr::kable(dist_ordinal, caption = "Distribusi Grade Pinjaman")
Distribusi Grade Pinjaman
grade n Persen
A 2454 24.60%
B 3032 30.39%
C 2649 26.55%
D 1438 14.41%
E 334 3.35%
F 57 0.57%
G 12 0.12%
ringkasan_ordinal <- data_ordinal %>%
  dplyr::summarise(
    Rata_rata_income_k = mean(annual_income_k),
    Median_income_k = median(annual_income_k),
    Rata_rata_dti = mean(debt_to_income),
    Median_dti = median(debt_to_income),
    Rata_rata_loan_amount_k = mean(loan_amount_k)
  )
knitr::kable(ringkasan_ordinal, caption = "Ringkasan Prediktor Utama Data Ordinal")
Ringkasan Prediktor Utama Data Ordinal
Rata_rata_income_k Median_income_k Rata_rata_dti Median_dti Rata_rata_loan_amount_k
79.41274 65 19.30819 17.57 16.35753
ggplot(data_ordinal, aes(x = grade)) +
  geom_bar() +
  labs(
    title = "Distribusi Grade Pinjaman Lending Club",
    x = "Grade",
    y = "Jumlah pinjaman"
  ) +
  theme_minimal()

7.5 Pembentukan Model Regresi Logistik Ordinal

Model ordinal dibentuk untuk menjelaskan faktor-faktor yang berhubungan dengan tingkat grade pinjaman. Model ini menggunakan spesifikasi MASS::polr() sebagai berikut:

\[ \log\left(\frac{P(Y \leq j)}{P(Y > j)}\right) = \alpha_j - x\beta \]

Dalam penelitian ini, variabel respon adalah grade, dengan urutan:

\[ A < B < C < D < E < F < G \]

Sehingga bentuk modelnya dapat ditulis sebagai:

\[ \log\left(\frac{P(Y \leq j)}{P(Y > j)}\right) = \alpha_j - \left( \beta_1 X_1 + \beta_2 X_2 + \beta_3 X_3 + \cdots + \beta_p X_p \right) \]

Karena model menggunakan bentuk \(\alpha_j - x\beta\), maka koefisien positif menunjukkan penurunan peluang kumulatif berada pada kategori rendah. Dengan kata lain, koefisien positif menunjukkan peningkatan kecenderungan pinjaman masuk ke grade yang lebih tinggi atau risiko yang lebih buruk.

model_ordinal <- MASS::polr(
  grade ~ annual_income_k + debt_to_income + delinq_2y + inquiries_last_12m +
    total_credit_lines + open_credit_lines + total_credit_limit_k + total_credit_utilized_k +
    num_historical_failed_to_pay + public_record_bankrupt + loan_amount_k + term +
    homeownership + verified_income + loan_purpose + application_type,
  data = data_ordinal,
  Hess = TRUE
)

summary(model_ordinal)
## Call:
## MASS::polr(formula = grade ~ annual_income_k + debt_to_income + 
##     delinq_2y + inquiries_last_12m + total_credit_lines + open_credit_lines + 
##     total_credit_limit_k + total_credit_utilized_k + num_historical_failed_to_pay + 
##     public_record_bankrupt + loan_amount_k + term + homeownership + 
##     verified_income + loan_purpose + application_type, data = data_ordinal, 
##     Hess = TRUE)
## 
## Coefficients:
##                                     Value Std. Error  t value
## annual_income_k                -0.0004366  0.0004111  -1.0622
## debt_to_income                  0.0189670  0.0018607  10.1936
## delinq_2y                       0.3863916  0.0280135  13.7930
## inquiries_last_12m              0.1206014  0.0080931  14.9018
## total_credit_lines             -0.0210112  0.0025525  -8.2315
## open_credit_lines               0.0082993  0.0049402   1.6800
## total_credit_limit_k           -0.0024280  0.0001605 -15.1249
## total_credit_utilized_k         0.0045864  0.0004819   9.5181
## num_historical_failed_to_pay    0.0836537  0.0280557   2.9817
## public_record_bankrupt          0.1050426  0.0611649   1.7174
## loan_amount_k                  -0.0141142  0.0022054  -6.3999
## term60                          1.7053905  0.0457152  37.3046
## homeownershipOWN                0.0399999  0.0596143   0.6710
## homeownershipRENT               0.1695171  0.0485386   3.4924
## verified_incomeSource Verified  0.5204831  0.0434310  11.9841
## verified_incomeVerified         1.1085540  0.0531020  20.8759
## loan_purposecredit_card        -0.2174709  0.1237707  -1.7570
## loan_purposedebt_consolidation  0.2336611  0.1206111   1.9373
## loan_purposehome_improvement   -0.1360832  0.1372344  -0.9916
## loan_purposehouse              -0.5827169  0.1899838  -3.0672
## loan_purposemajor_purchase     -0.0925206  0.1567966  -0.5901
## loan_purposemedical             0.0837639  0.1837933   0.4558
## loan_purposemoving             -0.0292612  0.2470419  -0.1184
## loan_purposeother               0.0487276  0.1315205   0.3705
## loan_purposerenewable_energy    0.3465701  0.2819415   1.2292
## loan_purposesmall_business      0.3061349  0.1983514   1.5434
## loan_purposevacation            0.7064138  0.2559893   2.7595
## application_typejoint          -0.1742241  0.0584236  -2.9821
## 
## Intercepts:
##     Value    Std. Error t value 
## A|B  -0.4266   0.1338    -3.1890
## B|C   1.2191   0.1342     9.0844
## C|D   2.7940   0.1367    20.4317
## D|E   4.6826   0.1451    32.2696
## E|F   6.5509   0.1823    35.9443
## F|G   8.3210   0.3196    26.0362
## 
## Residual Deviance: 26566.23 
## AIC: 26634.23

7.6 Persamaan Model Hasil Estimasi Ordinal

Chunk model-ordinal di atas sudah membangun model regresi logistik ordinal menggunakan MASS::polr(). Bentuk hasil estimasinya adalah:

\[ \log\left(\frac{\widehat{P}(grade_i \leq j)}{\widehat{P}(grade_i > j)}\right) = \hat{\alpha}_j - \widehat{\eta_i} \]

Dengan:

\[ \widehat{\eta_i} = \hat{\beta}_1X_{1i} + \hat{\beta}_2X_{2i} + \cdots + \hat{\beta}_pX_{pi} \]

Karena MASS::polr() memakai bentuk alpha_j - x beta, maka exp(beta) dibaca sebagai odds menuju grade yang lebih tinggi. Dalam laporan ini grade lebih tinggi berarti risiko lebih buruk.

\[ \widehat{\eta_i} = - 0.0004\,X_{income} + 0.019\,X_{dti} + 0.3864\,X_{delinq} + 0.1206\,X_{inq} - 0.021\,X_{tcl} + 0.0083\,X_{ocl} - 0.0024\,X_{limit} + 0.0046\,X_{utilized} + 0.0837\,X_{failed} + 0.105\,X_{bankrupt} - 0.0141\,X_{loan} + 1.7054\,X_{term60} + 0.04\,X_{homeownershipOWN} + 0.1695\,X_{homeownershipRENT} + 0.5205\,X_{verifiedincomeSourceVerified} + 1.1086\,X_{verifiedincomeVerified} - 0.2175\,X_{loanpurposecreditcard} + 0.2337\,X_{loanpurposedebtconsolidation} - 0.1361\,X_{loanpurposehomeimprovement} - 0.5827\,X_{loanpurposehouse} - 0.0925\,X_{loanpurposemajorpurchase} + 0.0838\,X_{loanpurposemedical} - 0.0293\,X_{loanpurposemoving} + 0.0487\,X_{loanpurposeother} + 0.3466\,X_{loanpurposerenewableenergy} + 0.3061\,X_{loanpurposesmallbusiness} + 0.7064\,X_{loanpurposevacation} - 0.1742\,X_{applicationtypejoint} \]

Dengan spesifikasi MASS::polr(), persamaan untuk setiap batas kumulatif adalah:

\[ \log\left(\frac{\widehat{P}(Y_i \leq A\mid B)}{\widehat{P}(Y_i > A\mid B)}\right) = -0.4266 - \widehat{\eta_i} \]

\[ \log\left(\frac{\widehat{P}(Y_i \leq B\mid C)}{\widehat{P}(Y_i > B\mid C)}\right) = 1.2191 - \widehat{\eta_i} \]

\[ \log\left(\frac{\widehat{P}(Y_i \leq C\mid D)}{\widehat{P}(Y_i > C\mid D)}\right) = 2.794 - \widehat{\eta_i} \]

\[ \log\left(\frac{\widehat{P}(Y_i \leq D\mid E)}{\widehat{P}(Y_i > D\mid E)}\right) = 4.6826 - \widehat{\eta_i} \]

\[ \log\left(\frac{\widehat{P}(Y_i \leq E\mid F)}{\widehat{P}(Y_i > E\mid F)}\right) = 6.5509 - \widehat{\eta_i} \]

\[ \log\left(\frac{\widehat{P}(Y_i \leq F\mid G)}{\widehat{P}(Y_i > F\mid G)}\right) = 8.321 - \widehat{\eta_i} \]

7.7 Koefisien dan Odds Ratio Model Ordinal

Pada tabel berikut, Odds_Ratio_Higher_Grade = exp(estimate) dibaca sebagai odds untuk berada pada kategori grade yang lebih tinggi. Ini sesuai dengan parameterisasi MASS::polr() yang berbentuk:

\[ \operatorname{logit}\{P(Y \leq j)\} = \alpha_j - x\beta \]

Jika ingin membaca odds kumulatif untuk berada pada kategori rendah atau sama dengan batas tertentu, gunakan Odds_Ratio_Lower_Cumulative = exp(-estimate).

coef_ordinal <- coef(summary(model_ordinal)) %>%
  as.data.frame()
coef_ordinal$term <- rownames(coef_ordinal)
names(coef_ordinal)[1:3] <- c("estimate", "std_error", "t_value")

coef_ordinal <- coef_ordinal %>%
  dplyr::mutate(
    p_value = 2 * pnorm(abs(t_value), lower.tail = FALSE),
    Odds_Ratio_Higher_Grade = exp(estimate),
    Odds_Ratio_Lower_Cumulative = exp(-estimate),
    Jenis = ifelse(stringr::str_detect(term, "\\|"), "Cutpoint", "Prediktor"),
    Variabel_Mudah = purrr::map_chr(term, label_ordinal),
    Keputusan_5persen = ifelse(p_value < 0.05, "Signifikan", "Tidak signifikan")
  ) %>%
  dplyr::relocate(term, Jenis)

knitr::kable(
  coef_ordinal %>% dplyr::filter(Jenis == "Prediktor") %>% dplyr::arrange(p_value) %>%
    dplyr::select(Variabel_Mudah, term, estimate, std_error, t_value, p_value, Odds_Ratio_Higher_Grade, Odds_Ratio_Lower_Cumulative, Keputusan_5persen) %>% head(25),
  digits = 4,
  caption = "Koefisien dan Odds Ratio Regresi Ordinal MASS::polr"
)
Koefisien dan Odds Ratio Regresi Ordinal MASS::polr
Variabel_Mudah term estimate std_error t_value p_value Odds_Ratio_Higher_Grade Odds_Ratio_Lower_Cumulative Keputusan_5persen
term60 tenor pinjaman: 60 dibanding kategori acuan term60 1.7054 0.0457 37.3046 0.0000 5.5035 0.1817 Signifikan
verified_incomeVerified verifikasi pendapatan: Verified dibanding kategori acuan verified_incomeVerified 1.1086 0.0531 20.8759 0.0000 3.0300 0.3300 Signifikan
total_credit_limit_k total limit kredit (per 1.000 dollar) total_credit_limit_k -0.0024 0.0002 -15.1249 0.0000 0.9976 1.0024 Signifikan
inquiries_last_12m jumlah pemeriksaan kredit 12 bulan terakhir inquiries_last_12m 0.1206 0.0081 14.9018 0.0000 1.1282 0.8864 Signifikan
delinq_2y jumlah keterlambatan 2 tahun terakhir delinq_2y 0.3864 0.0280 13.7930 0.0000 1.4717 0.6795 Signifikan
verified_incomeSource Verified verifikasi pendapatan: Source Verified dibanding kategori acuan verified_incomeSource Verified 0.5205 0.0434 11.9841 0.0000 1.6828 0.5942 Signifikan
debt_to_income rasio utang terhadap pendapatan debt_to_income 0.0190 0.0019 10.1936 0.0000 1.0191 0.9812 Signifikan
total_credit_utilized_k total kredit yang digunakan (per 1.000 dollar) total_credit_utilized_k 0.0046 0.0005 9.5181 0.0000 1.0046 0.9954 Signifikan
total_credit_lines total riwayat fasilitas kredit total_credit_lines -0.0210 0.0026 -8.2315 0.0000 0.9792 1.0212 Signifikan
loan_amount_k jumlah pinjaman (per 1.000 dollar) loan_amount_k -0.0141 0.0022 -6.3999 0.0000 0.9860 1.0142 Signifikan
homeownershipRENT kepemilikan rumah: RENT dibanding kategori acuan homeownershipRENT 0.1695 0.0485 3.4924 0.0005 1.1847 0.8441 Signifikan
loan_purposehouse tujuan pinjaman: house dibanding kategori acuan loan_purposehouse -0.5827 0.1900 -3.0672 0.0022 0.5584 1.7909 Signifikan
application_typejoint jenis aplikasi: joint dibanding kategori acuan application_typejoint -0.1742 0.0584 -2.9821 0.0029 0.8401 1.1903 Signifikan
num_historical_failed_to_pay riwayat gagal bayar sebelumnya num_historical_failed_to_pay 0.0837 0.0281 2.9817 0.0029 1.0873 0.9197 Signifikan
loan_purposevacation tujuan pinjaman: vacation dibanding kategori acuan loan_purposevacation 0.7064 0.2560 2.7595 0.0058 2.0267 0.4934 Signifikan
loan_purposedebt_consolidation tujuan pinjaman: debt_consolidation dibanding kategori acuan loan_purposedebt_consolidation 0.2337 0.1206 1.9373 0.0527 1.2632 0.7916 Tidak signifikan
loan_purposecredit_card tujuan pinjaman: credit_card dibanding kategori acuan loan_purposecredit_card -0.2175 0.1238 -1.7570 0.0789 0.8046 1.2429 Tidak signifikan
public_record_bankrupt catatan kebangkrutan publik public_record_bankrupt 0.1050 0.0612 1.7174 0.0859 1.1108 0.9003 Tidak signifikan
open_credit_lines jumlah fasilitas kredit yang masih terbuka open_credit_lines 0.0083 0.0049 1.6800 0.0930 1.0083 0.9917 Tidak signifikan
loan_purposesmall_business tujuan pinjaman: small_business dibanding kategori acuan loan_purposesmall_business 0.3061 0.1984 1.5434 0.1227 1.3582 0.7363 Tidak signifikan
loan_purposerenewable_energy tujuan pinjaman: renewable_energy dibanding kategori acuan loan_purposerenewable_energy 0.3466 0.2819 1.2292 0.2190 1.4142 0.7071 Tidak signifikan
annual_income_k pendapatan tahunan (per 1.000 dollar) annual_income_k -0.0004 0.0004 -1.0622 0.2881 0.9996 1.0004 Tidak signifikan
loan_purposehome_improvement tujuan pinjaman: home_improvement dibanding kategori acuan loan_purposehome_improvement -0.1361 0.1372 -0.9916 0.3214 0.8728 1.1458 Tidak signifikan
homeownershipOWN kepemilikan rumah: OWN dibanding kategori acuan homeownershipOWN 0.0400 0.0596 0.6710 0.5022 1.0408 0.9608 Tidak signifikan
loan_purposemajor_purchase tujuan pinjaman: major_purchase dibanding kategori acuan loan_purposemajor_purchase -0.0925 0.1568 -0.5901 0.5551 0.9116 1.0969 Tidak signifikan

Pada model ordinal dengan MASS::polr(), nilai Odds_Ratio_Higher_Grade = exp(\beta) digunakan untuk membaca kecenderungan menuju grade yang lebih tinggi. Karena grade diurutkan sebagai:

\[ A < B < C < D < E < F < G \]

maka grade yang lebih tinggi berarti risiko lebih buruk.

Sementara itu, Odds_Ratio_Lower_Cumulative = exp(-\beta) membaca odds kumulatif untuk berada pada kategori rendah atau sama dengan batas tertentu, yaitu:

\[ P(Y \leq j) \]

Dalam laporan ini, interpretasi substantif difokuskan pada Odds_Ratio_Higher_Grade.

7.8 Evaluasi Model Ordinal

pred_ordinal <- predict(model_ordinal, newdata = data_ordinal, type = "class")
grade_levels <- levels(data_ordinal$grade)
pred_ordinal_f <- factor(as.character(pred_ordinal), levels = grade_levels, ordered = TRUE)
aktual_ordinal_f <- factor(as.character(data_ordinal$grade), levels = grade_levels, ordered = TRUE)

conf_ordinal <- table(Prediksi = pred_ordinal_f, Aktual = aktual_ordinal_f)
conf_ordinal
##         Aktual
## Prediksi    A    B    C    D    E    F    G
##        A 1167  631  243   82    9    1    0
##        B 1118 1485 1120  458   63    4    1
##        C  164  805 1024  587  148   27    8
##        D    4  107  258  306  111   24    3
##        E    1    2    3    5    3    1    0
##        F    0    0    1    0    0    0    0
##        G    0    2    0    0    0    0    0
akurasi_ordinal <- mean(as.character(pred_ordinal_f) == as.character(aktual_ordinal_f), na.rm = TRUE)
akurasi_ordinal
## [1] 0.3994587
AIC_ordinal <- AIC(model_ordinal)
AIC_ordinal
## [1] 26634.23
prob_ordinal <- predict(model_ordinal, type = "probs")
knitr::kable(head(prob_ordinal, 6), digits = 4, caption = "Cuplikan Prediksi Probabilitas untuk Model Ordinal")
Cuplikan Prediksi Probabilitas untuk Model Ordinal
A B C D E F G
0.0341 0.1207 0.3147 0.3845 0.1203 0.0212 0.0045
0.3584 0.3849 0.1900 0.0560 0.0090 0.0014 0.0003
0.1901 0.3588 0.3057 0.1203 0.0211 0.0033 0.0007
0.3321 0.3884 0.2051 0.0623 0.0101 0.0016 0.0003
0.0654 0.2008 0.3705 0.2838 0.0663 0.0109 0.0023
0.2679 0.3869 0.2468 0.0822 0.0137 0.0021 0.0004

7.9 Visualisasi Probabilitas Prediksi Model Ordinal

Visualisasi ini digunakan untuk melihat bagaimana peluang masing-masing grade berubah ketika debt_to_income meningkat. Variabel lain ditahan pada nilai median atau kategori paling umum agar hubungan lebih mudah dibaca.

grid_ordinal <- data.frame(
  annual_income_k = median(data_ordinal$annual_income_k, na.rm = TRUE),
  debt_to_income = seq(
    quantile(data_ordinal$debt_to_income, 0.05, na.rm = TRUE),
    quantile(data_ordinal$debt_to_income, 0.95, na.rm = TRUE),
    length.out = 120
  ),
  delinq_2y = median(data_ordinal$delinq_2y, na.rm = TRUE),
  inquiries_last_12m = median(data_ordinal$inquiries_last_12m, na.rm = TRUE),
  total_credit_lines = median(data_ordinal$total_credit_lines, na.rm = TRUE),
  open_credit_lines = median(data_ordinal$open_credit_lines, na.rm = TRUE),
  total_credit_limit_k = median(data_ordinal$total_credit_limit_k, na.rm = TRUE),
  total_credit_utilized_k = median(data_ordinal$total_credit_utilized_k, na.rm = TRUE),
  num_historical_failed_to_pay = median(data_ordinal$num_historical_failed_to_pay, na.rm = TRUE),
  public_record_bankrupt = median(data_ordinal$public_record_bankrupt, na.rm = TRUE),
  loan_amount_k = median(data_ordinal$loan_amount_k, na.rm = TRUE),
  term = factor(modus(data_ordinal$term), levels = levels(data_ordinal$term)),
  homeownership = factor(modus(data_ordinal$homeownership), levels = levels(data_ordinal$homeownership)),
  verified_income = factor(modus(data_ordinal$verified_income), levels = levels(data_ordinal$verified_income)),
  loan_purpose = factor(modus(data_ordinal$loan_purpose), levels = levels(data_ordinal$loan_purpose)),
  application_type = factor(modus(data_ordinal$application_type), levels = levels(data_ordinal$application_type))
)

prob_grid_ordinal <- predict(
  model_ordinal,
  newdata = grid_ordinal,
  type = "probs"
)

plot_prob_ordinal <- grid_ordinal %>%
  dplyr::bind_cols(as.data.frame(prob_grid_ordinal)) %>%
  tidyr::pivot_longer(
    cols = levels(data_ordinal$grade),
    names_to = "grade",
    values_to = "Probabilitas"
  )

ggplot(
  plot_prob_ordinal,
  aes(x = debt_to_income, y = Probabilitas, color = grade)
) +
  geom_line(linewidth = 1.1) +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(
    title = "Prediksi Probabilitas Grade Berdasarkan Debt-to-Income Ratio",
    subtitle = "Variabel lain ditahan pada median atau kategori paling umum",
    x = "Debt-to-Income Ratio",
    y = "Probabilitas prediksi",
    color = "Grade"
  ) +
  theme_minimal()

Grafik ini membantu melihat perubahan peluang grade ketika rasio utang terhadap pendapatan meningkat. Jika probabilitas grade tinggi seperti D, E, F, atau G meningkat ketika debt_to_income naik, maka model menunjukkan bahwa beban utang yang lebih tinggi berkaitan dengan risiko kredit yang lebih buruk.

7.10 Pemeriksaan Asumsi Proportional Odds

Asumsi utama regresi logistik ordinal adalah proportional odds atau parallel lines. Artinya, pengaruh prediktor diasumsikan sama pada setiap batas kumulatif grade.

Dalam analisis ini, pemeriksaan dilakukan menggunakan fungsi clm() dan nominal_test() dari paket ordinal.

cek_proportional_odds <- tryCatch({
  model_ordinal_clm_simple <- ordinal::clm(
    grade ~ annual_income_k + debt_to_income + delinq_2y +
      inquiries_last_12m + loan_amount_k + term,
    data = data_ordinal,
    link = "logit"
  )

  print(summary(model_ordinal_clm_simple))

  ordinal::nominal_test(model_ordinal_clm_simple)

}, error = function(e) {
  cat("Pemeriksaan proportional odds dengan nominal_test() tidak berhasil dijalankan.\n")
  cat("Pesan error:", e$message, "\n")
  NULL
})
## formula: 
## grade ~ annual_income_k + debt_to_income + delinq_2y + inquiries_last_12m + loan_amount_k + term
## data:    data_ordinal
## 
##  link  threshold nobs logLik    AIC      niter max.grad cond.H 
##  logit flexible  9976 -13884.82 27793.64 7(0)  2.65e-11 2.5e+06
## 
## Coefficients:
##                      Estimate Std. Error z value             Pr(>|z|)    
## annual_income_k    -0.0039610  0.0004048  -9.784 < 0.0000000000000002 ***
## debt_to_income      0.0157440  0.0015465  10.180 < 0.0000000000000002 ***
## delinq_2y           0.3232870  0.0268864  12.024 < 0.0000000000000002 ***
## inquiries_last_12m  0.1057767  0.0077237  13.695 < 0.0000000000000002 ***
## loan_amount_k      -0.0084878  0.0021147  -4.014            0.0000598 ***
## term60              1.5669873  0.0446407  35.102 < 0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Threshold coefficients:
##     Estimate Std. Error z value
## A|B -0.66176    0.05296  -12.50
## B|C  0.85255    0.05310   16.06
## C|D  2.30485    0.05776   39.90
## D|E  4.09772    0.07433   55.13
## E|F  5.93822    0.13290   44.68
## F|G  7.70270    0.29416   26.18
cek_proportional_odds
cat("::: {.interpret-box}\n")
if (is.null(cek_proportional_odds)) {
  cat("Pemeriksaan proportional odds dengan `nominal_test()` tidak berhasil dijalankan secara stabil. Oleh karena itu, pada laporan ini asumsi proportional odds dicatat sebagai keterbatasan analisis. Model ordinal tetap digunakan sebagai model utama karena tujuan analisis adalah memahami hubungan antara karakteristik pinjaman dan tingkat grade risiko.\n")
} else {
  hasil_po <- as.data.frame(cek_proportional_odds)
  hasil_po$Variabel <- rownames(hasil_po)

  kolom_p <- grep("Pr", names(hasil_po), value = TRUE)[1]

  if (is.na(kolom_p)) {
    cat("Hasil `nominal_test()` berhasil diperoleh, tetapi kolom p-value tidak terdeteksi secara otomatis. Oleh karena itu, interpretasi dilakukan secara deskriptif melalui tabel output uji.\n")
  } else {
    hasil_po <- hasil_po %>%
      dplyr::filter(!is.na(.data[[kolom_p]]))

    signif_po <- hasil_po %>%
      dplyr::filter(.data[[kolom_p]] < 0.05)

    tidak_signif_po <- hasil_po %>%
      dplyr::filter(.data[[kolom_p]] >= 0.05)

    cat("Pemeriksaan proportional odds dilakukan menggunakan `ordinal::nominal_test()` pada model ordinal sederhana. ")

    if (nrow(signif_po) == 0) {
      cat("Berdasarkan hasil uji, tidak terdapat prediktor dengan p-value di bawah 0,05. Artinya, tidak ditemukan indikasi kuat bahwa asumsi proportional odds dilanggar pada model pemeriksaan ini. Dengan demikian, penggunaan model ordinal cumulative logit masih dapat diterima sebagai model awal.\n")
    } else {
      cat("Berdasarkan hasil uji, terdapat ", nrow(signif_po), " prediktor dengan p-value di bawah 0,05, yaitu: ",
          paste(signif_po$Variabel, collapse = ", "),
          ". Hal ini menunjukkan adanya indikasi bahwa efek prediktor tersebut tidak sepenuhnya konstan pada seluruh batas kumulatif grade. Dengan kata lain, asumsi proportional odds berpotensi tidak terpenuhi untuk prediktor tersebut.\n\n", sep = "")

      cat("Secara substantif, hasil ini berarti pengaruh beberapa karakteristik peminjam terhadap perpindahan dari grade rendah ke grade tinggi tidak selalu sama pada setiap batas grade. Misalnya, pengaruh suatu prediktor dalam membedakan grade A-B dengan grade C-G dapat berbeda dari pengaruhnya dalam membedakan grade A-D dengan grade E-G.\n")
    }
  }
}

Pemeriksaan proportional odds dilakukan menggunakan ordinal::nominal_test() pada model ordinal sederhana. Berdasarkan hasil uji, terdapat 4 prediktor dengan p-value di bawah 0,05, yaitu: delinq_2y, inquiries_last_12m, loan_amount_k, term. Hal ini menunjukkan adanya indikasi bahwa efek prediktor tersebut tidak sepenuhnya konstan pada seluruh batas kumulatif grade. Dengan kata lain, asumsi proportional odds berpotensi tidak terpenuhi untuk prediktor tersebut.

Secara substantif, hasil ini berarti pengaruh beberapa karakteristik peminjam terhadap perpindahan dari grade rendah ke grade tinggi tidak selalu sama pada setiap batas grade. Misalnya, pengaruh suatu prediktor dalam membedakan grade A-B dengan grade C-G dapat berbeda dari pengaruhnya dalam membedakan grade A-D dengan grade E-G.

cat(":::\n")
cat("::: {.warning-box}\n")
if (is.null(cek_proportional_odds)) {
  cat("Karena uji proportional odds tidak berhasil dijalankan secara stabil, hasil model ordinal perlu dibaca dengan hati-hati. Keterbatasan ini tidak membatalkan model, tetapi menunjukkan bahwa pemeriksaan asumsi belum dapat disimpulkan secara kuat dari output uji.\n")
} else {
  hasil_po <- as.data.frame(cek_proportional_odds)
  hasil_po$Variabel <- rownames(hasil_po)

  kolom_p <- grep("Pr", names(hasil_po), value = TRUE)[1]

  if (!is.na(kolom_p)) {
    signif_po <- hasil_po %>%
      dplyr::filter(!is.na(.data[[kolom_p]]), .data[[kolom_p]] < 0.05)

    if (nrow(signif_po) == 0) {
      cat("Kesimpulan pemeriksaan asumsi: tidak ada bukti kuat pelanggaran proportional odds pada taraf 5%. Oleh karena itu, model ordinal `MASS::polr()` tetap layak digunakan sebagai model utama untuk menjelaskan tingkat risiko pinjaman berdasarkan grade.\n")
    } else {
      cat("Kesimpulan pemeriksaan asumsi: terdapat indikasi pelanggaran proportional odds pada sebagian prediktor. Oleh karena itu, hasil model ordinal tetap dapat digunakan sebagai model awal, tetapi interpretasinya perlu dilakukan dengan hati-hati. Jika analisis ingin dikembangkan lebih lanjut, alternatif yang dapat dipertimbangkan adalah partial proportional odds model, generalized ordered logit model, atau regresi multinomial sebagai pembanding non-ordinal.\n")
    }
  } else {
    cat("Kesimpulan pemeriksaan asumsi belum dapat dibuat secara otomatis karena kolom p-value tidak terdeteksi. Output `nominal_test()` tetap perlu diperiksa secara manual.\n")
  }
}

Kesimpulan pemeriksaan asumsi: terdapat indikasi pelanggaran proportional odds pada sebagian prediktor. Oleh karena itu, hasil model ordinal tetap dapat digunakan sebagai model awal, tetapi interpretasinya perlu dilakukan dengan hati-hati. Jika analisis ingin dikembangkan lebih lanjut, alternatif yang dapat dipertimbangkan adalah partial proportional odds model, generalized ordered logit model, atau regresi multinomial sebagai pembanding non-ordinal.

cat(":::\n")

7.11 Interpretasi dan Kesimpulan Model Ordinal

sig_ordinal <- coef_ordinal %>%
  dplyr::filter(Jenis == "Prediktor", p_value < 0.05) %>%
  dplyr::arrange(p_value)

cat("Pada taraf signifikansi 5%, model ordinal menemukan ", nrow(sig_ordinal),
    " prediktor yang berhubungan signifikan dengan grade risiko pinjaman.\n\n", sep = "")

Pada taraf signifikansi 5%, model ordinal menemukan 15 prediktor yang berhubungan signifikan dengan grade risiko pinjaman.

if (nrow(sig_ordinal) > 0) {
  cat("Prediktor paling penting berdasarkan p-value terkecil adalah:\n\n")
  top_ordinal <- head(sig_ordinal, 8)
  for (i in seq_len(nrow(top_ordinal))) {
    row <- top_ordinal[i, ]
    arah <- ifelse(row$Odds_Ratio_Higher_Grade > 1,
                   "meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G",
                   "menurunkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi")
    cat("- **", row$Variabel_Mudah, "** memiliki OR kategori lebih tinggi = ", fmt_num(row$Odds_Ratio_Higher_Grade, 3),
        " dan p-value = ", fmt_p(row$p_value), ", sehingga variabel ini ", arah,
        ", dengan asumsi variabel lain tetap. Dalam parameterisasi `polr`, ini berasal dari model `logit(P(Y <= j)) = alpha_j - x beta`.\n", sep = "")
  }
  cat("\n")
}

Prediktor paling penting berdasarkan p-value terkecil adalah:

  • tenor pinjaman: 60 dibanding kategori acuan memiliki OR kategori lebih tinggi = 5.504 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • verifikasi pendapatan: Verified dibanding kategori acuan memiliki OR kategori lebih tinggi = 3.030 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • total limit kredit (per 1.000 dollar) memiliki OR kategori lebih tinggi = 0.998 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • jumlah pemeriksaan kredit 12 bulan terakhir memiliki OR kategori lebih tinggi = 1.128 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • jumlah keterlambatan 2 tahun terakhir memiliki OR kategori lebih tinggi = 1.472 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • verifikasi pendapatan: Source Verified dibanding kategori acuan memiliki OR kategori lebih tinggi = 1.683 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • rasio utang terhadap pendapatan memiliki OR kategori lebih tinggi = 1.019 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
  • total kredit yang digunakan (per 1.000 dollar) memiliki OR kategori lebih tinggi = 1.005 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan pinjaman masuk ke grade risiko yang lebih tinggi, yaitu mendekati G, dengan asumsi variabel lain tetap. Dalam parameterisasi polr, ini berasal dari model logit(P(Y <= j)) = alpha_j - x beta.
cat("Akurasi klasifikasi model ordinal adalah **", scales::percent(akurasi_ordinal),
    "**. AIC model adalah **", fmt_num(AIC_ordinal, 2), "**.\n\n", sep = "")

Akurasi klasifikasi model ordinal adalah 40%. AIC model adalah 26,634.23.

cat("**Kesimpulan substantif:** model ordinal menunjukkan faktor-faktor yang membedakan pinjaman berisiko rendah dan tinggi. Karena model menggunakan `MASS::polr` dengan bentuk `logit(P(Y <= j)) = alpha_j - x beta`, maka `exp(beta)` dibaca sebagai odds untuk berada pada kategori grade yang lebih tinggi. Dengan urutan A sampai G, OR kategori lebih tinggi di atas 1 berarti variabel tersebut berkaitan dengan grade risiko lebih buruk, sedangkan OR di bawah 1 berarti berkaitan dengan grade risiko lebih rendah.\n")

Kesimpulan substantif: model ordinal menunjukkan faktor-faktor yang membedakan pinjaman berisiko rendah dan tinggi. Karena model menggunakan MASS::polr dengan bentuk logit(P(Y <= j)) = alpha_j - x beta, maka exp(beta) dibaca sebagai odds untuk berada pada kategori grade yang lebih tinggi. Dengan urutan A sampai G, OR kategori lebih tinggi di atas 1 berarti variabel tersebut berkaitan dengan grade risiko lebih buruk, sedangkan OR di bawah 1 berarti berkaitan dengan grade risiko lebih rendah.

8 Bagian III — Regresi Logistik Multinomial

8.1 Tujuan Analisis

Tujuan analisis ini adalah mengetahui faktor-faktor yang berhubungan dengan status pinjaman Prosper. Status pinjaman tidak diperlakukan sebagai urutan, karena Current, Completed, Chargedoff, Defaulted, dan PastDue adalah jenis kondisi pinjaman yang berbeda.

8.2 Variabel yang Digunakan

Variabel respon adalah LoanStatus, yang kemudian dirapikan menjadi LoanStatus_recode.

Variabel yang Dipakai pada Model Multinomial
Kategori baru Arti sederhana
Completed Pinjaman sudah selesai dibayar
Current Pinjaman masih berjalan
Chargedoff Pinjaman sudah dianggap macet/rugi
Defaulted Pinjaman gagal bayar
PastDue Pinjaman sedang terlambat bayar
Variabel Peran Alasan_dipakai
LoanStatus_recode Respon Mewakili status pinjaman Prosper
BorrowerAPR Prediktor Menggambarkan biaya pinjaman tahunan
LoanOriginalAmount Prediktor Menggambarkan besar pinjaman awal
Term Prediktor Menggambarkan tenor pinjaman
EmploymentStatus Prediktor Menggambarkan kondisi pekerjaan peminjam
IncomeRange Prediktor Menggambarkan rentang pendapatan peminjam
DebtToIncomeRatio Prediktor Mengukur beban utang terhadap pendapatan
CreditScoreRangeLower Prediktor Menggambarkan skor kredit peminjam
ListingCategory (numeric) Prediktor Menggambarkan kategori tujuan pinjaman
StatedMonthlyIncome Prediktor Menggambarkan pendapatan bulanan yang dilaporkan

Variabel seperti LoanCurrentDaysDelinquent, LoanFirstDefaultedCycleNumber, dan variabel LP_... tidak digunakan karena muncul setelah pinjaman berjalan dan terlalu dekat dengan status pinjaman. Variabel seperti ini dapat menyebabkan data leakage.

8.3 Cleaning Data Multinomial

data_multinom <- data_multinom_raw %>%
  dplyr::rename(
    ProsperRating_Alpha = `ProsperRating (Alpha)`,
    ListingCategory_numeric = `ListingCategory (numeric)`
  ) %>%
  dplyr::mutate(
    LoanStatus_recode = dplyr::case_when(
      stringr::str_detect(LoanStatus, "Past Due") ~ "PastDue",
      LoanStatus %in% c("Completed", "Current", "Chargedoff", "Defaulted") ~ LoanStatus,
      TRUE ~ "Other"
    )
  ) %>%
  dplyr::filter(LoanStatus_recode %in% c("Completed", "Current", "Chargedoff", "Defaulted", "PastDue")) %>%
  dplyr::mutate(
    LoanStatus_recode = relevel(factor(LoanStatus_recode), ref = "Completed"),
    Term = factor(Term),
    EmploymentStatus = forcats::fct_lump_n(factor(EmploymentStatus), n = 6, other_level = "Other"),
    IncomeRange = factor(IncomeRange),
    ListingCategory_numeric = factor(ListingCategory_numeric),
    LoanOriginalAmount_k = LoanOriginalAmount / 1000,
    StatedMonthlyIncome_k = StatedMonthlyIncome / 1000
  ) %>%
  dplyr::select(
    LoanStatus_recode, BorrowerAPR, LoanOriginalAmount_k, Term,
    EmploymentStatus, IncomeRange, DebtToIncomeRatio, CreditScoreRangeLower,
    ListingCategory_numeric, StatedMonthlyIncome_k
  ) %>%
  tidyr::drop_na()

knitr::kable(head(data_multinom, 6), caption = "Cuplikan Data Multinomial Setelah Cleaning")
Cuplikan Data Multinomial Setelah Cleaning
LoanStatus_recode BorrowerAPR LoanOriginalAmount_k Term EmploymentStatus IncomeRange DebtToIncomeRatio CreditScoreRangeLower ListingCategory_numeric StatedMonthlyIncome_k
Completed 0.16516 9.425 36 Self-employed $25,000-49,999 0.17 640 0 3.083333
Current 0.12016 10.000 36 Employed $50,000-74,999 0.18 680 2 6.125000
Completed 0.28269 3.001 36 Not available Not displayed 0.06 480 0 2.083333
Current 0.12528 10.000 36 Employed $25,000-49,999 0.15 800 16 2.875000
Current 0.24614 15.000 36 Employed $100,000+ 0.26 680 2 9.583333
Current 0.15425 15.000 60 Employed $100,000+ 0.36 740 1 8.333333

Completed digunakan sebagai kategori acuan. Jadi hasil model akan membaca status lain dibanding pinjaman yang sudah selesai dibayar.

8.4 Analisis Deskriptif Data Multinomial

dist_multinom <- data_multinom %>%
  dplyr::count(LoanStatus_recode) %>%
  dplyr::mutate(Persen = scales::percent(n / sum(n)))
knitr::kable(dist_multinom, caption = "Distribusi Loan Status Setelah Recode")
Distribusi Loan Status Setelah Recode
LoanStatus_recode n Persen
Completed 33917 32.9%
Chargedoff 10463 10.2%
Current 52478 51.0%
Defaulted 4249 4.1%
PastDue 1857 1.8%
ringkasan_multinom <- data_multinom %>%
  dplyr::summarise(
    Rata_rata_APR = mean(BorrowerAPR),
    Median_APR = median(BorrowerAPR),
    Rata_rata_loan_amount_k = mean(LoanOriginalAmount_k),
    Median_loan_amount_k = median(LoanOriginalAmount_k),
    Rata_rata_DTI = mean(DebtToIncomeRatio)
  )
knitr::kable(ringkasan_multinom, caption = "Ringkasan Prediktor Utama Data Multinomial")
Ringkasan Prediktor Utama Data Multinomial
Rata_rata_APR Median_APR Rata_rata_loan_amount_k Median_loan_amount_k Rata_rata_DTI
0.2166657 0.2073 8.527668 6.6 0.2779702
ggplot(data_multinom, aes(x = LoanStatus_recode)) +
  geom_bar() +
  labs(
    title = "Distribusi Status Pinjaman Prosper",
    x = "Loan Status",
    y = "Jumlah pinjaman"
  ) +
  theme_minimal()

8.5 Pembentukan Model Regresi Logistik Multinomial

Model multinomial membandingkan setiap kategori status pinjaman terhadap kategori acuan Completed. Karena kategori selain Completed adalah Current, Chargedoff, Defaulted, dan PastDue, model membangun empat persamaan logit sekaligus.

Untuk setiap kategori status \(k\) selain Completed, bentuk modelnya adalah:

\[ \log\left( \frac{P(Y_i = k)}{P(Y_i = Completed)} \right) = \beta_{0k} + \beta_{1k}X_{1i} + \cdots + \beta_{pk}X_{pi} \]

Artinya, setiap koefisien selalu dibaca relatif terhadap kategori acuan Completed.

model_multinom <- nnet::multinom(
  LoanStatus_recode ~ BorrowerAPR + LoanOriginalAmount_k + Term + EmploymentStatus +
    IncomeRange + DebtToIncomeRatio + CreditScoreRangeLower +
    ListingCategory_numeric + StatedMonthlyIncome_k,
  data = data_multinom,
  trace = FALSE,
  maxit = 200,
  MaxNWts = 10000
)

summary(model_multinom)
## Call:
## nnet::multinom(formula = LoanStatus_recode ~ BorrowerAPR + LoanOriginalAmount_k + 
##     Term + EmploymentStatus + IncomeRange + DebtToIncomeRatio + 
##     CreditScoreRangeLower + ListingCategory_numeric + StatedMonthlyIncome_k, 
##     data = data_multinom, trace = FALSE, maxit = 200, MaxNWts = 10000)
## 
## Coefficients:
##            (Intercept) BorrowerAPR LoanOriginalAmount_k   Term36   Term60
## Chargedoff  -0.6295027    6.684549           0.06960958 1.543688 1.928403
## Current     -9.0123432   -6.171438           0.07133498 4.251528 5.047080
## Defaulted   -2.0802445    5.890494           0.08078609 2.288127 2.373327
## PastDue    -12.3376523    4.685553           0.08554448 2.849515 3.675825
##            EmploymentStatusFull-time EmploymentStatusNot available
## Chargedoff                0.03631025                    0.01860717
## Current                  -3.59344482                   19.58240081
## Defaulted                 0.67753261                    1.04107783
## PastDue                  -2.82464528                   -3.40871471
##            EmploymentStatusPart-time EmploymentStatusSelf-employed
## Chargedoff                -0.2877912                     0.4939120
## Current                   -4.4946527                    -3.2763642
## Defaulted                  0.1666370                     0.9999379
## PastDue                   -1.9619289                   -27.2650565
##            EmploymentStatusOther IncomeRange$1-24,999 IncomeRange$100,000+
## Chargedoff             0.4989151            0.3378266           -0.3613065
## Current                0.3201893            8.8117782            8.6567855
## Defaulted              0.7929610           -0.3501685           -0.1367631
## PastDue                0.1793325            7.0312452            6.7596505
##            IncomeRange$25,000-49,999 IncomeRange$50,000-74,999
## Chargedoff                 0.2086400               -0.05227022
## Current                    8.8280347                8.82613270
## Defaulted                 -0.1517018               -0.21522729
## PastDue                    6.9924241                6.86682065
##            IncomeRange$75,000-99,999 IncomeRangeNot displayed
## Chargedoff                -0.1699349               -0.3250956
## Current                    8.7365207              -23.4326132
## Defaulted                 -0.2175515               -0.1434447
## PastDue                    6.7891067               -2.7346498
##            IncomeRangeNot employed DebtToIncomeRatio CreditScoreRangeLower
## Chargedoff              -0.2673620        0.04322748          -0.005686828
## Current                -29.4389818        0.32910003          -0.010713248
## Defaulted               -0.8653875        0.07493480          -0.005769732
## PastDue                -44.0422496        0.27404756          -0.008016763
##            ListingCategory_numeric1 ListingCategory_numeric2
## Chargedoff               -0.5708640               -0.4102319
## Current                   5.5951129                5.3244649
## Defaulted                -0.6890061               -0.8126204
## PastDue                   4.1759018                4.4049329
##            ListingCategory_numeric3 ListingCategory_numeric4
## Chargedoff               -0.1091526              -0.09164516
## Current                   4.9849066             -19.31941238
## Defaulted                -0.4161347              -0.32889454
## PastDue                   4.2382908            -145.72917520
##            ListingCategory_numeric5 ListingCategory_numeric6
## Chargedoff               -0.5295448               -0.7036627
## Current                 -27.2799821                4.9521401
## Defaulted                -0.8701874               -1.0376967
## PastDue                 -26.1512089                3.8806954
##            ListingCategory_numeric7 ListingCategory_numeric8
## Chargedoff               -0.5496470                0.1609483
## Current                   4.9726225                6.0041333
## Defaulted                -0.8979768              -19.8076383
## PastDue                   3.8253652                4.7507223
##            ListingCategory_numeric9 ListingCategory_numeric10
## Chargedoff                -1.148400                 -0.368280
## Current                    4.984668                  5.251689
## Defaulted                -14.410266                 -1.004847
## PastDue                    3.949680                  4.303154
##            ListingCategory_numeric11 ListingCategory_numeric12
## Chargedoff                 -1.793221                 0.4877906
## Current                     5.413090                 5.4237962
## Defaulted                 -21.741148                 0.1127084
## PastDue                     4.359630                 4.8957947
##            ListingCategory_numeric13 ListingCategory_numeric14
## Chargedoff                 0.1619101                -0.3259399
## Current                    5.9994923                 5.8951513
## Defaulted                 -0.6488704                -0.8857277
## PastDue                    4.8947403                 5.1462304
##            ListingCategory_numeric15 ListingCategory_numeric16
## Chargedoff                0.03404026                 -2.787390
## Current                   6.07860353                  5.341409
## Defaulted                -0.71102302                 -1.981023
## PastDue                   5.31452702                  4.129824
##            ListingCategory_numeric17 ListingCategory_numeric18
## Chargedoff               -16.8872324                -0.3701332
## Current                    4.9597574                 6.0569545
## Defaulted                 -0.7242184                -1.1094231
## PastDue                    3.3796574                 4.8894867
##            ListingCategory_numeric19 ListingCategory_numeric20
## Chargedoff                -0.2054259                -0.5058006
## Current                    6.0258047                 5.8110789
## Defaulted                 -0.9403849                -1.0029376
## PastDue                    4.7436539                 4.3776057
##            StatedMonthlyIncome_k
## Chargedoff          -0.007556906
## Current             -0.002472433
## Defaulted           -0.062486512
## PastDue             -0.013091727
## 
## Std. Errors:
##            (Intercept) BorrowerAPR LoanOriginalAmount_k     Term36     Term60
## Chargedoff 0.045536970 0.037083609          0.002590117 0.03231556 0.03709095
## Current    0.042940975 0.050384682          0.002148251 0.02868112 0.02991584
## Defaulted  0.025610152 0.017306644          0.003441570 0.04344827 0.04479088
## PastDue    0.004453529 0.004306967          0.004991918 0.02952604 0.02885220
##            EmploymentStatusFull-time EmploymentStatusNot available
## Chargedoff               0.026669563              0.02018490998192
## Current                  0.032502948              0.00000010584371
## Defaulted                0.040883021              0.02267829817536
## PastDue                  0.006324081              0.00000000312831
##            EmploymentStatusPart-time EmploymentStatusSelf-employed
## Chargedoff               0.073529020        0.06388159859828143605
## Current                  0.002106384        0.00387143576458124196
## Defaulted                0.016589231        0.02788475866400276504
## PastDue                  0.001314815        0.00000000000001235172
##            EmploymentStatusOther IncomeRange$1-24,999 IncomeRange$100,000+
## Chargedoff            0.05829488           0.03983956           0.04657958
## Current               0.04134132           0.03579038           0.02876603
## Defaulted             0.02005086           0.06382447           0.06673275
## PastDue               0.02078589           0.03965622           0.04205807
##            IncomeRange$25,000-49,999 IncomeRange$50,000-74,999
## Chargedoff                0.02522149                0.02543147
## Current                   0.02005919                0.01989183
## Defaulted                 0.04027661                0.03782352
## PastDue                   0.04931018                0.04641457
##            IncomeRange$75,000-99,999 IncomeRangeNot displayed
## Chargedoff                0.03377200        0.020756548914746
## Current                   0.02424256        0.000000105843708
## Defaulted                 0.05014490        0.022853289120219
## PastDue                   0.05373256        0.000000004784348
##                      IncomeRangeNot employed DebtToIncomeRatio
## Chargedoff 0.0036259403988203055789474316128        0.01663586
## Current    0.0000000000000000085881086399226        0.03016698
## Defaulted  0.0015947819525250392889981210232        0.01896800
## PastDue    0.0000000000000000000000001404215        0.05639278
##            CreditScoreRangeLower ListingCategory_numeric1
## Chargedoff          0.0001471156               0.02873817
## Current             0.0001393542               0.02356747
## Defaulted           0.0001432285               0.04045566
## PastDue             0.0001145706               0.04461606
##            ListingCategory_numeric2 ListingCategory_numeric3
## Chargedoff               0.05006704               0.04684950
## Current                  0.03561136               0.04099614
## Defaulted                0.06018821               0.06931139
## PastDue                  0.06930417               0.06522677
##                                                                ListingCategory_numeric4
## Chargedoff 0.05616956550329447322988940527466183993965387344360351562500000000000000000
## Current    0.00000000000106822452679283688714313022005697462191164959222078323364257812
## Defaulted  0.07526216027288142040863050397092592902481555938720703125000000000000000000
## PastDue    0.00000000000000000000000000000000000000000000000000000000000000000001973953
##             ListingCategory_numeric5 ListingCategory_numeric6
## Chargedoff 0.02588308410529137348899              0.071878564
## Current    0.00000000000000005055312              0.052408358
## Defaulted  0.00594903836636222552170              0.009998349
## PastDue    0.00000000000000007009299              0.010097548
##            ListingCategory_numeric7 ListingCategory_numeric8
## Chargedoff               0.04065510     0.001102603846008551
## Current                  0.03185993     0.002186677187282552
## Defaulted                0.06607299     0.000000000000712633
## PastDue                  0.07005652     0.000546422384865483
##            ListingCategory_numeric9 ListingCategory_numeric10
## Chargedoff       0.0002448132412289              0.0006498580
## Current          0.0012111145759105              0.0012244402
## Defaulted        0.0000000001615604              0.0001227801
## PastDue          0.0002086859400089              0.0002965393
##            ListingCategory_numeric11 ListingCategory_numeric12
## Chargedoff     0.0002922166267297219              0.0004505171
## Current        0.0028446576926797317              0.0006599993
## Defaulted      0.0000000000001831248              0.0001282290
## PastDue        0.0006493307834530542              0.0001941926
##            ListingCategory_numeric13 ListingCategory_numeric14
## Chargedoff               0.056033285               0.016831564
## Current                  0.051702952               0.076020967
## Defaulted                0.004037303               0.001839924
## PastDue                  0.026698277               0.018723003
##            ListingCategory_numeric15 ListingCategory_numeric16
## Chargedoff               0.021330744              0.0001996018
## Current                  0.055934511              0.0056386055
## Defaulted                0.001958656              0.0001317935
## PastDue                  0.016634871              0.0009508215
##            ListingCategory_numeric17 ListingCategory_numeric18
## Chargedoff       0.00000000003706055               0.019576242
## Current          0.00065983728541946               0.079580967
## Defaulted        0.00013859277502570               0.001717409
## PastDue          0.00011865885701263               0.014504357
##            ListingCategory_numeric19 ListingCategory_numeric20
## Chargedoff               0.023230141               0.020786823
## Current                  0.078774850               0.081056264
## Defaulted                0.001881095               0.002258808
## PastDue                  0.010945065               0.011165208
##            StatedMonthlyIncome_k
## Chargedoff           0.004694496
## Current              0.002150989
## Defaulted            0.009234341
## PastDue              0.008540678
## 
## Residual Deviance: 158451.7 
## AIC: 158763.7

8.6 Persamaan Model Hasil Estimasi Multinomial

Untuk kategori Chargedoff dibanding Completed:

\[ \log\left(\frac{\widehat{P}(Y_i=\mathrm{Chargedoff})}{\widehat{P}(Y_i=\mathrm{Completed})}\right) = -0.6295 + 6.6845\,\mathrm{BorrowerAPR} + 0.0696\,\mathrm{LoanAmount_k} + 1.5437\,\mathrm{Term36} + 1.9284\,\mathrm{Term60} + 0.0363\,\mathrm{EmploymentStatusFulltime} + 0.0186\,\mathrm{EmploymentStatusNotavailable} - 0.2878\,\mathrm{EmploymentStatusParttime} + 0.4939\,\mathrm{EmploymentStatusSelfemployed} + 0.4989\,\mathrm{EmploymentStatusOther} + 0.3378\,\mathrm{IncomeRange124999} - 0.3613\,\mathrm{IncomeRange100000} + 0.2086\,\mathrm{IncomeRange2500049999} - 0.0523\,\mathrm{IncomeRange5000074999} - 0.1699\,\mathrm{IncomeRange7500099999} - 0.3251\,\mathrm{IncomeRangeNotdisplayed} - 0.2674\,\mathrm{IncomeRangeNotemployed} + 0.0432\,\mathrm{DTI} - 0.0057\,\mathrm{CreditScore} - 0.5709\,\mathrm{ListingCategory_numeric1} - 0.4102\,\mathrm{ListingCategory_numeric2} - 0.1092\,\mathrm{ListingCategory_numeric3} - 0.0916\,\mathrm{ListingCategory_numeric4} - 0.5295\,\mathrm{ListingCategory_numeric5} - 0.7037\,\mathrm{ListingCategory_numeric6} - 0.5496\,\mathrm{ListingCategory_numeric7} + 0.1609\,\mathrm{ListingCategory_numeric8} - 1.1484\,\mathrm{ListingCategory_numeric9} - 0.3683\,\mathrm{ListingCategory_numeric10} - 1.7932\,\mathrm{ListingCategory_numeric11} + 0.4878\,\mathrm{ListingCategory_numeric12} + 0.1619\,\mathrm{ListingCategory_numeric13} - 0.3259\,\mathrm{ListingCategory_numeric14} + 0.034\,\mathrm{ListingCategory_numeric15} - 2.7874\,\mathrm{ListingCategory_numeric16} - 16.8872\,\mathrm{ListingCategory_numeric17} - 0.3701\,\mathrm{ListingCategory_numeric18} - 0.2054\,\mathrm{ListingCategory_numeric19} - 0.5058\,\mathrm{ListingCategory_numeric20} - 0.0076\,\mathrm{Income_k} \]

Untuk kategori Current dibanding Completed:

\[ \log\left(\frac{\widehat{P}(Y_i=\mathrm{Current})}{\widehat{P}(Y_i=\mathrm{Completed})}\right) = -9.0123 - 6.1714\,\mathrm{BorrowerAPR} + 0.0713\,\mathrm{LoanAmount_k} + 4.2515\,\mathrm{Term36} + 5.0471\,\mathrm{Term60} - 3.5934\,\mathrm{EmploymentStatusFulltime} + 19.5824\,\mathrm{EmploymentStatusNotavailable} - 4.4947\,\mathrm{EmploymentStatusParttime} - 3.2764\,\mathrm{EmploymentStatusSelfemployed} + 0.3202\,\mathrm{EmploymentStatusOther} + 8.8118\,\mathrm{IncomeRange124999} + 8.6568\,\mathrm{IncomeRange100000} + 8.828\,\mathrm{IncomeRange2500049999} + 8.8261\,\mathrm{IncomeRange5000074999} + 8.7365\,\mathrm{IncomeRange7500099999} - 23.4326\,\mathrm{IncomeRangeNotdisplayed} - 29.439\,\mathrm{IncomeRangeNotemployed} + 0.3291\,\mathrm{DTI} - 0.0107\,\mathrm{CreditScore} + 5.5951\,\mathrm{ListingCategory_numeric1} + 5.3245\,\mathrm{ListingCategory_numeric2} + 4.9849\,\mathrm{ListingCategory_numeric3} - 19.3194\,\mathrm{ListingCategory_numeric4} - 27.28\,\mathrm{ListingCategory_numeric5} + 4.9521\,\mathrm{ListingCategory_numeric6} + 4.9726\,\mathrm{ListingCategory_numeric7} + 6.0041\,\mathrm{ListingCategory_numeric8} + 4.9847\,\mathrm{ListingCategory_numeric9} + 5.2517\,\mathrm{ListingCategory_numeric10} + 5.4131\,\mathrm{ListingCategory_numeric11} + 5.4238\,\mathrm{ListingCategory_numeric12} + 5.9995\,\mathrm{ListingCategory_numeric13} + 5.8952\,\mathrm{ListingCategory_numeric14} + 6.0786\,\mathrm{ListingCategory_numeric15} + 5.3414\,\mathrm{ListingCategory_numeric16} + 4.9598\,\mathrm{ListingCategory_numeric17} + 6.057\,\mathrm{ListingCategory_numeric18} + 6.0258\,\mathrm{ListingCategory_numeric19} + 5.8111\,\mathrm{ListingCategory_numeric20} - 0.0025\,\mathrm{Income_k} \]

Untuk kategori Defaulted dibanding Completed:

\[ \log\left(\frac{\widehat{P}(Y_i=\mathrm{Defaulted})}{\widehat{P}(Y_i=\mathrm{Completed})}\right) = -2.0802 + 5.8905\,\mathrm{BorrowerAPR} + 0.0808\,\mathrm{LoanAmount_k} + 2.2881\,\mathrm{Term36} + 2.3733\,\mathrm{Term60} + 0.6775\,\mathrm{EmploymentStatusFulltime} + 1.0411\,\mathrm{EmploymentStatusNotavailable} + 0.1666\,\mathrm{EmploymentStatusParttime} + 0.9999\,\mathrm{EmploymentStatusSelfemployed} + 0.793\,\mathrm{EmploymentStatusOther} - 0.3502\,\mathrm{IncomeRange124999} - 0.1368\,\mathrm{IncomeRange100000} - 0.1517\,\mathrm{IncomeRange2500049999} - 0.2152\,\mathrm{IncomeRange5000074999} - 0.2176\,\mathrm{IncomeRange7500099999} - 0.1434\,\mathrm{IncomeRangeNotdisplayed} - 0.8654\,\mathrm{IncomeRangeNotemployed} + 0.0749\,\mathrm{DTI} - 0.0058\,\mathrm{CreditScore} - 0.689\,\mathrm{ListingCategory_numeric1} - 0.8126\,\mathrm{ListingCategory_numeric2} - 0.4161\,\mathrm{ListingCategory_numeric3} - 0.3289\,\mathrm{ListingCategory_numeric4} - 0.8702\,\mathrm{ListingCategory_numeric5} - 1.0377\,\mathrm{ListingCategory_numeric6} - 0.898\,\mathrm{ListingCategory_numeric7} - 19.8076\,\mathrm{ListingCategory_numeric8} - 14.4103\,\mathrm{ListingCategory_numeric9} - 1.0048\,\mathrm{ListingCategory_numeric10} - 21.7411\,\mathrm{ListingCategory_numeric11} + 0.1127\,\mathrm{ListingCategory_numeric12} - 0.6489\,\mathrm{ListingCategory_numeric13} - 0.8857\,\mathrm{ListingCategory_numeric14} - 0.711\,\mathrm{ListingCategory_numeric15} - 1.981\,\mathrm{ListingCategory_numeric16} - 0.7242\,\mathrm{ListingCategory_numeric17} - 1.1094\,\mathrm{ListingCategory_numeric18} - 0.9404\,\mathrm{ListingCategory_numeric19} - 1.0029\,\mathrm{ListingCategory_numeric20} - 0.0625\,\mathrm{Income_k} \]

Untuk kategori PastDue dibanding Completed:

\[ \log\left(\frac{\widehat{P}(Y_i=\mathrm{PastDue})}{\widehat{P}(Y_i=\mathrm{Completed})}\right) = -12.3377 + 4.6856\,\mathrm{BorrowerAPR} + 0.0855\,\mathrm{LoanAmount_k} + 2.8495\,\mathrm{Term36} + 3.6758\,\mathrm{Term60} - 2.8246\,\mathrm{EmploymentStatusFulltime} - 3.4087\,\mathrm{EmploymentStatusNotavailable} - 1.9619\,\mathrm{EmploymentStatusParttime} - 27.2651\,\mathrm{EmploymentStatusSelfemployed} + 0.1793\,\mathrm{EmploymentStatusOther} + 7.0312\,\mathrm{IncomeRange124999} + 6.7597\,\mathrm{IncomeRange100000} + 6.9924\,\mathrm{IncomeRange2500049999} + 6.8668\,\mathrm{IncomeRange5000074999} + 6.7891\,\mathrm{IncomeRange7500099999} - 2.7346\,\mathrm{IncomeRangeNotdisplayed} - 44.0422\,\mathrm{IncomeRangeNotemployed} + 0.274\,\mathrm{DTI} - 0.008\,\mathrm{CreditScore} + 4.1759\,\mathrm{ListingCategory_numeric1} + 4.4049\,\mathrm{ListingCategory_numeric2} + 4.2383\,\mathrm{ListingCategory_numeric3} - 145.7292\,\mathrm{ListingCategory_numeric4} - 26.1512\,\mathrm{ListingCategory_numeric5} + 3.8807\,\mathrm{ListingCategory_numeric6} + 3.8254\,\mathrm{ListingCategory_numeric7} + 4.7507\,\mathrm{ListingCategory_numeric8} + 3.9497\,\mathrm{ListingCategory_numeric9} + 4.3032\,\mathrm{ListingCategory_numeric10} + 4.3596\,\mathrm{ListingCategory_numeric11} + 4.8958\,\mathrm{ListingCategory_numeric12} + 4.8947\,\mathrm{ListingCategory_numeric13} + 5.1462\,\mathrm{ListingCategory_numeric14} + 5.3145\,\mathrm{ListingCategory_numeric15} + 4.1298\,\mathrm{ListingCategory_numeric16} + 3.3797\,\mathrm{ListingCategory_numeric17} + 4.8895\,\mathrm{ListingCategory_numeric18} + 4.7437\,\mathrm{ListingCategory_numeric19} + 4.3776\,\mathrm{ListingCategory_numeric20} - 0.0131\,\mathrm{Income_k} \]

Chunk model-multinomial di atas sudah membangun model regresi logistik multinomial menggunakan nnet::multinom(). Persamaan logit yang dibentuk adalah sebagai berikut.

Untuk kategori Chargedoff dibanding Completed:

\[ \log\left(\frac{P(Y=\mathrm{Chargedoff})}{P(Y=\mathrm{Completed})}\right) = \beta_{0,\mathrm{Chargedoff}} + \beta_{1,\mathrm{Chargedoff}}\mathrm{BorrowerAPR} + \cdots + \beta_{p,\mathrm{Chargedoff}}X_p \]

Untuk kategori Current dibanding Completed:

\[ \log\left(\frac{P(Y=\mathrm{Current})}{P(Y=\mathrm{Completed})}\right) = \beta_{0,\mathrm{Current}} + \beta_{1,\mathrm{Current}}\mathrm{BorrowerAPR} + \cdots + \beta_{p,\mathrm{Current}}X_p \]

Untuk kategori Defaulted dibanding Completed:

\[ \log\left(\frac{P(Y=\mathrm{Defaulted})}{P(Y=\mathrm{Completed})}\right) = \beta_{0,\mathrm{Defaulted}} + \beta_{1,\mathrm{Defaulted}}\mathrm{BorrowerAPR} + \cdots + \beta_{p,\mathrm{Defaulted}}X_p \]

Untuk kategori PastDue dibanding Completed:

\[ \log\left(\frac{P(Y=\mathrm{PastDue})}{P(Y=\mathrm{Completed})}\right) = \beta_{0,\mathrm{PastDue}} + \beta_{1,\mathrm{PastDue}}\mathrm{BorrowerAPR} + \cdots + \beta_{p,\mathrm{PastDue}}X_p \]

8.7 Koefisien dan Relative Risk Ratio Model Multinomial

summary_multinom <- summary(model_multinom)
coef_multinom <- summary_multinom$coefficients
se_multinom <- summary_multinom$standard.errors

multinom_table <- purrr::map_dfr(rownames(coef_multinom), function(kelas) {
  tibble::tibble(
    Kategori = kelas,
    term = colnames(coef_multinom),
    estimate = as.numeric(coef_multinom[kelas, ]),
    std_error = as.numeric(se_multinom[kelas, ])
  )
}) %>%
  dplyr::mutate(
    z_value = estimate / std_error,
    p_value = 2 * pnorm(abs(z_value), lower.tail = FALSE),
    Relative_Risk_Ratio = exp(estimate),
    Variabel_Mudah = purrr::map_chr(term, label_multinom),
    Keputusan_5persen = ifelse(p_value < 0.05, "Signifikan", "Tidak signifikan")
  ) %>%
  dplyr::arrange(Kategori, p_value)

knitr::kable(
  multinom_table %>% dplyr::select(Kategori, Variabel_Mudah, term, estimate, std_error, z_value, p_value, Relative_Risk_Ratio, Keputusan_5persen) %>% head(35),
  digits = 4,
  caption = "Koefisien dan Relative Risk Ratio Regresi Multinomial"
)
Koefisien dan Relative Risk Ratio Regresi Multinomial
Kategori Variabel_Mudah term estimate std_error z_value p_value Relative_Risk_Ratio Keputusan_5persen
Chargedoff APR/biaya pinjaman tahunan BorrowerAPR 6.6845 0.0371 180.2562 0.0000 799.9501 Signifikan
Chargedoff tenor pinjaman: 36 bulan dibanding kategori acuan Term36 1.5437 0.0323 47.7692 0.0000 4.6818 Signifikan
Chargedoff tenor pinjaman: 60 bulan dibanding kategori acuan Term60 1.9284 0.0371 51.9912 0.0000 6.8785 Signifikan
Chargedoff rentang pendapatan: Not employed dibanding kategori acuan IncomeRangeNot employed -0.2674 0.0036 -73.7359 0.0000 0.7654 Signifikan
Chargedoff batas bawah skor kredit CreditScoreRangeLower -0.0057 0.0001 -38.6555 0.0000 0.9943 Signifikan
Chargedoff kategori tujuan listing: 8 dibanding kategori acuan ListingCategory_numeric8 0.1609 0.0011 145.9711 0.0000 1.1746 Signifikan
Chargedoff kategori tujuan listing: 9 dibanding kategori acuan ListingCategory_numeric9 -1.1484 0.0002 -4690.9212 0.0000 0.3171 Signifikan
Chargedoff kategori tujuan listing: 10 dibanding kategori acuan ListingCategory_numeric10 -0.3683 0.0006 -566.7084 0.0000 0.6919 Signifikan
Chargedoff kategori tujuan listing: 11 dibanding kategori acuan ListingCategory_numeric11 -1.7932 0.0003 -6136.6152 0.0000 0.1664 Signifikan
Chargedoff kategori tujuan listing: 12 dibanding kategori acuan ListingCategory_numeric12 0.4878 0.0005 1082.7348 0.0000 1.6287 Signifikan
Chargedoff kategori tujuan listing: 16 dibanding kategori acuan ListingCategory_numeric16 -2.7874 0.0002 -13964.7523 0.0000 0.0616 Signifikan
Chargedoff kategori tujuan listing: 17 dibanding kategori acuan ListingCategory_numeric17 -16.8872 0.0000 -455665951831.1931 0.0000 0.0000 Signifikan
Chargedoff jumlah pinjaman awal (per 1.000 dollar) LoanOriginalAmount_k 0.0696 0.0026 26.8751 0.0000 1.0721 Signifikan
Chargedoff kategori tujuan listing: 20 dibanding kategori acuan ListingCategory_numeric20 -0.5058 0.0208 -24.3327 0.0000 0.6030 Signifikan
Chargedoff kategori tujuan listing: 5 dibanding kategori acuan ListingCategory_numeric5 -0.5295 0.0259 -20.4591 0.0000 0.5889 Signifikan
Chargedoff kategori tujuan listing: 1 dibanding kategori acuan ListingCategory_numeric1 -0.5709 0.0287 -19.8643 0.0000 0.5650 Signifikan
Chargedoff kategori tujuan listing: 14 dibanding kategori acuan ListingCategory_numeric14 -0.3259 0.0168 -19.3648 0.0000 0.7218 Signifikan
Chargedoff kategori tujuan listing: 18 dibanding kategori acuan ListingCategory_numeric18 -0.3701 0.0196 -18.9073 0.0000 0.6906 Signifikan
Chargedoff rentang pendapatan: Not displayed dibanding kategori acuan IncomeRangeNot displayed -0.3251 0.0208 -15.6623 0.0000 0.7225 Signifikan
Chargedoff (Intercept) (Intercept) -0.6295 0.0455 -13.8240 0.0000 0.5329 Signifikan
Chargedoff kategori tujuan listing: 7 dibanding kategori acuan ListingCategory_numeric7 -0.5496 0.0407 -13.5198 0.0000 0.5772 Signifikan
Chargedoff kategori tujuan listing: 6 dibanding kategori acuan ListingCategory_numeric6 -0.7037 0.0719 -9.7896 0.0000 0.4948 Signifikan
Chargedoff kategori tujuan listing: 19 dibanding kategori acuan ListingCategory_numeric19 -0.2054 0.0232 -8.8431 0.0000 0.8143 Signifikan
Chargedoff status pekerjaan: Other dibanding kategori acuan EmploymentStatusOther 0.4989 0.0583 8.5585 0.0000 1.6469 Signifikan
Chargedoff rentang pendapatan: $1-24,999 dibanding kategori acuan IncomeRange$1-24,999 0.3378 0.0398 8.4797 0.0000 1.4019 Signifikan
Chargedoff rentang pendapatan: $25,000-49,999 dibanding kategori acuan IncomeRange$25,000-49,999 0.2086 0.0252 8.2723 0.0000 1.2320 Signifikan
Chargedoff kategori tujuan listing: 2 dibanding kategori acuan ListingCategory_numeric2 -0.4102 0.0501 -8.1937 0.0000 0.6635 Signifikan
Chargedoff rentang pendapatan: $100,000+ dibanding kategori acuan IncomeRange$100,000+ -0.3613 0.0466 -7.7568 0.0000 0.6968 Signifikan
Chargedoff status pekerjaan: Self-employed dibanding kategori acuan EmploymentStatusSelf-employed 0.4939 0.0639 7.7317 0.0000 1.6387 Signifikan
Chargedoff rentang pendapatan: $75,000-99,999 dibanding kategori acuan IncomeRange$75,000-99,999 -0.1699 0.0338 -5.0318 0.0000 0.8437 Signifikan
Chargedoff status pekerjaan: Part-time dibanding kategori acuan EmploymentStatusPart-time -0.2878 0.0735 -3.9140 0.0001 0.7499 Signifikan
Chargedoff kategori tujuan listing: 13 dibanding kategori acuan ListingCategory_numeric13 0.1619 0.0560 2.8895 0.0039 1.1758 Signifikan
Chargedoff rasio utang terhadap pendapatan DebtToIncomeRatio 0.0432 0.0166 2.5985 0.0094 1.0442 Signifikan
Chargedoff kategori tujuan listing: 3 dibanding kategori acuan ListingCategory_numeric3 -0.1092 0.0468 -2.3299 0.0198 0.8966 Signifikan
Chargedoff rentang pendapatan: $50,000-74,999 dibanding kategori acuan IncomeRange$50,000-74,999 -0.0523 0.0254 -2.0553 0.0398 0.9491 Signifikan

8.8 Evaluasi Model Multinomial

pred_multinom <- predict(model_multinom, type = "class")
conf_multinom <- table(Prediksi = pred_multinom, Aktual = data_multinom$LoanStatus_recode)
conf_multinom
##             Aktual
## Prediksi     Completed Chargedoff Current Defaulted PastDue
##   Completed      22573       6120    2196      3016     151
##   Chargedoff       851        986      51       396       9
##   Current        10371       3214   50231       586    1697
##   Defaulted        122        143       0       251       0
##   PastDue            0          0       0         0       0
akurasi_multinom <- mean(as.character(pred_multinom) == as.character(data_multinom$LoanStatus_recode))
akurasi_multinom
## [1] 0.719096
AIC_multinom <- AIC(model_multinom)
AIC_multinom
## [1] 158763.7
prob_multinom <- predict(model_multinom, type = "probs")
knitr::kable(head(prob_multinom, 6), digits = 4, caption = "Cuplikan Prediksi Probabilitas untuk Model Multinomial")
Cuplikan Prediksi Probabilitas untuk Model Multinomial
Completed Chargedoff Current Defaulted PastDue
0.4768 0.3608 0.0008 0.1616 0.0000
0.1041 0.0147 0.8677 0.0029 0.0106
0.3237 0.3121 0.0000 0.3642 0.0000
0.3010 0.0027 0.6838 0.0017 0.0107
0.1572 0.0525 0.7393 0.0119 0.0390
0.0689 0.0112 0.9040 0.0029 0.0131

8.9 Visualisasi Probabilitas Prediksi Model Multinomial

Visualisasi probabilitas prediksi digunakan untuk melihat bagaimana peluang masing-masing status pinjaman berubah ketika salah satu prediktor berubah. Dalam analisis ini, prediktor yang digunakan adalah BorrowerAPR, yaitu biaya pinjaman tahunan. Variabel lain ditahan pada nilai yang umum atau nilai terbanyak agar perubahan grafik lebih mudah dibaca.

grid_multinom <- data.frame(
  BorrowerAPR = seq(
    quantile(data_multinom$BorrowerAPR, 0.05, na.rm = TRUE),
    quantile(data_multinom$BorrowerAPR, 0.95, na.rm = TRUE),
    length.out = 100
  ),
  LoanOriginalAmount_k = median(data_multinom$LoanOriginalAmount_k, na.rm = TRUE),
  Term = factor(modus(data_multinom$Term), levels = levels(data_multinom$Term)),
  EmploymentStatus = factor(
    modus(data_multinom$EmploymentStatus),
    levels = levels(data_multinom$EmploymentStatus)
  ),
  IncomeRange = factor(
    modus(data_multinom$IncomeRange),
    levels = levels(data_multinom$IncomeRange)
  ),
  DebtToIncomeRatio = median(data_multinom$DebtToIncomeRatio, na.rm = TRUE),
  CreditScoreRangeLower = median(data_multinom$CreditScoreRangeLower, na.rm = TRUE),
  ListingCategory_numeric = factor(
    modus(data_multinom$ListingCategory_numeric),
    levels = levels(data_multinom$ListingCategory_numeric)
  ),
  StatedMonthlyIncome_k = median(data_multinom$StatedMonthlyIncome_k, na.rm = TRUE)
)

prob_grid_multinom <- predict(
  model_multinom,
  newdata = grid_multinom,
  type = "probs"
)

plot_prob_multinom <- grid_multinom %>%
  dplyr::bind_cols(as.data.frame(prob_grid_multinom)) %>%
  tidyr::pivot_longer(
    cols = levels(data_multinom$LoanStatus_recode),
    names_to = "LoanStatus_recode",
    values_to = "Probabilitas"
  )

ggplot(
  plot_prob_multinom,
  aes(x = BorrowerAPR, y = Probabilitas, color = LoanStatus_recode)
) +
  geom_line(linewidth = 1.1) +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(
    title = "Prediksi Probabilitas Status Pinjaman Berdasarkan BorrowerAPR",
    subtitle = "Variabel lain ditahan pada median atau kategori paling umum",
    x = "BorrowerAPR",
    y = "Probabilitas prediksi",
    color = "Status pinjaman"
  ) +
  theme_minimal()

Grafik ini membantu membaca hasil regresi multinomial secara lebih substantif. Jika probabilitas Chargedoff, Defaulted, atau PastDue meningkat ketika BorrowerAPR naik, maka model menunjukkan bahwa pinjaman dengan biaya pinjaman lebih tinggi cenderung memiliki peluang lebih besar masuk ke status bermasalah. Sebaliknya, jika probabilitas Completed menurun ketika BorrowerAPR naik, maka pinjaman dengan APR lebih tinggi cenderung lebih kecil peluangnya untuk selesai dibayar.

8.10 Catatan Evaluasi dan Asumsi Model Multinomial

Pada analisis ini, uji goodness-of-fit devians \(G^2\) tidak digunakan sebagai evaluasi utama karena data Prosper berbentuk data individu, yaitu satu baris untuk satu pinjaman, serta memiliki beberapa prediktor kontinu seperti BorrowerAPR, DebtToIncomeRatio, LoanOriginalAmount_k, dan CreditScoreRangeLower. Uji \(G^2\) lebih cocok digunakan pada data berbentuk grouped data atau tabel frekuensi, yaitu ketika satu baris mewakili satu kelompok dan respons ditampilkan sebagai jumlah atau frekuensi kategori.

Oleh karena itu, evaluasi model multinomial dalam laporan ini difokuskan pada koefisien model, relative risk ratio, AIC, prediksi probabilitas, dan confusion matrix.

Regresi logistik multinomial memiliki asumsi Independence of Irrelevant Alternatives atau IIA. Secara sederhana, asumsi ini menyatakan bahwa perbandingan peluang antara dua kategori status pinjaman tidak berubah secara drastis hanya karena kategori lain ditambahkan atau dihapus. Dalam konteks Prosper, asumsi ini perlu dicatat sebagai keterbatasan karena beberapa kategori seperti Chargedoff, Defaulted, dan PastDue sama-sama menggambarkan kondisi pinjaman yang kurang baik. Untuk tugas ini, asumsi IIA dicatat sebagai keterbatasan, bukan diuji secara mendalam.

8.11 Interpretasi dan Kesimpulan Model Multinomial

sig_multi <- multinom_table %>%
  dplyr::filter(term != "(Intercept)", p_value < 0.05) %>%
  dplyr::arrange(Kategori, p_value)

cat("Pada taraf signifikansi 5%, model multinomial menemukan ", nrow(sig_multi),
    " kombinasi prediktor-kategori yang signifikan. Semua interpretasi dibandingkan terhadap kategori acuan `Completed`.\n\n", sep = "")

Pada taraf signifikansi 5%, model multinomial menemukan 149 kombinasi prediktor-kategori yang signifikan. Semua interpretasi dibandingkan terhadap kategori acuan Completed.

if (nrow(sig_multi) > 0) {
  for (kelas in unique(sig_multi$Kategori)) {
    cat("**Status ", kelas, " dibanding Completed**\n\n", sep = "")
    top_kelas <- sig_multi %>% dplyr::filter(Kategori == kelas) %>% head(5)
    for (i in seq_len(nrow(top_kelas))) {
      row <- top_kelas[i, ]
      arah <- ifelse(row$Relative_Risk_Ratio > 1,
                     paste0("meningkatkan kecenderungan status ", kelas, " dibanding Completed"),
                     paste0("menurunkan kecenderungan status ", kelas, " dibanding Completed"))
      cat("- **", row$Variabel_Mudah, "** memiliki RRR = ", fmt_num(row$Relative_Risk_Ratio, 3),
          " dan p-value = ", fmt_p(row$p_value), ", sehingga variabel ini ", arah,
          ", dengan asumsi variabel lain tetap.\n", sep = "")
    }
    cat("\n")
  }
}

Status Chargedoff dibanding Completed

  • APR/biaya pinjaman tahunan memiliki RRR = 799.950 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Chargedoff dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 36 bulan dibanding kategori acuan memiliki RRR = 4.682 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Chargedoff dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 60 bulan dibanding kategori acuan memiliki RRR = 6.879 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Chargedoff dibanding Completed, dengan asumsi variabel lain tetap.
  • rentang pendapatan: Not employed dibanding kategori acuan memiliki RRR = 0.765 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status Chargedoff dibanding Completed, dengan asumsi variabel lain tetap.
  • batas bawah skor kredit memiliki RRR = 0.994 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status Chargedoff dibanding Completed, dengan asumsi variabel lain tetap.

Status Current dibanding Completed

  • APR/biaya pinjaman tahunan memiliki RRR = 0.002 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status Current dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 36 bulan dibanding kategori acuan memiliki RRR = 70.213 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Current dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 60 bulan dibanding kategori acuan memiliki RRR = 155.568 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Current dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Full-time dibanding kategori acuan memiliki RRR = 0.028 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status Current dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Not available dibanding kategori acuan memiliki RRR = 319,542,489.978 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Current dibanding Completed, dengan asumsi variabel lain tetap.

Status Defaulted dibanding Completed

  • APR/biaya pinjaman tahunan memiliki RRR = 361.584 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Defaulted dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 36 bulan dibanding kategori acuan memiliki RRR = 9.856 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Defaulted dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 60 bulan dibanding kategori acuan memiliki RRR = 10.733 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Defaulted dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Not available dibanding kategori acuan memiliki RRR = 2.832 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Defaulted dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Other dibanding kategori acuan memiliki RRR = 2.210 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status Defaulted dibanding Completed, dengan asumsi variabel lain tetap.

Status PastDue dibanding Completed

  • APR/biaya pinjaman tahunan memiliki RRR = 108.370 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status PastDue dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 36 bulan dibanding kategori acuan memiliki RRR = 17.279 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status PastDue dibanding Completed, dengan asumsi variabel lain tetap.
  • tenor pinjaman: 60 bulan dibanding kategori acuan memiliki RRR = 39.481 dan p-value = < 0.001, sehingga variabel ini meningkatkan kecenderungan status PastDue dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Full-time dibanding kategori acuan memiliki RRR = 0.059 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status PastDue dibanding Completed, dengan asumsi variabel lain tetap.
  • status pekerjaan: Not available dibanding kategori acuan memiliki RRR = 0.033 dan p-value = < 0.001, sehingga variabel ini menurunkan kecenderungan status PastDue dibanding Completed, dengan asumsi variabel lain tetap.
cat("Akurasi klasifikasi model multinomial adalah **", scales::percent(akurasi_multinom),
    "**. AIC model adalah **", fmt_num(AIC_multinom, 2), "**.\n\n", sep = "")

Akurasi klasifikasi model multinomial adalah 72%. AIC model adalah 158,763.70.

cat("**Kesimpulan substantif:** model multinomial menunjukkan karakteristik pinjaman dan peminjam yang membedakan status pinjaman yang sudah selesai dibayar (`Completed`) dengan status lain seperti masih berjalan, macet, gagal bayar, atau terlambat. Faktor signifikan dengan RRR lebih dari 1 meningkatkan kecenderungan suatu status dibanding `Completed`, sedangkan RRR kurang dari 1 menurunkannya.\n")

Kesimpulan substantif: model multinomial menunjukkan karakteristik pinjaman dan peminjam yang membedakan status pinjaman yang sudah selesai dibayar (Completed) dengan status lain seperti masih berjalan, macet, gagal bayar, atau terlambat. Faktor signifikan dengan RRR lebih dari 1 meningkatkan kecenderungan suatu status dibanding Completed, sedangkan RRR kurang dari 1 menurunkannya.

9 Bagian IV — Regresi Poisson

9.1 Tujuan Analisis

Tujuan analisis ini adalah mengetahui faktor-faktor yang berhubungan dengan jumlah pinjaman SBA 7(a) yang bermasalah. Dalam data SBA, pinjaman bermasalah diwakili oleh status CHGOFF, yaitu pinjaman yang sudah dianggap macet atau rugi oleh pemberi pinjaman.

9.2 Variabel yang Digunakan

Data awal SBA berbentuk satu baris per pinjaman. Untuk regresi Poisson, data diubah menjadi satu baris per kelompok pinjaman. Respon akhirnya adalah jumlah pinjaman bermasalah dalam setiap kelompok.

Variabel yang Dipakai pada Model Poisson
Variabel Peran Alasan_dipakai
LoanStatus Dasar pembentukan respon Dipakai untuk menandai pinjaman PIF atau CHGOFF
ChargedOff Variabel baru Bernilai 1 jika CHGOFF dan 0 jika PIF
ApprovalFY Prediktor kelompok Risiko bisa berbeda antar tahun persetujuan pinjaman
BorrState Prediktor kelompok Risiko bisa berbeda antar lokasi peminjam
Sector Prediktor kelompok Risiko bisa berbeda antar sektor industri
Loan_Size_Band Prediktor kelompok Risiko bisa berbeda menurut ukuran pinjaman
Term_Band Prediktor kelompok Risiko bisa berbeda menurut tenor pinjaman
BusinessType Prediktor kelompok Risiko bisa berbeda menurut bentuk usaha
CollateralInd Prediktor kelompok Agunan dapat berkaitan dengan risiko kredit
Total_Loan Offset/exposure Jumlah pinjaman dalam kelompok, digunakan agar model membaca rate bukan jumlah mentah
Jumlah_ChargedOff Respon Poisson Jumlah pinjaman CHGOFF dalam setiap kelompok

9.3 Variabel yang Tidak Digunakan pada Model Poisson

Variabel yang Tidak Digunakan pada Model Poisson
Variabel Alasan_sederhana
BorrName, BorrStreet, BorrZip Identitas dan alamat peminjam terlalu detail, sulit diinterpretasikan, dan bukan fokus model risiko
BankName, BankStreet, BankZip Identitas bank terlalu detail untuk model awal
LocationID, BankFDICNumber, BankNCUANumber Hanya kode teknis atau nomor identitas
PaidInFullDate, ChargeOffDate Terlalu dekat dengan hasil akhir pinjaman sehingga bisa menyebabkan data leakage
GrossChargeOffAmount Jumlah kerugian baru diketahui setelah pinjaman bermasalah
JobsSupported Bukan fokus utama risiko kredit dan bersifat laporan estimasi dari lender
BusinessAge Secara konsep relevan, tetapi banyak kosong untuk tahun 2010-2017 sehingga tidak dipakai pada model awal

9.4 Cleaning dan Pembentukan Data Agregat

data_poisson_clean <- data_poisson_raw %>%
  dplyr::filter(loanstatus %in% c("P I F", "CHGOFF")) %>%
  dplyr::mutate(
    ChargedOff = ifelse(loanstatus == "CHGOFF", 1L, 0L),
    Sector = stringr::str_sub(as.character(naicscode), 1, 2),
    Loan_Size_Band = dplyr::case_when(
      grossapproval <= 50000 ~ "Small",
      grossapproval <= 350000 ~ "Medium",
      grossapproval > 350000 ~ "Large",
      TRUE ~ NA_character_
    ),
    Term_Band = dplyr::case_when(
      terminmonths <= 60 ~ "Short",
      terminmonths <= 120 ~ "Medium",
      terminmonths > 120 ~ "Long",
      TRUE ~ NA_character_
    ),
    CollateralInd_clean = dplyr::case_when(
      tolower(as.character(collateralind)) %in% c("true", "1", "yes", "y") ~ "Collateral",
      tolower(as.character(collateralind)) %in% c("false", "0", "no", "n") ~ "No_Collateral",
      TRUE ~ NA_character_
    ),
    ApprovalFY = factor(approvalfy),
    BorrState = factor(borrstate),
    Sector = factor(Sector),
    Loan_Size_Band = factor(Loan_Size_Band, levels = c("Small", "Medium", "Large")),
    Term_Band = factor(Term_Band, levels = c("Short", "Medium", "Long")),
    BusinessType = factor(businesstype),
    CollateralInd = factor(CollateralInd_clean)
  ) %>%
  tidyr::drop_na(
    ApprovalFY, BorrState, Sector, Loan_Size_Band, Term_Band,
    BusinessType, CollateralInd, ChargedOff
  )

data_poisson_agg <- data_poisson_clean %>%
  dplyr::group_by(
    ApprovalFY, BorrState, Sector, Loan_Size_Band,
    Term_Band, BusinessType, CollateralInd
  ) %>%
  dplyr::summarise(
    Total_Loan = dplyr::n(),
    Jumlah_ChargedOff = sum(ChargedOff),
    .groups = "drop"
  ) %>%
  dplyr::filter(Total_Loan > 0)

knitr::kable(head(data_poisson_agg, 10), caption = "Cuplikan Data Agregat untuk Regresi Poisson")
Cuplikan Data Agregat untuk Regresi Poisson
ApprovalFY BorrState Sector Loan_Size_Band Term_Band BusinessType CollateralInd Total_Loan Jumlah_ChargedOff
2010 AK 11 Small Medium CORPORATION No_Collateral 1 0
2010 AK 11 Small Long CORPORATION Collateral 1 0
2010 AK 11 Medium Long INDIVIDUAL Collateral 1 0
2010 AK 11 Large Short CORPORATION No_Collateral 1 1
2010 AK 11 Large Medium CORPORATION Collateral 1 0
2010 AK 23 Small Short INDIVIDUAL Collateral 1 0
2010 AK 23 Small Medium CORPORATION No_Collateral 2 0
2010 AK 23 Medium Short CORPORATION Collateral 1 0
2010 AK 23 Medium Short INDIVIDUAL Collateral 1 0
2010 AK 23 Medium Medium INDIVIDUAL Collateral 1 0

9.5 Analisis Deskriptif Data Poisson

ringkasan_poisson <- data_poisson_agg %>%
  dplyr::summarise(
    Jumlah_kelompok = dplyr::n(),
    Total_pinjaman = sum(Total_Loan),
    Total_pinjaman_bermasalah = sum(Jumlah_ChargedOff),
    Rata_rata_bermasalah_per_kelompok = mean(Jumlah_ChargedOff),
    Median_bermasalah_per_kelompok = median(Jumlah_ChargedOff)
  )
knitr::kable(ringkasan_poisson, caption = "Ringkasan Data Agregat Poisson")
Ringkasan Data Agregat Poisson
Jumlah_kelompok Total_pinjaman Total_pinjaman_bermasalah Rata_rata_bermasalah_per_kelompok Median_bermasalah_per_kelompok
98766 422523 30838 0.312233 0
knitr::kable(
  data_poisson_clean %>%
    dplyr::count(loanstatus) %>%
    dplyr::mutate(Persen = scales::percent(n / sum(n))),
  caption = "Distribusi Status Pinjaman yang Digunakan"
)
Distribusi Status Pinjaman yang Digunakan
loanstatus n Persen
CHGOFF 30838 7%
P I F 391685 93%
plot_poisson_data <- data_poisson_agg %>%
  dplyr::filter(Jumlah_ChargedOff <= quantile(Jumlah_ChargedOff, 0.99))

ggplot(plot_poisson_data, aes(x = Jumlah_ChargedOff)) +
  geom_histogram(binwidth = 1) +
  labs(
    title = "Distribusi Jumlah Pinjaman Bermasalah per Kelompok",
    x = "Jumlah pinjaman bermasalah",
    y = "Jumlah kelompok"
  ) +
  theme_minimal()

9.6 Rate Pinjaman Bermasalah Berdasarkan Kelompok Utama

Rate pinjaman bermasalah dihitung sebagai:

\[ Rate = \frac{Jumlah\_ChargedOff}{Total\_Loan} \]

Rate ini membantu membandingkan risiko antar kelompok, karena jumlah pinjaman setiap kelompok tidak sama.

rate_by_size_term <- data_poisson_agg %>%
  dplyr::group_by(Loan_Size_Band, Term_Band) %>%
  dplyr::summarise(
    Total_Loan = sum(Total_Loan),
    Jumlah_ChargedOff = sum(Jumlah_ChargedOff),
    Rate_ChargedOff = Jumlah_ChargedOff / Total_Loan,
    .groups = "drop"
  ) %>%
  dplyr::arrange(desc(Rate_ChargedOff))

knitr::kable(
  rate_by_size_term %>%
    dplyr::mutate(Rate_ChargedOff = scales::percent(Rate_ChargedOff, accuracy = 0.01)),
  caption = "Rate Pinjaman Bermasalah berdasarkan Ukuran Pinjaman dan Tenor"
)
Rate Pinjaman Bermasalah berdasarkan Ukuran Pinjaman dan Tenor
Loan_Size_Band Term_Band Total_Loan Jumlah_ChargedOff Rate_ChargedOff
Large Short 5558 1354 24.36%
Medium Short 35390 6594 18.63%
Small Short 49785 8775 17.63%
Large Medium 36146 2231 6.17%
Medium Medium 115298 6529 5.66%
Small Long 1867 70 3.75%
Small Medium 102612 3570 3.48%
Large Long 53893 1248 2.32%
Medium Long 21974 467 2.13%

9.7 Pembentukan Model Regresi Poisson

Model Poisson yang digunakan:

\[ \log(\mu_i) = \beta_0 + \beta_1 X_{1i} + \beta_2 X_{2i} + \cdots + \beta_p X_{pi} + \log(Total\_Loan_i) \]

Dalam model ini, \(X_{1i}, X_{2i}, \ldots, X_{pi}\) mewakili ApprovalFY, BorrState, Sector, Loan_Size_Band, Term_Band, BusinessType, dan CollateralInd. Komponen \(\log(Total\_Loan_i)\) adalah offset.

Bagian offset(log(Total_Loan)) membuat model membandingkan rate pinjaman bermasalah. Artinya, kelompok dengan jumlah pinjaman lebih banyak tidak otomatis dianggap lebih berisiko hanya karena jumlah kasusnya lebih besar.

model_poisson <- glm(
  Jumlah_ChargedOff ~ ApprovalFY + BorrState + Sector +
    Loan_Size_Band + Term_Band + BusinessType + CollateralInd +
    offset(log(Total_Loan)),
  data = data_poisson_agg,
  family = poisson(link = "log")
)

summary(model_poisson)
## 
## Call:
## glm(formula = Jumlah_ChargedOff ~ ApprovalFY + BorrState + Sector + 
##     Loan_Size_Band + Term_Band + BusinessType + CollateralInd + 
##     offset(log(Total_Loan)), family = poisson(link = "log"), 
##     data = data_poisson_agg)
## 
## Coefficients:
##                             Estimate Std. Error  z value             Pr(>|z|)
## (Intercept)                 -2.46947    0.15788  -15.641 < 0.0000000000000002
## ApprovalFY2011              -0.24209    0.02716   -8.913 < 0.0000000000000002
## ApprovalFY2012              -0.29396    0.02893  -10.161 < 0.0000000000000002
## ApprovalFY2013              -0.29279    0.02878  -10.173 < 0.0000000000000002
## ApprovalFY2014              -0.19727    0.02697   -7.316 0.000000000000256404
## ApprovalFY2015              -0.06903    0.02523   -2.736             0.006228
## ApprovalFY2016               0.05423    0.02471    2.194             0.028215
## ApprovalFY2017               0.18465    0.02443    7.559 0.000000000000040696
## ApprovalFY2018               0.27549    0.02453   11.230 < 0.0000000000000002
## ApprovalFY2019               0.24332    0.02663    9.135 < 0.0000000000000002
## BorrStateAL                  0.41684    0.15676    2.659             0.007834
## BorrStateAR                  0.27004    0.16264    1.660             0.096847
## BorrStateAZ                  0.32399    0.15000    2.160             0.030780
## BorrStateCA                  0.22843    0.14533    1.572             0.116011
## BorrStateCO                  0.06094    0.14983    0.407             0.684210
## BorrStateCT                 -0.09801    0.15511   -0.632             0.527483
## BorrStateDC                  0.08759    0.19524    0.449             0.653695
## BorrStateDE                  0.08016    0.17878    0.448             0.653890
## BorrStateFL                  0.61101    0.14595    4.187 0.000028328546656523
## BorrStateFM                 -7.43694  104.72036   -0.071             0.943384
## BorrStateGA                  0.53549    0.14827    3.612             0.000304
## BorrStateGU                 -0.99354    0.28882   -3.440             0.000582
## BorrStateHI                 -0.56223    0.16309   -3.447             0.000566
## BorrStateIA                 -0.01058    0.15769   -0.067             0.946492
## BorrStateID                 -0.36327    0.16500   -2.202             0.027686
## BorrStateIL                  0.34962    0.14724    2.374             0.017575
## BorrStateIN                 -0.31480    0.15020   -2.096             0.036094
## BorrStateKS                 -0.12426    0.15879   -0.783             0.433920
## BorrStateKY                 -0.09080    0.15634   -0.581             0.561375
## BorrStateLA                  0.38275    0.15597    2.454             0.014126
## BorrStateMA                 -0.46103    0.14809   -3.113             0.001851
## BorrStateMD                  0.06567    0.15143    0.434             0.664516
## BorrStateME                 -0.55411    0.17128   -3.235             0.001216
## BorrStateMH                 -8.48450  104.72036   -0.081             0.935426
## BorrStateMI                 -0.52699    0.14846   -3.550             0.000386
## BorrStateMN                 -0.28438    0.14962   -1.901             0.057339
## BorrStateMO                  0.21966    0.14962    1.468             0.142056
## BorrStateMP                  0.31445    1.01052    0.311             0.755668
## BorrStateMS                  0.09516    0.15712    0.606             0.544723
## BorrStateMT                 -0.88110    0.18354   -4.801 0.000001582041871745
## BorrStateNC                  0.25033    0.14989    1.670             0.094902
## BorrStateND                 -1.01273    0.20124   -5.032 0.000000484197663264
## BorrStateNE                 -0.19367    0.16285   -1.189             0.234340
## BorrStateNH                 -0.53755    0.15946   -3.371             0.000749
## BorrStateNJ                  0.35466    0.14757    2.403             0.016246
## BorrStateNM                 -0.01682    0.17025   -0.099             0.921283
## BorrStateNV                  0.36220    0.15671    2.311             0.020820
## BorrStateNY                  0.09597    0.14586    0.658             0.510574
## BorrStateOH                 -0.44622    0.14682   -3.039             0.002372
## BorrStateOK                  0.03046    0.15604    0.195             0.845224
## BorrStateOR                 -0.19393    0.15498   -1.251             0.210807
## BorrStatePA                 -0.08363    0.14811   -0.565             0.572324
## BorrStatePR                 -0.29434    0.15772   -1.866             0.062008
## BorrStateRI                 -0.23438    0.16553   -1.416             0.156798
## BorrStateSC                  0.53736    0.15500    3.467             0.000527
## BorrStateSD                 -0.45081    0.20117   -2.241             0.025028
## BorrStateTN                  0.29929    0.15551    1.925             0.054276
## BorrStateTX                  0.52534    0.14546    3.611             0.000304
## BorrStateUT                 -0.09849    0.15165   -0.649             0.516067
## BorrStateVA                  0.17141    0.15051    1.139             0.254740
## BorrStateVI                  0.26294    0.40464    0.650             0.515806
## BorrStateVT                 -0.73539    0.18223   -4.036 0.000054462509707384
## BorrStateWA                 -0.19821    0.15068   -1.315             0.188375
## BorrStateWI                 -0.20688    0.15048   -1.375             0.169189
## BorrStateWV                 -0.35734    0.19164   -1.865             0.062232
## BorrStateWY                 -0.28210    0.19934   -1.415             0.157008
## Sector21                     0.16780    0.12352    1.359             0.174285
## Sector22                     0.09301    0.23178    0.401             0.688201
## Sector23                     0.53213    0.06314    8.428 < 0.0000000000000002
## Sector31                     0.52780    0.07341    7.190 0.000000000000650111
## Sector32                     0.40767    0.07561    5.392 0.000000069725213239
## Sector33                     0.31752    0.06862    4.627 0.000003708985025159
## Sector42                     0.48216    0.06533    7.380 0.000000000000158234
## Sector44                     0.69365    0.06332   10.955 < 0.0000000000000002
## Sector45                     0.76351    0.06613   11.546 < 0.0000000000000002
## Sector48                     0.37120    0.06512    5.700 0.000000011947801913
## Sector49                     0.52290    0.10912    4.792 0.000001649625681084
## Sector51                     0.48543    0.07999    6.069 0.000000001288851830
## Sector52                     0.12758    0.08236    1.549             0.121379
## Sector53                     0.36788    0.07617    4.830 0.000001367504057940
## Sector54                     0.40733    0.06396    6.369 0.000000000190651353
## Sector55                    -0.24403    0.38296   -0.637             0.523985
## Sector56                     0.47257    0.06620    7.139 0.000000000000939939
## Sector61                     0.65300    0.07674    8.510 < 0.0000000000000002
## Sector62                     0.26157    0.06531    4.005 0.000061925924576628
## Sector71                     0.85793    0.06758   12.696 < 0.0000000000000002
## Sector72                     0.79440    0.06278   12.654 < 0.0000000000000002
## Sector81                     0.62187    0.06372    9.759 < 0.0000000000000002
## Sector92                     0.51861    0.41284    1.256             0.209038
## Loan_Size_BandMedium         0.29419    0.01345   21.871 < 0.0000000000000002
## Loan_Size_BandLarge          0.43938    0.02020   21.753 < 0.0000000000000002
## Term_BandMedium             -1.55411    0.01235 -125.836 < 0.0000000000000002
## Term_BandLong               -2.44891    0.02798  -87.535 < 0.0000000000000002
## BusinessTypeINDIVIDUAL      -0.01455    0.01928   -0.755             0.450351
## BusinessTypePARTNERSHIP     -0.46048    0.05616   -8.199 0.000000000000000243
## CollateralIndNo_Collateral   0.39095    0.01323   29.546 < 0.0000000000000002
##                               
## (Intercept)                ***
## ApprovalFY2011             ***
## ApprovalFY2012             ***
## ApprovalFY2013             ***
## ApprovalFY2014             ***
## ApprovalFY2015             ** 
## ApprovalFY2016             *  
## ApprovalFY2017             ***
## ApprovalFY2018             ***
## ApprovalFY2019             ***
## BorrStateAL                ** 
## BorrStateAR                .  
## BorrStateAZ                *  
## BorrStateCA                   
## BorrStateCO                   
## BorrStateCT                   
## BorrStateDC                   
## BorrStateDE                   
## BorrStateFL                ***
## BorrStateFM                   
## BorrStateGA                ***
## BorrStateGU                ***
## BorrStateHI                ***
## BorrStateIA                   
## BorrStateID                *  
## BorrStateIL                *  
## BorrStateIN                *  
## BorrStateKS                   
## BorrStateKY                   
## BorrStateLA                *  
## BorrStateMA                ** 
## BorrStateMD                   
## BorrStateME                ** 
## BorrStateMH                   
## BorrStateMI                ***
## BorrStateMN                .  
## BorrStateMO                   
## BorrStateMP                   
## BorrStateMS                   
## BorrStateMT                ***
## BorrStateNC                .  
## BorrStateND                ***
## BorrStateNE                   
## BorrStateNH                ***
## BorrStateNJ                *  
## BorrStateNM                   
## BorrStateNV                *  
## BorrStateNY                   
## BorrStateOH                ** 
## BorrStateOK                   
## BorrStateOR                   
## BorrStatePA                   
## BorrStatePR                .  
## BorrStateRI                   
## BorrStateSC                ***
## BorrStateSD                *  
## BorrStateTN                .  
## BorrStateTX                ***
## BorrStateUT                   
## BorrStateVA                   
## BorrStateVI                   
## BorrStateVT                ***
## BorrStateWA                   
## BorrStateWI                   
## BorrStateWV                .  
## BorrStateWY                   
## Sector21                      
## Sector22                      
## Sector23                   ***
## Sector31                   ***
## Sector32                   ***
## Sector33                   ***
## Sector42                   ***
## Sector44                   ***
## Sector45                   ***
## Sector48                   ***
## Sector49                   ***
## Sector51                   ***
## Sector52                      
## Sector53                   ***
## Sector54                   ***
## Sector55                      
## Sector56                   ***
## Sector61                   ***
## Sector62                   ***
## Sector71                   ***
## Sector72                   ***
## Sector81                   ***
## Sector92                      
## Loan_Size_BandMedium       ***
## Loan_Size_BandLarge        ***
## Term_BandMedium            ***
## Term_BandLong              ***
## BusinessTypeINDIVIDUAL        
## BusinessTypePARTNERSHIP    ***
## CollateralIndNo_Collateral ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for poisson family taken to be 1)
## 
##     Null deviance: 83781  on 98765  degrees of freedom
## Residual deviance: 59081  on 98670  degrees of freedom
## AIC: 102778
## 
## Number of Fisher Scoring iterations: 8

9.8 Persamaan Model Hasil Estimasi Poisson

Chunk model-poisson di atas sudah membangun model regresi Poisson menggunakan glm() dengan family = poisson(link = "log"). Bentuk hasil estimasinya adalah:

\[ \log(\hat{\mu_i}) = \hat{\beta}_0 + \hat{\beta}_1X_{1i} + \cdots + \log(Total\_Loan_i) \]

Karena terdapat offset(log(Total_Loan)), model membaca rate pinjaman bermasalah, bukan sekadar jumlah mentah. Koefisien yang dieksponensialkan menjadi Incidence Rate Ratio atau IRR.

\[ \log(\widehat{\mu_i}) = -2.4695 - 0.2421\,\mathrm{FY2011} - 0.294\,\mathrm{FY2012} - 0.2928\,\mathrm{FY2013} - 0.1973\,\mathrm{FY2014} - 0.069\,\mathrm{FY2015} + 0.0542\,\mathrm{FY2016} + 0.1847\,\mathrm{FY2017} + 0.2755\,\mathrm{FY2018} + 0.2433\,\mathrm{FY2019} + 0.4168\,\mathrm{StateAL} + 0.27\,\mathrm{StateAR} + 0.324\,\mathrm{StateAZ} + 0.2284\,\mathrm{StateCA} + 0.0609\,\mathrm{StateCO} - 0.098\,\mathrm{StateCT} + 0.0876\,\mathrm{StateDC} + 0.0802\,\mathrm{StateDE} + 0.611\,\mathrm{StateFL} - 7.4369\,\mathrm{StateFM} + 0.5355\,\mathrm{StateGA} - 0.9935\,\mathrm{StateGU} - 0.5622\,\mathrm{StateHI} - 0.0106\,\mathrm{StateIA} - 0.3633\,\mathrm{StateID} + 0.3496\,\mathrm{StateIL} - 0.3148\,\mathrm{StateIN} - 0.1243\,\mathrm{StateKS} - 0.0908\,\mathrm{StateKY} + 0.3828\,\mathrm{StateLA} - 0.461\,\mathrm{StateMA} + 0.0657\,\mathrm{StateMD} - 0.5541\,\mathrm{StateME} - 8.4845\,\mathrm{StateMH} - 0.527\,\mathrm{StateMI} - 0.2844\,\mathrm{StateMN} + 0.2197\,\mathrm{StateMO} + 0.3144\,\mathrm{StateMP} + 0.0952\,\mathrm{StateMS} - 0.8811\,\mathrm{StateMT} + 0.2503\,\mathrm{StateNC} - 1.0127\,\mathrm{StateND} - 0.1937\,\mathrm{StateNE} - 0.5376\,\mathrm{StateNH} + 0.3547\,\mathrm{StateNJ} - 0.0168\,\mathrm{StateNM} + 0.3622\,\mathrm{StateNV} + 0.096\,\mathrm{StateNY} - 0.4462\,\mathrm{StateOH} + 0.0305\,\mathrm{StateOK} - 0.1939\,\mathrm{StateOR} - 0.0836\,\mathrm{StatePA} - 0.2943\,\mathrm{StatePR} - 0.2344\,\mathrm{StateRI} + 0.5374\,\mathrm{StateSC} - 0.4508\,\mathrm{StateSD} + 0.2993\,\mathrm{StateTN} + 0.5253\,\mathrm{StateTX} - 0.0985\,\mathrm{StateUT} + 0.1714\,\mathrm{StateVA} + 0.2629\,\mathrm{StateVI} - 0.7354\,\mathrm{StateVT} - 0.1982\,\mathrm{StateWA} - 0.2069\,\mathrm{StateWI} - 0.3573\,\mathrm{StateWV} - 0.2821\,\mathrm{StateWY} + 0.1678\,\mathrm{Sector21} + 0.093\,\mathrm{Sector22} + 0.5321\,\mathrm{Sector23} + 0.5278\,\mathrm{Sector31} + 0.4077\,\mathrm{Sector32} + 0.3175\,\mathrm{Sector33} + 0.4822\,\mathrm{Sector42} + 0.6936\,\mathrm{Sector44} + 0.7635\,\mathrm{Sector45} + 0.3712\,\mathrm{Sector48} + 0.5229\,\mathrm{Sector49} + 0.4854\,\mathrm{Sector51} + 0.1276\,\mathrm{Sector52} + 0.3679\,\mathrm{Sector53} + 0.4073\,\mathrm{Sector54} - 0.244\,\mathrm{Sector55} + 0.4726\,\mathrm{Sector56} + 0.653\,\mathrm{Sector61} + 0.2616\,\mathrm{Sector62} + 0.8579\,\mathrm{Sector71} + 0.7944\,\mathrm{Sector72} + 0.6219\,\mathrm{Sector81} + 0.5186\,\mathrm{Sector92} + 0.2942\,\mathrm{LoanSizeMedium} + 0.4394\,\mathrm{LoanSizeLarge} - 1.5541\,\mathrm{TermMedium} - 2.4489\,\mathrm{TermLong} - 0.0146\,\mathrm{BusinessTypeINDIVIDUAL} - 0.4605\,\mathrm{BusinessTypePARTNERSHIP} + 0.391\,\mathrm{CollateralNo_Collateral} + \log(Total\_Loan_i) \]

Karena terdapat offset, bentuk rate-nya dapat ditulis sebagai:

\[ \log\left(\frac{\widehat{\mu_i}}{Total\_Loan_i}\right) = -2.4695 - 0.2421\,\mathrm{FY2011} - 0.294\,\mathrm{FY2012} - 0.2928\,\mathrm{FY2013} - 0.1973\,\mathrm{FY2014} - 0.069\,\mathrm{FY2015} + 0.0542\,\mathrm{FY2016} + 0.1847\,\mathrm{FY2017} + 0.2755\,\mathrm{FY2018} + 0.2433\,\mathrm{FY2019} + 0.4168\,\mathrm{StateAL} + 0.27\,\mathrm{StateAR} + 0.324\,\mathrm{StateAZ} + 0.2284\,\mathrm{StateCA} + 0.0609\,\mathrm{StateCO} - 0.098\,\mathrm{StateCT} + 0.0876\,\mathrm{StateDC} + 0.0802\,\mathrm{StateDE} + 0.611\,\mathrm{StateFL} - 7.4369\,\mathrm{StateFM} + 0.5355\,\mathrm{StateGA} - 0.9935\,\mathrm{StateGU} - 0.5622\,\mathrm{StateHI} - 0.0106\,\mathrm{StateIA} - 0.3633\,\mathrm{StateID} + 0.3496\,\mathrm{StateIL} - 0.3148\,\mathrm{StateIN} - 0.1243\,\mathrm{StateKS} - 0.0908\,\mathrm{StateKY} + 0.3828\,\mathrm{StateLA} - 0.461\,\mathrm{StateMA} + 0.0657\,\mathrm{StateMD} - 0.5541\,\mathrm{StateME} - 8.4845\,\mathrm{StateMH} - 0.527\,\mathrm{StateMI} - 0.2844\,\mathrm{StateMN} + 0.2197\,\mathrm{StateMO} + 0.3144\,\mathrm{StateMP} + 0.0952\,\mathrm{StateMS} - 0.8811\,\mathrm{StateMT} + 0.2503\,\mathrm{StateNC} - 1.0127\,\mathrm{StateND} - 0.1937\,\mathrm{StateNE} - 0.5376\,\mathrm{StateNH} + 0.3547\,\mathrm{StateNJ} - 0.0168\,\mathrm{StateNM} + 0.3622\,\mathrm{StateNV} + 0.096\,\mathrm{StateNY} - 0.4462\,\mathrm{StateOH} + 0.0305\,\mathrm{StateOK} - 0.1939\,\mathrm{StateOR} - 0.0836\,\mathrm{StatePA} - 0.2943\,\mathrm{StatePR} - 0.2344\,\mathrm{StateRI} + 0.5374\,\mathrm{StateSC} - 0.4508\,\mathrm{StateSD} + 0.2993\,\mathrm{StateTN} + 0.5253\,\mathrm{StateTX} - 0.0985\,\mathrm{StateUT} + 0.1714\,\mathrm{StateVA} + 0.2629\,\mathrm{StateVI} - 0.7354\,\mathrm{StateVT} - 0.1982\,\mathrm{StateWA} - 0.2069\,\mathrm{StateWI} - 0.3573\,\mathrm{StateWV} - 0.2821\,\mathrm{StateWY} + 0.1678\,\mathrm{Sector21} + 0.093\,\mathrm{Sector22} + 0.5321\,\mathrm{Sector23} + 0.5278\,\mathrm{Sector31} + 0.4077\,\mathrm{Sector32} + 0.3175\,\mathrm{Sector33} + 0.4822\,\mathrm{Sector42} + 0.6936\,\mathrm{Sector44} + 0.7635\,\mathrm{Sector45} + 0.3712\,\mathrm{Sector48} + 0.5229\,\mathrm{Sector49} + 0.4854\,\mathrm{Sector51} + 0.1276\,\mathrm{Sector52} + 0.3679\,\mathrm{Sector53} + 0.4073\,\mathrm{Sector54} - 0.244\,\mathrm{Sector55} + 0.4726\,\mathrm{Sector56} + 0.653\,\mathrm{Sector61} + 0.2616\,\mathrm{Sector62} + 0.8579\,\mathrm{Sector71} + 0.7944\,\mathrm{Sector72} + 0.6219\,\mathrm{Sector81} + 0.5186\,\mathrm{Sector92} + 0.2942\,\mathrm{LoanSizeMedium} + 0.4394\,\mathrm{LoanSizeLarge} - 1.5541\,\mathrm{TermMedium} - 2.4489\,\mathrm{TermLong} - 0.0146\,\mathrm{BusinessTypeINDIVIDUAL} - 0.4605\,\mathrm{BusinessTypePARTNERSHIP} + 0.391\,\mathrm{CollateralNo_Collateral} \]

9.9 Koefisien dan Incidence Rate Ratio Model Poisson

Pada regresi Poisson, koefisien model berada pada skala log. Agar lebih mudah diinterpretasikan, koefisien diubah menjadi Incidence Rate Ratio atau IRR dengan rumus:

\[ IRR = \exp(\beta) \]

Jika IRR lebih dari 1, maka rate pinjaman bermasalah lebih tinggi dibanding kategori acuan. Jika IRR kurang dari 1, maka rate pinjaman bermasalah lebih rendah dibanding kategori acuan.

tabel_poisson <- broom::tidy(model_poisson) %>%
  dplyr::mutate(
    Incidence_Rate_Ratio = exp(estimate),
    Perubahan_Persen = 100 * (Incidence_Rate_Ratio - 1),
    Variabel_Mudah = purrr::map_chr(term, label_poisson),
    Keputusan_5persen = ifelse(p.value < 0.05, "Signifikan", "Tidak signifikan")
  ) %>%
  dplyr::arrange(p.value)

knitr::kable(
  tabel_poisson %>%
    dplyr::select(
      Variabel_Mudah,
      term,
      estimate,
      std.error,
      statistic,
      p.value,
      Incidence_Rate_Ratio,
      Perubahan_Persen,
      Keputusan_5persen
    ) %>%
    head(35),
  digits = 4,
  caption = "Koefisien dan Incidence Rate Ratio Regresi Poisson"
)
Koefisien dan Incidence Rate Ratio Regresi Poisson
Variabel_Mudah term estimate std.error statistic p.value Incidence_Rate_Ratio Perubahan_Persen Keputusan_5persen
tenor pinjaman: Medium dibanding tenor pendek Term_BandMedium -1.5541 0.0124 -125.8356 0.0000 0.2114 -78.8622 Signifikan
tenor pinjaman: Long dibanding tenor pendek Term_BandLong -2.4489 0.0280 -87.5349 0.0000 0.0864 -91.3612 Signifikan
status agunan: No_Collateral dibanding kategori acuan CollateralIndNo_Collateral 0.3910 0.0132 29.5461 0.0000 1.4784 47.8387 Signifikan
ukuran pinjaman: Medium dibanding pinjaman kecil Loan_Size_BandMedium 0.2942 0.0135 21.8709 0.0000 1.3420 34.2034 Signifikan
ukuran pinjaman: Large dibanding pinjaman kecil Loan_Size_BandLarge 0.4394 0.0202 21.7530 0.0000 1.5517 55.1747 Signifikan
(Intercept) (Intercept) -2.4695 0.1579 -15.6413 0.0000 0.0846 -91.5371 Signifikan
sektor industri: 71 dibanding sektor acuan Sector71 0.8579 0.0676 12.6959 0.0000 2.3583 135.8283 Signifikan
sektor industri: 72 dibanding sektor acuan Sector72 0.7944 0.0628 12.6543 0.0000 2.2131 121.3112 Signifikan
sektor industri: 45 dibanding sektor acuan Sector45 0.7635 0.0661 11.5463 0.0000 2.1458 114.5786 Signifikan
tahun persetujuan: 2018 dibanding tahun acuan ApprovalFY2018 0.2755 0.0245 11.2297 0.0000 1.3172 31.7181 Signifikan
sektor industri: 44 dibanding sektor acuan Sector44 0.6936 0.0633 10.9546 0.0000 2.0010 100.1000 Signifikan
tahun persetujuan: 2013 dibanding tahun acuan ApprovalFY2013 -0.2928 0.0288 -10.1733 0.0000 0.7462 -25.3821 Signifikan
tahun persetujuan: 2012 dibanding tahun acuan ApprovalFY2012 -0.2940 0.0289 -10.1612 0.0000 0.7453 -25.4695 Signifikan
sektor industri: 81 dibanding sektor acuan Sector81 0.6219 0.0637 9.7587 0.0000 1.8624 86.2408 Signifikan
tahun persetujuan: 2019 dibanding tahun acuan ApprovalFY2019 0.2433 0.0266 9.1354 0.0000 1.2755 27.5476 Signifikan
tahun persetujuan: 2011 dibanding tahun acuan ApprovalFY2011 -0.2421 0.0272 -8.9128 0.0000 0.7850 -21.5015 Signifikan
sektor industri: 61 dibanding sektor acuan Sector61 0.6530 0.0767 8.5096 0.0000 1.9213 92.1300 Signifikan
sektor industri: 23 dibanding sektor acuan Sector23 0.5321 0.0631 8.4282 0.0000 1.7026 70.2555 Signifikan
jenis usaha: PARTNERSHIP dibanding kategori acuan BusinessTypePARTNERSHIP -0.4605 0.0562 -8.1989 0.0000 0.6310 -36.9017 Signifikan
tahun persetujuan: 2017 dibanding tahun acuan ApprovalFY2017 0.1847 0.0244 7.5588 0.0000 1.2028 20.2801 Signifikan
sektor industri: 42 dibanding sektor acuan Sector42 0.4822 0.0653 7.3800 0.0000 1.6196 61.9563 Signifikan
tahun persetujuan: 2014 dibanding tahun acuan ApprovalFY2014 -0.1973 0.0270 -7.3155 0.0000 0.8210 -17.9029 Signifikan
sektor industri: 31 dibanding sektor acuan Sector31 0.5278 0.0734 7.1895 0.0000 1.6952 69.5205 Signifikan
sektor industri: 56 dibanding sektor acuan Sector56 0.4726 0.0662 7.1390 0.0000 1.6041 60.4118 Signifikan
sektor industri: 54 dibanding sektor acuan Sector54 0.4073 0.0640 6.3687 0.0000 1.5028 50.2794 Signifikan
sektor industri: 51 dibanding sektor acuan Sector51 0.4854 0.0800 6.0688 0.0000 1.6249 62.4878 Signifikan
sektor industri: 48 dibanding sektor acuan Sector48 0.3712 0.0651 5.7005 0.0000 1.4495 44.9477 Signifikan
sektor industri: 32 dibanding sektor acuan Sector32 0.4077 0.0756 5.3919 0.0000 1.5033 50.3305 Signifikan
state peminjam: ND dibanding state acuan BorrStateND -1.0127 0.2012 -5.0325 0.0000 0.3632 -63.6773 Signifikan
sektor industri: 53 dibanding sektor acuan Sector53 0.3679 0.0762 4.8297 0.0000 1.4447 44.4673 Signifikan
state peminjam: MT dibanding state acuan BorrStateMT -0.8811 0.1835 -4.8006 0.0000 0.4143 -58.5672 Signifikan
sektor industri: 49 dibanding sektor acuan Sector49 0.5229 0.1091 4.7922 0.0000 1.6869 68.6918 Signifikan
sektor industri: 33 dibanding sektor acuan Sector33 0.3175 0.0686 4.6271 0.0000 1.3737 37.3723 Signifikan
state peminjam: FL dibanding state acuan BorrStateFL 0.6110 0.1459 4.1865 0.0000 1.8423 84.2283 Signifikan
state peminjam: VT dibanding state acuan BorrStateVT -0.7354 0.1822 -4.0356 0.0001 0.4793 -52.0682 Signifikan

9.10 Evaluasi Model Poisson

AIC_poisson <- AIC(model_poisson)
AIC_poisson
## [1] 102778.3
dispersion_poisson <- deviance(model_poisson) / df.residual(model_poisson)
dispersion_poisson
## [1] 0.5987723
if (dispersion_poisson > 1.5) {
  cat("Terdapat indikasi overdispersion. Inferensi p-value sebaiknya dilihat juga menggunakan quasi-Poisson.\n")
} else {
  cat("Tidak ada indikasi overdispersion yang kuat berdasarkan rasio deviance/df residual.\n")
}
## Tidak ada indikasi overdispersion yang kuat berdasarkan rasio deviance/df residual.

9.11 Pemeriksaan Overdispersion dengan Pearson Dispersion

Selain rasio deviance terhadap derajat bebas residual, overdispersion juga dapat diperiksa menggunakan Pearson dispersion.

\[ \hat{\phi} = \frac{\sum r_{P,i}^2}{df} \]

Jika nilai dispersion jauh lebih besar dari 1, maka terdapat indikasi overdispersion.

pearson_dispersion <- sum(residuals(model_poisson, type = "pearson")^2) /
  df.residual(model_poisson)

tibble::tibble(
  Ukuran = "Pearson dispersion",
  Nilai = pearson_dispersion,
  Interpretasi = dplyr::case_when(
    pearson_dispersion < 1.5 ~ "Tidak ada indikasi overdispersion berat",
    pearson_dispersion < 2.5 ~ "Ada indikasi overdispersion sedang",
    TRUE ~ "Ada indikasi overdispersion kuat"
  )
) %>%
  dplyr::mutate(Nilai = round(Nilai, 3)) %>%
  knitr::kable(caption = "Pemeriksaan Overdispersion dengan Pearson Dispersion")
Pemeriksaan Overdispersion dengan Pearson Dispersion
Ukuran Nilai Interpretasi
Pearson dispersion 1.148 Tidak ada indikasi overdispersion berat

Jika nilai Pearson dispersion jauh lebih besar dari 1, maka variasi jumlah pinjaman bermasalah lebih besar daripada yang diasumsikan oleh model Poisson. Dalam kondisi tersebut, hasil signifikansi dari model Poisson standar perlu dibaca hati-hati dan model quasi-Poisson lebih aman digunakan sebagai pembanding.

model_quasipoisson <- glm(
  Jumlah_ChargedOff ~ ApprovalFY + BorrState + Sector +
    Loan_Size_Band + Term_Band + BusinessType + CollateralInd +
    offset(log(Total_Loan)),
  data = data_poisson_agg,
  family = quasipoisson(link = "log")
)

tabel_quasipoisson <- broom::tidy(model_quasipoisson) %>%
  dplyr::mutate(
    Incidence_Rate_Ratio = exp(estimate),
    Perubahan_Persen = 100 * (Incidence_Rate_Ratio - 1),
    Variabel_Mudah = purrr::map_chr(term, label_poisson),
    Keputusan_5persen = ifelse(p.value < 0.05, "Signifikan", "Tidak signifikan")
  ) %>%
  dplyr::arrange(p.value)

knitr::kable(
  tabel_quasipoisson %>% dplyr::select(Variabel_Mudah, term, estimate, std.error, statistic, p.value, Incidence_Rate_Ratio, Perubahan_Persen, Keputusan_5persen) %>% head(35),
  digits = 4,
  caption = "Koefisien dan IRR Quasi-Poisson"
)
Koefisien dan IRR Quasi-Poisson
Variabel_Mudah term estimate std.error statistic p.value Incidence_Rate_Ratio Perubahan_Persen Keputusan_5persen
tenor pinjaman: Medium dibanding tenor pendek Term_BandMedium -1.5541 0.0132 -117.4643 0.0000 0.2114 -78.8622 Signifikan
tenor pinjaman: Long dibanding tenor pendek Term_BandLong -2.4489 0.0300 -81.7116 0.0000 0.0864 -91.3612 Signifikan
status agunan: No_Collateral dibanding kategori acuan CollateralIndNo_Collateral 0.3910 0.0142 27.5805 0.0000 1.4784 47.8387 Signifikan
ukuran pinjaman: Medium dibanding pinjaman kecil Loan_Size_BandMedium 0.2942 0.0144 20.4159 0.0000 1.3420 34.2034 Signifikan
ukuran pinjaman: Large dibanding pinjaman kecil Loan_Size_BandLarge 0.4394 0.0216 20.3059 0.0000 1.5517 55.1747 Signifikan
(Intercept) (Intercept) -2.4695 0.1691 -14.6008 0.0000 0.0846 -91.5371 Signifikan
sektor industri: 71 dibanding sektor acuan Sector71 0.8579 0.0724 11.8513 0.0000 2.3583 135.8283 Signifikan
sektor industri: 72 dibanding sektor acuan Sector72 0.7944 0.0673 11.8124 0.0000 2.2131 121.3112 Signifikan
sektor industri: 45 dibanding sektor acuan Sector45 0.7635 0.0708 10.7781 0.0000 2.1458 114.5786 Signifikan
tahun persetujuan: 2018 dibanding tahun acuan ApprovalFY2018 0.2755 0.0263 10.4826 0.0000 1.3172 31.7181 Signifikan
sektor industri: 44 dibanding sektor acuan Sector44 0.6936 0.0678 10.2259 0.0000 2.0010 100.1000 Signifikan
tahun persetujuan: 2013 dibanding tahun acuan ApprovalFY2013 -0.2928 0.0308 -9.4965 0.0000 0.7462 -25.3821 Signifikan
tahun persetujuan: 2012 dibanding tahun acuan ApprovalFY2012 -0.2940 0.0310 -9.4853 0.0000 0.7453 -25.4695 Signifikan
sektor industri: 81 dibanding sektor acuan Sector81 0.6219 0.0683 9.1095 0.0000 1.8624 86.2408 Signifikan
tahun persetujuan: 2019 dibanding tahun acuan ApprovalFY2019 0.2433 0.0285 8.5276 0.0000 1.2755 27.5476 Signifikan
tahun persetujuan: 2011 dibanding tahun acuan ApprovalFY2011 -0.2421 0.0291 -8.3199 0.0000 0.7850 -21.5015 Signifikan
sektor industri: 61 dibanding sektor acuan Sector61 0.6530 0.0822 7.9435 0.0000 1.9213 92.1300 Signifikan
sektor industri: 23 dibanding sektor acuan Sector23 0.5321 0.0676 7.8675 0.0000 1.7026 70.2555 Signifikan
jenis usaha: PARTNERSHIP dibanding kategori acuan BusinessTypePARTNERSHIP -0.4605 0.0602 -7.6535 0.0000 0.6310 -36.9017 Signifikan
tahun persetujuan: 2017 dibanding tahun acuan ApprovalFY2017 0.1847 0.0262 7.0559 0.0000 1.2028 20.2801 Signifikan
sektor industri: 42 dibanding sektor acuan Sector42 0.4822 0.0700 6.8891 0.0000 1.6196 61.9563 Signifikan
tahun persetujuan: 2014 dibanding tahun acuan ApprovalFY2014 -0.1973 0.0289 -6.8288 0.0000 0.8210 -17.9029 Signifikan
sektor industri: 31 dibanding sektor acuan Sector31 0.5278 0.0786 6.7112 0.0000 1.6952 69.5205 Signifikan
sektor industri: 56 dibanding sektor acuan Sector56 0.4726 0.0709 6.6641 0.0000 1.6041 60.4118 Signifikan
sektor industri: 54 dibanding sektor acuan Sector54 0.4073 0.0685 5.9450 0.0000 1.5028 50.2794 Signifikan
sektor industri: 51 dibanding sektor acuan Sector51 0.4854 0.0857 5.6650 0.0000 1.6249 62.4878 Signifikan
sektor industri: 48 dibanding sektor acuan Sector48 0.3712 0.0698 5.3212 0.0000 1.4495 44.9477 Signifikan
sektor industri: 32 dibanding sektor acuan Sector32 0.4077 0.0810 5.0332 0.0000 1.5033 50.3305 Signifikan
state peminjam: ND dibanding state acuan BorrStateND -1.0127 0.2156 -4.6977 0.0000 0.3632 -63.6773 Signifikan
sektor industri: 53 dibanding sektor acuan Sector53 0.3679 0.0816 4.5084 0.0000 1.4447 44.4673 Signifikan
state peminjam: MT dibanding state acuan BorrStateMT -0.8811 0.1966 -4.4812 0.0000 0.4143 -58.5672 Signifikan
sektor industri: 49 dibanding sektor acuan Sector49 0.5229 0.1169 4.4734 0.0000 1.6869 68.6918 Signifikan
sektor industri: 33 dibanding sektor acuan Sector33 0.3175 0.0735 4.3192 0.0000 1.3737 37.3723 Signifikan
state peminjam: FL dibanding state acuan BorrStateFL 0.6110 0.1563 3.9080 0.0001 1.8423 84.2283 Signifikan
state peminjam: VT dibanding state acuan BorrStateVT -0.7354 0.1952 -3.7671 0.0002 0.4793 -52.0682 Signifikan
data_poisson_agg$fitted_poisson <- fitted(model_poisson)

ggplot(data_poisson_agg, aes(x = fitted_poisson, y = Jumlah_ChargedOff)) +
  geom_point(alpha = 0.35) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed") +
  labs(
    title = "Observed vs Fitted Jumlah Pinjaman Bermasalah",
    x = "Nilai fitted model",
    y = "Jumlah pinjaman bermasalah aktual"
  ) +
  theme_minimal()

9.12 Visualisasi Prediksi Rate Pinjaman Bermasalah

Visualisasi ini digunakan untuk melihat prediksi rate pinjaman bermasalah berdasarkan ukuran pinjaman dan tenor. Pada grafik ini, exposure ditetapkan sebesar 1 agar hasil yang ditampilkan dapat dibaca sebagai rate.

grid_poisson <- expand.grid(
  ApprovalFY = factor(modus(data_poisson_agg$ApprovalFY), levels = levels(data_poisson_agg$ApprovalFY)),
  BorrState = factor(modus(data_poisson_agg$BorrState), levels = levels(data_poisson_agg$BorrState)),
  Sector = factor(modus(data_poisson_agg$Sector), levels = levels(data_poisson_agg$Sector)),
  Loan_Size_Band = factor(levels(data_poisson_agg$Loan_Size_Band), levels = levels(data_poisson_agg$Loan_Size_Band)),
  Term_Band = factor(levels(data_poisson_agg$Term_Band), levels = levels(data_poisson_agg$Term_Band)),
  BusinessType = factor(modus(data_poisson_agg$BusinessType), levels = levels(data_poisson_agg$BusinessType)),
  CollateralInd = factor(modus(data_poisson_agg$CollateralInd), levels = levels(data_poisson_agg$CollateralInd)),
  Total_Loan = 1
)

pred_rate_poisson <- predict(
  model_poisson,
  newdata = grid_poisson,
  type = "link",
  se.fit = TRUE
)

grid_poisson_plot <- grid_poisson %>%
  dplyr::mutate(
    fit_link = pred_rate_poisson$fit,
    se_link = pred_rate_poisson$se.fit,
    Predicted_Rate = exp(fit_link),
    Rate_Lower = exp(fit_link - 1.96 * se_link),
    Rate_Upper = exp(fit_link + 1.96 * se_link)
  )

ggplot(
  grid_poisson_plot,
  aes(x = Loan_Size_Band, y = Predicted_Rate, fill = Term_Band)
) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  geom_errorbar(
    aes(ymin = Rate_Lower, ymax = Rate_Upper),
    position = position_dodge(width = 0.8),
    width = 0.2
  ) +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(
    title = "Prediksi Rate Pinjaman Bermasalah",
    subtitle = "Exposure ditetapkan 1; variabel lain ditahan pada kategori paling umum",
    x = "Ukuran Pinjaman",
    y = "Prediksi rate pinjaman bermasalah",
    fill = "Tenor"
  ) +
  theme_minimal()

Grafik ini menunjukkan perbedaan prediksi rate pinjaman bermasalah menurut ukuran pinjaman dan tenor, dengan variabel lain ditahan pada kategori paling umum. Jika batang pada kategori tertentu lebih tinggi, maka kelompok tersebut diprediksi memiliki rate pinjaman bermasalah yang lebih tinggi.

9.13 Interpretasi dan Kesimpulan Model Poisson

if (dispersion_poisson > 1.5) {
  tabel_pakai_poisson <- tabel_quasipoisson
  metode_pakai <- "quasi-Poisson"
} else {
  tabel_pakai_poisson <- tabel_poisson
  metode_pakai <- "Poisson"
}

sig_poisson <- tabel_pakai_poisson %>%
  dplyr::filter(term != "(Intercept)", p.value < 0.05) %>%
  dplyr::arrange(p.value)

cat("Rasio deviance/df residual adalah **", fmt_num(dispersion_poisson, 3), "**. ", sep = "")

Rasio deviance/df residual adalah 0.599.

if (dispersion_poisson > 1.5) {
  cat("Nilai ini menunjukkan overdispersion, sehingga interpretasi signifikansi lebih aman mengacu pada model quasi-Poisson.\n\n")
} else {
  cat("Nilai ini tidak menunjukkan overdispersion yang kuat, sehingga model Poisson standar masih memadai sebagai model awal.\n\n")
}

Nilai ini tidak menunjukkan overdispersion yang kuat, sehingga model Poisson standar masih memadai sebagai model awal.

cat("Dengan acuan inferensi ", metode_pakai, ", terdapat ", nrow(sig_poisson),
    " prediktor signifikan pada taraf 5%.\n\n", sep = "")

Dengan acuan inferensi Poisson, terdapat 56 prediktor signifikan pada taraf 5%.

if (nrow(sig_poisson) > 0) {
  cat("Prediktor paling penting berdasarkan p-value terkecil adalah:\n\n")
  top_poisson <- head(sig_poisson, 10)
  for (i in seq_len(nrow(top_poisson))) {
    row <- top_poisson[i, ]
    arah <- ifelse(row$Incidence_Rate_Ratio > 1,
                   "memiliki rate pinjaman bermasalah yang lebih tinggi",
                   "memiliki rate pinjaman bermasalah yang lebih rendah")
    cat("- **", row$Variabel_Mudah, "** memiliki IRR = ", fmt_num(row$Incidence_Rate_Ratio, 3),
        " dengan perubahan sekitar ", fmt_num(row$Perubahan_Persen, 2), "%",
        " dan p-value = ", fmt_p(row$p.value), ", sehingga kelompok ini ", arah,
        ", dengan asumsi variabel lain tetap.\n", sep = "")
  }
  cat("\n")
}

Prediktor paling penting berdasarkan p-value terkecil adalah:

  • tenor pinjaman: Medium dibanding tenor pendek memiliki IRR = 0.211 dengan perubahan sekitar -78.86% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih rendah, dengan asumsi variabel lain tetap.
  • tenor pinjaman: Long dibanding tenor pendek memiliki IRR = 0.086 dengan perubahan sekitar -91.36% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih rendah, dengan asumsi variabel lain tetap.
  • status agunan: No_Collateral dibanding kategori acuan memiliki IRR = 1.478 dengan perubahan sekitar 47.84% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • ukuran pinjaman: Medium dibanding pinjaman kecil memiliki IRR = 1.342 dengan perubahan sekitar 34.20% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • ukuran pinjaman: Large dibanding pinjaman kecil memiliki IRR = 1.552 dengan perubahan sekitar 55.17% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • sektor industri: 71 dibanding sektor acuan memiliki IRR = 2.358 dengan perubahan sekitar 135.83% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • sektor industri: 72 dibanding sektor acuan memiliki IRR = 2.213 dengan perubahan sekitar 121.31% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • sektor industri: 45 dibanding sektor acuan memiliki IRR = 2.146 dengan perubahan sekitar 114.58% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • tahun persetujuan: 2018 dibanding tahun acuan memiliki IRR = 1.317 dengan perubahan sekitar 31.72% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
  • sektor industri: 44 dibanding sektor acuan memiliki IRR = 2.001 dengan perubahan sekitar 100.10% dan p-value = < 0.001, sehingga kelompok ini memiliki rate pinjaman bermasalah yang lebih tinggi, dengan asumsi variabel lain tetap.
cat("AIC model Poisson adalah **", fmt_num(AIC_poisson, 2), "**.\n\n", sep = "")

AIC model Poisson adalah 102,778.27.

cat("**Kesimpulan substantif:** jumlah pinjaman bermasalah pada data SBA 7(a) tidak hanya dipengaruhi oleh banyaknya pinjaman dalam kelompok, tetapi juga oleh karakteristik kelompok seperti tahun persetujuan, state peminjam, sektor industri, ukuran pinjaman, tenor, jenis usaha, dan status agunan. Penggunaan offset `Total_Loan` membuat kesimpulan berfokus pada rate pinjaman bermasalah, bukan jumlah mentah.\n")

Kesimpulan substantif: jumlah pinjaman bermasalah pada data SBA 7(a) tidak hanya dipengaruhi oleh banyaknya pinjaman dalam kelompok, tetapi juga oleh karakteristik kelompok seperti tahun persetujuan, state peminjam, sektor industri, ukuran pinjaman, tenor, jenis usaha, dan status agunan. Penggunaan offset Total_Loan membuat kesimpulan berfokus pada rate pinjaman bermasalah, bukan jumlah mentah.

10 Perbandingan Empat Model

Model Respon Fungsi link Ukuran interpretasi Evaluasi utama
Logistik biner Gagal bayar 0/1 Logit Odds ratio Confusion matrix, AIC, ROC/AUC
Ordinal Grade A-G Cumulative logit dengan spesifikasi MASS::polr: logit(P(Y <= j)) = alpha_j - x beta exp(beta) sebagai odds ratio menuju grade lebih tinggi Confusion matrix, AIC, proportional odds check
Multinomial Status pinjaman Baseline-category logit Relative risk ratio Confusion matrix, AIC, prediksi probabilitas, catatan IIA
Poisson Jumlah pinjaman bermasalah Log Incidence rate ratio dan perubahan persen AIC, deviance dispersion, Pearson dispersion, overdispersion

11 Kesimpulan Umum

cat("Berdasarkan empat analisis yang dilakukan, setiap model menjawab bagian risiko kredit yang berbeda.\n\n")

Berdasarkan empat analisis yang dilakukan, setiap model menjawab bagian risiko kredit yang berbeda.

cat("- **Model biner** menjelaskan peluang nasabah kartu kredit mengalami gagal bayar. Model ini cocok karena respon hanya terdiri dari dua kategori, yaitu gagal bayar dan tidak gagal bayar.\n")
  • Model biner menjelaskan peluang nasabah kartu kredit mengalami gagal bayar. Model ini cocok karena respon hanya terdiri dari dua kategori, yaitu gagal bayar dan tidak gagal bayar.
cat("- **Model ordinal** menjelaskan tingkat risiko pinjaman Lending Club berdasarkan grade A sampai G. Model ini cocok karena grade memiliki urutan risiko.\n")
  • Model ordinal menjelaskan tingkat risiko pinjaman Lending Club berdasarkan grade A sampai G. Model ini cocok karena grade memiliki urutan risiko.
cat("- **Model multinomial** menjelaskan status pinjaman Prosper. Model ini cocok karena status pinjaman memiliki beberapa kategori yang tidak diperlakukan sebagai urutan.\n")
  • Model multinomial menjelaskan status pinjaman Prosper. Model ini cocok karena status pinjaman memiliki beberapa kategori yang tidak diperlakukan sebagai urutan.
cat("- **Model Poisson** menjelaskan jumlah pinjaman SBA 7(a) yang bermasalah pada setiap kelompok pinjaman. Model ini cocok karena respon berupa hitungan kejadian.\n\n")
  • Model Poisson menjelaskan jumlah pinjaman SBA 7(a) yang bermasalah pada setiap kelompok pinjaman. Model ini cocok karena respon berupa hitungan kejadian.
cat("Secara keseluruhan, analisis ini menunjukkan bahwa regresi untuk data kategori dan data hitungan dapat digunakan dalam konteks risk management. Model biner berguna untuk peluang gagal bayar, model ordinal untuk tingkat risiko, model multinomial untuk status pinjaman, dan model Poisson untuk jumlah kejadian pinjaman bermasalah.\n")

Secara keseluruhan, analisis ini menunjukkan bahwa regresi untuk data kategori dan data hitungan dapat digunakan dalam konteks risk management. Model biner berguna untuk peluang gagal bayar, model ordinal untuk tingkat risiko, model multinomial untuk status pinjaman, dan model Poisson untuk jumlah kejadian pinjaman bermasalah.