开门见山
目录:
1 背景介绍
2 基本数据处理
3 公司总体分析
4 贷款人分析
5 用户特征与违约率的关系
结论:
没有特别提到年份的地方,默认是18年。
公司:
从贷款数量上来看,07年到15年,经营规模发展得很快,但是15年到18年,经营规模没有明显提高,尤其15年到17年,基本没有进步。
13年的整体坏账率15.6%,13年到15年的3年期贷款坏账率逐年上升趋势明显。
从贷款规模上看,公司没有明显的淡旺季,年初偏低一点点。
公司对贷款人的信息并不是全部验证,可能由于公司对于申报信息未验证的贷款人审核更加严格,他们的违约率甚至低于信息已验证的贷款人。
贷款人:
住房以按揭和租住为主,两者合计占比超过85%。
工作年限偏低。
贷款人的平均年收入为8万美元,超过美国平均水平的两倍。贷款人的负债收入比不高,均值为21.9%,中位数为17.7%。单笔借贷金额比较集中在1到2万,中位数1.6万,最高也只有4万,贷款金额不高。
贷款人平均在用的信用产品数量为23。
贷款人特征与违约率的关系:
年收入越高,越不容易违约
负债收入比高于20时,违约率与dti正相关。但是也发现dti最低的十分之一,居然是违约率最高的人群。
工作年限对贷款人违约率的影响比较小,工作超过九年的贷款人违约率相对偏低,未填报工作年限的贷款人违约率较高。
当正在使用的信用产品数量较低时,违约率相对较高;当这个数量较高时,其与违约率关系不大。
能看出对信用评级比较差的,F、G这类的贷款人,还款期还没结束,就有超过10%会违约或拖欠还款。
相对于租房和已有房的贷款人,按揭买房的贷款人违约率低很多。
贷款目的:去除小样本类别后,small business的贷款人违约率最高。
背景介绍
LendingClub是美国最大的网络借贷平台,2006年成立,2014年12月在纽交所上市,以15美元发行,首日报收23.43美元,较发行价大涨56.20%。在18年年底跌至不到2.5美元,目前在10美元左右。
LendingClub的核心竞争力之一就是其成熟有效的基于FICO信用数据的风控模型。FICO信用分是由美国个人消费信用评估公司开发出的一种个人信用评级法,已经得到美国社会广泛接受。借款人提交贷款申请,LendingClub的系统会进行初步筛选,最终将借款人归入A至G共7个等级,每个等级又包含1至5五个子级,共有35个贷款等级。LendingClub会根据借款人的信用报告对每笔借款申请制定不同的借款利率,实行差别定价,等级越高,利率越低。
身为美国P2P龙头,LendingClub在上市前一直高速发展,2014年因收购Springstone而陷入巨额亏损,但其真正陨落是因为其创始人违规事件:LendingClub创始人Renaud Laplanche为达成2016年业绩目标篡改了两笔总额2200万美元贷款的申请日期,并将其违规出售给了机构投资者。2016年5月,Renaud Laplanche引咎辞职,直接导致其单日股价暴跌35%。
基本数据处理
这里用到的数据源在Kaggle上:https://www.kaggle.com/wendykan/lending-club-loan-data
或者去LendingClub官网也能找到,可以选择下载的具体年份,灵活一些,Kaggle只能全部下载。
这里我只选取了10个重要特征,原数据特征有140多个。
from IPython.core.interactiveshell import InteractiveShell
from jupyterthemes import jtplot
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from time import time
import datetime
#魔法函数
%matplotlib inline
#matplotlib 支持中文
#plt.rcParams['font.sans-serif'] = ['SimHei']
# matplotlib 正常显示负号
#plt.rcParams['axes.unicode_minus'] = False
#dataframe显示不换行
pd.set_option('expand_frame_repr', False)
pd.set_option('display.max_rows', 200)
pd.set_option('display.max_columns', 200)
#选择一个绘图主题与本身主题对应
jtplot.style(theme='oceans16')
#一个cell显示多个输出结果
InteractiveShell.ast_node_interactivity = "all"
data = pd.read_csv('PendingClubData.csv', header=0, parse_dates=['issue_d'])
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2260668 entries, 0 to 2260667
Data columns (total 13 columns):
# Column Dtype
--- ------ -----
0 issue_d datetime64[ns]
1 annual_inc float64
2 term object
3 loan_amnt int64
4 int_rate float64
5 verification_status object
6 home_ownership object
7 emp_length object
8 purpose object
9 grade object
10 total_acc float64
11 dti float64
12 loan_status object
dtypes: datetime64[ns](1), float64(4), int64(1), object(7)
memory usage: 224.2+ MB
字段名 | 具体含义 | 值集 |
---|---|---|
annual_inc | 贷款人申报年收入 | - |
verification_status | 填报信息是否经过验证 | Verified/Source Verified/Not Verified |
issue_d | 贷款发放月份 | - |
dti | 债务收入比 | - |
total_acc | 贷款人正在使用的信用产品数量 | - |
home_ownership | 贷款人房屋使用类型 | MORTGAGE/RENT/OWN/ANY/OTHER/NONE |
emp_length | 工作年限 | - |
purpose | 贷款目的 | - |
term | 还款时间 | 3年/5年 |
loan_amnt | 贷款本金额 | - |
grade | 信用等级 | A到G |
loan_status | 贷款状态 | - |
loan_status的值集 | 具体含义 |
---|---|
Fully Paid | 结清,完全到期还清 |
Current | 正常还款,还未到最后一个还款期 |
Charged Off | 坏账 |
Late (31-120 days) | 逾期31—120天 |
In Grace Period | 处于宽限期 |
Late (16-30 days) | 逾期16—30天 |
Default | 违约 |
issued | 审批通过 |
观察是否有缺失值
data.isnull().sum()
issue_d 0
annual_inc 4
term 0
loan_amnt 0
int_rate 0
verification_status 0
home_ownership 0
emp_length 146907
purpose 0
grade 0
total_acc 29
dti 1711
loan_status 0
dtype: int64
看下债务收入比dti的缺失值是不是由于收入很低接近0产生的
data.loc[data['dti'].isnull(), 'annual_inc'].sum()
111.36
dti有缺失值1711行的所有annual_inc年收入加一起只有100万,可以认为是收入过低造成的dti缺失值,处理方法是:填充缺失值为该特征最大值。
total_acc和emp_length缺失值填充为0
annual_inc删除缺失值
data[['emp_length']] = data[['emp_length']].fillna('unknown')
data = data.loc[(data['annual_inc'].notnull()) & (data['total_acc'].notnull()), :]
data.loc[data['dti'].isnull(), 'dti'] = data['dti'].max()
data.isnull().sum()
issue_d 0
annual_inc 0
term 0
loan_amnt 0
int_rate 0
verification_status 0
home_ownership 0
emp_length 0
purpose 0
grade 0
total_acc 0
dti 0
loan_status 0
dtype: int64
填充缺失值后,把index转换为正常的从0开始依次增加1
data = data.reset_index(drop=True)
data.head()
issue_d | annual_inc | term | loan_amnt | int_rate | verification_status | home_ownership | emp_length | purpose | grade | total_acc | dti | loan_status | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2018-12-01 | 55000.0 | 36 months | 2500 | 13.56 | Not Verified | RENT | 10+ years | debt_consolidation | C | 34.0 | 18.24 | Current |
1 | 2018-12-01 | 90000.0 | 60 months | 30000 | 18.94 | Source Verified | MORTGAGE | 10+ years | debt_consolidation | D | 44.0 | 26.52 | Current |
2 | 2018-12-01 | 59280.0 | 3 |