个人贷款违约预测模型
1 项目介绍
本项目通利用Kaggle平台predict-loan-defaulters (网盘下载提取码: tkup)贷款数据,通过逻辑回归模型来对这些数据进行预测判断,构建贷款违约预测模型,建立预测模型,预测正处于贷款期间的人的违约的概率 。
业务理解
在贷款管理方面,如果可以通过构建量化模型对客户的信用等级进行一定的区分。得知了每个账户的违约概率后,可以预估一下未来的坏账比例,及时做好资金安排。也可以对违约概可能性较高的客户进行更加频繁的“关怀”,及时发现问题,以避免损失。
在这个量化模型中,被解释变量为二分类变量,因此需要构建一个排序类分类模型。而排序类分类模型中常使用的算法是逻辑回归。
1.2 数据介绍
实际业务中的一个人可以拥有多个账户号(account_id),一个账户号(account_id)可以对应有多个顾客(client_id),即多个顾客共享一个账户号(account_id),但是每个帐户号(account_id)的所有者(即最高权限者)只能是一人。
账户号(account_id)与客户号(client_id)的对应关系,在表“disposition”中进行列示;
表“Loan”为银行提供给账户号(account_id)的服务;
表“Credit card”为银行提供给的顾客(client_id)的服务,每个客户可以申请一张信用卡;
贷款为基于账户的服务,一个账户(account_id)在一个时点最多只能有一笔贷款。
本次数据建模分析共用了八个数据表:
2 数据处理
2.1 导入数据
import pandas as pd import os os.chdir("data") # 数据文件存放在"data"文件夹里 loanfile = os.listdir() createVar = locals() for i in loanfile: if i.endswith("txt"): createVar[i.split('.')[0]] = pd.read_csv(i, encoding = 'gbk',sep=';') print(i.split('.')[0])
accounts card clients disp district loans order trans
- 预览数据
loans.head()
loans.info()
2.2 生成被解释变量bad_good
贷款表(loans)中的还款的状态可分为 A:代表合同终止,没问题B:代表合同终止,贷款没支付C:代表合同处于执行期,至今正常;D:代表合同处于执行期,欠债状态。对数据进行转换,使A=0,B、D=1,C=2
bad_good = {'B':1, 'D':1, 'A':0, 'C': 2} loans['bad_good'] = loans.status.map(bad_good) loans.head()
2.3 数据整理
- 借款人的年龄、性别
data2 = pd.merge(loans, disp, on = 'account_id', how = 'left') data2 = pd.merge(data2, clients, on = 'client_id', how = 'left') data2=data2[data2.type=='所有者'] data2.head()
- 借款人居住地的经济状况
data3 = pd.merge(data2, district, left_on = 'district_id', right_on = 'A1', how = 'left') data3.head()
- 变异系数的计算:先计算每个账户余额的平均值和标准差,然后用标准差/均值。
data_4temp1 = pd.merge(loans[['account_id', 'date']], trans[['account_id','type','amount','balance','date']], on = 'account_id') data_4temp1.columns = ['account_id', 'date', 'type', 'amount', 'balance', 't_date'] data_4temp1 = data_4temp1.sort_values(by = ['account_id','t_date']) # 日期格式转换:将data_4temp1的date和t_date列数据类型转换为时间类型 data_4temp1['date']=pd.to_datetime(data_4temp1['date']) data_4temp1['t_date']=pd.to_datetime(data_4temp1['t_date']) data_4temp1.tail()
- 账户余额进行清洗
# 将data4_t1的amount和balance列数据类型转换为数值类型 data_4temp1['balance2'] = data_4temp1['balance'].map( lambda x: int(''.join(x[1:].split(',')))) data_4temp1['amount2'] = data_4temp1['amount'].map( lambda x: int(''.join(x[1:].split(',')))) data_4temp1.head()
- 根据取数窗口(设置为1年)提取交易数据
import datetime data_4temp2 = data_4temp1[data_4temp1.date>data_4temp1.t_date][ data_4temp1.date<data_4temp1.t_date+datetime.timedelta(days=365)] data_4temp2.tail()
- 得到变异系数
data_4temp3 = data_4temp2.groupby('account_id')['balance2'].agg({'avg_balance':'mean', 'stdev_balance':'std'}) data_4temp3['cv_balance'] = data_4temp3[['avg_balance','stdev_balance']].apply(lambda x: x[1]/x[0],axis = 1) data_4temp3.head()
- 平均支出和平均收入的比例
type_dict = {'借':'out','贷':'income'} data_4temp2['type1'] = data_4temp2.type.map(type_dict) data_4temp4 = data_4temp2.groupby(['account_id','type1'])[['amount2']].sum() data_4temp5 = pd.pivot_table( data_4temp4, values = 'amount2', index = 'account_id', columns = 'type1') data_4temp5.fillna(0, inplace = True) data_4temp5['r_out_in'] = data_4temp5[ ['out','income']].apply(lambda x: x[0]/x[1], axis = 1) data4 = pd.merge(data3, data_4temp3, left_on='account_id', right_index= True, how = 'left') data4 = pd.merge(data4, data_4temp5, left_on='account_id', right_index= True, how = 'left') data4.head()
- 计算贷存比,贷收比
data4['r_lb'] = data4[['amount','avg_balance']].apply(lambda x: x[0]/x[1],axis = 1) data4['r_lincome'] = data4[['amount','income']].apply(lambda x: x[0]/x[1],axis = 1) data4.head()
3 构建Logistic模型
数据挖掘方法分为分类和描述两大类,其中预测账户的违约情况属于分类模型。使用逻辑回归对刚才创建的数据建立模型,建模语句如下。
- 提取状态为C的用于预测。其它样本随机抽样,建立训练集与测试集
data_model=data4[data4.status!='C'] for_predict=data4[data4.status=='C'] train = data_model.sample(frac=0.7, random_state=1235).copy() test = data_model[~ data_model.index.isin(train.index)].copy() print(' 训练集样本量: %i \n 测试集样本量: %i' %(len(train), len(test))
训练集样本量: 195 测试集样本量: 84
- 向前法 筛选有用的字段名
def forward_select(data, response): import statsmodels.api as sm import statsmodels.formula.api as smf remaining = set(data.columns) remaining.remove(response) selected = [] current_score, best_new_score = float('inf'), float('inf') while remaining: aic_with_candidates=[] for candidate in remaining: formula = "{} ~ {}".format( response,' + '.join(selected + [candidate])) aic = smf.glm( formula=formula, data=data, family=sm.families.Binomial(sm.families.links.logit) ).fit().aic aic_with_candidates.append((aic, candidate)) aic_with_candidates.sort(reverse=True) best_new_score, best_candidate=aic_with_candidates.pop() if current_score > best_new_score: remaining.remove(best_candidate) selected.append(best_candidate) current_score = best_new_score print ('aic is {},continuing!'.format(current_score)) else: print ('forward selection over!') break formula = "{} ~ {} ".format(response,' + '.join(selected)) print('final formula is {}'.format(formula)) model = smf.glm( formula=formula, data=data, family=sm.families.Binomial(sm.families.links.logit) ).fit() return(model)
candidates = ['bad_good', 'A1', 'GDP', 'A4', 'A10', 'A11', 'A12','amount', 'duration', 'A13', 'A14', 'A15', 'a16', 'avg_balance', 'stdev_balance', 'cv_balance', 'income', 'out', 'r_out_in', 'r_lb', 'r_lincome'] data_for_select = train[candidates] lg_m1 = forward_select(data=data_for_select, response='bad_good') lg_m1.summary().tables[1]
- 可见,预测效果最佳的两个因素是:
贷存比 (r_lb ) ,可反映客户用钱的需求度
存款变异系数(cv_balance),可反映客户经济状况是否稳定 - 假设显著性水平设定为0.01,由上图可知,逻辑回归各变量都已通过显著性检验,满足要求
4 模型验证
要验证模型的预测能力,通过ROC曲线和AUC来评估模型的拟合能力。
from sklearn.metrics import roc_curve,auc import matplotlib.pyplot as plt fpr,tpr,threshold=roc_curve(test.bad_good, lg_m1.predict(test)) rocauc=auc(fpr,tpr) plt.plot(fpr,tpr,'b',label='AUC=%0.2f'% rocauc) plt.legend(loc='lower right') plt.plot([0,1],[0,1],'r--') plt.title('ROC curve') plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.show()
从上图可知,AUC值为0.88,说明模型的预测能力较好。
5 测试模型
- 在这个案例中,贷款状态为”C”的帐户是尚没有出现违约的合同未到期客户。这些贷款客户中有些人的违约可能性较高,需要业务人员重点关注。一旦发现问题时,可以及时处理,挽回损失。可以通过以下语句得到每笔贷款的违约”概率”。
for_predict['prob']=lg_m1.predict(for_predict) for_predict[['account_id','prob']].head()
结论:由测试模型得出账户号为1071,5313的客户违约的概率比较高,需要注意
6 参考文献
- 宽胖子. 数据科学实战:Python篇(案例:个人贷款违约预测模型)
- bombTree. 基于逻辑回归模型 下的简单用户违约预测分析 .csdn
- qq_39963880.全栈技术详解1-个人贷款违约预测模型 .csdn
附:百度网盘 predict-loan-defaulters .zip 提取码: tkup
阅读更多- 【python】Logistics模型预测银行贷款违约
- 信用卡违约客户的预测模型的选择(二)验证过程
- Loan default predictor(贷款违约预测)
- 信用卡违约客户的预测模型的选择(三)线性回归
- 信用卡违约客户的预测模型的选择(四)logistic模型及模型比较
- 信用卡违约客户的预测模型的选择(一)相关技术介绍
- (1)风控算法实践之用户贷款违约预测——问题描述与思路
- 基于逻辑回归模型 下的简单用户违约预测分析
- 用R做逻辑回归之汽车贷款违约模型
- 如何预测一个互联网产品的未来:一套关于产品的数学模型
- 民间借贷是为了弥补国家金融体系放贷不做,中小企业业主和个人贷款难的问题而存在的
- Tensorflow使用的预训练的resnet_v2_50,resnet_v2_101,resnet_v2_152等模型预测,训练
- 使用基于Apache Spark的随机森林方法预测贷款风险
- 【TensorFlow系列】【五】利用inception v3 pb模型文件做预测
- 2010年9月到2011年8月个人总结 --知识就是模型
- 集成模型(回归)对Boston数据进行训练并对数据做出预测
- 灰色预测模型
- 用flask开发个人博客(23)—— flask中的数据模型关系
- 利用树的集成回归模型RandomForestRegressor/ExtraTreesRegressor/GradientBoostingRegressor进行回归预测(复习11)
- 简单数据预测—使用Python训练回归模型并进行预测(转自蓝鲸网站分析博客)