標籤:

網貸平台貸款數據分析

今天看了一部電影《利益風暴》,影片中風險評估員皮特·蘇利文得到被解僱的上司正在進行的一個風險模型分析資料,然後認真進行了分析,最終發現了公司財務評估的一個巨大漏洞,公司所持有的資產的風險價值(VAR)存在重大風險,如果這些資產出現了問題,那麼虧損將會超過公司的價值,從而高層展開了一系列的挽救工作。

看完後,給我對於數據分析、數據建模有了很大的感觸,如果不是收集了歷史數據將它們整合在一起,建立模型,或許這個漏洞沒有那麼快發現。

基於此,在kaggle上查找了是否有類似的數據可以作為練習使用,然後想起來曾經關注過的社群小夥伴的實踐項目Prosper Loan Data | Kaggle,於是參照實踐作業,以及自己的理解,進行分析,最終的目的是建立模型,預測哪些人貸款後會還款、哪些人會賴賬。

第一步:數據導入

###導入數據nlibrary(readr)nloandata <- read_csv("F:/prosperLoanData.csv")nView(loandata)nstr(loandata) n

總共有113937行數據。

這個loandata共有81個變數,113937行數據。

第二步:理解數據

由於有81個變數,一些對分析的結果,即貸款狀態影響變化不大的變數不予考慮,在此就不做名詞解釋了。

  • ListingCreationDate:表創建時間
  • LoanStatus:貸款狀態(Completed、Current、Defaulted、Chargedoff等)
  • EmploymentStatus:受僱傭狀態(Self-employed、Employed等)
  • EmploymentStatusDuration:受僱傭狀態持續時間(以月為計算單位)
  • IsBorrowerHomeowner:借款人是否擁有房屋
  • CreditScoreRangeLower/CreditScoreRangeUpper:消費信用最低/最高分
  • InquiriesLast6Months:最近6個月查過多少次徵信記錄
  • BorrowerRate:借款標利率,作為P2P平台資金借貸價格的代理變數,BorrowerRate不包含其他費用,是籌資者付給投資人的報酬,也是融資最直接和最重要的成本,其體現了資金供求雙方在綜合考慮各種因素情況下所認可的資金使用成本.
  • Term:期限,籌資者通過網貸平台進行借款時所承諾的最終償還期限,借款期限體現該資產的流動性,期限較長的資產應存在著流動性溢價(利率上漲).
  • CreditGrade/ProsperRating(Alpha):信用等級,前者反映的是2009年7月1日前客戶的信用等級,後者反映的是2009年7月1日後的信用等級.信用等級越高,其償債能力越強.
  • CreditScore:由消費信用公司提供的消費信用評分,類似於國內的芝麻信用分。
  • StatedMonthlyIncome:客戶月收入,月收入越高,投資者對該借款本息按時迴流越有信心.
  • DelinquenciesLast7Years:信用資料提交時借款人過去7年違約次數,該指標在一定程度上可以體現借款標的發布者的信用狀況
  • BankcardUtilization:信用資料提交時借款人信用卡使用額度和信用卡總透支額度的百分比
  • LoanOriginalAmount:借款人在借款時已經向prosper借入的資金,如果沒有歷史記錄則為0,顯然,借入本金越多,其還款壓力越大,但是這項指標大的話也可能說明該客戶對prosper依賴性較強.
  • DebtToIncomeRatio:借款人的債務收入比,債務收入比越高說明籌資者財務狀況越差,還款能力較低.其向P2P平台借款時,投資者應要求有更高的回報.
  • Occupation:貸款人職業
  • IncomeRange:貸款人年收入範圍
  • BorrowerState:貸款人所在州

此次分析將基於上述的數據對貸款狀況LoanStatus進行預測模型建立。

第三步、數據預處理

3.1選擇子集

由於變數較大,篩選部分有需要的變數,重新建立一個新數據集newloandata。

###3.1篩選子集nlibrary(dplyr)n##對變數重新命名nnames(loandata)[c(14,15,17)] <- c("ProsperRating.numeric","ProsperRating.Alpha","ListingCategory.numeric")n##篩選子集nnewloandata <- select(loandata,ListingCreationDate,LoanStatus,EmploymentStatus,EmploymentStatusDuration,n IsBorrowerHomeowner,CreditScoreRangeLower,CreditScoreRangeUpper,n InquiriesLast6Months,BorrowerRate,Term,CreditGrade,ProsperRating.Alpha,n StatedMonthlyIncome,DelinquenciesLast7Years,BankcardUtilization,n LoanOriginalAmount,DebtToIncomeRatio,Occupation,IncomeRange,BorrowerState,LoanOriginalAmountn)nView(newloandata)n

3.2 數據重編碼

主要是對LoanStatus進行重編碼,定義「已還款」為「1」,「未還款」為「0」。

##3.2查看LoanStatus的具體內容nPastDue <- c("Past Due (>120 days)","Past Due (1-15 days)","Past Due (16-30 days)",n "Past Due (31-60 days)","Past Due (61-90 days)","Past Due (91-120 days)")n##標籤為Past Due的統一歸類為PastDuennewloandata$LoanStatus[newloandata$LoanStatus %in% PastDue] <- "PastDue"n##cancelled歸類到current中nnewloandata$LoanStatus[newloandata$LoanStatus=="Cancelled"]<-"Current"n##defaulted歸類為chargedoffnnewloandata$LoanStatus[newloandata$LoanStatus=="Defaulted"]<-"Chargedoff"n##FinalPaymentInProgress歸類為completednnewloandata$LoanStatus[newloandata$LoanStatus=="FinalPaymentInProgress"]<-"Completed"n##查看數據ntable(newloandata$LoanStatus)n

再進一步分類:

##將PastDue歸類到completed中,屬於還款狀態nnewloandata$LoanStatus[newloandata$LoanStatus=="PastDue"]<-"Completed"n##將正在進行中的數據刪除,也就是current數據刪除nnewloandata <- newloandata[!(newloandata$LoanStatus=="Current"),]n##再次查看數據ntable(newloandata$LoanStatus)n

將LoanStatus用0和1表示未還款、已還款:

##將completed賦值為1,屬於已還款狀態nnewloandata$LoanStatus[newloandata$LoanStatus=="Completed"]<-"1"n##將Chargedoff賦值為0,屬於未還款狀態nnewloandata$LoanStatus[newloandata$LoanStatus=="Chargedoff"]<-"0"nnewloandata$LoanStatus <- as.factor(newloandata$LoanStatus)n##再次查看數據ntable(newloandata$LoanStatus)n

3.3查看是否有缺失值

使用以下代碼篩選出含有缺失值的變數:

data <- sapply(newloandata,function(x) sum(is.na(x))) ##查找數據的NA值ndata1 <- data[data!=0]ndata1n

由於缺失數值的變數特別多,上圖並不是很直觀看到數據缺失的情況,因此用missmap()函數繪圖分析:

missmap(newloandata,main="Missing Value Of Loandata")n

缺失值排在前三的是CreditGrade、ProsperRating.Alpha和EmploymentStatusDuration,其中前兩個是信用等級,是由於2009年7月日後prosper平台對評級名詞產生了變化,第三個是受僱傭狀態保持時間。這三個指標都對貸款狀態有影響,所以需要對缺失值進行補全。

3.3補全缺失值

3.3.1 EmploymentStatusDuration補全數值

首先是找到缺失值的位置:

###補充EmploymentStatusDurationn####找到EmploymentStatusDuration缺失的位置nwhich(newloandata$EmploymentStatusDuration %in% NA)n

然後查看對應的EmploymentStatus的情況:

###查看相對應的EmploymentStatus的情況nnewloandata$EmploymentStatus[which(newloandata$EmploymentStatusDuration %in% NA)]n

此處的EmploymentStatus不是「NA」,就是「Not available」,因此可以將缺失的EmploymentStatusDuration以「0」補全:

###EmploymentStatusDuration以「0」補全nnewloandata$EmploymentStatusDuration[which(newloandata$EmploymentStatusDuration %in% NA)] <- "0"n###查找EmploymentStatusDuration是否有缺失值nsapply(newloandata,function(x) sum(is.na(x))) n

EmploymentStatusDuration缺失值已完全補充。

3.3.2 EmploymentStatus補全數值

用「Not available」補全EmploymentStatus數值:

###補充EmploymentStatusn###EmploymentStatusDuration以「Not available」補全nnewloandata$EmploymentStatus[which(newloandata$EmploymentStatus %in% NA)] <- "Not available"n###查找EmploymentStatus是否有缺失值nsapply(newloandata,function(x) sum(is.na(x)))n

EmploymentStatus缺失值已完全補充。

3.3.3 CreditScoreRangeLower/CreditScoreRangeUpper補全數值

###將CreditScoreRangeLower/CreditScoreRangeUpper取兩者平均值作為一個新的變數nnewloandata$CreditScore <- (newloandata$CreditScoreRangeLower+newloandata$CreditScoreRangeUpper)/2n###查看CreditScore的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

缺失值還是存在,由於屬於消費評分,因此可以考慮用中位數補充缺失值。

首先繪圖查看是否可以用中位數補充數值:

###繪圖看是否可用中位數補充缺失值nlibrary(ggplot2)nlibrary(ggthemes)nggplot(newloandata,aes(x=CreditScore,))+n geom_density(fill="pink",alpha=0.4)+n geom_vline(aes(xintercept=median(CreditScore,na.rm = T)),colour="red",linetype="dashed",lwd=1)+n theme_few()+ggtitle("The density of CreditScore")n

從圖中可以看出數值大部分集中在500到750之間,因此可以用中位數補充缺失值:

###用中位數補充缺失值nnewloandata$CreditScore[which(newloandata$CreditScore %in% NA)] <- median(newloandata$CreditScore,na.rm = T)n###再次查看CreditScore的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

CreditScore缺失值已完全補充。

3.3.4 InquiriesLast6Months補全數值

繪圖查看是否可以用中位數補充數值:

ggplot(newloandata,aes(x=InquiriesLast6Months,))+n geom_density(fill="skyblue",alpha=0.4)+n geom_vline(aes(xintercept=median(InquiriesLast6Months,na.rm = T)),colour="red",linetype="dashed",lwd=1)+n theme_few()+ggtitle("The density of InquiriesLast6Months")n

從圖中可以看出數值大部分集中在0到20之間,因此可以用中位數補充缺失值:

###用中位數補充缺失值nnewloandata$InquiriesLast6Months[which(newloandata$InquiriesLast6Months %in% NA)] <- median(newloandata$InquiriesLast6Months,na.rm = T)n###再次查看InquiriesLast6Months的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

InquiriesLast6Months缺失值已完全補充。

3.3.5 DelinquenciesLast7Years補全數值

繪圖查看是否可以用中位數補充數值:

ggplot(newloandata,aes(x=DelinquenciesLast7Years,))+n geom_density(fill="blue",alpha=0.4)+n geom_vline(aes(xintercept=median(DelinquenciesLast7Years,na.rm = T)),colour="red",linetype="dashed",lwd=1)+n theme_few()+ggtitle("The density of DelinquenciesLast7Years")n

從圖中可以看出數值大部分集中在0到10之間,因此可以用中位數補充缺失值:

###用中位數補充缺失值nnewloandata$DelinquenciesLast7Years[which(newloandata$DelinquenciesLast7Years %in% NA)] <- median(newloandata$DelinquenciesLast7Years,na.rm = T)n###再次查看DelinquenciesLast7Years的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

DelinquenciesLast7Years缺失值已完全補充。

3.3.6 BankcardUtilization補全數值

繪圖查看是否可以用中位數補充數值:

ggplot(newloandata,aes(x=BankcardUtilization,))+n geom_density(fill="grey",alpha=0.4)+n geom_vline(aes(xintercept=median(BankcardUtilization,na.rm = T)),colour="red",linetype="dashed",lwd=1)+n theme_few()+ggtitle("The density of BankcardUtilization")n

用中位數填充缺失值:

###用中位數補充缺失值nnewloandata$BankcardUtilization[which(newloandata$BankcardUtilization %in% NA)] <- median(newloandata$BankcardUtilization,na.rm = T)n###再次查看BankcardUtilization的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

BankcardUtilization缺失值已完全補充。

接著對BankcardUtilization的數值進行分類:

###BankcardUtilization的數據進行分類nnewloandata$BankCardUse[newloandata$BankcardUtilizationn <quantile(newloandata$BankcardUtilization,n 0.25,"na.rm" = TRUE)] <- "Mild Use"nnewloandata$BankCardUse[(newloandata$BankcardUtilization>=n quantile(newloandata$BankcardUtilization,0.25,na.rm = TRUE))&(n newloandata$BankcardUtilization<n quantile(newloandata$BankcardUtilization,0.5,na.rm = TRUE))]<-"Medium Use"nnnewloandata$BankCardUse[(newloandata$BankcardUtilization>=n quantile(newloandata$BankcardUtilization,0.5,na.rm = TRUE))&(n newloandata$BankcardUtilization<1)]<-"Heavy Use"nnewloandata$BankCardUse[newloandata$BankcardUtilization>=1]<-"Super Use"nnewloandata$BankCardUse <- as.factor(newloandata$BankCardUse)n

3.3.7 DebtToIncomeRatio補全數值

loandata_1 <- newloandata[which(newloandata$DebtToIncomeRatio %in% NA),]nnames(loandata_1)nloandata_1 <- loandata_1[,c(2,17)] ntable(loandata_1$LoanStatus)n

未還款的比例較大,可以考慮用四分位數對缺失值進行補充:

summary(newloandata$DebtToIncomeRatio,na.rm=T)n

Q1是0.13,Q3是0.3 ,因此:

###四分位數補充缺失值nnewloandata$DebtToIncomeRatio[which(newloandata$DebtToIncomeRatio %in% NA)] <- runif(nrow(loandata_1),0.13,0.3)n###再次查看DebtToIncomeRatio的缺失值:nsapply(newloandata,function(x) sum(is.na(x)))n

DebtToIncomeRatio缺失值補全。

3.3.8 Occupation補全數值

####找到Occupation缺失的位置nwhich(newloandata$Occupation %in% NA)n###查看相對應的EmploymentStatus的情況nnewloandata$EmploymentStatus[which(newloandata$Occupation %in% NA)]n

缺失值對應的EmploymentStatus不是「other」,就是「Not available」,因此可以用「other」補充缺失值:

###Occupation以「Other」補全nnewloandata$Occupation[which(newloandata$Occupation %in% NA)] <- "Other"n###查找Occupation是否有缺失值nsapply(newloandata,function(x) sum(is.na(x)))n

Occupation缺失值補充完整。

3.3.9 BorrowerState補全數值

###BorrowerState補全數值nloandata_2 <- newloandata[which(newloandata$BorrowerState %in% NA),]nnames(loandata_2)nloandata_2 <- loandata_2[,c(2,20)] ntable(loandata_2$LoanStatus)n

未還款占的比例較大,且這是貸款人所在州的標籤,因此可以用一個因子代替缺失值:

###BorrowerState以「None」補全nnewloandata$BorrowerState[which(newloandata$BorrowerState %in% NA)] <- "None"n###查找BorrowerState是否有缺失值nsapply(newloandata,function(x) sum(is.na(x)))n

BorrowerState缺失值補充完整。

3.3.10 CreditGrade/ProsperRating.Alpha補全數值

接下來是對CreditGrade和ProsperRating.Alpha數據進行缺失值的補充,由於這兩個值是2009年7月1日前後客戶信用等級,因此需要對數據進行按照2009年7月1日來分割。

3.3.10.1 CreditGrade缺失值補充

###按照2009年7月1日將數據進行分割nnewloandata$ListingCreationDate <- as.Date(newloandata$ListingCreationDate)nloandata_before <- newloandata[newloandata$ListingCreationDate < "2009-7-1",]n###CreditGrade缺失值情況nsapply(loandata_before,function(x) sum(is.na(x)))n

共有131個缺失值,由於數量較小,可以忽略不計,因此刪除缺失值:

###篩選非缺失值數據nloandata_before <- filter(loandata_before,!is.na(CreditGrade))n###查找BorrowerState是否有缺失值nsapply(loandata_before,function(x) sum(is.na(x)))n

CreditGrade的缺失值已經處理完畢。

3.3.10.2 ProsperRating.Alpha缺失值補充

###按照2009年7月1日將數據進行分割nloandata_after <- newloandata[newloandata$ListingCreationDate >= "2009-7-1",]n###CreditGrade缺失值情況nsapply(loandata_after,function(x) sum(is.na(x)))n

按照2009年7月1日分割數據後,ProsperRating.Alpha並沒有缺失值。

到了此時,全部缺失值都處理好了。

第四步:數據計算&顯示

這部分主要是分析以下幾點:

1.受僱傭狀態持續時間與貸款狀態的關係?

2.借款人是否有房屋和貸款狀態的關係?

3.消費信用分與貸款狀態的關係?

4.徵信記錄查詢次數與貸款狀態的關係?

5.信用等級與貸款狀態的關係?

6.客戶的職業、月收入、年收入與貸款狀態的關係?

7.客戶7年內違約次數與貸款狀態的關係?

8.信用卡使用情況與貸款狀態的關係?

9.在Prosper平台是否借款與貸款狀態的關係?

10.債務收入比例與貸款狀態的關係?

11.借款標利率與貸款狀態的關係?

4.1 受僱傭狀態持續時間與貸款狀態的關係?

分析受僱傭狀體持續時間和貸款狀態是否有關係,即僱用時間越長,是不是具備還款能力越好。

library(ggplot2)n###1.受僱傭狀態持續時間與貸款狀態的關係?nnewloandata$EmploymentStatusDuration <- as.integer(newloandata$EmploymentStatusDuration)nggplot(data = newloandata,n aes(x = EmploymentStatusDuration, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By EmploymentStatusDuration",n x = "EmploymentStatusDuration",n y = "Count",n fill = "LoanStatus")n

從圖中可以看出來隨著受僱傭時間越長,貸款未還款率降低,到了後期,基本上不存在毀約現象。也就是說,一個有穩定工作收入的人,不容易出現貸款毀約,不還款。

4.2 借款人是否有房屋和貸款狀態的關係?

###2.借款人是否有房屋和貸款狀態的關係?nmosaicplot(table(newloandata$IsBorrowerHomeowner,newloandata$LoanStatus),main="The Loanstatus By IsBorrowerHomeowner",n color = c(pink,skyblue))n

從圖中可以看出,當貸款人擁有房的時候,還款率較無房的貸款人稍高一點,但是這個因素對是否還款影響不大。

4.3 消費信用分與貸款狀態的關係?

###3.消費信用分與貸款狀態的關係?noptions(digits=1)nnewloandata$CreditScore <- newloandata$CreditScorenclass(newloandata$CreditScore)nggplot(data = newloandata,n aes(x = CreditScore, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By CreditScore",n x = "CreditScore",n y = "Count",n fill = "LoanStatus")n

從圖中可以看出,隨著消費信用分越高,還款率越高,因此個人的消費信用分會對貸款最終還款狀態有一定的影響。

4.4 徵信記錄查詢次數與貸款狀態的關係?

ggplot(data = newloandata[newloandata$InquiriesLast6Months < 20,],n aes(x = InquiriesLast6Months, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By InquiriesLast6Months",n x = "InquiriesLast6Months",n y = "Count",n fill = "LoanStatus")n

當徵信記錄查詢記錄小於10的時候,還可以看出來對貸款狀態有些影響,但是大於10之後,還款與未還款的曲線基本趨於一致,所以,可以大膽猜測這個對貸款人是否有能力還款影響不大。

4.5 信用等級與貸款狀態的關係?

###5.信用等級與貸款狀態的關係?npar(mfrow=c(2,1))n###考慮2009年7月1日之前的信用等級對貸款狀態的影響:CreditGradenmosaicplot(table(loandata_before$CreditGrade,loandata_before$LoanStatus),main="The Loanstatus By CreditGrade",n color = c(pink,skyblue))nn###考慮2009年7月1日之後的信用等級對貸款狀態的影響:ProsperRating.Alphanmosaicplot(table(loandata_after$ProsperRating.Alpha,loandata_after$LoanStatus),main="The Loanstatus By ProsperRating.Alpha",n color = c(pink,skyblue))n

馬賽克圖中可以看出,信用等級越高還款率越高,因此AA等級還款率最高,NC最低。而且大部分人的等級集中在C、D等級,AA等級還款率和NC等級還款率相差較大,因此,信用等級對貸款狀態有一定的影響。

4.6 客戶的職業分布,以及月收入、年收入與貸款狀態的關係?

職業分布:

ggplot(data=newloandata,aes(x=Occupation))+geom_bar()+n theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))n

職業中,選擇「other」的人數更多,跟之前數據處理得出的結果一樣,說明很多人在申請貸款的時候會不選擇自己的職業,或者是有欺騙的可能性。

月收入和年收入與貸款狀態的關係:

###月收入與貸款狀態的關係nnewloandata$Monthly[newloandata$StatedMonthlyIncome < 3000] <- c("0-3000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 3000 &n newloandata$StatedMonthlyIncome < 6000 ] <- c("3000-6000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 6000 &n newloandata$StatedMonthlyIncome < 9000 ] <- c("6000-9000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 9000 &n newloandata$StatedMonthlyIncome < 12000 ] <- c("9000-12000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 12000 &n newloandata$StatedMonthlyIncome < 15000 ] <- c("12000-15000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 15000 &n newloandata$StatedMonthlyIncome < 20000 ] <- c("15000-20000")nnewloandata$Monthly[newloandata$StatedMonthlyIncome >= 20000 ] <- c(">20000")nnewloandata$Monthly <- factor(newloandata$Monthly,levels=c("0-3000","3000-6000","6000-9000",n "9000-12000","12000-15000",n "15000-20000"))np1 <- ggplot(data = newloandata,n aes(x = Monthly, fill = LoanStatus)) +n geom_bar(position="fill")+ggtitle("The Loanstatus By MonthlyIncome")+n theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))nn###年收入對貸款狀態的關係nnewloandata$MonthlyIncome <- factor(newloandata$MonthlyIncome,levels=c("Not employed","Not displayed","$0",n "$1-24999","$25000-49999",n "$50000-74999","$75000-99999","$100000+"))np2 <- ggplot(data = newloandata,n aes(x = IncomeRange, fill = LoanStatus)) +n geom_bar(position="fill")+ggtitle("The Loanstatus By IncomeRange")+n theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))nlibrary(gridExtra)ngrid.arrange(p1, p2, ncol=2)n

從圖中可以看出來,月收入越高,還款率相對來說也高一點,但是區別不大,年收入也是高收入的相對來說還款率大,但是一樣是區別不大。也就是無法單憑收入判斷一個人的還款情況。

4.7 客戶7年內違約次數與貸款狀態的關係?

ggplot(data = newloandata,aes(x = DelinquenciesLast7Years, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By DelinquenciesLast7Years",n x = "DelinquenciesLast7Years",n y = "Count",n fill = "LoanStatus")n

過去7年一次也沒有違約的客戶還款率更高,而違約次數越高,還款率越低。

4.8 信用卡使用情況與貸款狀態的關係?

###8.信用卡使用情況與貸款狀態的關係?nggplot(data = newloandata,n aes(x = BankCardUse, fill = LoanStatus)) +n geom_bar(position="fill")+ggtitle("The Loanstatus By BankCardUse")+n theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))n

貸款人的信用卡使用情況為「Mild Use」和「Medium Use」的還款率相對較大,而「Super Use」還款率最低,因此可以根據使用信用卡的狀況初步確定貸款人的還款能力。

4.9 在Prosper平台是否借款與貸款狀態的關係?

###9.在Prosper平台是否借款與貸款狀態的關係?nnewloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 1000 &n newloandata$LoanOriginalAmount <4000]<-"1000-4000"nnewloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 4000 &n newloandata$LoanOriginalAmount <7000]<-"4000-7000"nnewloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 7000 &n newloandata$LoanOriginalAmount <10000]<-"7000-10000"nnewloandata$LoanOriginal[newloandata$LoanOriginalAmount >= 10000 &n newloandata$LoanOriginalAmount <=13000]<-"10000-13000"nnewloandata$LoanOriginal[newloandata$LoanOriginalAmount > 13000]<-">13000"nnewloandata$MonthlyIncome <- factor(newloandata$MonthlyIncome,levels=c("1000-4000","4000-7000",n "7000-10000","10000-13000",n ">13000"))nggplot(data=newloandata,aes(x=LoanOriginal,fill=LoanStatus))+n geom_bar(position = "fill")+n ggtitle("The Loanstatus By LoanOriginalAmount")n

在Prosper平台有借款對貸款狀態影響不大,還款率大致上趨於一致。

4.10 債務收入比例與貸款狀態的關係?

summary(newloandata$DebtToIncomeRatio)n

DebtToIncomeRatio的四分位數都是0,而最大值是10,也就是說大部分的數值是在小於1的範圍內。

###10.債務收入比例與貸款狀態的關係?nggplot(data = newloandata[newloandata$DebtToIncomeRatio < 1,],n aes(x = DebtToIncomeRatio, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By DebtToIncomeRatio",n x = "DebtToIncomeRatio",n y = "Count",n fill = "LoanStatus")n

債務比越低,還款率越高,也就是說貸款人本身的債務不高的情況下,具備還款能力越高。

4.11 借款標利率與貸款狀態的關係?

###11.借款標利率與貸款狀態的關係?nggplot(data = newloandata,n aes(x = BorrowerRate, color = LoanStatus)) +n geom_line(aes(label = ..count..), stat = bin) +n labs(title = "The LoanStatus By BorrowerRate",n x = "BorrowerRate",n y = "Count",n fill = "LoanStatus")n

借款標的利率越高,還款率越低,也就是說這個會影響貸款狀態。

第五步:建模,做預測分析

通過上述的分析,可以知道EmploymentStatusDuration、CreditScore、CreditGrade、ProsperRating.Alpha、DelinquenciesLast7Years、BankCardUse、DebtToIncomeRatio、BorrowerRate對貸款狀態有一定的影響,所以建模時將這幾個選擇為影響因子。

###建模n###訓練集和測試集,以2009年7月1日為分界點n###從loandata_before數據集中隨機抽70%定義為訓練數據集,30%為測試數據集nset.seed(156)ntain_before1 <- sample(nrow(loandata_before),0.7*nrow(loandata_before))nset.seed(156)ntain_before <- loandata_before[tain_before1,]ntest_before <- loandata_before[-tain_before1,]n###利用隨機森林建立模型nlibrary(randomForest)nbefore_mode <- randomForest(LoanStatus~StatusDuration+CreditScore+n CreditGrade+Delinquencies+n BankCardUse+DebtRatio+LoanBorrowerRate,data=tain_before,importance=TRUE)n

由於建模的變數需要因子化,且因子水平不宜很多,所以對各個因子進行分組,減少因子水平數量。對EmploymentStatusDuration、CreditScore、DelinquenciesLast7Years、DebtToIncomeRatio、BorrowerRate進行分組。

###顯示模型誤差nplot(before_mode,ylim = c(0,1))nlegend("topright",colnames(before_mode$err.rate),col=1:3,fill=1:3)n

從圖可以看出相對於預測不還款的情況,這個模型對於還款預測誤差較低,比較容易預測誰更可能還款。

###對因子的重要性進行分析nimportance <- importance(before_mode)nvarImportance <- data.frame(variables=row.names(importance),Importance=round(importance[,MeanDecreaseGini],2))n###對於變數根據重要係數進行排列nlibrary(dplyr)nrankImportance <- varImportance %>% mutate(Ranke= paste0(#,dense_rank(desc(Importance))))n###使用ggplot繪製重要變數相關係圖nggplot(rankImportance,aes(x=reorder(variables,Importance),y=Importance,fill=Importance))+n geom_bar(stat=identity)+n geom_text(aes(x=variables,y=0.5,label=Ranke),hjust=0,vjust=0.55,size=4,colour=red)+n labs(x=Variables)+n coord_flip()+theme_few()+ggtitle(The Importance of Variables)n

因子重要性排名前三的是BorrowerRate、CreditGrade、DebtToIncomeRatio。

###對測試集預測npredit_before <- predict(before_mode,test_before)npert_before <- table(test_before$LoanStatus,predit_before,dnn = c("Actual","Predicted"))n> pert_beforen PredictednActual 0 1n 0 1179 2022n 1 822 4662n

模型預測還款的人預測的比較准,但是預測準確率不高,只有67.25%,看來還需要繼續優化因子篩選。

接下來看2009年7月1日之後的模型:

###訓練集和測試集,以2009年7月1日為分界點n###從loandata_before數據集中隨機抽70%定義為訓練數據集,30%為測試數據集nset.seed(187)ntain_after1 <- sample(nrow(loandata_after),0.7*nrow(loandata_after))nset.seed(187)ntain_after <- loandata_after[tain_after1,]ntest_after <- loandata_after[-tain_after1,]n###利用隨機森林建立模型nlibrary(randomForest)nafter_mode <- randomForest(LoanStatus~StatusDuration+CreditScore+n ProsperRating.Alpha+Delinquencies+n BankCardUse+DebtRatio+LoanBorrowerRate,data=tain_after,importance=TRUE)n

查看模型評估誤差:

###顯示模型誤差nplot(after_mode,ylim = c(0,1))nlegend("topright",colnames(after_mode$err.rate),col=1:3,fill=1:3)n

同樣是更容易預測誰可以還款,為不還款的誤差較大。

###對因子的重要性進行分析nimportance <- importance(after_mode)nvarImportance <- data.frame(variables=row.names(importance),Importance=round(importance[,MeanDecreaseGini],2))n###對於變數根據重要係數進行排列nlibrary(dplyr)nrankImportance <- varImportance %>% mutate(Ranke= paste0(#,dense_rank(desc(Importance))))n###使用ggplot繪製重要變數相關係圖nggplot(rankImportance,aes(x=reorder(variables,Importance),y=Importance,fill=Importance))+n geom_bar(stat=identity)+n geom_text(aes(x=variables,y=0.5,label=Ranke),hjust=0,vjust=0.55,size=4,colour=red)+n labs(x=Variables)+n coord_flip()+theme_few()+ggtitle(The Importance of Variables)n

因子重要性排名前三的是BorrowerRate、ProsperRating.Alpha、DebtToIncomeRatio。這個跟之前的一樣。

> predit_after <- predict(after_mode,test_after)n> pert_after <- table(test_after$LoanStatus,predit_after,dnn = c("Actual","Predicted"))n> pert_aftern PredictednActual 0 1n 0 39 1855n 1 48 6542n

此時的模型預測準確率是77.57%,比起2009年7月1日前建造的模型準確率提高了很多,也就是說平台改變了信用等級後,將評估模型也進行了修改,保障了平台的利益。

而且,的確是預測還款的準確率比預測不還款的準確率要高一點。

六、總結:

通過此次練習,對於隨機森林預測模型有了更進一步的認識,在建造模型的時候,遇到了很多問題,通過在網路搜索解決問題,雖然費了一些時間,但是起碼在建造2009年7月1日之後的模型再遇上同樣問題時可以快速解決。

此處,感謝周榮技的兩篇文章:

網貸平台Prosper2005~2014數據預測分析

網貸平台Prosper2005~2014業務數據分析


推薦閱讀:

【APT報告】海蓮花團伙的活動新趨勢
快消與大數據:利用DataHunter制定異常庫存處理策略
為什麼現在那麼多妹子做數據分析師?我一個人帶4個妹子團隊壓力好大(><) 沒有性別歧視,只是好奇男的都跑哪去了?
你費那麼大勁做的數據分析,有用嗎?

TAG:数据分析 |