数据分析项目实战—信用卡客户违约概率预测

阅读之前看这里👉:博主是正在学习数据分析的一员,博客记录的是在学习过程中一些总结,也希望和大家一起进步,在记录之时,未免存在很多疏漏和不全,如有问题,还请私聊博主指正。
博客地址:天阑之蓝的博客,学习过程中不免有困难和迷茫,希望大家都能在这学习的过程中肯定自己,超越自己,最终创造自己。

项目背景:
因信用卡使用给人们带来便利,越来越多的人使用信用卡。信用卡要求人们按时还款,若未按时还款,银行将收取一定的利息获益,因此各大银行为了抢占市场,最大化发展客户。但有一些客户可能会违约使银行利益受损,故控制违约情况显得迫在眉睫。本文通过预测某人在未来两年内遭遇财务困境的可能性,来提高自己在信用评分方面的水平。目标是建立一个借款人可以用来帮助做出最佳财务决策的模型。
本文主要从分析框架、数据处理和建立预测模型等几个方面进行分析和介绍:

1、明确分析需求

1.1数据介绍

本数据来kaggle数据集:
提供了25万借款人的历史数据,包括训练集、测试集以及数据集信息。

首先查看数据包含的文件:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import os
for dirname, _, filenames in os.walk('GiveMeSomeCredit'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

结果:

GiveMeSomeCredit\cs-test.csv
GiveMeSomeCredit\cs-training.csv
GiveMeSomeCredit\Data Dictionary.xls
GiveMeSomeCredit\sampleEntry.csv

我们可以看到文件有训练集和测试集,以及一个资料字典,还有提交样例。
查看一下资料字典里的信息:
在这里插入图片描述
主要是讲的各字段所代表的名称,含义和类型。
各字段代表的含义:

字段名 字段含义
SeriousDlqin2yrs 逾期90天以上的标记,即目标变量,1逾期,0表示没有逾期
RevolvingUtilizationOfUnsecuredLines 信用卡和个人信用额度的总余额,除房地产和汽车贷款等分期付款债务外,除以信用额度总和
age 年龄
NumberOfTime30-59DaysPastDueNotWorse 借款人逾期30-59天的次数,但在过去两年没有恶化。
DebtRatio 每月的债务,赡养费,生活费除以每月的总收入
MonthlyIncome 月收入
NumberOfOpenCreditLinesAndLoans 未偿还贷款的数量(如汽车贷款或抵押贷款的分期付款)和信用额度(如信用卡)
NumberOfTimes90DaysLate 借款人逾期90天或以上的次数。
NumberRealEstateLoansOrLines 抵押贷款和房地产贷款的数量,包括房屋净值信贷额度
NumberOfTime60-89DaysPastDueNotWorse 借款人逾期60-89天的次数,但在过去两年没有恶化。
NumberOfDependents 家庭成员(不包括本身)的受养人数目(配偶、子女等)

1.2明确分析思路

我们看到这些数据,到底有什么用呢,如何去分析呢?
首先明确目的:信用卡数据的各个信息对我们分析有什么用,最终目的什么,可以得到什么结论?
目的:通过这些数据预测信用卡客户违约的预测概率。
思路:通过分析数据之间的相关性,关联性,进行特征分析,选择合适的特征进行建模。
具体方法:查看各数据的统计信息,与是否逾期的关系,进行可视化表示,并得到相应的一些结论。

1.3 数据探索

首先看一下训练集中的内容:

df = pd.read_csv("GiveMeSomeCredit//cs-training.csv")
df.drop('Unnamed: 0',axis =1,inplace = True)
df.head()

在这里插入图片描述
为了看起来方便,将英文名替换成中文名

# 中文名替换
zh_label = ['目标变量','信用卡余额百分比','年龄','逾期30-59天的次数','每月开支占比','月收入','未偿还债务','抵押贷款和房地产贷款的数量','借款人逾期60-89天的次数','家庭成员数目']
en_label = df.columns.values.tolist()
zh_label_dict = dict(zip(en_label,zh_label))
zh_label_dict
df.rename(columns =zh_label_dict ,inplace=True)
df.head()

在这里插入图片描述
查看一下数据的基本信息:
数据大小

df.shape

(150000, 11) 共有150000个数据,特征向量有11个。

查看数据类型

df.dtypes.value_counts()
int64      7
float64    4
dtype: int64

一共有7个特征是整型,4个特征是浮点型。
数据信息

df.info()

在这里插入图片描述
观察到部分数据有缺失,所以接下来需要对缺失值的处理

1.4数据清洗和处理

查看缺失值

df.isnull().sum()[df.isnull().sum() != 0]
月收入       29731
家庭成员数目     3924

可以看到月收入和家庭成员数目有缺失,一般数据缺失有几种处理方法:

  • 直接删除
  • 用众数、中位数等进行替换
  • 根据变量之间的相关关系填补缺失值

不过考虑到总数为15万,家庭成员数目占比较小,缺失数据可以删除。月收入应当是一个重要的因素,且占比不算小,可以根据变量之间的相关关系填补缺失值。
采用随机森林法:

# 用随机森林对缺失值预测填充函数
def set_missing(df):
    # 把已有的数值型特征取出来
    process_df = df.iloc[:,[5,0,1,2,3,4,6,7,8,9]]
    # 分成已知该特征和未知该特征两部分
    # dataframe.values获取的是dataframe中的数据为数组array
    known = process_df[process_df.月收入.notnull()].values
    unknown = process_df[process_df.月收入.isnull()].values
    # X为已知MonthlyIncome的特征属性值
    X = known[:, 1:]
    # y为结果标签值MonthlyIncome
    y = known[:, 0]
    # X与y用于训练随机森林模型,fit到RandomForestRegressor之中
    rfr = RandomForestRegressor(random_state=0, n_estimators=200,max_depth=3,n_jobs=-1)
    rfr.fit(X,y)
    # 用得到的模型进行未知特征值预测
    predicted = rfr.predict(unknown[:, 1:]).round(0)
    # 用得到的预测结果填补原缺失数据
    df.loc[(df.月收入.isnull()), '月收入'] = predicted
    return df
df=set_missing(df)              # 用随机森林填补比较多的缺失值
df=df.dropna()                  # 删除比较少的缺失值
df = df.drop_duplicates()       # 删除重复项
df.info()
 0   目标变量            145563 non-null  int64  
 1   信用卡余额百分比        145563 non-null  float64
 2   年龄              145563 non-null  int64  
 3   逾期30-59天的次数     145563 non-null  int64  
 4   每月开支占比          145563 non-null  float64
 5   月收入             145563 non-null  float64
 6   未偿还债务           145563 non-null  int64  
 7   逾期90天或以上的次数     145563 non-null  int64  
 8   抵押贷款和房地产贷款的数量   145563 non-null  int64  
 9   借款人逾期60-89天的次数  145563 non-null  int64  
 10  家庭成员数目          145563 non-null  float64

可以看到数量变成了145563个了。

观察正负样本数量是否大致相等

df.目标变量.value_counts()
0    135732
1      9831

可以看到大约为13比1的情况

异常值检测
缺失值处理完毕后,我们还需要进行异常值处理。异常值是指明显偏离大多数抽样数据的数值,比如个人客户的年龄为0时,通常认为该值为异常值。找出样本总体中的异常值,通常采用离群值检测的方法。

df["年龄"].describe()
count    145563.000000
mean         52.110701
std          14.567652
min           0.000000
25%          41.000000
50%          52.000000
75%          62.000000
max         107.000000

我们可以看到最小值为0,所以需要对其异常值处理。应当删掉此异常值。

df.drop(df[(df['年龄'] == 0)].index.tolist(),inplace = True)
df["年龄"<
  • 22
    点赞
  • 227
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值