作者:刘小芬,R语言中文社区专栏作者。知乎专栏:https://www.zhihu.com/people/liu-xiao-fen-10/columns 今天看了一部电影《利益风暴》,影片中风险评估员皮特·苏利文得到被解雇的上司正在进行的一个风险模型分析资料,然后认真进行了分析,最终发现了公司财务评估的一个巨大漏洞,公司所持有的资产的风险价值(VAR)存在重大风险,如果这些资产出现了问题,那么亏损将会超过公司的价值,从而高层展开了一系列的挽救工作。 看完后,给我对于数据分析、数据建模有了很大的感触,如果不是收集了历史数据将它们整合在一起,建立模型,或许这个漏洞没有那么快发现。 基于此,在kaggle上查找了是否有类似的数据可以作为练习使用,然后想起来曾经关注过的社群小伙伴的实践项目Prosper Loan Data(公众号后台回复“网贷”下载数据),于是参照实践作业,以及自己的理解,进行分析,最终的目的是建立模型,预测哪些人贷款后会还款、哪些人会赖账。 第一步:数据导入 ###导入数据library(readr)loandata <- read_csv("F:/prosperLoanData.csv")View(loandata)str(loandata) 总共有113937行数据。 这个loandata共有81个变量,113937行数据。 第二步:理解数据 由于有81个变量,一些对分析的结果,即贷款状态影响变化不大的变量不予考虑,在此就不做名词解释了。
此次分析将基于上述的数据对贷款状况LoanStatus进行预测模型建立。 第三步:数据预处理 3.1选择子集 由于变量较大,筛选部分有需要的变量,重新建立一个新数据集newloandata。 ###3.1筛选子集library(dplyr)##对变量重新命名names(loandata)[c(14,15,17)] <- c("ProsperRating.numeric","ProsperRating.Alpha","ListingCategory.numeric")##筛选子集newloandata <- select(loandata,ListingCreationDate,LoanStatus,EmploymentStatus,EmploymentStatusDuration, IsBorrowerHomeowner,CreditScoreRangeLower,CreditScoreRangeUpper, InquiriesLast6Months,BorrowerRate,Term,CreditGrade,ProsperRating.Alpha, StatedMonthlyIncome,DelinquenciesLast7Years,BankcardUtilization, LoanOriginalAmount,DebtToIncomeRatio,Occupation,IncomeRange,BorrowerState,LoanOriginalAmount)View(newloandata) ![]() 3.2 数据重编码 主要是对LoanStatus进行重编码,定义“已还款”为“1”,“未还款”为“0”。 ##3.2查看LoanStatus的具体内容PastDue <- c("Past Due (>120 days)","Past Due (1-15 days)","Past Due (16-30 days)", "Past Due (31-60 days)","Past Due (61-90 days)","Past Due (91-120 days)")##标签为Past Due的统一归类为PastDuenewloandata$LoanStatus[newloandata$LoanStatus %in% PastDue] <- "PastDue"##cancelled归类到current中newloandata$LoanStatus[newloandata$LoanStatus=="Cancelled"]<-"Current"##defaulted归类为chargedoffnewloandata$LoanStatus[newloandata$LoanStatus=="Defaulted"]<-"Chargedoff"##FinalPaymentInProgress归类为completednewloandata$LoanStatus[newloandata$LoanStatus=="FinalPaymentInProgress"]<-"Completed"##查看数据table(newloandata$LoanStatus) ![]() 再进一步分类: ##将PastDue归类到completed中,属于还款状态newloandata$LoanStatus[newloandata$LoanStatus=="PastDue"]<-"Completed"##将正在进行中的数据删除,也就是current数据删除newloandata <- newloandata[!(newloandata$LoanStatus=="Current"),]##再次查看数据table(newloandata$LoanStatus) ![]() 将LoanStatus用0和1表示未还款、已还款: ##将completed赋值为1,属于已还款状态newloandata$LoanStatus[newloandata$LoanStatus=="Completed"]<-"1"##将Chargedoff赋值为0,属于未还款状态newloandata$LoanStatus[newloandata$LoanStatus=="Chargedoff"]<-"0"newloandata$LoanStatus <- as.factor(newloandata$LoanStatus)##再次查看数据table(newloandata$LoanStatus) ![]() 3.3查看是否有缺失值 使用以下代码筛选出含有缺失值的变量: data <- sapply(newloandata,function(x) sum(is.na(x))) ##查找数据的NA值data1 <- data[data!=0]data1 ![]() 由于缺失数值的变量特别多,上图并不是很直观看到数据缺失的情况,因此用missmap()函数绘图分析: missmap(newloandata,main="Missing Value Of Loandata") ![]() 缺失值排在前三的是CreditGrade、ProsperRating.Alpha和EmploymentStatusDuration,其中前两个是信用等级,是由于2009年7月日后prosper平台对评级名词产生了变化,第三个是受雇佣状态保持时间。这三个指标都对贷款状态有影响,所以需要对缺失值进行补全。 3.3补全缺失值 3.3.1 EmploymentStatusDuration补全数值 首先是找到缺失值的位置: ###补充EmploymentStatusDuration####找到EmploymentStatusDuration缺失的位置which(newloandata$EmploymentStatusDuration %in% NA) ![]() 然后查看对应的EmploymentStatus的情况: ###查看相对应的EmploymentStatus的情况newloandata$EmploymentStatus[which(newloandata$EmploymentStatusDuration %in% NA)] ![]() 此处的EmploymentStatus不是“NA”,就是“Not available”,因此可以将缺失的EmploymentStatusDuration以“0”补全: ###EmploymentStatusDuration以“0”补全newloandata$EmploymentStatusDuration[which(newloandata$EmploymentStatusDuration %in% NA)] <- "0"###查找EmploymentStatusDuration是否有缺失值sapply(newloandata,function(x) sum(is.na(x))) ![]() EmploymentStatusDuration缺失值已完全补充。 3.3.2 EmploymentStatus补全数值 用“Not available”补全EmploymentStatus数值: ###补充EmploymentStatus###EmploymentStatusDuration以“Not available”补全newloandata$EmploymentStatus[which(newloandata$EmploymentStatus %in% NA)] <- "Not available"###查找EmploymentStatus是否有缺失值sapply(newloandata,function(x) sum(is.na(x))) ![]() EmploymentStatus缺失值已完全补充。 3.3.3 CreditScoreRangeLower/CreditScoreRangeUpper补全数值 ###将CreditScoreRangeLower/CreditScoreRangeUpper取两者平均值作为一个新的变量newloandata$CreditScore <- (newloandata$CreditScoreRangeLower+newloandata$CreditScoreRangeUpper)/2###查看CreditScore的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() 缺失值还是存在,由于属于消费评分,因此可以考虑用中位数补充缺失值。 首先绘图查看是否可以用中位数补充数值: ###绘图看是否可用中位数补充缺失值library(ggplot2)library(ggthemes)ggplot(newloandata,aes(x=CreditScore,))+ geom_density(fill="pink",alpha=0.4)+ geom_vline(aes(xintercept=median(CreditScore,na.rm = T)),colour="red",linetype="dashed",lwd=1)+ theme_few()+ggtitle("The density of CreditScore") ![]() 从图中可以看出数值大部分集中在500到750之间,因此可以用中位数补充缺失值: ###用中位数补充缺失值newloandata$CreditScore[which(newloandata$CreditScore %in% NA)] <- median(newloandata$CreditScore,na.rm = T)###再次查看CreditScore的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() CreditScore缺失值已完全补充。 3.3.4 InquiriesLast6Months补全数值 绘图查看是否可以用中位数补充数值: ggplot(newloandata,aes(x=InquiriesLast6Months,))+ geom_density(fill="skyblue",alpha=0.4)+ geom_vline(aes(xintercept=median(InquiriesLast6Months,na.rm = T)),colour="red",linetype="dashed",lwd=1)+ theme_few()+ggtitle("The density of InquiriesLast6Months") ![]() 从图中可以看出数值大部分集中在0到20之间,因此可以用中位数补充缺失值: ###用中位数补充缺失值newloandata$InquiriesLast6Months[which(newloandata$InquiriesLast6Months %in% NA)] <- median(newloandata$InquiriesLast6Months,na.rm = T)###再次查看InquiriesLast6Months的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() InquiriesLast6Months缺失值已完全补充。 3.3.5 DelinquenciesLast7Years补全数值 绘图查看是否可以用中位数补充数值: ggplot(newloandata,aes(x=DelinquenciesLast7Years,))+ geom_density(fill="blue",alpha=0.4)+ geom_vline(aes(xintercept=median(DelinquenciesLast7Years,na.rm = T)),colour="red",linetype="dashed",lwd=1)+ theme_few()+ggtitle("The density of DelinquenciesLast7Years") ![]() 从图中可以看出数值大部分集中在0到10之间,因此可以用中位数补充缺失值: ###用中位数补充缺失值newloandata$DelinquenciesLast7Years[which(newloandata$DelinquenciesLast7Years %in% NA)] <- median(newloandata$DelinquenciesLast7Years,na.rm = T)###再次查看DelinquenciesLast7Years的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() DelinquenciesLast7Years缺失值已完全补充。 3.3.6 BankcardUtilization补全数值 绘图查看是否可以用中位数补充数值: ggplot(newloandata,aes(x=BankcardUtilization,))+ geom_density(fill="grey",alpha=0.4)+ geom_vline(aes(xintercept=median(BankcardUtilization,na.rm = T)),colour="red",linetype="dashed",lwd=1)+ theme_few()+ggtitle("The density of BankcardUtilization") ![]() 用中位数填充缺失值: ###用中位数补充缺失值newloandata$BankcardUtilization[which(newloandata$BankcardUtilization %in% NA)] <- median(newloandata$BankcardUtilization,na.rm = T)###再次查看BankcardUtilization的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() BankcardUtilization缺失值已完全补充。 接着对BankcardUtilization的数值进行分类: ###BankcardUtilization的数据进行分类newloandata$BankCardUse[newloandata$BankcardUtilization <quantile(newloandata$BankcardUtilization, 0.25,"na.rm" = TRUE)] <- "Mild Use"newloandata$BankCardUse[(newloandata$BankcardUtilization>= quantile(newloandata$BankcardUtilization,0.25,na.rm = TRUE))&( newloandata$BankcardUtilization< quantile(newloandata$BankcardUtilization,0.5,na.rm = TRUE))]<-"Medium Use"newloandata$BankCardUse[(newloandata$BankcardUtilization>= quantile(newloandata$BankcardUtilization,0.5,na.rm = TRUE))&( newloandata$BankcardUtilization<1)]<-"Heavy Use"newloandata$BankCardUse[newloandata$BankcardUtilization>=1]<-"Super Use"newloandata$BankCardUse <- as.factor(newloandata$BankCardUse) 3.3.7 DebtToIncomeRatio补全数值 loandata_1 <- newloandata[which(newloandata$DebtToIncomeRatio %in% NA),]names(loandata_1)loandata_1 <- loandata_1[,c(2,17)] table(loandata_1$LoanStatus) ![]() 未还款的比例较大,可以考虑用四分位数对缺失值进行补充: summary(newloandata$DebtToIncomeRatio,na.rm=T) ![]() Q1是0.13,Q3是0.3 ,因此: ###四分位数补充缺失值newloandata$DebtToIncomeRatio[which(newloandata$DebtToIncomeRatio %in% NA)] <- runif(nrow(loandata_1),0.13,0.3)###再次查看DebtToIncomeRatio的缺失值:sapply(newloandata,function(x) sum(is.na(x))) ![]() DebtToIncomeRatio缺失值补全。 3.3.8 Occupation补全数值 ####找到Occupation缺失的位置which(newloandata$Occupation %in% NA)###查看相对应的EmploymentStatus的情况newloandata$EmploymentStatus[which(newloandata$Occupation %in% NA)] ![]() 缺失值对应的EmploymentStatus不是“other”,就是“Not available”,因此可以用“other”补充缺失值: ###Occupation以“Other”补全newloandata$Occupation[which(newloandata$Occupation %in% NA)] <- "Other"###查找Occupation是否有缺失值sapply(newloandata,function(x) sum(is.na(x))) ![]() Occupation缺失值补充完整。 3.3.9 BorrowerState补全数值 ###BorrowerState补全数值loandata_2 <- newloandata[which(newloandata$BorrowerState %in% NA),]names(loandata_2)loandata_2 <- loandata_2[,c(2,20)] table(loandata_2$LoanStatus) ![]() 未还款占的比例较大,且这是贷款人所在州的标签,因此可以用一个因子代替缺失值: ###BorrowerState以“None”补全newloandata$BorrowerState[which(newloandata$BorrowerState %in% NA)] <- "None"###查找BorrowerState是否有缺失值sapply(newloandata,function(x) sum(is.na(x))) ![]() BorrowerState缺失值补充完整。 3.3.10 CreditGrade/ProsperRating.Alpha补全数值 接下来是对CreditGrade和ProsperRating.Alpha数据进行缺失值的补充,由于这两个值是2009年7月1日前后客户信用等级,因此需要对数据进行按照2009年7月1日来分割。 3.3.10.1 CreditGrade缺失值补充 ###按照2009年7月1日将数据进行分割newloandata$ListingCreationDate <- as.Date(newloandata$ListingCreationDate)loandata_before <- newloandata[newloandata$ListingCreationDate < "2009-7-1",]###CreditGrade缺失值情况sapply(loandata_before,function(x) sum(is.na(x))) ![]() 共有131个缺失值,由于数量较小,可以忽略不计,因此删除缺失值: ###筛选非缺失值数据loandata_before <- filter(loandata_before,!is.na(CreditGrade))###查找BorrowerState是否有缺失值sapply(loandata_before,function(x) sum(is.na(x))) ![]() CreditGrade的缺失值已经处理完毕。 3.3.10.2 ProsperRating.Alpha缺失值补充 ###按照2009年7月1日将数据进行分割loandata_after <- newloandata[newloandata$ListingCreationDate >= "2009-7-1",]###CreditGrade缺失值情况sapply(loandata_after,function(x) sum(is.na(x))) ![]() 按照2009年7月1日分割数据后,ProsperRating.Alpha并没有缺失值。 到了此时,全部缺失值都处理好了。 第四步:数据计算&显示 这部分主要是分析以下几点: 1.受雇佣状态持续时间与贷款状态的关系? 2.借款人是否有房屋和贷款状态的关系? 3.消费信用分与贷款状态的关系? 4.征信记录查询次数与贷款状态的关系? 5.信用等级与贷款状态的关系? 6.客户的职业、月收入、年收入与贷款状态的关系? 7.客户7年内违约次数与贷款状态的关系? 8.信用卡使用情况与贷款状态的关系? 9.在Prosper平台是否借款与贷款状态的关系? 10.债务收入比例与贷款状态的关系? 11.借款标利率与贷款状态的关系? 4.1 受雇佣状态持续时间与贷款状态的关系? 分析受雇佣状体持续时间和贷款状态是否有关系,即雇用时间越长,是不是具备还款能力越好。 library(ggplot2)###1.受雇佣状态持续时间与贷款状态的关系?newloandata$EmploymentStatusDuration <- as.integer(newloandata$EmploymentStatusDuration)ggplot(data = newloandata, aes(x = EmploymentStatusDuration, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By EmploymentStatusDuration", x = "EmploymentStatusDuration", y = "Count", fill = "LoanStatus") ![]() 从图中可以看出来随着受雇佣时间越长,贷款未还款率降低,到了后期,基本上不存在毁约现象。也就是说,一个有稳定工作收入的人,不容易出现贷款毁约,不还款。 4.2 借款人是否有房屋和贷款状态的关系? ###2.借款人是否有房屋和贷款状态的关系?mosaicplot(table(newloandata$IsBorrowerHomeowner,newloandata$LoanStatus),main="The Loanstatus By IsBorrowerHomeowner", color = c('pink','skyblue')) ![]() 从图中可以看出,当贷款人拥有房的时候,还款率较无房的贷款人稍高一点,但是这个因素对是否还款影响不大。 4.3 消费信用分与贷款状态的关系? ###3.消费信用分与贷款状态的关系?options(digits=1)newloandata$CreditScore <- newloandata$CreditScoreclass(newloandata$CreditScore)ggplot(data = newloandata, aes(x = CreditScore, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By CreditScore", x = "CreditScore", y = "Count", fill = "LoanStatus") ![]() 从图中可以看出,随着消费信用分越高,还款率越高,因此个人的消费信用分会对贷款最终还款状态有一定的影响。 4.4 征信记录查询次数与贷款状态的关系? ggplot(data = newloandata[newloandata$InquiriesLast6Months < 20,], aes(x = InquiriesLast6Months, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By InquiriesLast6Months", x = "InquiriesLast6Months", y = "Count", fill = "LoanStatus") ![]() 当征信记录查询记录小于10的时候,还可以看出来对贷款状态有些影响,但是大于10之后,还款与未还款的曲线基本趋于一致,所以,可以大胆猜测这个对贷款人是否有能力还款影响不大。 4.5 信用等级与贷款状态的关系? ###5.信用等级与贷款状态的关系?par(mfrow=c(2,1))###考虑2009年7月1日之前的信用等级对贷款状态的影响:CreditGrademosaicplot(table(loandata_before$CreditGrade,loandata_before$LoanStatus),main="The Loanstatus By CreditGrade", color = c('pink','skyblue'))###考虑2009年7月1日之后的信用等级对贷款状态的影响:ProsperRating.Alphamosaicplot(table(loandata_after$ProsperRating.Alpha,loandata_after$LoanStatus),main="The Loanstatus By ProsperRating.Alpha", color = c('pink','skyblue')) ![]() 马赛克图中可以看出,信用等级越高还款率越高,因此AA等级还款率最高,NC最低。而且大部分人的等级集中在C、D等级,AA等级还款率和NC等级还款率相差较大,因此,信用等级对贷款状态有一定的影响。 4.6 客户的职业分布,以及月收入、年收入与贷款状态的关系? 职业分布: ggplot(data=newloandata,aes(x=Occupation))+geom_bar()+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) ![]() 职业中,选择“other”的人数更多,跟之前数据处理得出的结果一样,说明很多人在申请贷款的时候会不选择自己的职业,或者是有欺骗的可能性。 月收入和年收入与贷款状态的关系: ###月收入与贷款状态的关系newloandata$Monthly[newloandata$StatedMonthlyIncome < 3000] <- c("0-3000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 3000 & newloandata$StatedMonthlyIncome < 6000 ] <- c("3000-6000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 6000 & newloandata$StatedMonthlyIncome < 9000 ] <- c("6000-9000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 9000 & newloandata$StatedMonthlyIncome < 12000 ] <- c("9000-12000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 12000 & newloandata$StatedMonthlyIncome < 15000 ] <- c("12000-15000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 15000 & newloandata$StatedMonthlyIncome < 20000 ] <- c("15000-20000")newloandata$Monthly[newloandata$StatedMonthlyIncome >= 20000 ] <- c(">20000")newloandata$Monthly <- factor(newloandata$Monthly,levels=c("0-3000","3000-6000","6000-9000", "9000-12000","12000-15000", "15000-20000"))p1 <- ggplot(data = newloandata, aes(x = Monthly, fill = LoanStatus)) + geom_bar(position="fill")+ggtitle("The Loanstatus By MonthlyIncome")+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))###年收入对贷款状态的关系newloandata$MonthlyIncome <- factor(newloandata$MonthlyIncome,levels=c("Not employed","Not displayed","$0", "$1-24999","$25000-49999", "$50000-74999","$75000-99999","$100000+"))p2 <- ggplot(data = newloandata, aes(x = IncomeRange, fill = LoanStatus)) + geom_bar(position="fill")+ggtitle("The Loanstatus By IncomeRange")+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))library(gridExtra)grid.arrange(p1, p2, ncol=2) ![]() 从图中可以看出来,月收入越高,还款率相对来说也高一点,但是区别不大,年收入也是高收入的相对来说还款率大,但是一样是区别不大。也就是无法单凭收入判断一个人的还款情况。 4.7 客户7年内违约次数与贷款状态的关系? ggplot(data = newloandata,aes(x = DelinquenciesLast7Years, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By DelinquenciesLast7Years", x = "DelinquenciesLast7Years", y = "Count", fill = "LoanStatus") ![]() 过去7年一次也没有违约的客户还款率更高,而违约次数越高,还款率越低。 4.8 信用卡使用情况与贷款状态的关系? ###8.信用卡使用情况与贷款状态的关系?ggplot(data = newloandata, aes(x = BankCardUse, fill = LoanStatus)) + geom_bar(position="fill")+ggtitle("The Loanstatus By BankCardUse")+ theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) ![]() 贷款人的信用卡使用情况为“Mild Use”和“Medium Use”的还款率相对较大,而“Super Use”还款率最低,因此可以根据使用信用卡的状况初步确定贷款人的还款能力。 4.9 在Prosper平台是否借款与贷款状态的关系? ###9.在Prosper平台是否借款与贷款状态的关系?newloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 1000 & newloandata$LoanOriginalAmount <4000]<-"1000-4000"newloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 4000 & newloandata$LoanOriginalAmount <7000]<-"4000-7000"newloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 7000 & newloandata$LoanOriginalAmount <10000]<-"7000-10000"newloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 10000 & newloandata$LoanOriginalAmount <=13000]<-"10000-13000"newloandata$LoanOriginal[newloandata$LoanOriginalAmount > 13000]<-">13000"newloandata$MonthlyIncome <- factor(newloandata$MonthlyIncome,levels=c("1000-4000","4000-7000", "7000-10000","10000-13000", ">13000"))ggplot(data=newloandata,aes(x=LoanOriginal,fill=LoanStatus))+ geom_bar(position = "fill")+ ggtitle("The Loanstatus By LoanOriginalAmount") ![]() 在Prosper平台有借款对贷款状态影响不大,还款率大致上趋于一致。 4.10 债务收入比例与贷款状态的关系? summary(newloandata$DebtToIncomeRatio) ![]() DebtToIncomeRatio的四分位数都是0,而最大值是10,也就是说大部分的数值是在小于1的范围内。 ###10.债务收入比例与贷款状态的关系?ggplot(data = newloandata[newloandata$DebtToIncomeRatio < 1,], aes(x = DebtToIncomeRatio, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By DebtToIncomeRatio", x = "DebtToIncomeRatio", y = "Count", fill = "LoanStatus") ![]() 债务比越低,还款率越高,也就是说贷款人本身的债务不高的情况下,具备还款能力越高。 4.11 借款标利率与贷款状态的关系? ###11.借款标利率与贷款状态的关系?ggplot(data = newloandata, aes(x = BorrowerRate, color = LoanStatus)) + geom_line(aes(label = ..count..), stat = 'bin') + labs(title = "The LoanStatus By BorrowerRate", x = "BorrowerRate", y = "Count", fill = "LoanStatus") ![]() 借款标的利率越高,还款率越低,也就是说这个会影响贷款状态。 第五步:建模,做预测分析 通过上述的分析,可以知道EmploymentStatusDuration、CreditScore、CreditGrade、ProsperRating.Alpha、DelinquenciesLast7Years、BankCardUse、DebtToIncomeRatio、BorrowerRate对贷款状态有一定的影响,所以建模时将这几个选择为影响因子。 ###建模###训练集和测试集,以2009年7月1日为分界点###从loandata_before数据集中随机抽70%定义为训练数据集,30%为测试数据集set.seed(156)tain_before1 <- sample(nrow(loandata_before),0.7*nrow(loandata_before))set.seed(156)tain_before <- loandata_before[tain_before1,]test_before <- loandata_before[-tain_before1,]###利用随机森林建立模型library(randomForest)before_mode <- randomForest(LoanStatus~StatusDuration+CreditScore+ CreditGrade+Delinquencies+ BankCardUse+DebtRatio+LoanBorrowerRate,data=tain_before,importance=TRUE) 由于建模的变量需要因子化,且因子水平不宜很多,所以对各个因子进行分组,减少因子水平数量。对EmploymentStatusDuration、CreditScore、DelinquenciesLast7Years、DebtToIncomeRatio、BorrowerRate进行分组。 ###显示模型误差plot(before_mode,ylim = c(0,1))legend("topright",colnames(before_mode$err.rate),col=1:3,fill=1:3) ![]() 从图可以看出相对于预测不还款的情况,这个模型对于还款预测误差较低,比较容易预测谁更可能还款。 ###对因子的重要性进行分析importance <- importance(before_mode)varImportance <- data.frame(variables=row.names(importance),Importance=round(importance[,'MeanDecreaseGini'],2))###对于变量根据重要系数进行排列library(dplyr)rankImportance <- varImportance %>% mutate(Ranke= paste0('#',dense_rank(desc(Importance))))###使用ggplot绘制重要变量相关系图ggplot(rankImportance,aes(x=reorder(variables,Importance),y=Importance,fill=Importance))+ geom_bar(stat='identity')+ geom_text(aes(x=variables,y=0.5,label=Ranke),hjust=0,vjust=0.55,size=4,colour='red')+ labs(x='Variables')+ coord_flip()+theme_few()+ggtitle('The Importance of Variables') ![]() 因子重要性排名前三的是BorrowerRate、CreditGrade、DebtToIncomeRatio。 ###对测试集预测predit_before <- predict(before_mode,test_before)pert_before <- table(test_before$LoanStatus,predit_before,dnn = c("Actual","Predicted"))> pert_before PredictedActual 0 1 0 1179 2022 1 822 4662 模型预测还款的人预测的比较准,但是预测准确率不高,只有67.25%,看来还需要继续优化因子筛选。 接下来看2009年7月1日之后的模型: ###训练集和测试集,以2009年7月1日为分界点###从loandata_before数据集中随机抽70%定义为训练数据集,30%为测试数据集set.seed(187)tain_after1 <- sample(nrow(loandata_after),0.7*nrow(loandata_after))set.seed(187)tain_after <- loandata_after[tain_after1,]test_after <- loandata_after[-tain_after1,]###利用随机森林建立模型library(randomForest)after_mode <- randomForest(LoanStatus~StatusDuration+CreditScore+ ProsperRating.Alpha+Delinquencies+ BankCardUse+DebtRatio+LoanBorrowerRate,data=tain_after,importance=TRUE) 查看模型评估误差: ###显示模型误差plot(after_mode,ylim = c(0,1))legend("topright",colnames(after_mode$err.rate),col=1:3,fill=1:3) 同样是更容易预测谁可以还款,为不还款的误差较大。 ###对因子的重要性进行分析importance <- importance(after_mode)varImportance <- data.frame(variables=row.names(importance),Importance=round(importance[,'MeanDecreaseGini'],2))###对于变量根据重要系数进行排列library(dplyr)rankImportance <- varImportance %>% mutate(Ranke= paste0('#',dense_rank(desc(Importance))))###使用ggplot绘制重要变量相关系图ggplot(rankImportance,aes(x=reorder(variables,Importance),y=Importance,fill=Importance))+ geom_bar(stat='identity')+ geom_text(aes(x=variables,y=0.5,label=Ranke),hjust=0,vjust=0.55,size=4,colour='red')+ labs(x='Variables')+ coord_flip()+theme_few()+ggtitle('The Importance of Variables') 因子重要性排名前三的是BorrowerRate、ProsperRating.Alpha、DebtToIncomeRatio。这个跟之前的一样。 > predit_after <- predict(after_mode,test_after)> pert_after <- table(test_after$LoanStatus,predit_after,dnn = c("Actual","Predicted"))> pert_after PredictedActual 0 1 0 39 1855 1 48 6542 此时的模型预测准确率是77.57%,比起2009年7月1日前建造的模型准确率提高了很多,也就是说平台改变了信用等级后,将评估模型也进行了修改,保障了平台的利益。 而且,的确是预测还款的准确率比预测不还款的准确率要高一点。 第六步:总结 通过此次练习,对于随机森林预测模型有了更进一步的认识,在建造模型的时候,遇到了很多问题,通过在网络搜索解决问题,虽然费了一些时间,但是起码在建造2009年7月1日之后的模型再遇上同样问题时可以快速解决。
|
手机版|口子爷 ( 鲁ICP备2024117064号-1 )
GMT+8, 2025-7-5 10:31 , Processed in 0.045390 second(s), 14 queries .
Powered by kouziye
Copyright © 2001-2025