美文网首页
贷款违约预测2-完整的数据分析

贷款违约预测2-完整的数据分析

作者: 木头里有虫911 | 来源:发表于2020-09-18 22:15 被阅读0次

承接上文,上次说到我们要开始做一个完整的数据竞赛项目,并且在前文中具体阐述了该赛题的具体任务和数据基本预览。(小伙伴可以通过该链接直达:https://www.jianshu.com/p/ae4f917788e5
接下来,我们就来到了该项目的第二部分——探索性数据分析,即EDA,Exploratory Data Analysis。
一般来说,数据描述性统计分析是一个数据挖掘/机器学习项目的第一步,有时候也被称为探索性数据分析。但两者有一些细微的区别:

  • 数据描述统计强调方法,即如何从数据中获取信息。比如用平均数/中位数/众数/方差等描述城市的人员收入水平。
  • 数据探索强调过程,即通过对数据进行研究发现其规律,对研究的对象有更加深入的认识。例如通过对不同人员的工作年限行业教育水平和薪资的关系,找到影响收入的因素等

好了,接下来就开展的工作,主要是探索赛题提供的数据,并总结一些分析中的套路。
主要包括:

  • 查看数据基本情况,包括缺失值和唯一值等
  • 深入数据-查看数据类型,包括:
    • 类别型数据
    • 数值型数据
    • 离散数值型数据
    • 连续数值型数据
  • 数据间相关关系
  • 特征和特征之间关系
  • 特征和目标变量之间关系

1. 缺省值查看

首先还是万年不变的导包+导数据!

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import warnings
warnings.filterwarnings('ignore')

train = pd.read_csv('./train.csv')
test = pd.read_csv('./testA.csv')

多学一招
我们知道python在运行的时候有时会因为版本等问题抛出警告,虽然不影响程序运行,但是影响心情!可以用“warnings.filterwarnings('ignore')”忽略掉警告。

然后就是导入数据,并使用shape/info/describe等查看数据的基本情况。这个在这里不在赘述。在这里我们主要看一下缺省值的情况
先看一下数据的前五行和最后五行

#查看前五行和后五行
train.head(5).append(train.tail(5))
捕获.JPG

小技巧
将head和tail用append方法拼接起来一句代码就可以打印出来,省事!

下面查看一下哪些字段有缺省值

# 查看缺省值
d = (train.isnull().sum()/len(train)).to_dict()
print(d)
print('*'*30)
print(f'There are {train.isnull().any().sum()} columns in train dataset with missing values.')

>>>{'id': 0.0, 'loanAmnt': 0.0, 'term': 0.0, 'interestRate': 0.0, 'installment': 0.0, 'grade': 0.0, 'subGrade': 0.0, 'employmentTitle': 1.25e-06, 'employmentLength': 0.05849875, 'homeOwnership': 0.0, 'annualIncome': 0.0, 'verificationStatus': 0.0, 'issueDate': 0.0, 'isDefault': 0.0, 'purpose': 0.0, 'postCode': 1.25e-06, 'regionCode': 0.0, 'dti': 0.00029875, 'delinquency_2years': 0.0, 'ficoRangeLow': 0.0, 'ficoRangeHigh': 0.0, 'openAcc': 0.0, 'pubRec': 0.0, 'pubRecBankruptcies': 0.00050625, 'revolBal': 0.0, 'revolUtil': 0.00066375, 'totalAcc': 0.0, 'initialListStatus': 0.0, 'applicationType': 0.0, 'earliesCreditLine': 0.0, 'title': 1.25e-06, 'policyCode': 0.0, 'n0': 0.0503375, 'n1': 0.0503375, 'n2': 0.0503375, 'n3': 0.0503375, 'n4': 0.04154875, 'n5': 0.0503375, 'n6': 0.0503375, 'n7': 0.0503375, 'n8': 0.05033875, 'n9': 0.0503375, 'n10': 0.04154875, 'n11': 0.08719, 'n12': 0.0503375, 'n13': 0.0503375, 'n14': 0.0503375}
******************************
>>>There are 22 columns in train dataset with missing values.

上面的代码逻辑:

  1. train.isnull()返回一个bool类型,判断哪些值为缺省值。若该处为缺失值,返回True,否则不为缺失值,则返回False
  2. 在上面的代码上叠加sum,即train.isnull().sum(),可以统计每一列缺省值的个数(True相当于1)
  3. 在和长度比较,得出每一列缺省值的占比,在之后按照key-value存入一个字典
    上面的代码一气呵成,充分体现的python的简洁和优雅
    从上面的结果可以看出train数据集中的47个字段有22个存在缺省值的情况。下面可视化一下缺省值数量占比。做这一步是因为如果一个字段存在大量的缺省值,比如占到总数的50%,理论上对分析作用不大,这样就可以省略该字段。
# 可视化
(train.isnull().sum()/len(train)).plot.bar(figsize = (20,6))
1.png

可以看到所有的特征缺失值都在10%以内,全部保留。
下面在查看是否有只有一个值的字段

# 查看是否有只有一个值的字段
one_value_fea = [col for col in train.columns if train[col].nunique() <= 1]
one_value_fea_test = [col for col in test.columns if test[col].nunique() <= 1]
print(one_value_fea)
print('---------')
print(one_value_fea_test)

>>>['policyCode']
---------
>>>['policyCode']

总结以上
47列数据中有22列都缺少少量数据,这在现实世界中很正常。‘policyCode’具有一个唯一值(或全部缺失),这项在后期的特征工程中可以干掉,不作为后期机器学习建模的变量。另外有很多连续变量和一些分类变量。下面我们就具体看一下这些变量

2. 特征的数值类型分析和可视化

  • 特征一般都是由类别型特征和数值型特征组成,而数值型特征又分为连续型和离散型。
  • 类别型特征有时具有非数值关系,有时也具有数值关系。比如‘grade’中的等级A,B,C等,是否只是单纯的分类,还是A优于其他要结合业务判断。
  • 数值型特征本是可以直接入模的,但往往风控人员要对其做分箱,转化为WOE编码进而做标准评分卡等操作。从模型效果上来看,特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度。从而使模型更加稳定。

在开始展开分析工作前,我们要在心中明确一下分析的目的: 查找挖掘目标变量贷款违约(isDefault)和其他变量的关系。因而有必要先知道目标值的分布情况。

# 查看目标变量isDefault的分布,做到心中有数
train.isDefault.value_counts()
Out[32]:
0    640390
1    159610
Name: isDefault, dtype: int64

取值为0为否,即没有违约,为1是违约客户
也可以加入normalize参数,查看百分比:

train.isDefault.value_counts(normalize=True)
0    0.800488
1    0.199513
Name: isDefault, dtype: float64

即80.05%的客户没有出现违约,而剩下19.95%(共159610)个客户违约。

2.1 首先统计数值型的字段(特征)

#统计数值型类别的特征(连续型和离散型)
def get_numerical_continus_fea(data,feas):
    numerical_continus_fea = []
    numerical_discrete_fea = []
    for fea in feas:
        temp = data[fea].nunique()
        # 自定义变量的值的取值个数小于10为离散型变量
        if temp <= 10:
            numerical_discrete_fea.append(fea)
            continue
        numerical_continus_fea.append(fea)
    return numerical_continus_fea,numerical_discrete_fea
numerical_continus_fea,numerical_discrete_fea = get_numerical_continus_fea(train,numerical_fea)

print('Following features are continous features:')
print(numerical_continus_fea)
print('*' * 30)
print('Following features are discrete features:')
print(numerical_discrete_fea)

>>>Following features are continous features:
['id', 'loanAmnt', 'interestRate', 'installment', 'employmentTitle', 'annualIncome', 'purpose', 'postCode', 'regionCode', 'dti', 'delinquency_2years', 'ficoRangeLow', 'ficoRangeHigh', 'openAcc', 'pubRec', 'pubRecBankruptcies', 'revolBal', 'revolUtil', 'totalAcc', 'title', 'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n13', 'n14']
******************************
>>>Following features are discrete features:
['term', 'homeOwnership', 'verificationStatus', 'isDefault', 'initialListStatus', 'applicationType', 'policyCode', 'n11', 'n12']

2.1.1 离散型数值变量
对于离散型的数值型变量,我们可以简单的用value_counts函数统计相应取值的总个数,例如:

train.homeOwnership.value_counts()
>>>
0    395732
1    317660
2     86309
3       185
5        81
4        33
Name: homeOwnership, dtype: int64

加入可视化,可以更加直观。下面用homeOwnership和employmentLength两个特征用柱状图来展示

# 加入可视化,更加直观
plt.style.use('bmh')
plt.figure(figsize=(15, 8))

plt.subplot(121)
sns.barplot(train["homeOwnership"].value_counts(dropna=False).keys(),
            train["homeOwnership"].value_counts(dropna=False)
            )
plt.title('feature homeOwnership value overview')


plt.subplot(122)
sns.barplot(train["employmentLength"].value_counts(dropna=False)[:20],
            train["employmentLength"].value_counts(dropna=False).keys()[:20])
plt.title('feature employmentLength value overview')
下载.png

2.1.2 连续型数值变量
对于连续型变量,可以通过变量的概率密度分布图查看变量的大体分布情况

# 数值连续型特征概率分布可视化
f = pd.melt(train, value_vars=numerical_continus_fea)
g = sns.FacetGrid(f, col="variable",  col_wrap=4, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
2.png

做这一步的目的是查看某一个数值型变量的分布,观察该变量是否符合正态分布,如果不符合正太分布的变量可以log化后再观察下是否符合正态分布。
正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。
下面就loanAmnt这个变量举例,看看log后的分布:

#loanAmount Values Distribution and after log
plt.figure(figsize=(20,12))

plt.suptitle('loanAmount Values Distribution', fontsize=22)
plt.subplot(221)
sub_plot_1 = sns.distplot(train['loanAmnt'])
sub_plot_1.set_title("loanAmnt Distribuition", fontsize=18)
sub_plot_1.set_xlabel("")
sub_plot_1.set_ylabel("Probability", fontsize=15)

plt.subplot(222)
sub_plot_2 = sns.distplot(np.log(train['loanAmnt']))
sub_plot_2.set_title("loanAmnt (Log) Distribuition", fontsize=18)
sub_plot_2.set_xlabel("")
sub_plot_2.set_ylabel("Probability", fontsize=15)
3.png

另外,在实际操作中,除了可以用概率密度分布来查看某一个变量的数据分布外,还常用箱线图来查看数据分布集中度。下面从上面挑选几个变量举例。
通过观察,可以看到 'loanAmnt', 'interestRate', 'installment', 'postCode', 'regionCode', ' 'openAcc', 'totalAcc', 'n2', 'n3', 等变量分布类似于正态分布,选择这些变量进一步用箱线图查看分布

# 单特征箱线图,区分是否违约
box_fea = [ 'loanAmnt', 'interestRate', 'installment',  'postCode', 'regionCode', 'openAcc', 'totalAcc', 'n2', 'n3']
f, ax = plt.subplots(3,3, figsize = (20,15))

for i, col in enumerate(box_fea):
    sns.boxplot(x = 'isDefault', y = col, saturation=0.5, palette='pastel', data = train, ax = ax[i//3][i%3])
image.png

大体观察一下,可以发现贷款金额(loanAmt)和贷款利率('interestRate)较高时出现贷款违约的风险更高,即isDefault(目标变量)值为1。其他特征未发现明显区别。

2.2 下面在考察目标Y(是否违约欺诈)和单一变量X的统计关系

2.2.1 观察类别型变量

# 类别型变量X和y
train_loan_isDefault = train.loc[train['isDefault'] == 1]
train_loan_nonDefault= train.loc[train['isDefault'] == 0]

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(20, 10))
train_loan_isDefault.groupby('grade')['grade'].count().plot(kind='barh', ax=ax1, title='Count of grade Default')
train_loan_nonDefault.groupby('grade')['grade'].count().plot(kind='barh', ax=ax2, title='Count of grade non-Default')
train_loan_isDefault.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax3, title='Count of employmentLength Default')
train_loan_nonDefault.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=ax4, title='Count of employmentLength non-Default')
image.png

2.2.2 观察数值连续型变量

这里我们就不在描述,留给读者自己验证

2.3 时间序列处理

因为train和test数据中都有时间特征issueDate, (猜测为贷款发放日期),可以简单验证一下

#转化成时间格式  issueDateDT特征表示数据日期离数据集中日期最早的日期(2007-06-01)的天数
train['issueDate'] = pd.to_datetime(train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
train['issueDateDT'] = train['issueDate'].apply(lambda x: x-startdate).dt.days

#测试数据集转化成时间格式
test['issueDate'] = pd.to_datetime(test['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
test['issueDateDT'] = test['issueDate'].apply(lambda x: x-startdate).dt.days

plt.figure(figsize=(10,6))
plt.hist(train['issueDateDT'], label='train', bins = 20);
plt.hist(test['issueDateDT'], label='test',bins = 20)
plt.legend();
plt.title('Distribution of issueDateDT dates');
#train 和 test issueDateDT 日期有重叠 所以使用基于时间的分割进行验证是不明智的
image.png

train 和 test issueDateDT 日期有重叠 ,所以使用基于时间的分割进行验证是不明智的。

好了,本次的数据分析任务结束。我们通过各个简单的统计量来对数据整体的了解,分析各个类型变量相互之间的关系,以及用合适的图形可视化出来直观观察。通过对数据进行探索性分析,我们初步了解数据的分布情况,熟悉数据。这项工作为特征工程做准备的阶段。数据分析之所以重要,是因为很多时候该阶段提取出来的特征可以直接当作规则来用。下一期我们就进入重头戏,特征工程!敬请期待!

相关文章

  • 贷款违约预测2-完整的数据分析

    承接上文,上次说到我们要开始做一个完整的数据竞赛项目,并且在前文中具体阐述了该赛题的具体任务和数据基本预览。(小伙...

  • 信用贷款违约预测

    项目背景:依据客户的信用卡信息,分期付款信息,信用局信息等预测客户贷款是否会违约。分析流程:首先对数据进行可视化探...

  • 贷款违约预测-Task2 数据分析

    Task2 数据分析 此部分为零基础入门金融风控的 Task2 数据分析部分,带你来了解数据,熟悉数据,为后续的特...

  • 贷款客户违约预测模型

    背景:根据已有贷款客户的还款情况数据,以预测客户是否违约,提前预警。数据:某融资担保公司所拥有的数据,包括基本身份...

  • tianchi——贷款违约预测

    解决的问题是预测预测用户贷款是否违约为任务。提交的形式应该是一个二分类形式(2个字段,一个是id,一个是违约的可能...

  • 债务违约预测之二:图形探索

    在债务违约预测之一:数据探索中,按各个属性对借贷者分组,再分析其违约率。现在换一个角度,分为违约者和未违约两类,再...

  • Kaggle: Home Credit Default Risk

    项目背景: 1、目的:通过数据集提供的相关数据,预测客户贷款是否违约2、数据集介绍:一共有8个数据集,包括1个主训...

  • 金融风控赛一

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

  • 大数据金融数据分析GBDT模型、神经网络模型、违约预测模型视频教

    大数据金融数据分析GBDT模型、神经网络模型、违约预测模型视频教程网盘下载 38套大数据,云计算,架构,数据分析师...

  • 个人贷款违约预测模型

    案例背景 案例来源《python数据科学:技术详解与商业实践》数据下载地址该案例使用一套来自某银行真实数据集构建贷...

网友评论

      本文标题:贷款违约预测2-完整的数据分析

      本文链接:https://www.haomeiwen.com/subject/mnejyktx.html