超详细用Python进行信用评分卡建模【kaggle的give me some credit数据集】【风控建模】

本文基于kaggle的'Give Me Some Credit'数据集,详述使用Python进行信用评分卡建模的过程,包括数据导入、缺失值与异常值处理、探索性分析、变量选择(WOE与IV值计算)、Logistic回归模型建立与评估(AUC、KS值)。通过对个人财务数据的分析,构建预测违约风险的模型。
摘要由CSDN通过智能技术生成

1 信用评分卡模型简介

信用评分卡是一个通过个人数据对其还款能力、还款意愿进行定量评估的系统。在消费金融行业,信用评分卡主要有三种(A、B、C卡):

A卡:申请评分卡,贷前阶段使用,在客户获取期,建立信用风险评分,预测客户带来违约风险的概率大小;

B卡:行为评分卡,贷中阶段引入,在客户借款处理期,建立申请风险评分模型,预测客户违约拖欠的风险概率,我们的B卡采用的是T+1离线计算出来的,针对复借用户特别有效,针对首借用户,B卡自动转为申请评分;B卡另外的价值还在于用户授信到借款之间的时间比较长的话,通过B卡能计算用户最近的信用情况,有效阻止“好人变坏”的情形。

C卡:催收评分卡,侧重贷后,在帐户管理期,建立催收评分模型,预测用户逾期的概率,从而采取合适的催收措施,经验表明,在预测用户逾期7天的概率较高时,给予短信提示的效果不错。

%%HTML
<style type="text/css">
table.dataframe td, table.dataframe th {
   
    border: 1px  black solid !important;
  color: black !important;
}   #设置df表格输出样式

2 数据导入

该数据来源于kaggle网站的Give Me Some Credit
数据包括了25万条个人财务情况的样本数据,通过对于该数据集的学习,构建一个信用卡评分模型,以期望对新用户预测其违约风险。

#导入包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib

#导入数据
train=pd.read_csv('cs-training.csv')  #训练集
test=pd.read_csv('cs-test.csv')       #测试集

#了解数据集
train.info() #给出样本数据的相关信息概览
train.head() #查看前5行数据
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 12 columns):
Unnamed: 0                              150000 non-null int64
SeriousDlqin2yrs                        150000 non-null int64
RevolvingUtilizationOfUnsecuredLines    150000 non-null float64
age                                     150000 non-null int64
NumberOfTime30-59DaysPastDueNotWorse    150000 non-null int64
DebtRatio                               150000 non-null float64
MonthlyIncome                           120269 non-null float64
NumberOfOpenCreditLinesAndLoans         150000 non-null int64
NumberOfTimes90DaysLate                 150000 non-null int64
NumberRealEstateLoansOrLines            150000 non-null int64
NumberOfTime60-89DaysPastDueNotWorse    150000 non-null int64
NumberOfDependents                      146076 non-null float64
dtypes: float64(4), int64(8)
memory usage: 13.7 MB
Unnamed: 0 SeriousDlqin2yrs RevolvingUtilizationOfUnsecuredLines age NumberOfTime30-59DaysPastDueNotWorse DebtRatio MonthlyIncome NumberOfOpenCreditLinesAndLoans NumberOfTimes90DaysLate NumberRealEstateLoansOrLines NumberOfTime60-89DaysPastDueNotWorse NumberOfDependents
0 1 1 0.766127 45 2 0.802982 9120.0 13 0 6 0 2.0
1 2 0 0.957151 40 0 0.121876 2600.0 4 0 0 0 1.0
2 3 0 0.658180 38 1 0.085113 3042.0 2 1 0 0 0.0
3 4 0 0.233810 30 0 0.036050 3300.0 5 0 0 0 0.0
4 5 0 0.907239 49 1 0.024926 63588.0 7 0 1 0 0.0

可以知道样本数有15万条,特征变量有12个,具体各变量的含义如下:
在这里插入图片描述

因变量等1时为坏客户,因此取坏客户为正样本

#将变量名换为中文便于理解
states={
   
        'Unnamed: 0':'id',
        'SeriousDlqin2yrs':'好坏客户',
        'RevolvingUtilizationOfUnsecuredLines':'可用额度比值', #无担保放款循环利用比值
        'age':'年龄',
        'NumberOfTime30-59DaysPastDueNotWorse':'逾期30-59天笔数',
        'DebtRatio':'负债率',
        'MonthlyIncome':'月收入',
        'NumberOfOpenCreditLinesAndLoans':'信贷数量',
        'NumberOfTimes90DaysLate':'逾期90天笔数',
        'NumberRealEstateLoansOrLines':'固定资产贷款量',
        'NumberOfTime60-89DaysPastDueNotWorse':'逾期60-89天笔数',
        'NumberOfDependents':'家属数量'
         } #创建字典

train.rename(columns=states,inplace=True)
train.head()
id 好坏客户 可用额度比值 年龄 逾期30-59天笔数 负债率 月收入 信贷数量 逾期90天笔数 固定资产贷款量 逾期60-89天笔数 家属数量
0 1 1 0.766127 45 2 0.802982 9120.0 13 0 6 0 2.0
1 2 0 0.957151 40 0 0.121876 2600.0 4 0 0 0 1.0
2 3 0 0.658180 38 1 0.085113 3042.0 2 1 0 0 0.0
3 4 0 0.233810 30 0 0.036050 3300.0 5 0 0 0 0.0
4 5 0 0.907239 49 1 0.024926 63588.0 7 0 1 0 0.0
#对变量进行描述性统计分析
train.describe()
id 好坏客户 可用额度比值 年龄 逾期30-59天笔数 负债率 月收入 信贷数量 逾期90天笔数 固定资产贷款量 逾期60-89天笔数 家属数量
count 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 1.202690e+05 150000.000000 150000.000000 150000.000000 150000.000000 146076.000000
mean 75000.500000 0.066840 6.048438 52.295207 0.421033 353.005076 6.670221e+03 8.452760 0.265973 1.018240 0.240387 0.757222
std 43301.414527 0.249746 249.755371 14.771866 4.192781 2037.818523 1.438467e+04 5.145951 4.169304 1.129771 4.155179 1.115086
min 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000e+00 0.000000 0.000000 0.000000 0.000000 0.000000
25% 37500.750000 0.000000 0.029867 41.000000 0.000000 0.175074 3.400000e+03 5.000000 0.000000 0.000000 0.000000 0.000000
50% 75000.500000 0.000000 0.154181 52.000000 0.000000 0.366508 5.400000e+03 8.000000 0.000000 1.000000 0.000000 0.000000
75% 112500.250000 0.000000 0.559046 63.000000 0.000000 0.868254 8.249000e+03 11.000000 0.000000 2.000000 0.000000 1.000000
max 150000.000000 1.000000 50708.000000 109.000000 98.000000 329664.000000 3.008750e+06 58.000000 98.000000 54.000000 98.000000 20.000000

上述描述统计表发现变量月收入和家庭数量的样本数小于15w,两个变量存在缺失值。

#求两个变量的缺失比
print("月收入缺失比:{:.2%}".format(train['月收入'].isnull().sum()/train.shape[0]))
print("家属数量缺失比:{:.2%}".format(train['家属数量'].isnull().sum()/train.shape[0]))
月收入缺失比:19.82%
家属数量缺失比:2.62%

3 缺失值处理

缺失值的类型:完全随机缺失,随机缺失,非随机缺失
处理方法:
1、删除含有缺失值的个案
2、可能值插补缺失值
(1)均值插补
(2)利用同类均值插补。
(3)极大似然估计(Max Likelihood ,ML)
(4)多重插补(Multiple Imputation,MI)

月收入的缺失比较大,应该进行缺失值的估计插补,本文采用均值插补方法,月收入变量数据为定距型,采用该变量的均值进行填补,而家属数量的缺失比较低,可以直接删除有缺失的样本。

#用均值填补月收入缺失值
train['月收入']=train['月收入'].fillna(train['月收入'].mean())

#删除存在缺失值的样本
train=train.dropna()
train.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 146076 entries, 0 to 149999
Data columns (total 12 columns):
id            146076 non-null int64
好坏客户          146076 non-null int64
可用额度比值        146076 non-null float64
年龄            146076 non-null int64
逾期30-59天笔数    146076 non-null int64
负债率           146076 non-null float64
月收入           146076 non-null float64
信贷数量          146076 non-null int64
逾期90天笔数       146076 non-null int64
固定资产贷款量       146076 non-null int64
逾期60-89天笔数    146076 non-null int64
家属数量          146076 non-null float64
dtypes: float64(4), int64(8)
memory usage: 14.5 MB

4 异常值处理

异常值即离群点,一般大于3倍标准差外的数值为异常值,可以采用箱线图判断异常值。

train.head()
id 好坏客户 可用额度比值 年龄 逾期30-59天笔数 负债率 月收入 信贷数量 逾期90天笔数 固定资产贷款量 逾期60-89天笔数 家属数量
0 1 1 0.766127 45 2 0.802982 9120.0 13 0 6 0 2.0
1 2 0 0.957151 40 0 0.121876 2600.0 4 0 0 0 1.0
2 3 0 0.658180 38 1 0.085113 3042.0 2 1 0 0 0.0
3 4 0 0.233810 30 0 0.036050 3300.0 5 0 0 0 0.0
4 5 0 0.907239 49 1 0.024926 63588.0 7 0 1 0 0.0
'''画箱线图,采用组合图的方式'''
#建立画板和画纸
fig=plt.figure(figsize=(15,10))
a=fig.add_subplot(3,2,1)
b=fig.add_subplot(3,2,2)
c=fig.add_subplot(3,2,3)
d=fig.add_subplot(3,2,4)
e=fig.add_subplot(3,2,5)
f=fig.add_subplot(3,2,6)

a.boxplot(train['可用额度比值'])
b.boxplot([train['年龄'],train['好坏客户']])
c.boxplot([train['逾期30-59天笔数'],train['逾期60-89天笔数'],train['逾期90天笔数']])
d.boxplot([train['信贷数量'],train['固定资产贷款量'],train['家属数量']])
e.boxplot(train['月收入'])
f.boxplot(train['负债率'])

{'whiskers': [<matplotlib.lines.Line2D at 0x2623ef39ef0>,
  <matplotlib.lines.Line2D at 0x2623b30b518>],
 'caps': [<matplotlib.lines.Line2D at 0x2623b8ba470>,
  <matplotlib.lines.Line2D at 0x262392194e0>],
 'boxes': [<matplotlib.lines.Line2D at 0x2623ef39d68>],
 'medians': [<matplotlib.lines.Line2D at 0x2623ed1cd30>],
 'fliers': [<matplotlib.lines.Line2D at 0x2623ed3e470>],
 'means': []}

在这里插入图片描述

处在箱线图上下边缘之外的为异常值

用公式去除异常值,计算第一和第三四分位数(Q1、Q3),异常值是位于四分位数范围之外的数据点x i:
在这里插入图片描述
使用四分位数乘数值k=1.5,范围限制是典型的上下晶须的盒子图。计算出来的正是箱线图的上下限。


                
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值