信用卡“坏账”客户分析(一)

总第92篇

01|背景:

随着人们的消费观念的升级,所谓的“花明天的钱,圆今天的梦”。银行以及私营企业推出了各种各样的消费金融服务,具有代表性的是各大银行的信用卡,支付宝的花呗、京东白条,还有一些专门针对针对学生群体的平台,比如趣分期哈、分期乐之类的,把这些统称为信用卡用户。

只要涉及到金融借贷的,就有可能有坏账的存在。

坏账说的通俗一点就是你借出去的钱要不回来了。

每个公司都在用各种手段来降低坏账的发生,最常见的方法就是根据一定的规则,给每个用户打分进行预测,哪些用户可能会发生坏账,针对预测结果采取相应的措施。

本篇将针对历史坏账用户进行分析,分析坏账用户都有哪些特征,为后续的建模做准备。数据来自kaggle上的https://www.kaggle.com/c/GiveMeSomeCredit/data 比赛。

02|导入数据:

#导入相关库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#导入数据
df=pd.read_csv(r"D:\Data-Science\Exercisedata\评分卡\cs-training.csv",engine="python")
df.head(5)

因字段太长,所以预览不全,直接打印出columns。

print(df.columns)
----------------------------
Index(['ID', 'SeriousDlqin2yrs', 'RevolvingUtilizationOfUnsecuredLines', 'age',
       'NumberOfTime30-59DaysPastDueNotWorse', 'DebtRatio', 'MonthlyIncome',
       'NumberOfOpenCreditLinesAndLoans', 'NumberOfTimes90DaysLate',
       'NumberRealEstateLoansOrLines', 'NumberOfTime60-89DaysPastDueNotWorse',
       'NumberOfDependents'],
      dtype='object')
#数据指标解读
ID——用户编号
SeriousDlqin2yrs——好坏客户区分,这里以逾期90天为界,超过90天表示“坏客户”,用1表示是;未超过90天表示“好客户”,用0表示
RevolvingUtilizationOfUnsecuredLines——贷款以及信用卡可以用额度与总额度比值
age——借款人的年龄
NumberOfTime30-59DaysPastDueNotWorse——借款人逾期30-59天但过去两年不是坏账的次数(笔数)
DebtRatio——负债率,每月要支付的债务、赡养费、生活费占每月总收入的比值
MonthlyIncome——月收入
NumberOfOpenCreditLinesAndLoans——贷款和信用卡数量
NumberOfTimes90DaysLate——逾期90天的次数
NumberRealEstateLoansOrLines——固定资产贷款数量
NumberOfTime60-89DaysPastDueNotWorse——逾期60-89天次数
NumberOfDependents——家属数量

英文字段看着太难受了,利用df.rename()函数将columns转化为中文,

states={"ID":"用户ID",
        "SeriousDlqin2yrs":"好坏客户",
        "RevolvingUtilizationOfUnsecuredLines":"可用额度比值",
        "age":"年龄",
        "NumberOfTime30-59DaysPastDueNotWorse":"逾期30-59天笔数",
        "DebtRatio":"负债率",
        "MonthlyIncome":"月收入",
        "NumberOfOpenCreditLinesAndLoans":"信贷数量",
        "NumberOfTimes90DaysLate":"逾期90天笔数",
        "NumberRealEstateLoansOrLines":"固定资产贷款量",
        "NumberOfTime60-89DaysPastDueNotWorse":"逾期60-89天笔数",
        "NumberOfDependents":"家属数量"}
df.rename(columns=states,inplace=True)

处理后的表

03|数据预处理:

数据预处理主要是对一些缺失值以及异常值进行处理,先利用df.info()看看有没有缺失值。

3.1缺失值处理

df.info()
------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 12 columns):
用户ID          150000 non-null int64
好坏客户          150000 non-null int64
可用额度比值        150000 non-null float64
年龄            150000 non-null int64
逾期30-59天笔数    150000 non-null int64
负债率           150000 non-null float64
月收入           120269 non-null float64
信贷数量          150000 non-null int64
逾期90天笔数       150000 non-null int64
固定资产贷款量       150000 non-null int64
逾期60-89天笔数    150000 non-null int64
家属数量          146076 non-null float64
dtypes: float64(4), int64(8)

看到总共有150000条数据,其中变量月收入和家属数量有缺失值。

print("月收入缺失比:{:.2%}".format((150000-120269)/150000))
print("家属数量 缺失比:{:.2%}".format((150000-146076)/150000))
----------------------------------------
月收入缺失比:19.82%
家属数量缺失比:2.62%

关于缺失值我们一般的处理方法有直接删除、利用平均值、中位数、众数进行填充。

月收入缺失比比较高,不能直接删除,利用填充平均值的方法进行补充,家属数量的缺失比只有2.6%,直接删除。

#缺失值填充
df=df.fillna({"月收入":df["月收入"].mean()})
#缺失值删除
df1=df.dropna()

3.2异常值处理

异常值处理中我们首先需要对异常值进行检测,采用的方法是箱形图。

x1=df1["可用额度比值"]
x2=df1["负债率"]
fig=plt.figure(1)
ax=fig.add_subplot(111)
ax.boxplot([x1,x2])
ax.set_xticklabels(["可用额度比值","负债率"])

可用额度的比值是该客户的可用额度比总额度的比值,所以值不应该大于1,大于1的部分进行删除。

plt.rcParams["font.sans-serif"]='SimHei'
x3=df1["年龄"]
fig=plt.figure(2)
ax1=fig.add_subplot(111)
ax1.boxplot(x3)
ax1.set_xticklabels("年龄")

年龄不可能有0岁,把等于0的删除。

x4=df1["逾期30-59天笔数"]
x5=df1["逾期60-89天笔数"]
x6=df1["逾期90天笔数"]
fig=plt.figure(3)
ax=fig.add_subplot(111)
ax.boxplot([x4,x5,x6])
ax.set_xticklabels(["逾期30-59天笔数","逾期60-89天笔数","逾期90天笔数"])

逾期天数大于80的均算作异常值,进行删除。

x7=df1["信贷数量"]
x8=df1["固定资产贷款量"]
fig=plt.figure(4)
ax=fig.add_subplot(111)
ax.boxplot([x7,x8])
ax.set_xticklabels(["信贷数量","固定资产贷款量"])

固定资产贷款数量大于50的算作异常值,删除。

#异常值过滤
df1=df1[df1["可用额度比值"]<=1]
df1=df1[df1["年龄"]>0]
df1=df1[df1["逾期30-59天笔数"]<80]
df1=df1[df1["固定资产贷款量"]<50]

04|探索性分析:

针对用户的年龄、月收入、负债率等指标进行分析,看坏账用户与哪些指标有关。

4.1单变量分析

先来看看好坏客户的整体情况。

grouped=df1["用户ID"].groupby(df1["好坏客户"]).count()
print("坏客户占比:{:.2%}".format(grouped[1]/grouped[0]))
grouped.plot(kind="bar")
----------------

坏客户占比:6.34%
age_cut=pd.cut(df1["年龄"],5)
age_cut_grouped=df1["好坏客户"].groupby(age_cut).count()
age_cut_grouped1=df1["好坏客户"].groupby(age_cut).sum()
df2=pd.merge(pd.DataFrame(age_cut_grouped), pd.DataFrame(age_cut_grouped1),right_index=True,left_index=True)
df2.rename(columns={"好坏客户_x":"好客户","好坏客户_y":"坏客户"},inplace=True)
df2.insert(2,"坏客户率",df2["坏客户"]/df2["好客户"])
ax1=df2[["好客户","坏客户"]].plot.bar()
ax1.set_xticklabels(df2.index,rotation=15)
ax1.set_ylabel("客户数")
ax1.set_title("年龄与好坏客户数分布图")
ax11=df2["坏客户率"].plot()
ax11.set_ylabel("坏客户率")
ax11.set_title("坏客户率随年龄的变化趋势图")

通过上面的年龄-好坏客户分布图和坏客户率与年龄变化图可以看出,38-55岁这一部分人中好客户和坏客户的绝对数量均是top1,随着年龄的增长,坏客户率在降低,且38-72之间降低最快。

cut_bins=[0,5000,10000,15000,20000,100000]
month_cut=pd.cut(df1["月收入"],cut_bins)
month_cut_grouped=df1["好坏客户"].groupby(month_cut).count()
month_cut_grouped1=df1["好坏客户"].groupby(month_cut).sum()
df3=pd.merge(pd.DataFrame(month_cut_grouped), pd.DataFrame(month_cut_grouped1),right_index=True,left_index=True)
df3.rename(columns={"好坏客户_x":"好客户","好坏客户_y":"坏客户"},inplace=True)
df3.insert(2,"坏客户率",df3["坏客户"]/df3["好客户"])
ax23=df3[["好客户","坏客户"]].plot.bar()
ax23.set_xticklabels(df3.index,rotation=15)
ax23.set_ylabel("客户数")
ax23.set_title("好坏客户数与月收入关系")
ax231=df3["坏客户率"].plot()
ax231.set_ylabel("坏客户率")
ax231.set_title("月收入与坏客户率关系")

好坏客户的绝对量级主要集中在月收入在10000以下的群体中,月收入在0-15000之间,坏客户率随着月收入的增加而降低,之后进入平稳,当月收入超过20000时,坏客户率又开始上升。这可能是在月收入在15000以下的群体中,大部分的收入来源比较固定,收入越多,坏账可能性越低。而月收入大于20000的这一部分人的的可能不是从事普通工作的,收入不太固定,所以坏账的可能性比较大。

cut_bins=[0,2,4,20]
family_cut=pd.cut(df1["家属数量"],cut_bins)
family_cut_grouped=df1["好坏客户"].groupby(family_cut).count()
family_cut_grouped1=df1["好坏客户"].groupby(family_cut).sum()
df4=pd.merge(pd.DataFrame(family_cut_grouped), pd.DataFrame(family_cut_grouped1),right_index=True,left_index=True)
df4.rename(columns={"好坏客户_x":"好客户","好坏客户_y":"坏客户"},inplace=True)
df4.insert(2,"坏客户率",df4["坏客户"]/df4["好客户"])
ax24=df4[["好客户","坏客户"]].plot.bar()
ax24.set_xticklabels(df4.index,rotation=15)
ax24.set_ylabel("客户数")
ax24.set_title("好坏客户数与家属数量关系")
ax241=df4["坏客户率"].plot()
ax241.set_ylabel("坏客户率")
ax241.set_title("坏客户率与家属数量的关系")

好坏客户的绝对量级集中在家属数量0-2之间,随着家属数量的增加,坏账的可能性也就越大。这也可以理解,家属数量越大,需要的支出就比较大,更容易坏账。

单变量的分析思路都差不多,主要就是看某一个自变量和因变量之间的关系,其他变量大家可以自行练习。

4.2多变量分析

多变量分析主要是分析变量之间的关系。

plt.rcParams["font.sans-serif"]='SimHei'
plt.rcParams['axes.unicode_minus'] = False
corr = df1.corr()#计算各变量的相关性系数
xticks = list(corr.index)#x轴标签
yticks = list(corr.index)#y轴标签
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
sns.heatmap(corr, annot=True, cmap="rainbow",ax=ax1,linewidths=.5, annot_kws={'size': 9, 'weight': 'bold', 'color': 'blue'})
ax1.set_xticklabels(xticks, rotation=35, fontsize=10)
ax1.set_yticklabels(yticks, rotation=0, fontsize=10)
plt.show()

我们用热力图来表示不同变量之间的关系,单元格颜色越深,代表该单元格交叉的两个变量相关性越强。

注意区分相关关系和因果关系。

变量逾期30-59天笔数和固定资产贷款量的相关系数最大为0.43,可用额度比值和信贷数量的相关系数也为0.34,可能是这个人的贷款频次多,比较活跃,银行给了更多的额度,但是他每次贷款的额度较低,所以就会出现可用额度比值较高。

本篇只是对数据做了一个基本的探索性分析,后续会针对该批数据进行建模,对每一个用户进行打分,以此来评判每个用户的信用等级,合理的预防坏账的发生。

原文发布于微信公众号 - 张俊红(zhangjunhong0428)

原文发表时间:2018-01-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量化投资与机器学习

【解读】遗传基因程序二元机器代码自动归纳合成算法

可能这个算法出来已经一段时间了,今天在一个策略网站上偶然发现,觉得很有意思,因此,查阅了一些资料进行学习。 遗传基因程序二元机器代码自动归纳合成算法(Autom...

1986
来自专栏ACM算法日常

浅谈ACM算法学习与有效训练

一、什么是有效地训练?   很多ACMer入门的时候,都被告知:要多做题,做500多道就变牛了。其实,这既不是充分条件、也不会是必要条件。   我觉得一般情...

952
来自专栏新智元

【Science】算法揭秘深度学习大牛,谁影响了谁?

【新智元导读】当今计算机科学领域哪位科学家的影响力最大?由微软联合创始人保罗·艾伦创立的艾伦人工智能研究所推出Semantic Scholar学术搜索引擎,使用...

3987
来自专栏PPV课数据科学社区

机器学习原来如此有趣:如何用深度学习进行语音识别

语音识别正在「入侵」我们的生活。我们的手机、游戏主机和智能手表都内置了语音识别。他甚至在自动化我们的房子。只需50美元,你就可以买到一个Amazon Echo ...

46812
来自专栏量化投资与机器学习

【独家发布】期货市场内外盘低频统计套利基于Python

声明 作者: 阿布 公众号独家授权 未经允许 禁止转载 github地址: https://github.com/bbfamily/abu 本策略可直接运行,运...

4417
来自专栏灯塔大数据

塔荐 | 机器学习与人工智能学习资源大放送合集

? 我经常在 TopLanguage 讨论组上推荐一些书籍,也经常问里面的牛人们搜罗一些有关的资料,人工智能、机器学习、自然语言处理、知识发现(特别地,数据挖...

3377
来自专栏CDA数据分析师

浅谈KL散度(相对熵)在用户画像中的应用

本文由CDA作者库成员Charlotte原创,并授权发布。 原文:http://www.cnblogs.com/charlotte77/p/5392052.ht...

2878
来自专栏智能算法

来自机器学习系统的排名:计算机科学与神经科学大牛TOP10

Science11月11日报道,艾伦人工智能研究院Semantic Scholar的人工智能搜索学术引擎近日推出了神经科学学术领域最有影响力的10位学者。 Sc...

3838
来自专栏华章科技

那些虐哭过你的大学数学课都有什么用处?看完后恍然大悟!

导读:高等数学有什么用?很多人都在问这个问题。其实大多数人在问这个问题的时候,心里已经预设了否定的答案。确实,对于大多数人来说,已经发展到了连数字都基本很少用了...

2252
来自专栏PPV课数据科学社区

会学习!会写字!这个机器人太牛了!

最近,《科学》杂志封面刊登了一篇重磅研究:人工智能终于能像人类一样学习,并通过了图灵测试。 这个人工智能像你一样学习写字 假设你从来没有见过菠萝。有一天,有人...

39211

扫码关注云+社区

领取腾讯云代金券