基于python的prosper借贷平台之数据分析

项目介绍:

p2p 借贷业务具有门槛低,渠道成本低的特性,风险防控对于出借企业来说非常重要。本项目需要

从大量借贷者的数据集中分析出容易违约和不容易违约的人群画像特征,以给业务做贷前决策使

用。同时使用机器学习算法,实现自动识别风险人群(精准率为 89.86%),加快人工审查效率。

项目具体内容:

1、使用 python pandas 工具进行数据清洗、缺失值、异常值处理以及特征指标筛选。

2、使用 python matplotlib 可视化工具进行探索式数据分析,展示用户关键特征如月收入、信用卡

透支情况对于违约率的影响情况。

3、使用机器学习随机森林进行建模分析,使用学习曲线、网格搜索、交叉验证,最终得到了一个评

分为 84.9%、精准率为 89.86%、召回率为 80.70%、auc 面积为 0.9337 数据预测模型。


一、数据预处理(上)

二、数据探索

三、数据预处理(下)

三、数据建模

    本次数据训练使用的模型是随机森林分类算法,通过对预处理过的数据集进行训练,使用学习曲线、网格搜索、交叉验证。最终得到了一个评分为84.9%、精准率为89.86%、召回率为80.70%、auc面积为0.9337数据预测模型。 


数据预处理的基本流程与思路:

1、首先要明确有多少特征,哪些是连续的,哪些是类别的。

2、检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。

3、对连续的数值型特征进行标准化,使得均值为0,方差为1。

4、对类别型的特征进行one-hot编码。

5、将需要转换成类别型数据的连续型数据进行二值化。

6、为防止过拟合或者其他原因,选择是否要将数据进行正则化。

7、在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。

8、根据实际问题分析是否需要对特征进行相应的函数转换。


一、数据预处理(上)

导入数据集,并查看数据基本情况。可以看到prosper原始数据量比较庞大,一个有113937个样本,80个特征列,1个标签列。

# 导入prosper借贷数据集

data=pd.read_csv("prosperLoanData.csv")

# 查看数据信息,有113937个样本,80个特征,一个标签。数据量较大。

# dtypes: bool(3), float64(50), int64(11), object(17)

data.info()

1.1、特征较多,先共删减一部分无用的特征。

# 删除冗余变量

data.drop(["ListingKey","ListingNumber","LoanKey","LoanNumber"], axis=1,inplace=True)

# 删除无关变量

data.drop(["FirstRecordedCreditLine","ListingCreationDate","ClosedDate","DateCreditPulled","LoanOriginationQuarter","MemberKey"], axis=1,inplace=True)

# 删除贷后变量

data.drop(["LoanCurrentDaysDelinquent","LoanFirstDefaultedCycleNumber","LoanMonthsSinceOrigination","LP_CustomerPayments","LP_CustomerPrincipalPayments","LP_InterestandFees","LP_ServiceFees","LP_CollectionFees","LP_GrossPrincipalLoss","LP_NetPrincipalLoss","LP_NonPrincipalRecoverypayments"],axis=1,inplace=True)

1.2 查看数据缺失情况,可以看到有40个特征是存在数据缺失的,缺失率从0.000219-0.882909不等。下面处理缺失数据。

# 处理数值型变量的缺失

missing= pd.concat([data.isnull().any(),data.count()],axis =1)

column= ['是否缺失','数量']

missing= pd.DataFrame(list(missing.values),index = list(missing.index),columns = column)

total= missing['数量'].max()

missing['缺失数量']= total- missing['数量']

missing['总数量']= [total]*missing.shape[0]

missing['缺失率']= missing['缺失数量']/total

miss= missing[missing['是否缺失']== True]

print("\n 数据缺失情况:\n",miss.shape)

print(miss)

1.2.1 删除缺失值比较多的特征

下面两个特征缺失率太高,且与我们要分析的相关性不大,直接删除掉。

# CreditGrade,信用等级,反映的是2009年7月1日前客户的信用级,信用等级越高,其偿债能力越强。缺失率0.745

# GroupKey,借款人是其成员的小组的关键。 如果借款人没有团体关系,价值将为空。缺失率0.882

data.drop(["CreditGrade","GroupKey"],axis=1,inplace=True)

1.2.2 获取数据类型是分类变量的所有特征,并使用unknown进行填充

categorical= data.select_dtypes(include=["object"]).columns.values

print("类型为object的特征:\n",categorical)

data[categorical]= data[categorical].fillna("Unknown")

1.2.3 特殊变量使用计算公式进行填充

# EstimatedEffectiveYield 估计的有效收益。缺失率为25%

# 有效收益等于借款人利率(i)减去服务费率,(ii)减去收取的未收取利息,(iii)加上估计收取的滞纳金。 适用于2009年7月以后发放的贷款。

# EstimatedEffectiveYield = BorrowerRate - 利率的其他费用损失

# 预估的费用损失

estimated_loss_from_fees= data["BorrowerRate"]- data["EstimatedEffectiveYield"]

data["EstimatedEffectiveYield"].fillna(data["BorrowerRate"]- estimated_loss_from_fees.median(),inplace=True)

# EstimatedReturn 在创建时分配给上市公司的预计收益。估计收益是估计的有效收益与估计损失率之间的差额。适用于2009年7月以后发放的贷款。缺失率为25%

# EstimatedReturn = EstimatedEffectiveYield - EstimatedLoss

data["EstimatedReturn"].fillna(data["EstimatedReturn"].median(), inplace=True)

data["EstimatedLoss"].fillna(data["EstimatedLoss"].median(), inplace=True)

# DebtToIncomeRatio 负债收入比。缺失率为7.5%

#DebtToIncomeRatio = MonthlyLoanPayment/StatedMonthlyIncome

#用未核实的收入来计算 DebtToIncomeRatio , 把0月收入的账户记为1

data["DebtToIncomeRatio"].fillna(data["MonthlyLoanPayment"]/ (data["StatedMonthlyIncome"]+ 1),inplace = True)

# 不可估计的用中位数填充

# ProsperRating (numeric),创建列表时分配的Prosper评级:0 - N / A,1 - HR,2 - E,3 - D,4 - C,5 - B,6 - A,7 - AA。 适用于2009年7月以后发放的贷款。缺失率25%

data["ProsperRating (numeric)"].fillna(data["ProsperRating (numeric)"].median(),inplace=True)

# ProsperScore,使用历史Prosper数据构建的自定义风险评分。 得分从1-10开始,10分是最好的,或者是最低的风险分数。 适用于2009年7月以后发放的贷款。缺失率25%

data["ProsperScore"].fillna(data["ProsperScore"].median(),inplace=True)

# 客户历史贷款数据的缺失值补0

# 用0填补缺失的Prosper历史数据

prosper_vars= ["TotalProsperLoans",# 缺失率80.6%

                "TotalProsperPaymentsBilled",# 缺失率80.6%

                "OnTimeProsperPayments",# 缺失率80.6%

                "ProsperPaymentsLessThanOneMonthLate",# 缺失率80.6%

                "ProsperPaymentsOneMonthPlusLate",# 缺失率80.6%

                "ProsperPrincipalBorrowed",# 缺失率80.6%

                "ProsperPrincipalOutstanding",

"ScorexChangeAtTimeOfListing"]# 缺失率80.6%

data[prosper_vars]= data[prosper_vars].fillna(0)

1.2.4 去掉意义重复列

# BorrowerAPR,BorrowerRate直接相关,只对BorrowerAPR进行分析;

# ProsperRating (numeric), ProsperRating (Alpha)只是不同表达形式,只使用ProsperRating (numeric);

# CreditScoreRangeUpper,CreditScoreRangeLower直接相关,使用平均信用分。

data['CreditScoreRange']=((data['CreditScoreRangeUpper']+data['CreditScoreRangeLower'])/2).round(0)

data= data.drop(['BorrowerRate','ProsperRating (Alpha)','CreditScoreRangeLower','CreditScoreRangeUpper'],axis=1)

1.2.5 删除缺失率比较少的特征的缺失数据行

data.dropna(subset=["BorrowerAPR",#0.0002%

                    "EmploymentStatusDuration",#0.066%

                    "CurrentCreditLines",#0.066%

                    "TotalCreditLinespast7years",#0.006%

                    "TotalInquiries" #0.010%

                    ]

,inplace=True)

处理完缺失数据后,样本量为106290,特征量为55

print("缺失值处理后",data.shape)

1.3 数据过滤

1.3.1 从2009年7月开始,Prosper调整了对客户的评估方式,此次我们只对2009-07-01后的贷款进行分析。

过滤完数据后,样本量变为82931,特征量为54

data= data[data['LoanOriginationDate']>'2009-7-1']

data.drop(["LoanOriginationDate"],axis=1,inplace=True)


二、数据探索

2.1单变量分析

0为未违约人数,1位违约人数,可以看到2009.07以后,违约率为22.90%

print("未违约率为:{};违约率为{}".format(1-data["LoanStatus"].mean(),data["LoanStatus"].mean()))

fig= plt.figure()

ax1= fig.add_subplot(111)

sns.countplot(data["LoanStatus"])

plt.show()

2.1.1不同地区贷款数量分布

从图中可以看到加利福尼亚州贷款数量远比其他州的数量高。由于prosper总部就位于加利福尼亚州,这与实际情况一致。其他排名靠前的分别是得克萨斯、纽约、佛罗里达、伊利诺伊,贷款数据均超过了5000条。根据2015年美国各州的GDP排名,这5个州刚好排名前五,而且顺序也是一致的。说明Prosper平台的用户主要分布在美国经济发达的地区。

State=data.BorrowerState

State_counts=State.value_counts()

print("地区分布数据",State_counts)

plt.figure(figsize=(15,10))

sns.barplot(x=State_counts.values,y=State_counts.index)

plt.title('BorrowerState',fontsize=20)

plt.xlabel('Order Numbers of each State',fontsize=20)

plt.ylabel('State in Abbreviation',fontsize=20)

plt.show()

2.1.2 贷款人收入情况分布

年薪在25000美金以上在美国属于技术性白领或者有一定学历的职员,50000美金已经是近金领阶层,比如:大学教授,医生等。从图中可以看出Prosper平台用户的收入水平都相对较高,有利于用户还款,利于平台和投资者的风险控制。

IncomeRange=data.IncomeRange

plt.figure(figsize=(15,10))

sns.countplot(IncomeRange,order=['Not employed','Not displayed','$0','$1-24,999','$25,000-49,999','$50,000-74,999','$75,000-99,999','$100,000+'])

2.1.3贷款人职业分布

从图中可以看出,除了不愿意透露具体职业的人,大部分用户是教授、程序员、企业高管等具有一定社会地位的人,这部分人受过高等教育,信用有一定保障。另外,这与之前看到的收入情况相符。

Occupation=data.Occupation

Occupation_count=Occupation.value_counts()

plt.figure(figsize=(18,10))

sns.barplot(x=Occupation_count.values,y=Occupation_count.index)

2.1.4贷款人债务收入比分布

大部分用户的债务收入比在0.2左右,超过0.5的占很少部分。说明Prosper平台用户的还款能力还是比较乐观的

DebtToIncomeRatio_1=data.loc[data.DebtToIncomeRatio<1,'DebtToIncomeRatio']

plt.figure(figsize=(15,10))

sns.distplot(DebtToIncomeRatio_1,kde=False)

2.1.5 贷款者信用卡使用情况

BankcardUtilization代表的是信用卡使用金额和信用卡额度的比值,可以体现用户的资金需求。Prosper用户多是0.5~1之间,说明用户每个月还有信用卡要还,降低了其还款能力。

2.2 相关的关键因素对贷款违约率的影响

2.2.1借贷人收入IncomeRange对违约率的影响

从图中可以看出:

1.一般来说收入越高违约率越低

2.贷款的人员主要集中在中等收入群体

# 使用groupby来统计数量

print("IncomeRange:\n",data['IncomeRange'].value_counts())

data_IncomeRange=data.groupby(['IncomeRange','LoanStatus'])['LoanStatus'].count().unstack()

# 重命名索引

data_IncomeRange=data_IncomeRange.reindex(['Not displayed','Not employed','$0','$1-24,999','$25,000-49,999','$50,000-74,999','$75,000-99,999','$100,000+'])

# 计算违约率

data_IncomeRange['DefaultedRate']=data_IncomeRange['Defaulted']/(data_IncomeRange['Defaulted']+data_IncomeRange['Completed'])

print(data_IncomeRange.head())

# 开始绘图

f,ax1=plt.subplots(figsize=(16,9))

data_IncomeRange[['Completed','Defaulted']].plot(kind='bar',ax=ax1,rot=0,fontsize=14)

ax2=ax1.twinx()

data_IncomeRange['DefaultedRate'].plot(ax=ax2,style='g.-',fontsize=14)

plt.title('DefaultedRate by IncomeRange',fontsize=20)

ax1.set_xlabel('IncomeRange',fontsize=16)

ax1.set_ylabel('Count',fontsize=16)

ax2.legend(loc='center right',fontsize=14)

ax1.legend(fontsize=14)

plt.savefig("explore/IncomeRange-LoanStatus.png")

2.2.2 债务收入比DebtToIncomeRatio对违约率的影响

从上图可以看出:

1.债务收入比小于0.6时,违约数明显小于未违约数,

2.当债务收入比大于0.6时,两者的差距不是很明显甚至违约数大于未违约数,说明了债务收入比越大的人越容易违约

f,ax=plt.subplots(figsize=(16,9))

data.loc[data['LoanStatus']=='Completed','DebtToIncomeRatio'].plot(kind='hist',bins=1000,ax=ax,label='Completed')

data.loc[data['LoanStatus']=='Defaulted','DebtToIncomeRatio'].plot(kind='hist',bins=1000,ax=ax,label='Defaulted')

plt.xlim(0,1)

plt.legend(loc='best',fontsize=14)

ax.set_xlabel('DebtToIncomeRatio',fontsize=16)

ax.set_ylabel('Count',fontsize=16)

ax.set_title('DefaultedRate by DebtToIncomeRatio',fontsize=20)

plt.savefig('explore/DebtToIncomeRatio-LoanStatus.png')

2.2.3 借款人BankcardUtilization对违约率的影响

1.总的来说,随着信用卡的透支比例越来越高,违约率也越来越高

2.SuperUse的违约率到了37.5%,这部分人群需要严格了监控,No Use人群也有31%的违约率,当初将信用卡透支比例为0和NA的数据都归类为No Use,显然没有这么简单,应该是大部分人群的NA值是为了隐藏自己的高透支比例而填写的

data_BankcardUse=data.groupby(['BankcardUse','LoanStatus'])['LoanStatus'].count().unstack()# 列转行

#按索引重新排列

data_BankcardUse=data_BankcardUse.reindex(['No Use','Mild Use','Medium Use','Heavy Use','Super Use'])

#计算对应的违约率

data_BankcardUse['DefaultedRate']=data_BankcardUse['Defaulted']/(data_BankcardUse['Defaulted']+data_BankcardUse['Completed'])

#开始绘图

f,ax1=plt.subplots(figsize=(16,9))

data_BankcardUse[['Completed','Defaulted']].plot(kind='bar',ax=ax1,rot=0,fontsize=14)

ax1.set_xlabel('BankCardUse',fontsize=16)

ax1.set_ylabel('Count',fontsize=16)

ax2=ax1.twinx()

data_BankcardUse['DefaultedRate'].plot(style='g.-',ax=ax2,fontsize=14)

ax1.legend(fontsize=14)

ax2.legend(loc='center right',fontsize=14)

plt.title('DefaultedRate by BankCardUse',fontsize=20)

plt.savefig('explore/BankCardUse-LoanStatus.png')

2.2.4 消费信用分CreditScoreRange对违约率的影响

从上图可以看出:

1.随着信用分数CreditScore的上升,它的违约率在下降

2.大部分贷款者的信用分为650-800,违约率在0.06-0.02

data_CreditScore=data.groupby(['CreditScoreRange','LoanStatus'])['LoanStatus'].count().unstack()

data_CreditScore['DefaultedRate']=data_CreditScore['Defaulted']/(data_CreditScore['Defaulted']+data_CreditScore['Completed'])

#开始绘图

f,ax1=plt.subplots(figsize=(16,9))

data_CreditScore[['Completed','Defaulted']].plot(kind='line',ax=ax1,rot=0,fontsize=14)

ax1.set_xlabel('CreditScore',fontsize=16)

ax1.set_ylabel('Count',fontsize=16)

ax2=ax1.twinx()

data_CreditScore['DefaultedRate'].plot(style='g.-',ax=ax2,fontsize=14)

ax1.legend(fontsize=14)

ax2.legend(loc='center right',fontsize=14)

plt.title('DefaultedRate by CreditScoreRange',fontsize=20)

plt.savefig('explore/CreditScore-LoanStatus.png')

2.2.5 过去7年借款人违约次数DelinquenciesLast7Years对违约率的影响

过去七年违约次数(DelinquenciesLast7Years)能够衡量一个人在过去七年中征信情况,违约一次或以上的人在借款时违约概率更大。

 从上图可以看出:

1.总体来说过去7年违约次数越多,违约率越高

2.过去7年未违约的人数相对来说比其他违约的人数高很多,具体看下面的分析

data_DelinquenciesLast7Years=data.groupby(['DelinquenciesLast7Years','LoanStatus'])['LoanStatus'].count().unstack()

data_DelinquenciesLast7Years['DefaultedRate']=data_DelinquenciesLast7Years['Defaulted']/(data_DelinquenciesLast7Years['Defaulted']+data_DelinquenciesLast7Years['Completed'])

f,ax1=plt.subplots(figsize=(16,9))

data_DelinquenciesLast7Years[['Completed','Defaulted']].plot(kind='line',ax=ax1,rot=0,fontsize=14)

ax1.set_xlabel('DelinquenciesLast7Years')

ax1.set_ylabel('Count',fontsize=16)

ax1.set_xticks(range(0,100,2))

ax1.set_xticklabels(range(0,100,2))

ax2=ax1.twinx()

data_DelinquenciesLast7Years['DefaultedRate'].plot(style='g.-',ax=ax2,fontsize=14)

ax1.legend(fontsize=14)

ax2.legend(loc='center right',fontsize=14)

plt.title('DefaultedRate by DelinquenciesLast7Years',fontsize=20)

plt.savefig('explore/DelinquenciesLast7Years-LoanStatu.png')


三、数据预处理(下)

3.1 数据转化

3.1.1类变量进行哑变量化

样本量变为82931,特征量为127

def harmonize_data(df):

    # bool值变成0,1

    df["IsBorrowerHomeowner"]=df["IsBorrowerHomeowner"].astype(int)

    df["IncomeVerifiable"]= df["IncomeVerifiable"].astype(int)

    df["CurrentlyInGroup"]= df["CurrentlyInGroup"].astype(int)

    # BorrowerState(贷款人所在州)

    le= LabelEncoder().fit(df['BorrowerState'].astype(str))

    df.loc[:,'BorrowerState']= le.transform(df['BorrowerState'].astype(str))

    # Occupation(贷款人职业)

    occupation= pd.get_dummies(df["Occupation"])

    df= df.join(occupation,rsuffix="_Occupation")

    df.drop("Occupation",axis=1,inplace=True)

    ## EmploymentStatus

    employment= pd.get_dummies(df["EmploymentStatus"])

    df= df.join(employment,rsuffix="_employmentstatus")

    df.drop("EmploymentStatus",axis=1,inplace=True)

    #IncomeRange(贷款人年收入范围)

    df.loc[df['IncomeRange']== 'Not displayed','IncomeRange']= 0

    df.loc[df['IncomeRange']== 'Not employed','IncomeRange']= 1

    df.loc[df['IncomeRange']== '$0','IncomeRange']= 2

    df.loc[df['IncomeRange']== '$1-24,999','IncomeRange']= 3

    df.loc[df['IncomeRange']== '$25,000-49,999','IncomeRange']= 4

    df.loc[df['IncomeRange']== '$50,000-74,999','IncomeRange']= 5

    df.loc[df['IncomeRange']== '$75,000-99,999','IncomeRange']= 6

    df.loc[df['IncomeRange']== '$100,000+','IncomeRange']= 7

    return df

data= harmonize_data(data)

3.1.2 标签变量进行二分类

已完成贷款的样本量变为26365,特征量为127

# 根据投资人有无损失,贷款是否完成将已关闭的交易分为四组

# Cancelled:贷款取消

# Defaulted:包含Defaulted、Chargedoff

# Current:贷款还款中

# Completed:包含Completed、FinalPaymentInProgress、Past Due

def switch_data1(x):

    if x=='Current':

        y='Current'

    elif x=='Chargedoff' or x=='Defaulted':

        y='Defaulted'

    elif x=='Cancelled':

        y='Cancelled'

    else:

        y='Completed'

    return y

# 转换数据

data['LoanStatus']=data['LoanStatus'].apply(switch_data1)

# 由于Cancelled数据只有五条,现将其去除

data=data[data['LoanStatus']!='Cancelled']

#将数据集分成已完成(Loandata_finished)和未完成(Loandata_unfinished)两部分

data_unfinished = data[data['LoanStatus']=='Current']

data = data[data['LoanStatus']!='Current']

data["LoanStatus"] = (data["LoanStatus"] == "Completed").astype(int)

未违约率为:0.7709084012895885;违约率为0.22909159871041151

print("未违约率为:{};违约率为{}".format(data["LoanStatus"].mean(),1-data["LoanStatus"].mean()))

fig = plt.figure()

ax1 = fig.add_subplot(221)

sns.countplot(data["LoanStatus"])

plt.show()


3.2 至此,数据预处理的工作就告一段落,保存预处理好的数据。

data.to_csv("prosperLoanData-clean-finished.csv",index=False)

data_unfinished.to_csv("prosperLoanData-clean-unfinished.csv",index=False)


四、建模建模

 导入经过预处理的prosper借贷数据集

data=pd.read_csv("prosperLoanData-clean-finished.csv")

Y= data['LoanStatus']

X= data.drop(["LoanStatus"],axis=1) 

4.1 手工挑选特征查看一下建模效果

准确率为0.7695

X = data[['ProsperRating (numeric)','IncomeRange','DebtToIncomeRatio', 'BankcardUtilization','StatedMonthlyIncome', 'IsBorrowerHomeowner','ListingCategory (numeric)', 'EmploymentStatusDuration', 'InquiriesLast6Months', 'CreditScoreRange','BorrowerState', 'CurrentDelinquencies', 'LoanOriginalAmount']]

print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

#建立模型

rfc = RandomForestClassifier(random_state=42,n_estimators=100)

score = cross_val_score(rfc, X, Y, cv=10).mean()

print("初步看一下准确率",score)

print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

4.2 使用模型自己选取特征

准确率为0.7780

Y= data['LoanStatus']

X= data.drop(["LoanStatus"],axis=1)

4.3 使用学习曲线选取最优n_estimators

在0-200/20内学习,得到最优n_estimators=161,score = 0.8508

在151-171/20内学习,得到最优n_estimators=163,score = 0.8511

#print ("n_estimators学习曲线开始:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

score1= []

# for i in range(1,201,20): # 161附近,0.7777左右

for i in range(151,171,2):

    rfc= RandomForestClassifier(n_estimators=i,random_state=42)

    scores= cross_val_score(rfc,X,Y,cv=10)

    score1.append(scores.mean())

print ("n_estimators学习曲线结束:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

print(score1)

# 0.7782668779703795,171

print("最高的准确率",max(score1),score1.index(max(score1)))

plt.figure(figsize=[15,10])

plt.plot(range(151,171,2),score1)

# plt.plot(range(1,201,20),score1)

plt.show()

4.4 使用网格搜索调其他参数

在0-60/5内学习,得到最优max_depth=41

在0-60/5内学习,得到最优max_features=16

这里由于比较耗时,没有进一步细化选择更高的参数

print ("网格搜索学习曲线开始:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

param_grid= {'max_depth':np.arange(1,60,5)}# {'max_depth': 41} 0.7769 ,9分钟

param_grid= {'max_features':np.arange(1,60,5)}# {'max_features': 16} 0.7778 ,27分钟

rfc= RandomForestClassifier(n_estimators=84)

GS= GridSearchCV(rfc,param_grid,cv=10)

GS.fit(X,Y)

print ("网格搜索学习曲线结束:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

print(GS.best_params_)

print(GS.best_score_)

4.4 最终模型效果

最终准确率 0.8490528905289052

混淆矩阵:

[[5552  554]

[1175 4914]]

精准率: [0.82533076 0.89868325]

召回率: [0.90926957 0.80702907]

roc和auc面积为0.9337

4.5 查看各特征的重要性

FeatureImp= pd.Series(rfc.feature_importances_,index=list(X_train.columns)).sort_values(ascending=False)

#特征重要性作图

plt.figure(figsize=(18,20))

print("特征重要程度")

print(FeatureImp[:20])

FeatureImp[:20].sort_values(ascending=True).plot(kind='barh')

plt.xlabel('Feature Importance')

plt.title('Feature Importance')

plt.show()

重要特征.png

4.6 数据预测

预测的违约率0.0427

X_unfinished= data_unfinished.drop(["LoanStatus"],axis=1)

unfinished_predict= rfc.predict(X_unfinished)

X_unfinished['LoanStatusPredict']= pd.DataFrame(unfinished_predict)

print(unfinished_predict)

defaulted_ratio_predict= 1-X_unfinished['LoanStatusPredict'].mean()

print("预测的违约率",defaulted_ratio_predict)

#保存预测数据

X_unfinished.to_csv('LoanData_unfinished_predict.csv')

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容