2.天池金融风控-贷款违约预测新人赛之数据分析

前一部分我们对一些分类指标等一些预备知识进行了学习,接下来我们要进行的是探索性的数据分析(EDA)
EDA是我们进行数据挖掘非常重要的一步,做的好的EDA可以让我们对数据作出更准确的分析,一方面是让我们了解整个数据集,包括缺失值,异常值,变量间的练习等,另一方面也是为我们之后的特征工程做好准备

1.数据的总体了解,缺失值,唯一值

#导入需要的库
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import datetime
import warnings
%matplotlib inline

#导入我们的训练集和测试集
train_data = pd.read_csv('train.csv')
test_A_data = pd.read_csv('testA.csv')

#一些查看数据总体特征的方法
train_data.shape
train_data.info()
train_data.describe()

#先来查看训练集的缺失值
train_data.isnull()            #data中的数据空变为False,非空为True
train_data.isnull().any()      #判断每一列是空or非空
train_data.isnull().any().sum()#对无缺失值的列求和

#可以找出缺失量大于某个值的columns,p可更改,如果缺失过多可以直接删除列
have_null_fea_dict = (train_data.isnull().sum()/len(train_data)).to_dict()
p = 0.5
fea_null_morethanhalf = {}
for key,value in have_null_fea_dict.items():
    if float(value) > p:
        fea_null_morethanhalf[key] = value

#查看有缺失值的列和它们缺失的比重
missing = train_data.isnull().sum()/len(train_data)
missing = missing[missing > 0]
missing.sort_values(inplace = True)
missing.plot.bar()

缺失值的比重直方图
了解哪些列存在 “nan”, 并可以把nan的个数打印,主要的目的在于 nan存在的个数是否真的很大,如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉.

#查看数据集中的特征是否只有一个值(唯一值)
one_value_fea = [col for col in train_data.columns if train_data[col].nunique() <= 1]
one_value_fea
#['policyCode']

2.查看数据的数值类型和对象类型

  • 特征一般分为数值型和类别型。类别型有可能具有数值关系,有时不具有。
  • 数值型特征可以直接入模,但一般都要进行分箱,目的是降低变量复杂性,减少变量噪音的影响,提高自变量和因变量的相关性,使模型更加稳定
#分别提取数值型特征和类别型特征
numerical_fea = list(train_data.select_dtypes(exclude=['object']).columns)
category_fea = list(train_data.select_dtypes(include = ['object']).columns)
category_fea
# ['grade', 'subGrade', 'employmentLength', 'issueDate', 'earliesCreditLine']

#划分数值型变量中的连续变量和分类变量
#我们把数字型变量里数字类别<=10的特征当作类别型数值变量
def split_numerical_or_not(data,feas):
    numerical_Series_fea = []
    numerical_noSeries_fea = []
    for fea in feas:
        if data[fea].nunique() <= 10:
            numerical_noSeries_fea.append(fea)
        else:
            numerical_Series_fea.append(fea)
    return numerical_Series_fea,numerical_noSeries_fea

numerical_series_fea,numerical_noseries_fea = split_numerical_or_not(train_data,numerical_fea)

#分离出来之后对数值类别型特征进行一些简单的分析
for col in numerical_noseries_fea:
    print(train_data[col].value_counts(),'\n')
'''
results:
3    606902
5    193098
Name: term, dtype: int64 

0    395732
1    317660
2     86309
3       185
5        81
4        33
Name: homeOwnership, dtype: int64 

1    309810
2    248968
0    241222
Name: verificationStatus, dtype: int64 

0    640390
1    159610
Name: isDefault, dtype: int64 

0    466438
1    333562
Name: initialListStatus, dtype: int64 

0    784586
1     15414
Name: applicationType, dtype: int64 

1.0    800000
Name: policyCode, dtype: int64 (这个数据只有一个值,没有用)

0.0    729682
1.0       540
2.0        24
4.0         1
3.0         1
Name: n11, dtype: int64  (数据相差悬殊,没什么用)

0.0    757315
1.0      2281
2.0       115
3.0        16
4.0         3
Name: n12, dtype: int64 (数据相差悬殊,没什么用)
'''

#接下来对数值型的连续型特征进行分析
#melt是将宽数据变为长数据,value_vars:需要转变的变量
f = pd.melt(train_data,value_vars=numerical_series_fea) 

#FacetGrid:引入数据,布置横向画布
g = sns.FacetGrid(f,col = 'variable' , col_wrap=2 , sharex=False , sharey=False) 

#map:填充数据进入
g = g.map(sns.distplot,'value') 
  • 查看某一个数值型变量的分布,查看变量是否符合正态分布,如果不符合正态分布的变量可以log化后再观察下是否符合正态分布。
  • 如果想统一处理一批数据变标准化 必须把这些之前已经正态化的数据提出
#绘制一个交易金额的值的分布图
#设置一个画布
plt.figure(figsize=(16,12))
#设置标题
plt.suptitle('Transaction Amount Distribution',fontsize = 22)
#画出loanAmnt的概率分布子图 displot:直方图和密度图的结合
plt.subplot(221)
subplot_1 = sns.distplot(train_data['loanAmnt'])
subplot_1.set_title('Loan Amount Distribution',fontsize = 18)
subplot_1.set_xlabel('')
subplot_1.set_ylabel('probability')

#画出loanAmnt log后的子图
plt.subplot(222)
subplot_2 = sns.distplot(np.log(train_data['loanAmnt']))
subplot_2.set_title('(Log) Loan Amount Distribution',fontsize = 18)
subplot_2.set_xlabel('')
subplot_2.set_ylabel('probability')

交易额(log后)的分布图
接下来对一些非数值型的特征做一些分析

#先看看有哪些特征
category_fea

#简单看看各个特征的每个值的数量
train_data['grade'].value_counts()
train_data['subGrade'].value_counts()
train_data['employmentLength'].value_counts()
train_data['issueDate'].value_counts()
train_data['earliesCreditLine'].value_counts()

3.变量的可视化分析

#但一变量的可视化分布
#准备画布
plt.figure(figsize=(16,12))
#barplot:条形图
sns.barplot(train_data['employmentLength'].value_counts(dropna = False),
           train_data['employmentLength'].value_counts(dropna = False).keys())
plt.show()

就业年限条形图

#对于不同y值的类型特征进行一些可视化分析
train_loan_fr = train_data.loc[train_data['isDefault'] == 1]
train_loan_nofr = train_data.loc[train_data['isDefault'] == 0]

#对于isdefault对等级和就业年限的可视化分析
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 8))
train_loan_fr.groupby('grade')['grade'].count().plot(kind = 'barh', ax = ax1, title = 'Count of grade fraud')
train_loan_nofr.groupby('grade')['grade'].count().plot(kind = 'barh', ax = ax2, title = 'Count of grade non-fraud')
train_loan_fr.groupby('employmentLength')['employmentLength'].count().plot(kind = 'barh', ax = ax3, title = 'Count of employmentLength fraud')
train_loan_nofr.groupby('employmentLength')['employmentLength'].count().plot(kind = 'barh', ax = ax4, title = 'Count of employmentLength non-fraud')

#对于不同y值的数值特征进行一些可视化分析
fig,((ax1,ax2)) = plt.subplots(1,2,figsize = (12,8))
train_data.loc[train_data['isDefault'] == 1]['loanAmnt'].apply(np.log).plot(kind = 'hist', color = 'r', bins = 100, ax = ax1, xlim = (-3,10), title = 'Count of loanAmnt fraud')
train_data.loc[train_data['isDefault'] == 0]['loanAmnt'].apply(np.log).plot(kind = 'hist', color = 'b', bins = 100, ax = ax2, xlim = (-3,10), title = 'Count of loanAmnt non-fraud')

(log后)loanAmnt的条形图分布
下面这段还要再仔细看看

total = len(train_data)
total_amt = train_data.groupby(['isDefault'])['loanAmnt'].sum().sum()
plt.figure(figsize=(12,5))
plt.subplot(121)##1代表行,2代表列,所以一共有2个图,1代表此时绘制第一个图。
plot_tr = sns.countplot(x='isDefault',data=train_data)#data_train‘isDefault’这个特征每种类别的数量**
plot_tr.set_title("Fraud Loan Distribution \n 0: good user | 1: bad user", fontsize=14)
plot_tr.set_xlabel("Is fraud by count", fontsize=16)
plot_tr.set_ylabel('Count', fontsize=16)
for p in plot_tr.patches:
    height = p.get_height()
    plot_tr.text(p.get_x()+p.get_width()/2.,
            height + 3,
            '{:1.2f}%'.format(height/total*100),
            ha="center", fontsize=15) 
    
percent_amt = (train_data.groupby(['isDefault'])['loanAmnt'].sum())
percent_amt = percent_amt.reset_index()
plt.subplot(122)
plot_tr_2 = sns.barplot(x='isDefault', y='loanAmnt',  dodge=True, data=percent_amt)
plot_tr_2.set_title("Total Amount in loanAmnt  \n 0: good user | 1: bad user", fontsize=14)
plot_tr_2.set_xlabel("Is fraud by percent", fontsize=16)
plot_tr_2.set_ylabel('Total Loan Amount Scalar', fontsize=16)
for p in plot_tr_2.patches:
    height = p.get_height()
    plot_tr_2.text(p.get_x()+p.get_width()/2.,
            height + 3,
            '{:1.2f}%'.format(height/total_amt * 100),
            ha="center", fontsize=15)   

在这里插入图片描述

4.时间格式的数据处理

#训练集中的issuedate的格式转换,将日期转换为距离2007-06-01这一天的天数
data_train['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days

5.数据透视表

##透视表pivot_table 索引可以有多个,“columns(列)”是可选的,聚合函数aggfunc最后是被应用到了变量“values”中你所列举的项目上。
pivot = pd.pivot_table(train_data, index = ['grade'], columns=['issueDateDT'],values =['loanAmnt'],aggfunc=np.sum)
pivot

6.生成数据报告

import pandas_profiling
pfr = pandas_profiling.ProfileReport(data_train)
pfr.to_file("./data_report.html")
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值