DSEB
NHÓM 7
Nguyễn Thị Kim Anh 11210617
Nguyễn Thị Kim Anh 11216984
Lê Thị Thu Hà 11211884
Phạm Thị Thu Hương 11216994
Trần Thị Phương Nguyên 11214476
options(repos = "https://cloud.r-project.org/")
# Load some packages for data manipulation:
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.2
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
## Warning: package 'readr' was built under R version 4.3.3
library(Amelia)
## Warning: package 'Amelia' was built under R version 4.3.3
## Loading required package: Rcpp
## ##
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.1, built: 2022-11-18)
## ## Copyright (C) 2005-2024 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
##
## Attaching package: 'plyr'
## The following objects are masked from 'package:dplyr':
##
## arrange, count, desc, failwith, id, mutate, rename, summarise,
## summarize
library(tables)
## Warning: package 'tables' was built under R version 4.3.3
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.2
## Warning: package 'forcats' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ plyr::arrange() masks dplyr::arrange()
## ✖ purrr::compact() masks plyr::compact()
## ✖ plyr::count() masks dplyr::count()
## ✖ plyr::desc() masks dplyr::desc()
## ✖ plyr::failwith() masks dplyr::failwith()
## ✖ dplyr::filter() masks stats::filter()
## ✖ plyr::id() masks dplyr::id()
## ✖ dplyr::lag() masks stats::lag()
## ✖ plyr::mutate() masks dplyr::mutate()
## ✖ plyr::rename() masks dplyr::rename()
## ✖ plyr::summarise() masks dplyr::summarise()
## ✖ plyr::summarize() masks dplyr::summarize()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(Amelia)
library(car)
## Warning: package 'car' was built under R version 4.3.2
## Loading required package: carData
##
## Attaching package: 'car'
##
## The following object is masked from 'package:purrr':
##
## some
##
## The following object is masked from 'package:dplyr':
##
## recode
library(psych)
## Warning: package 'psych' was built under R version 4.3.2
##
## Attaching package: 'psych'
##
## The following object is masked from 'package:car':
##
## logit
##
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.3.3
## corrplot 0.92 loaded
library(nnet)
library(caTools)
library(ROCR)
## Warning: package 'ROCR' was built under R version 4.3.3
library(ggplot2)
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.3.3
library(ggmosaic)
## Warning: package 'ggmosaic' was built under R version 4.3.3
I. TỔNG QUAN DỮ LIỆU
Giới thiệu chung
Sử dụng tập dữ liệu ” HMEQ” bao gồm 13 biến, với 5960 quan sát
Nguồn: Dữ liệu được lấy trên trang Kaggle
Các biến sử dụng trong tập dữ liệu
| BAD | Tình trạng khách hàng 0= Khách hàng trả được nợ( không nợ xấu) 1= Khách hàng nợ xấu |
|---|---|
| LOAN | Số tiền khách hàng yêu cầu vay |
| MORTDUE | Số tiền phải trả cho khoản thế chấp hiện tại |
| VALUE | Giá trị hiện tại của tài sản( ngôi nhà) |
| REASON | Lý do yêu cầu vay Homelmp= sửa nhà DebtCon= gộp nợ |
| JOB | Nghề nghiệp |
| YOJ | Thời gian làm việc của khách hàng( đơn vị: năm) |
| DEROG | Số lượng ghi chép vào lịch sử tín dụng xấu |
| DELINQ | Số lượng khoản vay quá hạn |
| CLAGE | Thời gian của hạn mức tín dụng cũ nhất( đơn vị: tháng) |
| NINQ | Sô lượng tra cứu tín dụng gần đây |
| CLNO | Số lượng hạn mức tín dụng hiện tại |
| DEBTINC | Tỷ lệ nợ trên thu nhập |
Thống kê dữ liệu
# Import data:
library(readr)
data <- read_csv("C:/Users/pc/Downloads/hmeq.csv")
## Rows: 5960 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): REASON, JOB
## dbl (11): BAD, LOAN, MORTDUE, VALUE, YOJ, DEROG, DELINQ, CLAGE, NINQ, CLNO, ...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
### Descriptive statistic
summary(data)
## BAD LOAN MORTDUE VALUE
## Min. :0.0000 Min. : 1100 Min. : 2063 Min. : 8000
## 1st Qu.:0.0000 1st Qu.:11100 1st Qu.: 46276 1st Qu.: 66076
## Median :0.0000 Median :16300 Median : 65019 Median : 89236
## Mean :0.1995 Mean :18608 Mean : 73761 Mean :101776
## 3rd Qu.:0.0000 3rd Qu.:23300 3rd Qu.: 91488 3rd Qu.:119824
## Max. :1.0000 Max. :89900 Max. :399550 Max. :855909
## NA's :518 NA's :112
## REASON JOB YOJ DEROG
## Length:5960 Length:5960 Min. : 0.000 Min. : 0.0000
## Class :character Class :character 1st Qu.: 3.000 1st Qu.: 0.0000
## Mode :character Mode :character Median : 7.000 Median : 0.0000
## Mean : 8.922 Mean : 0.2546
## 3rd Qu.:13.000 3rd Qu.: 0.0000
## Max. :41.000 Max. :10.0000
## NA's :515 NA's :708
## DELINQ CLAGE NINQ CLNO
## Min. : 0.0000 Min. : 0.0 Min. : 0.000 Min. : 0.0
## 1st Qu.: 0.0000 1st Qu.: 115.1 1st Qu.: 0.000 1st Qu.:15.0
## Median : 0.0000 Median : 173.5 Median : 1.000 Median :20.0
## Mean : 0.4494 Mean : 179.8 Mean : 1.186 Mean :21.3
## 3rd Qu.: 0.0000 3rd Qu.: 231.6 3rd Qu.: 2.000 3rd Qu.:26.0
## Max. :15.0000 Max. :1168.2 Max. :17.000 Max. :71.0
## NA's :580 NA's :308 NA's :510 NA's :222
## DEBTINC
## Min. : 0.5245
## 1st Qu.: 29.1400
## Median : 34.8183
## Mean : 33.7799
## 3rd Qu.: 39.0031
## Max. :203.3121
## NA's :1267
head(data)
## # A tibble: 6 × 13
## BAD LOAN MORTDUE VALUE REASON JOB YOJ DEROG DELINQ CLAGE NINQ CLNO
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 1100 25860 39025 HomeImp Other 10.5 0 0 94.4 1 9
## 2 1 1300 70053 68400 HomeImp Other 7 0 2 122. 0 14
## 3 1 1500 13500 16700 HomeImp Other 4 0 0 149. 1 10
## 4 1 1500 NA NA <NA> <NA> NA NA NA NA NA NA
## 5 0 1700 97800 112000 HomeImp Office 3 0 0 93.3 0 14
## 6 1 1700 30548 40320 HomeImp Other 9 0 0 101. 1 8
## # ℹ 1 more variable: DEBTINC <dbl>
str(data)
## spc_tbl_ [5,960 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ BAD : num [1:5960] 1 1 1 1 0 1 1 1 1 1 ...
## $ LOAN : num [1:5960] 1100 1300 1500 1500 1700 1700 1800 1800 2000 2000 ...
## $ MORTDUE: num [1:5960] 25860 70053 13500 NA 97800 ...
## $ VALUE : num [1:5960] 39025 68400 16700 NA 112000 ...
## $ REASON : chr [1:5960] "HomeImp" "HomeImp" "HomeImp" NA ...
## $ JOB : chr [1:5960] "Other" "Other" "Other" NA ...
## $ YOJ : num [1:5960] 10.5 7 4 NA 3 9 5 11 3 16 ...
## $ DEROG : num [1:5960] 0 0 0 NA 0 0 3 0 0 0 ...
## $ DELINQ : num [1:5960] 0 2 0 NA 0 0 2 0 2 0 ...
## $ CLAGE : num [1:5960] 94.4 121.8 149.5 NA 93.3 ...
## $ NINQ : num [1:5960] 1 0 1 NA 0 1 1 0 1 0 ...
## $ CLNO : num [1:5960] 9 14 10 NA 14 8 17 8 12 13 ...
## $ DEBTINC: num [1:5960] NA NA NA NA NA ...
## - attr(*, "spec")=
## .. cols(
## .. BAD = col_double(),
## .. LOAN = col_double(),
## .. MORTDUE = col_double(),
## .. VALUE = col_double(),
## .. REASON = col_character(),
## .. JOB = col_character(),
## .. YOJ = col_double(),
## .. DEROG = col_double(),
## .. DELINQ = col_double(),
## .. CLAGE = col_double(),
## .. NINQ = col_double(),
## .. CLNO = col_double(),
## .. DEBTINC = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
table(data$JOB)
##
## Mgr Office Other ProfExe Sales Self
## 767 948 2388 1276 109 193
Tại tập dữ liệu này, biến ” BAD” là biến mục tiêu sẽ sử dụng trong bài báo cáo, mục đích hướng tới là quan sát thống kê các ảnh hưởng, sử tương quan của các biến khác tới biến mục tiêu. Cụ thể, biến “BAD” bao gồm giá trị 0 và 1
Trong đó:
1- Không có khả năng trả nợ
0- Có khả năng trả nợ
II. XỬ LÝ DỮ LIỆU
#sapply(data, function(data) sum(is.na(data)))
colSums(is.na(data))
## BAD LOAN MORTDUE VALUE REASON JOB YOJ DEROG DELINQ CLAGE
## 0 0 518 112 252 279 515 708 580 308
## NINQ CLNO DEBTINC
## 510 222 1267
sum(is.na(data))
## [1] 5271
attach(data)
library(Amelia)
missmap(data, col = c("brown", "pink"), legend = TRUE)
## Warning: Unknown or uninitialised column: `arguments`.
## Unknown or uninitialised column: `arguments`.
## Warning: Unknown or uninitialised column: `imputations`.
Ta thấy số lượng Missing data tương đối nhiều ( điển hình biến debtinc lên tới 1267 giá trị bị thiếu), chiếm phần lớn so với tổng quan sát mà chúng ta sử dụng. Do vậy, chúng ta sẽ không xóa toàn bộ các giá trị thiếu, mà sẽ thay thế các NA thành giá trị như mean, mode và median. Cụ thể thay thế như thế nào, ta sẽ sử dụng đồ thị Histogram để xác định. Dưới đây là histogram cho từng biến
# Vẽ histogram cho biến DEBTINC
hist(data$DEBTINC, main = "Histogram of DEBTINC", xlab = "DEBTINC", ylab = "Frequency", col = "skyblue", border = "black")
# Vẽ histogram cho biến NINQ
hist(data$NINQ, main = "Histogram of NINQ", xlab = "NINQ", ylab = "Frequency", col = "skyblue", border = "black")
#DEROG
hist(data$DEROG, main = "Histogram of DEROG", xlab = "DEROG", ylab = "Frequency", col = "skyblue", border = "black")
#VALUE
hist(data$VALUE, main = "Histogram of VALUE", xlab = "VALUE", ylab = "Frequency", col = "skyblue", border = "black")
#CLNO
hist(data$CLNO, main = "Histogram of CLNO", xlab = "CLNO", ylab = "Frequency", col = "skyblue", border = "black")
#CLAGE
hist(data$CLAGE, main = "Histogram of CLAGE", xlab = "CLAGE", ylab = "Frequency", col = "skyblue", border = "black")
#YOJ
hist(data$YOJ, main = "Histogram of YOJ", xlab = "YOJ", ylab = "Frequency", col = "skyblue", border = "black")
#DELINQ
hist(data$DELINQ, main = "Histogram of DELINQ", xlab = "DELINQ", ylab = "Frequency", col = "skyblue", border = "black")
#LOAN
hist(data$LOAN, main = "Histogram of LOAN", xlab = "LOAN", ylab = "Frequency", col = "skyblue", border = "black")
#MORTDUE
hist(data$MORTDUE, main = "Histogram of MORYDUE", xlab = "MORTDUE", ylab = "Frequency", col = "skyblue", border = "black")
Trong đó biến JOB sẽ thay thế bằng giá trị mode, và các biến còn lại thay thế bằng giá trị median
# Điền vào giá trị null của biến REASON bằng "Other reason"
data$REASON[is.na(data$REASON)] <- "Other reason"
# Điền vào giá trị null của biến JOB bằng giá trị mode
library(dplyr)
mode_job <- data$JOB %>% na.omit() %>%table() %>% names() %>% as.character() %>%
.[which.max(table(.))]
data <- data %>%
mutate(JOB = ifelse(is.na(JOB), mode_job, JOB))
# Thay thế các giá trị NA của biến JOB bằng mode_value
data$JOB[is.na(data$JOB)] <- mode_job
# DEROG
data <- data %>%
mutate(DEROG = ifelse(is.na(DEROG), median(DEROG, na.rm = TRUE), DEROG))
# DELINQ
data <- data %>%
mutate(DELINQ = ifelse(is.na(DELINQ), median(DELINQ, na.rm = TRUE), DELINQ))
##
median(data$MORTDUE, na.rm = TRUE)
## [1] 65019
data<- data %>%
mutate(MORTDUE = ifelse(is.na(MORTDUE), median(MORTDUE, na.rm = TRUE), MORTDUE))
##YOJ
data <- data %>%
mutate(YOJ = ifelse(is.na(YOJ), median(YOJ, na.rm = TRUE), YOJ))
## CLNO
data <- data %>%
mutate(CLNO = ifelse(is.na(CLNO), median(CLNO, na.rm = TRUE), CLNO))
## CLAGE
data <- data %>%
mutate(CLAGE = ifelse(is.na(CLAGE), median(CLAGE, na.rm = TRUE), CLAGE))
## NINQ
data <- data %>%
mutate(NINQ = ifelse(is.na(NINQ), median(CLNO, na.rm = TRUE), NINQ))
##DEBTINC
data <- data %>%
mutate(DEBTINC = ifelse(is.na(DEBTINC), median(DEBTINC, na.rm = TRUE), DEBTINC))
#VALUE
data <- data %>%
mutate(VALUE = ifelse(is.na(VALUE), median(VALUE, na.rm = TRUE), VALUE))
head(data)
## # A tibble: 6 × 13
## BAD LOAN MORTDUE VALUE REASON JOB YOJ DEROG DELINQ CLAGE NINQ CLNO
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 1100 25860 39025 HomeImp Other 10.5 0 0 94.4 1 9
## 2 1 1300 70053 68400 HomeImp Other 7 0 2 122. 0 14
## 3 1 1500 13500 16700 HomeImp Other 4 0 0 149. 1 10
## 4 1 1500 65019 89236. Other … Mgr 7 0 0 173. 20 20
## 5 0 1700 97800 112000 HomeImp Offi… 3 0 0 93.3 0 14
## 6 1 1700 30548 40320 HomeImp Other 9 0 0 101. 1 8
## # ℹ 1 more variable: DEBTINC <dbl>
colSums(is.na(data))
## BAD LOAN MORTDUE VALUE REASON JOB YOJ DEROG DELINQ CLAGE
## 0 0 0 0 0 0 0 0 0 0
## NINQ CLNO DEBTINC
## 0 0 0
missmap(data, col = c("brown", "pink"), legend = TRUE)
## Warning: Unknown or uninitialised column: `arguments`.
## Unknown or uninitialised column: `arguments`.
## Warning: Unknown or uninitialised column: `imputations`.
Sau khi thay thế các giá trị NA thành giá trị mode và median, kiểm tra lại các giá trị còn thiếu, đây là kết quả sau cùng, chúng ta đã xử lý được các giá trị thiếu.
par(mfrow = c(2,3))
boxplot(data$LOAN, main = "LOAN")
boxplot(data$MORTDUE, main = "MORTDUE")
boxplot(data$VALUE, main = "VALUE")
boxplot(data$YOJ, main = "YOJ")
boxplot(data$DEROG, main = "DEROG")
boxplot(data$DELINQ, main = "DELINQ")
boxplot(data$CLAGE, main = "CLAGE")
boxplot(data$NINQ, main = "NINQ")
boxplot(data$CLNO, main = "CLNO")
boxplot(data$DEBTINC, main = "DEBTINC")
summary(LOAN)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1100 11100 16300 18608 23300 89900
minLOAN=quantile(LOAN,probs=0.25) - 1.5*IQR(LOAN)
maxLOAN=quantile(LOAN,probs=0.75) + 1.5*IQR(LOAN)
LOAN[LOAN> maxLOAN|LOAN<minLOAN]= mean(LOAN)
boxplot(LOAN)
summary(MORTDUE)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 2063 46276 65019 73761 91488 399550 518
minMORTDUE= quantile(MORTDUE, probs = 0.25, na.rm = TRUE) - 1.5 * IQR(MORTDUE, na.rm = TRUE)
maxMORTDUE= quantile(MORTDUE, probs = 0.75, na.rm = TRUE) + 1.5 * IQR(MORTDUE, na.rm = TRUE)
MORTDUE[MORTDUE> maxMORTDUE|MORTDUE<minLOAN]= mean(MORTDUE)
boxplot(MORTDUE)
summary(VALUE)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 8000 66076 89236 101776 119824 855909 112
minVALUE=quantile(VALUE,probs=0.25, na.rm = TRUE) - 1.5*IQR(VALUE, na.rm = TRUE)
maxVALUE=quantile(VALUE,probs=0.75, na.rm = TRUE) + 1.5*IQR(VALUE, na.rm = TRUE)
VALUE[VALUE> maxVALUE|VALUE<minVALUE]= mean(VALUE)
boxplot(VALUE)
summary(CLAGE)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0 115.1 173.5 179.8 231.6 1168.2 308
minCLAGE=quantile(CLAGE,probs=0.25, na.rm = TRUE) - 1.5*IQR(CLAGE, na.rm = TRUE)
maxCLAGE=quantile(CLAGE,probs=0.75, na.rm = TRUE) + 1.5*IQR(CLAGE, na.rm = TRUE)
CLAGE[CLAGE> maxCLAGE|CLAGE<minCLAGE]= mean(CLAGE)
boxplot(CLAGE)
summary(DEBTINC)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.5245 29.1400 34.8183 33.7799 39.0031 203.3121 1267
minDEBTINC=quantile(DEBTINC,probs=0.25, na.rm = TRUE) - 1.5*IQR(DEBTINC, na.rm = TRUE)
maxDEBTINC=quantile(DEBTINC,probs=0.75, na.rm = TRUE) + 1.5*IQR(DEBTINC, na.rm = TRUE)
DEBTINC[DEBTINC>maxDEBTINC|DEBTINC<minDEBTINC]= mean(DEBTINC)
boxplot(DEBTINC)
##
summary(YOJ)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.000 3.000 7.000 8.922 13.000 41.000 515
minYOJ=quantile(YOJ,probs=0.25, na.rm = TRUE) - 1.5*IQR(YOJ, na.rm = TRUE)
maxYOJ=quantile(YOJ,probs=0.75, na.rm = TRUE) + 1.5*IQR(YOJ, na.rm = TRUE)
YOJ[YOJ> maxYOJ|YOJ<minLOAN]= mean(YOJ)
boxplot(YOJ)
summary(DEROG)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.0000 0.0000 0.2546 0.0000 10.0000 708
minDEROG=quantile(DEROG,probs=0.25, na.rm = TRUE) - 1.5*IQR(DEROG, na.rm = TRUE)
maxDEROG=quantile(DEROG,probs=0.75, na.rm = TRUE) + 1.5*IQR(DEROG, na.rm = TRUE)
DEROG[DEROG> maxDEROG|DEROG<minDEROG]= mean(DEROG)
boxplot(DEROG)
summary(DELINQ)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.0000 0.0000 0.4494 0.0000 15.0000 580
minDELINQ=quantile(DELINQ,probs=0.25, na.rm = TRUE) - 1.5*IQR(DELINQ, na.rm = TRUE)
maxDELINQ=quantile(DELINQ,probs=0.75, na.rm = TRUE) + 1.5*IQR(DELINQ, na.rm = TRUE)
DELINQ[DELINQ> maxDELINQ|DELINQ<minDELINQ]= mean(DELINQ)
boxplot(DELINQ)
summary(NINQ)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.000 0.000 1.000 1.186 2.000 17.000 510
minNINQ=quantile(NINQ,probs=0.25, na.rm = TRUE) - 1.5*IQR(NINQ, na.rm = TRUE)
maxNINQ=quantile(NINQ,probs=0.75, na.rm = TRUE) + 1.5*IQR(NINQ, na.rm = TRUE)
NINQ[NINQ> maxNINQ|NINQ<minNINQ]= mean(NINQ)
boxplot(NINQ)
summary(CLNO)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0 15.0 20.0 21.3 26.0 71.0 222
minCLNO=quantile(CLNO,probs=0.25, na.rm = TRUE) - 1.5*IQR(CLNO, na.rm = TRUE)
maxCLNO=quantile(CLNO,probs=0.75, na.rm = TRUE) + 1.5*IQR(CLNO, na.rm = TRUE)
CLNO[CLNO> maxLOAN|CLNO<minCLNO]= mean(CLNO)
boxplot(CLNO)
Tính toán giá trị min của từng biến bằng cách lấy phân vị 25% (Q1) của biến đó và trừ đi 1.5 lần khoảng IQR(khoảng tứ phân vị= Q3-Q1). Đây là giá trị dưới ngưỡng dưới để xác định outliers.
Tương tự tính max của biến bằng cách lấy phân vị 75% (Q3) của biến và cộng thêm 1.5 lần khoảng IQR của LOAN. Đây là giá trị trên ngưỡng trên để xác định outliers.
Sau đó, thay thế các giá trị của biến nằm ngoài khoảng [min, max] bằng giá trị trung bình .
Việc loại bỏ outliers giúp làm sạch dữ liệu và cải thiện chất lượng của các phân tích và mô hình học máy sau này. Bằng cách thay thế các giá trị outliers bằng giá trị trung bình của biến, chúng ta có thể giảm thiểu ảnh hưởng của các giá trị ngoại lệ lên các phân tích thống kê và mô hình dự đoán. Điều này giúp tăng độ chính xác và đáng tin cậy của kết quả cuối cùng.
III. TRỰC QUAN HÓA DỮ LIỆU
####1. Bad rate
# Data Overview
ggplot(data, aes(BAD, fill = BAD)) +
geom_bar() +
theme(legend.position = 'none')
## Warning: The following aesthetics were dropped during statistical transformation: fill
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
## the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
## variable into a factor?
table(BAD)
## BAD
## 0 1
## 4771 1189
round(prop.table(table(BAD)),3)
## BAD
## 0 1
## 0.801 0.199
# xem tỉ lệ bad-good
table(data$Bad)
## Warning: Unknown or uninitialised column: `Bad`.
## < table of extent 0 >
round(prop.table(table(data$Bad)),3)
## Warning: Unknown or uninitialised column: `Bad`.
## numeric(0)
Đây là tỷ lệ giữa giá trị 0 và 1 của biến ” BAD”, có tỷ lệ BAD= 1 chiếm khoảng 19,9%
### xem mối liên hệ với biến bad
plot_dt <- data
plot_dt$BAD <- factor(plot_dt$BAD, labels = c("Paid", "Defaulted"))
#Disable exponential notation in graphs
options(scipen = 999)
library(ggcorrplot)
## Warning: package 'ggcorrplot' was built under R version 4.3.3
numericVarName <- names(which(sapply(data, is.numeric)))
corr <- cor(data[,numericVarName], use = 'pairwise.complete.obs')
corr
## BAD LOAN MORTDUE VALUE YOJ
## BAD 1.000000000 -0.075098920 -0.046186035 -0.036492382 -0.05395626
## LOAN -0.075098920 1.000000000 0.216380410 0.331522435 0.09687850
## MORTDUE -0.046186035 0.216380410 1.000000000 0.788735625 -0.07620054
## VALUE -0.036492382 0.331522435 0.788735625 1.000000000 0.01363839
## YOJ -0.053956262 0.096878497 -0.076200545 0.013638392 1.00000000
## DEROG 0.269921278 0.006995633 -0.047123015 -0.043807846 -0.05772929
## DELINQ 0.346503256 -0.028869500 0.003580167 -0.008158179 0.05158005
## CLAGE -0.165614000 0.088237005 0.129798674 0.169535991 0.18620260
## NINQ 0.012298953 -0.051559758 -0.021913110 -0.062052290 -0.09205959
## CLNO -0.004542564 0.074317173 0.318515335 0.265029453 0.03281478
## DEBTINC 0.154544141 0.068937824 0.134575084 0.113079575 -0.04648154
## DEROG DELINQ CLAGE NINQ CLNO
## BAD 0.269921278 0.346503256 -0.16561400 0.0122989530 -0.0045425643
## LOAN 0.006995633 -0.028869500 0.08823700 -0.0515597576 0.0743171733
## MORTDUE -0.047123015 0.003580167 0.12979867 -0.0219131098 0.3185153351
## VALUE -0.043807846 -0.008158179 0.16953599 -0.0620522898 0.2650294529
## YOJ -0.057729293 0.051580048 0.18620260 -0.0920595941 0.0328147754
## DEROG 1.000000000 0.171285977 -0.07948222 0.0450988433 0.0520749270
## DELINQ 0.171285977 1.000000000 0.02632362 -0.0437902468 0.1611534330
## CLAGE -0.079482222 0.026323621 1.00000000 -0.0495990038 0.2338015567
## NINQ 0.045098843 -0.043790247 -0.04959900 1.0000000000 0.0002945141
## CLNO 0.052074927 0.161153433 0.23380156 0.0002945141 1.0000000000
## DEBTINC 0.020541539 0.048307219 -0.04074138 -0.0637962094 0.1598499744
## DEBTINC
## BAD 0.15454414
## LOAN 0.06893782
## MORTDUE 0.13457508
## VALUE 0.11307958
## YOJ -0.04648154
## DEROG 0.02054154
## DELINQ 0.04830722
## CLAGE -0.04074138
## NINQ -0.06379621
## CLNO 0.15984997
## DEBTINC 1.00000000
ggcorrplot(corr, lab = TRUE)
Trong thống kê mô hình, đa cộng tuyến là hiện tượng tránh để xuất hiện, vì nó có thể làm giảm đáng kể độ chính xác của ước lượng cũng như làm yếu đi ý nghĩa thống kê của mô hình. Bởi vậy cần xem xét sự tương quan giữa các biến có trong tập dữ liệu. Sử dụng biểu đồ nhiệt để quan sát. Ta thấy MORTDUE và VALUE có hệ số tương quan cao.
Xem tương quan giữa VALUe và mortdue
#VALUE vs MORTDUE
library(cowplot)
## Warning: package 'cowplot' was built under R version 4.3.2
##
## Attaching package: 'cowplot'
## The following object is masked from 'package:ggthemes':
##
## theme_map
## The following object is masked from 'package:lubridate':
##
## stamp
library(plotly)
## Warning: package 'plotly' was built under R version 4.3.3
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following objects are masked from 'package:plyr':
##
## arrange, mutate, rename, summarise
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
fit <- lm(plot_dt$MORTDUE~plot_dt$VALUE)
scatter1 <- ggplot(plot_dt, aes(VALUE, MORTDUE, color = BAD)) +
geom_count(position = "jitter", alpha = 0.6, size = 1.6, show.legend = F) +
geom_line(aes(y = predict(fit)), col = "brown", size = 0.9) +
ylim(c(0, 225000)) +
scale_x_log10() +
labs(title = "Property value vs Outstanding mortgage", x = "Property value", y = "Outstanding mortgage", size = "Size", color = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 11), text = element_text(family = "serif"),panel.grid = element_blank()) +
scale_color_manual(values = c("steelblue", "brown"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
#NINQ vs CLNO
fit2 <- lm(plot_dt$CLNO~plot_dt$NINQ)
scatter2 <- ggplot(plot_dt, aes(NINQ, CLNO, color = BAD)) +
geom_count(position = "jitter", alpha = 0.6, size = 1.6) +
labs(title = "Recent credit inquiries vs Total credit lines", x = "Recent inquiries", y = "Total credit lines", size = "Size", color = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 11), text = element_text(family = "serif"),
panel.grid = element_blank()) +
scale_color_manual(values = c("steelblue", "brown"))
#Aggregate plots
plot_grid(scatter1, scatter2)
## Warning: Removed 69 rows containing non-finite values (`stat_sum()`).
## Warning: Removed 18 rows containing missing values (`geom_line()`).
Sử dụng biểu đồ quan sát mối tương quan giữa MORTDUE- VALUE và NINQ- CLNO
Có một mối tương quan dương mạnh mẽ theo cấp số nhân giữa giá trị tài sản hiện tại của khách hàng và các khoản thế chấp chưa thanh toán. Vì vậy, chúng ta không được để cả 2 biến này cùng xuất hiện trong mô hình, cần loại bỏ 1 trong 2 biến để tránh trường hợp đa cộng tuyến và cải thiện hiệu suất của mô hình cũng như phân tích thống kê.
Mặt khác, có mối tương quan cực kỳ yếu giữa các yêu cầu tín dụng gần đây của khách hàng và tổng hạn mức tín dụng. Điều này có nghĩa là việc bao gồm NINQ và CLNO cùng nhau sẽ không gây nguy hiểm cho độ chính xác của mô hình.
# Xóa bỏ biến " MORTDUE"
plot_dt <- subset(plot_dt, select = -c(MORTDUE))
#BAD vs DELINQ
bar1 <- ggplot(plot_dt, aes(BAD, DELINQ, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Delinquent Credit Lines", x = "", y = "Delinquent Credit Lines", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs DEBTINC
bar2 <- ggplot(plot_dt, aes(BAD, DEBTINC, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Debt-Income Ratio", x = "", y = "Debt:Income", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs DEROG
bar3 <- ggplot(plot_dt, aes(BAD, DEROG, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Derogatory Reports", x = "", y = "Derogatory Reports", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs CLAGE
bar4 <- ggplot(plot_dt, aes(BAD, CLAGE, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Oldest Credit Line", x = "", y = "Age", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs LOAN
bar5 <- ggplot(plot_dt, aes(BAD, LOAN, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Loan Request Amount", x = "", y = "Loan", color = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs NINQ
bar6 <- ggplot(plot_dt, aes(BAD, NINQ, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Recent Credit Inquiries", x = "", y = "Recent Inquiries", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
#BAD vs CLNO
bar7 <- ggplot(plot_dt, aes(BAD, CLNO, fill = BAD)) +
geom_bar(stat = "identity", show.legend = F, width = 0.4) +
labs(title = "Total Credit Lines", x = "", y = "Credit Lines", fill = "Status") +
theme_bw() +
theme(plot.title = element_text(face = "bold", hjust = 0.5, size = 10), text = element_text(family = "serif"),
aspect.ratio = 2/1, panel.grid = element_blank()) +
scale_fill_manual(values = c("steelblue", "brown"))
library(cowplot)
library(plotly)
plot_grid(bar1, bar3)
Khi một người có nhiều khoản vay quá hạn(DELINQ) hoặc bị ghi chép vào lịch sử tín dụng xấu(DEROG), họ có thể gặp khó khăn trong việc trả nợ và vay được thêm tiền. Điều này có thể dẫn đến một vòng lặp tiêu cực khi họ không thể trả nợ hiện tại và tiếp tục tích lũy thêm nợ, tạo ra một môi trường không thuận lợi cho việc trả nợ. Do đó, người không có khả năng trả nợ thường có nhiều khoản vay quá hạn hơn và bị ghi chép vào lịch sử tín dụng xấu.
plot_grid(bar4, bar6, bar7, ncol = 3, nrow = 1)
Một cách hiểu đơn giản, những người vay đã trả nợ thường được ngân hàng đánh giá là đáng tin cậy hơn, do đó họ có lịch sử tín dụng lâu hơn(CLAGE càng lớn thì cho thấy lịch sử tín dụng dài và ổn định), thực hiện nhiều lần tra cứu tín dụng gần đây hơn(NINQ) và thường có nhiều tài khoản tín dụng hơn so với khách hàng không trả nợ.
Các biến CLAGE, NINQ và CLNO trong bộ dữ liệu có thể có các ý nghĩa như sau:
1. CLAGE (Age of the oldest credit line in months): đo lường sự ổn định và lịch sử tín dụng của người vay. Một CLAGE lớn hơn có thể cho thấy một lịch sử tín dụng dài hạn và ổn định.
2. NINQ (Number of recent credit inquiries): Biến này đếm số lần kiểm tra tín dụng gần đây. Số lượng kiểm tra tín dụng cao có thể cho thấy người vay đang tìm kiếm vay nợ hoặc mở thêm tài khoản tín dụng mới, có thể tăng nguy cơ về khả năng trả nợ.
3. CLNO (Number of existing credit lines): Biến này đếm số lượng tài khoản tín dụng hiện có của người vay. Nó có thể phản ánh khả năng quản lý tài chính của họ, với số lượng tài khoản lớn có thể gợi ý đến việc họ có kinh nghiệm trong việc quản lý nhiều khoản vay hoặc tăng cường tài chính, trong khi số lượng tài khoản ít có thể cho thấy họ không có kinh nghiệm hoặc có nhiều nguy cơ hơn khi vay nợ.
plot_grid(bar2, bar5)
Những người vay mà không gặp khó khăn về trả nợ thì có tỉ lệ nợ thu nhập(DEBTINC) và số tiền vay(LOAN) cao hơn đáng kể, vì họ có khả năng tiếp tục vay từ ngân hàng dựa trên lịch sử tín dụng tích cực, với các khoản vay trước đó được trả đúng hạn và không có nợ xấu=> họ trở nên đáng tin cậy hơn trong mắt ngân hàng nên được vay nhiều hơn (mà không cần phải làm đơn vay mới).
1. Người vay có DEBTINC cao hơn có thể có khả năng tài chính tốt hơn, tức là thu nhập của họ đủ để chi trả một lượng nợ lớn hơn mà không làm ảnh hưởng đến tỷ lệ nợ thu nhập.
2. Số tiền vay cao hơn trong biến LOAN có thể phản ánh nhu cầu tài chính lớn hơn từ người vay. Họ có thể muốn vay một số tiền lớn để đầu tư vào dự án lớn, mua nhà mới hoặc thậm chí là trả nợ cho các khoản vay khác.
Tóm lại, các giá trị cao của DEBTINC và LOAN có thể phản ánh sự ổn định tài chính, nhu cầu tài chính lớn và lịch sử tín dụng tích cực của người vay.
### Bivariate Analysis
# Cài đặt thư viện ggplot2 nếu chưa có
# Nhập thư viện ggplot2
library(ggplot2)
# Vẽ biểu đồ boxplot
#LOAN- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = LOAN, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "LOAN") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
# MORTDUE- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = MORTDUE, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "MORTDUE") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
## Warning: Removed 752 rows containing non-finite values (`stat_boxplot()`).
#VALUE- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = VALUE, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "VALUE") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#YOJ- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = YOJ, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "YOJ") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#DEGROG- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = DEROG, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "DEROG") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#DELINQ-BAD
ggplot(plot_dt, aes(x = factor(BAD), y = DELINQ, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "DELINQ") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#CLAGE-BAD
ggplot(plot_dt, aes(x = factor(BAD), y = MORTDUE, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "MORTDUE") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
## Warning: Removed 752 rows containing non-finite values (`stat_boxplot()`).
#NINQ- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = NINQ, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "NINQ") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#CLNO- BAD
ggplot(plot_dt, aes(x = factor(BAD), y = CLNO, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "CLNO") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
#DEBTINC-BAD
ggplot(plot_dt, aes(x = factor(BAD), y = DEBTINC, fill = factor(BAD))) +
geom_boxplot() +
labs(x = "BAD", y = "DEBTINC") +
scale_fill_manual(values = c("blue", "red")) +
theme_minimal()
## Tương quan biến định tính và BAD
#REASON- BAD
# Vẽ biểu đồ cột chồng
ggplot(plot_dt, aes(x = REASON, fill = factor(BAD))) +
geom_bar(position = "fill") +
labs(x = "Reason", y = "Proportion", fill = "BAD") +
scale_y_continuous(labels = scales::percent) +
theme_minimal()
#JOB- BAD
ggplot(plot_dt, aes(x = JOB, fill = factor(BAD))) +
geom_bar(position = "fill") +
labs(x = "Job", y = "Proportion", fill = "BAD") +
scale_y_continuous(labels = scales::percent) +
theme_minimal()
Đánh giá tầm quan trọng của các biến đến biến “BAD”
4.1. Classification Tree
Sử dụng mô hình cây phân loại Classification Tree để đánh giá tầm quan trọng của các biến có trong tập dữ liệu đối với biến ” BAD”, tức là xác định yếu tố quan trọng nhất từ khách hàng ảnh hưởng tới xác suất vỡ nợ của họ. Điều này sẽ giúp ngân hàng và các tổ chức tín dụng hiểu rõ hơn về nguyên nhân dẫn đến vỡ nợ, từ đó giúp đưa ra quyết định cho vay cũng như quản lý rủi ro
Trước tiên tạo biến giả cho các biến định tính bằng one- hot
## Cây quyến định Regression Tree
# One-hot encoding( Tạo biến giải bằng one-hot)
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
## The following object is masked from 'package:purrr':
##
## lift
dummy <- dummyVars(" ~ .", data = plot_dt)
data_new <- data.frame(predict(dummy, newdata = data))
## Warning in model.frame.default(Terms, newdata, na.action = na.action, xlev =
## object$lvls): variable 'BAD' is not a factor
names(data_new)
## [1] "BAD" "LOAN" "VALUE"
## [4] "REASONDebtCon" "REASONHomeImp" "REASONOther.reason"
## [7] "JOBMgr" "JOBOffice" "JOBOther"
## [10] "JOBProfExe" "JOBSales" "JOBSelf"
## [13] "YOJ" "DEROG" "DELINQ"
## [16] "CLAGE" "NINQ" "CLNO"
## [19] "DEBTINC"
# Chuyển biến BAD thành hai cấp
data_new$BAD <- as.factor(data_new$BAD)
set.seed(26)
# Huấn luyện mô hình sử dụng phương pháp rpart
model <- train(BAD ~ ., data = data_new, method = "rpart")
model
## CART
##
## 5960 samples
## 18 predictor
## 2 classes: '0', '1'
##
## No pre-processing
## Resampling: Bootstrapped (25 reps)
## Summary of sample sizes: 5960, 5960, 5960, 5960, 5960, 5960, ...
## Resampling results across tuning parameters:
##
## cp Accuracy Kappa
## 0.03448276 0.8667946 0.5175924
## 0.04205214 0.8608695 0.4837222
## 0.08326325 0.8319534 0.2920002
##
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was cp = 0.03448276.
# Đánh giá tầm quan trọng của các biến
rankVars <- varImp(model)
print(rankVars)
## rpart variable importance
##
## Overall
## DEBTINC 100.000
## DELINQ 57.697
## DEROG 55.887
## CLAGE 30.635
## LOAN 19.685
## NINQ 9.108
## CLNO 5.099
## VALUE 0.000
## JOBMgr 0.000
## JOBSales 0.000
## JOBOther 0.000
## JOBOffice 0.000
## JOBSelf 0.000
## YOJ 0.000
## JOBProfExe 0.000
## REASONHomeImp 0.000
## REASONOther.reason 0.000
## REASONDebtCon 0.000
# Vẽ biểu đồ tầm quan trọng của các biến
plot(rankVars, top = 18, main = 'Variable Importance')
Theo mô hình này, mức độ quan trọng của các biến đối với biến “BAD” lần lượt là: DEBTINC, DELINQ, DEROG, CLAGE, LOAN, NINQ, CLNO.
4.2. Random Forest
Mô hình Random Forest là một phương pháp học máy dựa trên việc xây dựng nhiều cây quyết định (decision trees) và kết hợp kết quả từ tất cả các cây để đưa ra kết quả cuối cùng giúp xác định các biến quan trọng. Như vậy trong phần này 2 mô hình đang sử dụng cùng mục đích, tìm hiểu yếu tố nào ảnh hưởng nhiều nhất tới rủi ro của khách hàng.
## Mô hình Random Forest
# Cài đặt và nhập thư viện
install.packages("randomForest")
## Installing package into 'C:/Users/pc/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'randomForest' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\pc\AppData\Local\Temp\RtmpGCDKUA\downloaded_packages
library(randomForest)
## Warning: package 'randomForest' was built under R version 4.3.3
## randomForest 4.7-1.1
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:psych':
##
## outlier
## The following object is masked from 'package:ggplot2':
##
## margin
## The following object is masked from 'package:dplyr':
##
## combine
# Tạo mô hình RandomForest
rf_model <- randomForest(BAD ~ ., data = data_new)
# Tính toán tầm quan trọng của các biến
importance <- importance(rf_model)
# Sắp xếp theo thứ tự giảm dần
sorted_importance <- sort(importance, decreasing = TRUE)
rf<-varImp(rf_model)
print(rf)
## Overall
## LOAN 175.170591
## VALUE 188.422743
## REASONDebtCon 20.279171
## REASONHomeImp 19.360510
## REASONOther.reason 9.082943
## JOBMgr 18.282091
## JOBOffice 20.629889
## JOBOther 23.748949
## JOBProfExe 17.719019
## JOBSales 11.409519
## JOBSelf 10.284756
## YOJ 124.115807
## DEROG 106.259406
## DELINQ 186.608274
## CLAGE 203.374751
## NINQ 82.352444
## CLNO 160.910159
## DEBTINC 456.829048
# Vẽ biểu đồ tầm quan trọng của các biến
plot(sorted_importance, main = 'Variable Importance', ylab = "", xlab = "Variable Index")
lines(sorted_importance)
Theo mô hình này, mức độ quan trọng của các biến đối với biến “BAD” lần lượt là: DEBTINC, CLAGE, VALUE, DELINQ, LOAN, CLNO
Như vậy, từ 2 mô hình trên, ta thấy rằng DEBTINC là biến quan trọng nhất, hay yếu tố Tỷ lệ nợ trên thu nhất có ảnh hưởng lớn nhất đối với xác suất vỡ nợ của khách hàng
IV. TỔNG KẾT
Các giá trị cao của DEBTINC và LOAN có thể phản ánh sự ổn định tài chính, nhu cầu tài chính lớn và lịch sử tín dụng tích cực của người vay.
Khi một người có nhiều khoản vay quá hạn(DELINQ) hoặc bị ghi chép vào lịch sử tín dụng xấu(DEROG), họ có thể gặp khó khăn trong việc trả nợ và vay được thêm tiền. Điều này có thể dẫn đến một vòng lặp tiêu cực khi họ không thể trả nợ hiện tại và tiếp tục tích lũy thêm nợ, tạo ra một môi trường không thuận lợi cho việc trả nợ. Do đó, người không có khả năng trả nợ thường có nhiều khoản vay quá hạn hơn và bị ghi chép vào lịch sử tín dụng xấu.
Yếu tố Tỷ lệ nợ trên thu nhập có ảnh hưởng lớn nhất đối với xác suất vỡ nợ của khách hàng
Khi đánh giá tỷ lệ nợ xấu của các nhóm ngành, đáng chú ý, Người vay trong lĩnh vực Sales hoặc tự làm chủ có tỷ lệ nợ xấu cao hơn so với các nhóm ngành khác
Như vậy, việc thống kê, trực quan hóa dữ liệu là bước làm giúp ích cho quá trình nhận định và đưa ra quyết định của các tổ chức tài chính. Điển hình là các ngân hàng, dựa vào các yếu tố của các cá nhân khách hàng để đánh giá, dự báo về xác suất vỡ nợ của họ, từ đó có cái nhìn tốt hơn đối với rủi ro tín dụng, giúp các ngân hàng đưa ra quyết định cho vay đối với khách hàng nào, giúp giảm thiểu rủi ro cho ngân hàng, tăng doanh thu, lợi nhuận, góp phần vào việc phát triển nền kinh tế