天池竞赛:金融风控-贷款违约预测

竞赛地址:https://tianchi.aliyun.com/competition/entrance/531830/information

 

一、简介

1.1 赛题描述

    赛题以金融风控中的个人信贷为背景,要求选手根据贷款申请人的数据信息预测其是否有违约的可能,以此判断是否通过此项贷款,这是一个典型的分类问题。

1.2 比赛评估

  提交结果为每个测试样本是1的概率,也就是y为1的概率。评价方法为AUC评估模型效果(越大越好)。

 为了更好地理解AUC值,先说下ROC,以下是ROC曲线,

  • 横坐标:1-Specificity,伪正类率(False positive rate, FPR),预测为正但实际为负的样本占所有负例样本的比例;
  • 纵坐标:Sensitivity,真正类率(True positive rate, TPR)预测为正且实际为正的样本占所有正例样本的比例。

  AUC (Area Under Curve) 被定义为ROC曲线下的面积,

1.3数据描述

    该数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。为了保证比赛的公平性,将会从中抽取80万条作为训练集,20万条作为测试集A,20万条作为测试集B,同时会对employmentTitle、purpose、postCode和title等信息进行脱敏。

二、描述性分析

1、读取数据

2、查看数据特征类型

data.info()

根据数据类型划分为类别变量和数值变量,方面后续的分析; 

category_features = ['grade', 'subGrade', 'homeOwnership','verificationStatus','issueDate',
                     'purpose','postCode','regionCode','initialListStatus','applicationType','earliesCreditLine',
                     'title','policyCode']
numerical_features = ['loanAmnt', 'term','employmentLength','interestRate', 'employmentTitle','installment','annualIncome', 'dti',
                      'delinquency_2years', 'ficoRangeLow','ficoRangeHigh', 'openAcc', 
                      'pubRec', 'pubRecBankruptcies', 'revolBal', 'revolUtil', 'totalAcc']
anonymity_features = ['n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8','n9', 'n10', 'n11', 'n12', 'n13', 'n14']

y_feature= 'isDefault'

3、查看目标变量的分布

从结果中显示,0和1的比例为8:2,即80%用户贷款有违约的,20%的用户贷款没有违约的;

三、特征工程

1、查看缺失特征及缺失率

结果显示,以上特征是存在缺失数值的,为了后面的建模,需要对缺失值进行处理。

2、处理缺失值

(1)对于不同类型的特征,每个特征中缺失率的大小来采取不同的填充方法;对于类别变量,并且缺失值较少的特征,可以使用众数来填充;

employmentTitle_fillna = data['employmentTitle'].mode().values[0]
data['employmentTitle'].fillna(employmentTitle_fillna,inplace=True)
title_fillna = data['title'].mode().values[0]
data['title'].fillna(title_fillna,inplace=True)
postCode_fillna = data['postCode'].mode().values[0]
data['postCode'].fillna(postCode_fillna,inplace=True)

(2)可以根据缺失值与其他特征的关系,根据某个特征进行分组汇总,使用每个组内平均值填充;比如employmentLength:就业年限(年,可以使用同就业职称的平均就业年限填充。

# 处理就业年限(年),<1年令其为0,大于10年令其为10;
data['employmentLength'].replace('< 1 year','0 year',inplace=True)
data['employmentLength'].replace('10+ years','10 year',inplace=True)
data['employmentLength'] = data['employmentLength'].apply(lambda x:float(str(x).split(' ')[0]))

# 填充缺失值,使用同就业职称的平均就业年限填充
employmentLenght_fillna = data.groupby('employmentTitle')['employmentLength'].mean().reset_index()
employmentLenght_fillna.rename(columns={'employmentLength':'employmentLengthByTitle'},inplace=True)
data = pd.merge(data,employmentLenght_fillna,on='employmentTitle',how='left')
data['employmentLength'] = np.where(data['employmentLength'].isna(),data['employmentLengthByTitle'],
                                    data['employmentLength'])
data.drop(columns='employmentLengthByTitle',inplace=True)

(3)根据特征的现实经济意义填充。比如dti(债务收入比),同时annualIncome(年收入)和loanAmnt(贷款金额)可知,当dti为na值时,年收入为0,从经济含义是上看是由于无年收入导致债务收入比为na,从另一层面上也可以理解成债务收入比为无限大,但是无限大这数据不太符合实际应用,故这里只使用了债务收入比的最大值来填充缺失值。

(4)对于数值特征。可以使用均值填充。

3、处理分类变量

查看分类变量的数目和类别,对于数量较少的进行虚拟化处理,数量较多的进行分组处理;

4、概率密度函数--查看数值特征的分布

  • 检查数据是否满足正态分布:如果不满足则需要进行正态化处理;
  • 正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。
  • 对于严重右偏的数据可以通过log处理;

(1)峰度和偏度

  • 偏度系数等于0为正态,大于零为右偏(负偏),小于零为左偏(负偏);
  • 峰度系数等于3为正态,大于3为尖峰,小于3为平顶;
skewed_feats = data[numerical_features].apply(lambda x: skew(x.dropna())).sort_values(ascending=False)
kurt_feats = data[numerical_features].apply(lambda x: stats.kurtosis(x.dropna())).sort_values(ascending=False)
print("\nSkew and Kurtosis in numerical features: \n")
normal_metric = pd.DataFrame({'Skew' :skewed_feats,'Kurt':kurt_feats})
normal_metric

(2)概率密度函数--查看数值特征的分布

通过直方图和qq图查看数据的分布

sns.distplot(data['interestRate'] , fit=norm);

# Get the fitted parameters used by the function
(mu, sigma) = norm.fit(data['interestRate'])
print( '\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))

#Now plot the distribution
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f} )'.format(mu, sigma)],loc='best')
plt.ylabel('Frequency')
plt.title('贷款的分布')

#Get also the QQ-plot
fig = plt.figure()
res = stats.probplot(data['interestRate'], plot=plt)
plt.show()

四、建模与调参

1、构建基础模型

构建分类的基础模型,使用Gradient Boosting Classifier 、XGBoost、LightGBM作为基础模型

2、Simplest Stacking approach : Averaging base models

使用基本模型的预测值,进行投票决定最终预测结果。

 

3、Less simple Stacking : Adding a Meta-model

使用base model预测结果,并把预测结果作为meta model的输入

 

五、模型融合

常见的模型融合是指将多个不同的 Base Model 组合成一个 Ensemble Model 的方法。它可以同时降低最终模型的 Bias 和 Variance,从而在提高分数的同时又降低 Overfitting 的风险。

1、常见的ensemble算法

  • Bagging:使用训练数据的不同随机子集来训练每个 Base Model,最后进行每个 Base Model 权重相同的 Vote。也即 Random Forest 的原理。

  • Boosting:迭代地训练 Base Model,每次根据上一个迭代中预测错误的情况修改训练样本的权重。也即 Gradient Boosting,Adaboost 的原理。比 Bagging 效果好,但更容易 Overfit。 

        Bagging,Boosting二者之间的区别

     (1)样本选择上:

    Bagging:训练集是在原始集中有放回选取的,从原始集中选出的各轮训练集之间是独立的。

    Boosting:每一轮的训练集不变,只是训练集中每个样例在分类器中的权重发生变化。而权值是根据上一轮的分类结果进行调整。

    (2)样例权重:

    Bagging:使用均匀取样,每个样例的权重相等

    Boosting:根据错误率不断调整样例的权值,错误率越大则权重越大。

    (3)预测函数:

    Bagging:所有预测函数的权重相等。

    Boosting:每个弱分类器都有相应的权重,对于分类误差小的分类器会有更大的权重。

    (4)并行计算:

    Bagging:各个预测函数可以并行生成

    Boosting:各个预测函数只能顺序生成,因为后一个模型参数需要前一轮模型的结果。

 

  • Blending:用不相交的数据训练不同的 Base Model,将它们的输出取(加权)平均。实现简单,但对训练数据利用少了。

  • Stacking:接下来会详细介绍。

    stacking是一种分层模型集成框架。以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为特征加入训练集进行再训练,从而得到完整的stacking模型。stacking的方法在各大数据挖掘比赛上都很风靡,模型融合之后能够小幅度的提高模型的预测准确度。

2、stacking的含义

stacking是一种分层模型集成框架。以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为特征加入训练集进行再训练,从而得到完整的stacking模型。stacking的方法在各大数据挖掘比赛上都很风靡,模型融合之后能够小幅度的提高模型的预测准确度。

 

3、stacking的详细过程

 

 

假设Training data有10000行,test data有2000行,stacking的步骤如下:

对测试集的处理:

(1)将全部数据划分成training set 和test set,training set采用五折交叉验证,划分成5份数据;

(2)对每一折数据使用base model 五分之四的数据训练,五分之一的数据预测,记为a1,a2,a3,a4,a5,最终得到5列2000行的预测值;

(3)拼接上面5列数据,得到1列当前base model的预测,值(10000行);(a1,a2,a3,a4,a5)的转置

(4)假如有10个base model,就会得到10列10000行的预测值;

(5) 最后使用一个模型来训练这10列数据(把这10预测值当作训练数据);

对训练集的处理有两种方法,

  • 一种是上一步训练完成后,一次性预测Test data的;

  • 另一种方法是,对于每个base model每折训练完后,就对test data进行预测,得到b1,1个base model就会有5次的预测值,最终有b1,b2,b3,b4,b5,对这5列2000行的数据取平均值,得到1列数据。10个base model就有10列数据,用上一步最后训练的模型来对10列数据做预测,得到1列预测值

  • 3
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值