↑↑↑关注后"星标"Datawhale
每日干货 & 每月组队学习,不错过
Datawhale干货
作者:陶旭东,北京师范大学,Datawhale成员
一、背景介绍
本文以天池的金融风控赛为背景,梳理了金融风控的整个实践流程,帮助大家避坑学习。赛事的场景是个人信贷,要求选手根据贷款申请人的数据信息预测其是否有违约的可能,以此判断是否通过此项贷款,这个问题在现实的风控场景中很常见,属于典型的分类问题。另外,准入模型,评分卡模型皆是属于这个范畴。
二、数据概况
数据下载地址:https://tianchi.aliyun.com/competition/entrance/531830/information(阿里天池-金融风控赛事)
本次数据训练集80万数据,测试集20万数据。原始特征47维,其中匿名特征15个。详细字段如下:
- id 为贷款清单分配的唯一信用证标识
- loanAmnt 贷款金额
- term 贷款期限(year)
- interestRate 贷款利率
- installment 分期付款金额
- grade 贷款等级
- subGrade 贷款等级之子级
- employmentTitle 就业职称
- employmentLength 就业年限(年)
- homeOwnership 借款人在登记时提供的房屋所有权状况
- annualIncome 年收入
- verificationStatus 验证状态
- issueDate 贷款发放的月份
- purpose 借款人在贷款申请时的贷款用途类别
- postCode 借款人在贷款申请中提供的邮政编码的前3位数字
- regionCode 地区编码
- dti 债务收入比
- delinquency_2years 借款人过去2年信用档案中逾期30天以上的违约事件数
- ficoRangeLow 借款人在贷款发放时的fico所属的下限范围
- ficoRangeHigh 借款人在贷款发放时的fico所属的上限范围
- openAcc 借款人信用档案中未结信用额度的数量
- pubRec 贬损公共记录的数量
- pubRecBankruptcies 公开记录清除的数量
- revolBal 信贷周转余额合计
- revolUtil 循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额
- totalAcc 借款人信用档案中当前的信用额度总数
- initialListStatus 贷款的初始列表状态
- applicationType 表明贷款是个人申请还是与两个共同借款人的联合申请
- earliesCreditLine 借款人最早报告的信用额度开立的月份
- title 借款人提供的贷款名称
- policyCode 公开可用的策略_代码=1新产品不公开可用的策略_代码=2
- n系列匿名特征 匿名特征n0-n14,为一些贷款人行为计数特征的处理
三、数据分析:
数据探索性分析即我们常说的EDA过程,此过程以了解数据,熟悉数据,为后续的特征工程做准备为目的。需要了解整个数据集的基本情况(缺失值,异常值),变量间的相互关系、变量与预测值之间的存在关系,为特征工程做准备。
3.1 使用pandas读取训练集和测试集文件,并使用其进行处理
data_train = pd.read_csv('./train.csv')
data_test_a = pd.read_csv('./testA.csv')
读取文件的拓展知识:
pandas读取数据时相对路径载入报错时,尝试使用os.getcwd()查看当前工作目录。
TSV与CSV的区别:
从名称上即可知道,TSV是用制表符(Tab,'\t')作为字段值的分隔符;CSV是用半角逗号(',')作为字段值的分隔符;
Python对TSV文件的支持:
Python的csv模块准确的讲应该叫做dsv模块,因为它实际上是支持范式的分隔符分隔值文件(DSV,delimiter-separated values)的。
delimiter参数值默认为半角逗号,即默认将被处理文件视为CSV。当delimiter='\t'时,被处理文件就是TSV。
读取文件的部分(适用于文件特别大的场景)
通过nrows参数,来设置读取文件的前多少行,nrows是一个大于等于0的整数。
分块读取
3.2 查看数据集的样本个数和原始特征维度
data_test_a.shape
Out [53]:(200000, 48)
data_train.shape
Out [53]:(800000, 47)
查看所有列:
data_train.columns
Index(['id', 'loanAmnt', 'term', 'interestRate', 'installment', 'grade',
'subGrade', 'employmentTitle', 'employmentLength', 'homeOwnership',
'annualIncome', 'verificationStatus', 'issueDate', 'isDefault',
'purpose', 'postCode', 'regionCode', 'dti', 'delinquency_2years',
'ficoRangeLow', 'ficoRangeHigh', 'openAcc', 'pubRec',
'pubRecBankruptcies', 'revolBal', 'revolUtil', 'totalAcc',
'initialListStatus', 'applicationType', 'earliesCreditLine', 'title',
'policyCode', 'n0', 'n1', 'n2', 'n2.1', 'n4', 'n5', 'n6', 'n7', 'n8',
'n9', 'n10', 'n11', 'n12', 'n13', 'n14'],
dtype='object')
通过info()来熟悉数据类型:
总体粗略的查看数据集各个特征的一些基本统计量:
3.3 查看缺失值
print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')
There are 22 columns in train dataset with missing values.
了解哪些列存在 “nan”, 并可以把nan的个数打印,主要的目的在于 nan存在的个数是否真的很大,如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉。
3.4 查看异常值
3.4.1 检测异常的方法一:均方差
在统计学中,如果一个数据分布近似正态,那么大约 68% 的数据值会在均值的一个标准差范围内,大约 95% 会在两个标准差范围内,大约 99.7% 会在三个标准差范围内。
def find_outliers_by_3segama(data,fea):
data_std = np.std(data[fea])
data_mean = np.mean(data[fea])
outliers_cut_off = data_std * 3
lower_rule = data_mean - outliers_cut_off
upper_rule = data_mean + outliers_cut_off
data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x < lower_rule else '正常值')
return data
3.4.2检测异常的方法二:箱型图
总结一句话:四分位数会将数据分为三个点和四个区间,IQR = Q3 -Q1,下触须=Q1 − 1.5* IQR,上触须=Q3 + 1.5* IQR;
3.5 查看特征的数值类型
特征一般都是由类别型特征和数值型特征组成,类别型特征有时不仅仅代表特征属性不同的一个分类,有时各个属性之间还具有数值关系。比如特征‘grade’中的属性为等级A,B,C等,不同的类别属性A,B,C之间和逾期率是正比关系的。
数值型特征本是可以直接入模的,但往往风控人员要对其做分箱,转化为WOE编码进而做标准评分卡等操作。从模型效果上来看,特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,从而使模型更加稳定。
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
3.5.1 查看某一个离散特征的逾期率:(其他离散特征均可以如此分析,比如贷款期限等)
#贷前等级的逾期情况