使用C5.0决策树识别高风险银行贷款

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972


   个人介绍: 研一|统计学|干货分享

         擅长Python、Matlab、R等主流编程软件

         累计十余项国家级比赛奖项,参与研究经费10w、40w级横向

文章目录

  • 1 目的
  • 2 数据来源
  • 3 案例演示
    • 3.1 探索数据
    • 3.2 模型建立及优化
      • 3.2.1 创建训练集和测试集
      • 3.2.2 基于数据训练模型
      • 3.2.3 评估模型性能
      • 3.2.4 提高模型性能

        1 目的

          使用C5.0决策树方法识别高风险银行贷款

        2 数据来源

          该演示数据来源于: 机器学习和智能系统中心

        3 案例演示

        3.1 探索数据

        1. 读取数据并查看数据类型

          运行代码:

        data<-read.csv("G:\\机器学习\\第三次作业\\credit.csv") #读取数据
        str(data)                                              #查看数据类型
        

           结果展示:

        ## 'data.frame':    1000 obs. of  17 variables:
        ##  $ checking_balance    : Factor w/ 4 levels "< 0 DM","> 200 DM",..: 1 3 4 1 1 4 4 3 4 3 ...
        ##  $ months_loan_duration: int  6 48 12 42 24 36 24 36 12 30 ...
        ##  $ credit_history      : Factor w/ 5 levels "critical","good",..: 1 2 1 2 4 2 2 2 2 1 ...
        ##  $ purpose             : Factor w/ 6 levels "business","car",..: 5 5 4 5 2 4 5 2 5 2 ...
        ##  $ amount              : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
        ##  $ savings_balance     : Factor w/ 5 levels "< 100 DM","> 1000 DM",..: 5 1 1 1 1 5 4 1 2 1 ...
        ##  $ employment_duration : Factor w/ 5 levels "< 1 year","> 7 years",..: 2 3 4 4 3 3 2 3 4 5 ...
        ##  $ percent_of_income   : int  4 2 2 2 3 2 3 2 2 4 ...
        ##  $ years_at_residence  : int  4 2 3 4 4 4 4 2 4 2 ...
        ##  $ age                 : int  67 22 49 45 53 35 53 35 61 28 ...
        ##  $ other_credit        : Factor w/ 3 levels "bank","none",..: 2 2 2 2 2 2 2 2 2 2 ...
        ##  $ housing             : Factor w/ 3 levels "other","own",..: 2 2 2 1 1 1 2 3 2 2 ...
        ##  $ existing_loans_count: int  2 1 1 1 2 1 1 1 1 2 ...
        ##  $ job                 : Factor w/ 4 levels "management","skilled",..: 2 2 4 2 2 4 2 1 4 1 ...
        ##  $ dependents          : int  1 1 2 2 2 2 1 1 1 1 ...
        ##  $ phone               : Factor w/ 2 levels "no","yes": 2 1 1 1 1 2 1 2 1 1 ...
        ##  $ default             : Factor w/ 2 levels "no","yes": 1 2 1 1 2 1 1 1 1 2 ...
        

          通过运行结果我们可以看到原始数据有1000个观测值,并且每个观测值存在17个特征变量,其中存在整型变量和因子型变量。

        2 .查看数据特征

          运行代码:

        table(data$checking_balance) #支票账户余额
        table(data$savings_balance)  #储蓄账户余额
        

          结果展示:

        > table(data$checking_balance) #支票账户余额
        ## 
        ## < 0 DM   > 200 DM 1 - 200 DM    unknown 
        ##        274         63        269        394
        > table(data$savings_balance)  #储蓄账户余额
        ## 
        ## < 100 DM     > 1000 DM  100 - 500 DM 500 - 1000 DM       unknown 
        ##           603            48           103            63           183
        

          通过运行结果我们可以看到观测数据的支票和储蓄账户余额大致分布情况。

          运行代码:

        summary(data$months_loan_duration) #贷款期限
        summary(data$amount)               #贷款金额
        

          结果展示:

        > summary(data$months_loan_duration) #贷款期限
        ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
        ##     4.0    12.0    18.0    20.9    24.0    72.0
        > summary(data$amount)               #贷款金额
        ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
        ##     250    1366    2320    3271    3972   18424
        

          可以发现,观测数据的贷款余额介于250-18424马克之间,贷款余额的中位数为2320马克;贷款期限介于4-752之间,贷款期限的中位数为18个月。

           运行代码:

        table(data$default)      #是否违约
        

          

        结果展示:

        ## 
        ##  no yes 
        ## 700 300
        

          根据结果显示,1000个观测数据中,有300个观测数据存在违约记录,表明该数据集中,所有申请贷款的有30%陷入违约。

        3.2 模型建立及优化

        3.2.1 创建训练集和测试集

          运行代码:

        set.seed(12)                         #提供一个随机数种子值
        data_train_sample<-sample(1000,900)  #挑选训练集
        data_train<-data[data_train_sample,] #创建训练集
        data_test<-data[-data_train_sample,] #创建测试集
        prop.table(table(data_train$default))#训练集违约情况
        prop.table(table(data_test$default)) #测试集违约情况
        

           结果展示:

        > prop.table(table(data_train$default))#训练集违约情况限
        ##        no       yes 
        ## 0.7011111 0.2988889
        > prop.table(table(data_test$default)) #测试集违约情况
        ## 
        ##   no  yes 
        ## 0.69 0.31
        

           经过测试,发现随机种子设置任意值12,划分的训练集和测试集违约率十分接近,且大约为30%,似乎已经是一个相当平衡的分割。所以可以开始建立决策树。

        3.2.2 基于数据训练模型

          运行代码:

        library("C50")                                       #加载包
        data_model<-C5.0(data_train[-17],data_train$default) #将是否违约从训练集框排除,作为目标因子向量
        data_model                                           #查看此决策树的基本数据
        summary(data_model)                     #由于输出结果太长,故以截图方式显示关键代码结果
        

           结果展示:

        1.决策树总览效果

        ## 
        ## Call:
        ## C5.0.default(x = data_train[-17], y = data_train$default)
        ## 
        ## Classification Tree
        ## Number of samples: 900 
        ## Number of predictors: 16 
        ## 
        ## Tree size: 45 
        ## 
        ## Non-standard options: attempt to group attributes
        

        2.决策树详情

           根据运行结果显示:利用C5.0算法训练决策树模型,该树有45个决策。其中,前三个决策分支表示:

          (1)如果支票余额大于200马克或未知,则归类为不太可能违约,其中有422个案例符合该决策条件,57个案例被错误的归类为不太可能违约。

          (2)否则,支票余额小于0马克或介于0-200马克之间。

          (3)信用记录完美或非常好,其中,储蓄余额小于100马克,归类于很有可能违约;储蓄余额大于1000马克或介于500-1000马克,归类于不太可能违约。

          根据输出的混淆矩阵可以发现,900个训练案例中,除了134个案例被错误分类,其余案例都被正确分类,此分类器错误率为14.9%。其中44个真实值为no的实例被错误的归类为yes(假阳性),而90个真实值为yes的实例被错误的归类为no(假阴性)。

        3.2.3 评估模型性能

           运行代码:

        data_pred<-predict(data_model,data_test)                #预测测试数据所属类别
        library("gmodels")                                      #加载包
        CrossTable(data_test$default,data_pred,
                   prop.chisq = F,
                   prop.c = F,
                   prop.r = F,
                   dnn=c("actual default","predicted default")) #模型性能
        

           结果展示:

        predicted defefault
        actual defefaultnoyesRow Total
        no60969
        0.6000.090
        yes191231
        0.1900.120
        Column Total7921100
           根据结果显示,100个贷款申请记录测试中,我们的模型正确预测了60个申请者确实没有违约,而12个申请者确实违约了,模型准确率为72%,而模型的错误率为28%。其中9个真实值为no的实例被错误的归类为yes(假阳性),而19个真实值为yes的实例被错误的归类为no(假阴性),模型的预测准确率较低,需进一步改进。

        3.2.4 提高模型性能

        1.通过boosting算法提高模型性能

           运行代码:

        data_boost10<-C5.0(data_train[-17],data_train$default,
                           trials = 10)                         #boosting算法增强性能
        data_boost10                                            #决策树情况
        data_boost_pred10<-predict(data_boost10,data_test)
        CrossTable(data_test$default,data_boost_pred10,
                   prop.chisq = F,
                   prop.c = F,
                   prop.r = F,
                   dnn=c("actual default","predicted default")) #模型性能
        

           结果展示:

        ## 
        ## Call:
        ## C5.0.default(x = data_train[-17], y = data_train$default, trials = 10)
        ## 
        ## Classification Tree
        ## Number of samples: 900 
        ## Number of predictors: 16 
        ## 
        ## Number of boosting iterations: 10 
        ## Average tree size: 40.2 
        ## 
        ## Non-standard options: attempt to group attributes
        
        predicted defefault
        actual defefaultnoyesRow Total
        no62769
        0.6200.070
        yes191231
        0.1900.120
        Column Total8119100

           利用boosting算法改进后,通过10次迭代,决策树变小,在900个训练案例中,此算法下该分类器犯了38个错误,错误率为4.2%,相比于未加入boosting算法之间,训练案例的错误率为14.9%,该分类器的准确率大大提高。在测试案例中,总的错误率由之前的28%下降到现在的26%,预测效果仍不是很好。

        2.犯一些比其他错误更严重的错误

           运行代码:

        matrix_dimensions<-list(c("no","yes"),c("no","yes"))  #创建矩阵
        names(matrix_dimensions)<-c("predicted","actual")     #对矩阵行、列命名
        error_cost<-matrix(c(0,1,4,0),nrow = 2,
                           dimnames = matrix_dimensions)      #创建惩罚矩阵
                           data_cost<-C5.0(data_train[-17],data_train$default,
                        cost=error_cost)                      #加入惩罚矩阵
        data_cost_pred<-predict(data_cost,data_test)
        CrossTable(data_test$default,data_cost_pred,
                   prop.chisq = F,
                   prop.c = F,
                   prop.r = F,
                   dnn=c("actual default","predicted default")) #模型性能
        

           结果展示:

        predicted defefault
        actual defefaultnoyesRow Total
        no313869
        0.3100.380
        yes32831
        0.0300.280
        Column Total3466100
           根据加入惩罚矩阵(相对于代价为1的假阳性案例,假阴性案例的代价为4)后,在测试集中,此分类器的错误率为41%。但犯错误的类型却相差很大。在此模型中,90%的真实贷款违约者被预测为违约者。若我们的代价估算是准确的,那么以增加假阴性的来减少假阳性的方案是可以接受的。