评分卡模型开发技术报告韩江涛2018年02月12日Contents1前言1 2评分卡开发流程2 3数据获取33.1采样范围选择 (3)3.2收集整理数据 (3)3.3German Credit数据集 (3)4探索性数据分析74.1统计特性和分布 (7)4.2缺失值处理 (11)4.3离群点处理 (14)5数据准备165.1创建数据集 (16)5.2平衡训练集 (16)5.3数据分箱 (17)5.4证据权重(WoE)转换 (20)5.5相关性分析 (23)5.5.1相关系数分析 (23)5.5.2多重共线性检测 (24)6变量选取和模型开发266.1模型指标变量选择 (26)6.2模型训练 (26)6.3Bias v.s.Variance (29)7模型评价307.1混淆矩阵 (30)7.2ROC、AUC和Gini值 (31)7.3KS曲线及KS值 (32)8评分卡创建和实施358.1评分卡创建 (35)8.2评分验证 (37)8.3评分卡实施 (39)8.4拒绝推论 (39)9监测40 10Appendix4110.1Change Log (41)10.1.12018-2-12 (41)10.1.22017-10-20 (41)10.1.32017-9-6 (41)参考文献42List of Figures1评分卡开发流程图 (2)2名义变量分布统计 (8)3数值变量分布统计 (9)4类别分布统计 (11)5查看缺失值 (13)6使用Cook距离标记离群点 (14)7类别分布统计 (17)8连续变量分箱结果 (19)9WoE转换结果 (21)10信息值 (22)11相关性分析 (24)12LASSO回归的交叉验证曲线 (27)13LASSO Trace (28)14学习曲线 (29)15混淆矩阵及其衍生指标的定义 (30)16ROC曲线和AUC (32)17KS曲线和KS-value (34)18German Credit的实际得分分布与理论分布对比 (39)List of Tables1评分卡数据介绍 (3)2评分卡刻度表 (35)3评分卡表 (36)4平衡数据集和非平衡数据集的效果对比 (41)1前言 信用评分卡是一种常用的信用风险量化工具。
主要分为申请评分卡和行为评分卡,前者用于新贷款、授信申请的风险量化,后者主要用于贷后管理,两者具有相似的开发过程。
随着中国银行业内部竞争加剧和经营水平的提高,信用评分工具也受到了越来越多的重视。
本文以R语言实战的形式简要介绍信用评分卡的开发过程,实际上在开发的各个环节,都有大量值得深入挖掘的优化方法,而某些方法的实施,很可能要花项目10%的时间却只带来1%的效果提升。
本文浅尝辄止,望能抛砖引玉。
2评分卡开发流程 评分卡的简要开发思路就是使用有监督机器学习中的分类算法,利用已知分类的数据训练模型来预测未知数据的分类。
如Figure 1所示,主要分为以下步骤:数据获取,探索性数据分析,数据准备,变量选取,模型开发,模型评价,评分卡创建,评分卡实施,监测等。
Figure1:评分卡开发流程图3数据获取目的:使后面所有工作能够开展工具:任何你熟悉的工具,Excel,R,SQL…… 收集数据是评分卡建模的第一步。
收集数据包含两个方面的问题:数据采样范围和维度(即指标)选择。
3.1采样范围选择 数据收集的时候有两个窗口:观察窗口和表现窗口。
比如我们将目标变量定义为:有超过90天的逾期为坏客户,否则为好客户,而预测指标中有“近60天的平均余额”,那么在计算这个指标前,就需要对数据窗口进行对齐,比如将违约起始日期作为表现窗口的开始,按照窗口进行对齐,再计算出所需指标。
再比如将坏客户定义为未来半年内有逾期可能的客户,表现窗口就会长达半年。
所以数据获取,通常并不是按照自然日历获取,而是要按照窗口的定义获取。
对于申请评分卡,我们抽样一些申请通过客户并根据其后期行为标记为好、坏,然而这些客户不包括前期被拒绝的客户,这时,抽样是有偏的。
将被拒客户的数据加入模型,被称为“拒绝推论”,这本质上是一个纠偏的问题。
3.2收集整理数据 根据信用评分卡不同的应用,需要有经验的业务人员和数据分析人员一起确定相应的指标选取范围。
指标一般可分为以下两类:1.原始指标:是指存在于数据库中的原始数据;2.衍生指标:是指分析人员对原始数据进行转换、加工、计算后得到的新指标。
通常,会在条件允许的情况下收集尽量多的指标,并根据业务先验知识,计算衍生指标。
在指标严重缺乏的情况下,除了设计有业务含义的衍生指标,还可以考虑加入原始指标的幂。
3.3German Credit数据集 本文描述了评分卡的开发过程。
使用了UC Irvine的German Credit Data1作为样例。
German Credit数据集有20个变量,1000个样本。
(R的caret包中内置了这些数据,并且经过了One-Hot Encoding) 使用German Credit Data数据集省去了收集整理数据的麻烦。
数据集提供了20个特征(Attribute),这些特征中,很多也已经不是原始变量,而是统计量或已经经过分箱,这些操作和方法将在数据准备里详细介绍。
一个目标变量:Class。
如下表。
Table1:评分卡数据介绍特征类型含义取值CheckingAccountStatus Norm.支票账户状态•A11:…<0DM(马克)•A12:0<=…<200DM•A13:…>=200DM或有一年以上的工资收入•A14:没有支票账户Duration Num.账龄(月)1著名的数据挖掘数据集,/ml/datasets/Statlog+(German+Credit+Data)CreditHistory Norm.信用历史•A30:无贷款、所有贷款到期前已结清•A31:在本行的所有贷款已结清•A32:有贷款正常还款中•A33:有逾期历史•A34:Critical账户、在他行有未结清贷款Purpose Norm.贷款用途•A40:新车•A41:二手车•A42:家具、设备•A43:音响、电视•A44:家用电器•A45:维修•A46:教育•A47:休假•A48:再教育•A49:商务•A410:其他Amount Num.贷款金额SavingsAccountBonds Norm.储蓄账户、债券余额•A61:…<100DM(马克)•A62:100<=…<500DM•A63:500<=…<1000DM•A64:…>=1000DM•A65:未知、没有储蓄账户EmploymentDuration Norm.工作年限•A71:无业•A72: (1)•A73:1<= (4)•A74:4<= (7)•A75:…>=7年InstallmentRatePercentage Num.还款占收入比例Personal Norm.个人状态•A91:男,离异、分居•A92:女,离异、分居、已婚•A93:男,单身•A94:男,已婚、丧偶•A95:女,单身OtherDebtorsGuarantors Norm.其他借方或担保人•A101:无•A102:共同还款人•A103:担保人ResidenceDuration Num.当前居住地居住时长|Property Norm.资产•A121:房产•A122:如无A121:公积金、人寿保险•A123:如无A121/A122:车或其他非储蓄、债券资产•A124:未知、无Age Num.年龄OtherInstallmentPlans Norm.其他分期计划•A141:银行•A142:商店•A143:无Housing Norm.住房情况•A151:租赁•A152:自有•A153:无偿使用NumberExistingCredits Num.在本行现存授信数Job Norm.工作•A171:无业、非技术工作且非本地居民•A172:非技术工作且是本地居民•A173:技术工作、公务员•A174:管理人员、自营、高级雇员、主管NumberPeopleMaintenance Num.需赡养的人数Telephone Norm.电话情况•A191:无•A192:有,注册在客户名下ForeignWorker Norm.是否外籍•A201:是•A202:否Class Norm.是否好客户•1:是•2:否4探索性数据分析目的:初步了解数据工具:R 数据收集好之后,就可以进行探索性数据分析(Exploratory Data Analysis,EDA),探索性数据分析的目的是了解数据,主要包括:•候选预测变量的统计特性和分布;•预测变量与目标变量,预测变量之间是否具有相关性;•检查缺失值和极端值,评估其对模型的影响;•分析候选预测变量对目标变量的分布情况。
4.1统计特性和分布 单变量统计时,名义变量通常统计频数,可以用柱形图方便的表示,R中可以用ggplot2包的geom_bar()实现。
German Credit Data中的名义变量分布情况如Figure2所示。
plots<-NULLgrobs<-NULLblank_img<-readPNG("./img/blank.png")#空白图片,用来填充图片上的一些空白区域empty<-ggplot(data.frame(x=1:10,y=1:10),aes(x,y))+annotation_raster(blank_img,-Inf,Inf,-Inf,Inf)+theme(axis.title.x=element_blank(),axis.title.y=element_blank(),axis.text.x=element_blank(),axis.text.y=element_blank(),axis.ticks=element_blank())for(i in1:length(NormVar)){plots[[i]]<-ggplot(german_credit)+geom_bar(aes_string(x=NormVar[[i]],fill=NormVar[[i]]),width=0.5,alpha=0.5,show.legend=F)+theme(axis.text=element_text(size=8,color="black",vjust=0.5,hjust=0.5))+theme(axis.title=element_text(size=10,color="black",vjust=0.5,hjust=0.5));}layout_matrix<-matrix(c(1,2,4,5,6,7,8,9,10,11,12,13,3,3,14,14),nrow=4,byrow=TRUE)grid.arrange(plots[[1]],plots[[2]],plots[[3]],plots[[4]],plots[[5]],plots[[6]],plots[[7]],plots[[8]],plots[[9]],plots[[10]],plots[[11]],plots[[12]],plots[[13]],empty,layout_matrix=layout_matrix,heights=c(1,1,1,2))Figure2:名义变量分布统计for(i in1:length(NumVar)){plots[[i]]<-ggplot(german_credit)+geom_histogram(aes_string(x=NumVar[[i]],y="..count.."),fill="blue",alpha=0.2)+theme(axis.text=element_text(size=8,color="black",vjust=0.5,hjust=0.5))+ theme(axis.title=element_text(size=10,color="black",face="bold",vjust=0.5,hjust=0.5));}layout_matrix<-matrix(c(1,2,3,4,5,6,7,8),ncol=4,byrow=FALSE)grid.arrange(plots[[1]],plots[[2]],plots[[3]],plots[[4]],plots[[5]],plots[[6]],plots[[7]],empty,layout_matrix=layout_matrix)Figure3:数值变量分布统计对于均值、中位数、分位数这些统计信息,可以用summary()获得。