金融风控训练营赛题理解(task 2)学习笔记

本学习笔记为阿里云天池龙珠计划Docker训练营的学习内容,学习链接为:https://tianchi.aliyun.com/notebook-ai/detail?spm=5176.20850282.J_3678908510.4.f2984d57AnIOhB&postId=170949

Task2目的:
1.EDA价值主要在于熟悉了解整个数据集的基本情况(缺失值,异常值),对数据集进行验证是否可以进行接下来的机器学习或者深度学习建模.
2.了解变量间的相互关系、变量与预测值之间的存在关系。
3.为特征工程做准备

1、学习知识概要

  • 学习如何对数据集整体概况进行分析,包括数据集的基本情况(缺失值,异常值)
  • 学习如何对数据进行统计规整,按条件进行筛选
  • 学习如何利用matplotlib进行数据可视化作图
  • 数据总体了解
    • 读取数据集并了解数据集大小,原始特征维度;
    • 通过info熟悉数据类型;
    • 粗略查看数据集中各特征基本统计量;
  • 缺失值和唯一值:
    • 查看数据缺失值情况
    • 查看唯一值特征情况
  • 深入数据-查看数据类型
    • 类别型数据
    • 数值型数据
      • 离散数值型数据
      • 连续数值型数据
  • 时间格式数据处理及查看
  • 掌握数据透视图
  • 用pandas_profiling生成数据报告

2、学习内容

2.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')
import pandas profiling

读取数据

data_train = pd.read_csv('train.csv')
data_test_a = pd.read_csv('testA.csv')

倘若遇到数据量过大的表格,最好加入chunksize分块读入
pd.read_csv用法

查看一下数据大概长啥样

id	loanAmnt	term	interestRate	installment	   grade	subGrade	employmentTitle	employmentLength	homeOwnership	...	 n5	  n6    n7	   n8	  n9	 n10	 n11	n12    n13	 n14
0	35000.0	      5	        19.52	       917.97	     E	       E2	          320.0	         2 years	          2	        ...	9.0	  8.0	4.0	   12.0	  2.0	 7.0	 0.0	0.0	   0.0	 2.0

查看数据信息
可以创建一个实例,自己代入理解,例如:
data_train=pd.DataFrame({“A”:[1,2,3,4,5,6],“B”:[3,4,NAN,7,NAN,5],“C”:[2,NAN,3,7,NAN,3],“D”:[2,6,7,9,5,5]})

金融风控训练营赛题理解(task 2)学习笔记

data_train.info()#总体数据信息
data_train.shape #返回数据行列数
data_train.columns #返回数据列名
data_train.describe()#返回数据集各个特征的一些基本统计量,包括均值、总数、最大小值、方差、主要分位数
data_train.head(2).append(data_train.tail(2))#查看头两列和尾两列信息,用append连成一个表

具体列名介绍

  • id 为贷款清单分配的唯一信用证标识
  • loanAmnt 贷款金额
  • term 贷款期限(year)
  • interestRate 贷款利率
  • installment 分期付款金额
  • grade 贷款等级
  • subGrade 贷款等级之子级
  • employmentTitle 就业职称
  • employmentLength 就业年限(年)
  • homeOwnership 借款人在登记时提供的房屋所有权状况
  • annualIncome 年收入
  • verificationStatus 验证状态
  • issueDate 贷款发放的月份
  • purpose 借款人在贷款申请时的贷款用途类别
  • postCode 借款人在贷款申请中提供的邮政编码的前3位数字
  • regionCode 地区编码
  • dti 债务收入比
  • delinquency_2years 借款人过去2年信用档案中逾期30天以上的违约事件数
  • ficoRangeLow 借款人在贷款发放时的fico所属的下限范围
  • ficoRangeHigh 借款人在贷款发放时的fico所属的上限范围
  • openAcc 借款人信用档案中未结信用额度的数量
  • pubRec 贬损公共记录的数量
  • pubRecBankruptcies 公开记录清除的数量
  • revolBal 信贷周转余额合计
  • revolUtil 循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额
  • totalAcc 借款人信用档案中当前的信用额度总数
  • initialListStatus 贷款的初始列表状态
  • applicationType 表明贷款是个人申请还是与两个共同借款人的联合申请
  • earliesCreditLine 借款人最早报告的信用额度开立的月份
  • title 借款人提供的贷款名称
  • policyCode 公开可用的策略_代码=1新产品不公开可用的策略_代码=2
  • n系列匿名特征 匿名特征n0-n14,为一些贷款人行为计数特征的处理

2.2 缺失值和唯一值

查看训练集测试集中特征属性含缺失值的特征

print(len(data_train))#返回行数
print(data_train.isnull())##is.null()在相应数据单元格返回布尔型数据,是缺失值就返回True,否则返回False   
print(data_train.isnull().sum()) #sum()默认列统计 sum参数:0-列,1-行
print(data_train.isnull().any()) #any() 有一个True就返回True   all()得全部是True才返回True
#any(0)列操作  any(1)行操作
print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.') #等价于print('There are {} columns in train dataset with missing values.'.format(data_train.isnull().any().sum()))#这里sum对True计数

运行上面代码可得训练集有22列特征有缺失值,那么我们进一步查看缺失特征中缺失率大于50%的特征

have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict()#.to_dict()将表格数据转换成字典格式 
fea_null_moreThanHalf = {}
for key,value in have_null_fea_dict.items(): #遍历字典
    if value > 0.5:
        fea_null_moreThanHalf[key] = value #为字典添加新元素
print(fea_null_moreThanHalf)#返回所要特征

to_dict用法

采用matplotlib将数据可视化,具体的查看缺失特征及缺失率

missing = data_train.isnull().sum()/len(data_train) # 返回缺失率,missing是个series 
missing = missing[missing > 0] #选取missing中大于0的数据
missing.sort_values(inplace=True )#sort_values是按值大小进行排序
missing.plot.bar()#画条形图

金融风控训练营赛题理解(task 2)学习笔记

  • 纵向了解哪些列存在 “nan”, 并可以把nan的个数打印,主要的目的在于查看某一列nan存在的个数是否真的很大,如果nan存在的过多,说明这一列对label的影响几乎不起作用了,可以考虑删掉。如果缺失值很小一般可以选择填充。
  • 另外可以横向比较,如果在数据集中,某些样本数据的大部分列都是缺失的且样本足够的情况下可以考虑删除**。**#data_train.dropna()

查看训练集测试集中特征属性只有一值的特征

#unique返回唯一值,nunique返回指标个数
one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 1] #输出结果:['policyCode']
one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1] #输出结果:['policyCode']

[col for col in data_train.columns if data_train[col].nunique()]
[返回值 迭代器 条件] 返回一个list列表
(n)unique用法


2.3 深入数据-查看数据类型

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

查看并过滤数据类型

data_train.dtypes #可返回各列数据类型 注意只要有一个object类型就返回object
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns) #根据数据类型选择特征
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
#filter()函数被用于过滤序列,它会过滤掉不符合条件的数据,filter函数返回的结果是一个可迭代对象。
#如果第二条代码不以list开头则要用for循环迭代取出

filter函数用法

过滤数值型类别特征:分为结果数目大于10和≤10的列,实际上也算是一种将变量分为连续型和离散型的操作,方便对离散型数据进行统计与作条形统计图,对连续性数据做折线图或核密度直方图

def get_numerical_serial_fea(data,feas):
    numerical_serial_fea = []
    numerical_noserial_fea = []
    for fea in feas:
        temp = data[fea].nunique()#过滤条件
        if temp <= 10:
            numerical_noserial_fea.append(fea)
            continue
        numerical_serial_fea.append(fea)
    return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(data_train,numerical_fea)

#返回的离散型变量为:
numerical_noserial_fea:['term','homeOwnership','verificationStatus','isDefault','initialListStatus','applicationType','policyCode','n11','n12']

离散型变量的统计 .value_count()

data_train['term'].value_counts()

3    606902
5    193098
Name: term, dtype: int64
-------------------------------
data_train['homeOwnership'].value_counts()

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

根据y值不同可视化x某个特征的分布

  • 首先查看类别型变量在不同y值上的分布
  • 再依据分布进行可视化分析
train_loan_fr = data_train.loc[data_train['isDefault'] == 1] #loc函数选择数据,还有一个是iloc,可以再查阅一下reindex
train_loan_nofr = data_train.loc[data_train['isDefault'] == 0]
fig, axes = plt.subplots(2, 2, figsize=(15, 8))
train_loan_fr.groupby('grade')['grade'].count().plot(kind='barh', ax=axes[0,0], title='Count of grade fraud')
train_loan_nofr.groupby('grade')['grade'].count().plot(kind='barh', ax=axes[0,1], title='Count of grade non-fraud')
train_loan_fr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=axes[1,0], title='Count of employmentLength fraud')
train_loan_nofr.groupby('employmentLength')['employmentLength'].count().plot(kind='barh', ax=axes[1,1], title='Count of employmentLength non-fraud')
plt.show()

金融风控训练营赛题理解(task 2)学习笔记
loc和iloc函数用法

连续型变量的可视化分布

f = pd.melt(data_train, value_vars=numerical_serial_fea) #pd.melt 将宽透视为长,pd.pivot将长透视为宽
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False) #col_wrap=2 每行两个子图
g = g.map(sns.distplot, "value")#直方加核密度图 https://www.sogou.com/link?url=hedJjaC291P3yGwc7N55kLSc2ls_Ks2xmk1vI0c0xdDbaJ2KBnWAiC--N4hJvhoHri2jTBr9OJ8.

FaceGrid用法
displot函数用法

部分图表截图

金融风控训练营赛题理解(task 2)学习笔记

  • 查看某一个数值型变量的分布,查看变量是否符合正态分布(Shapiro_Wilk检验),如果不符合正太分布的变量可以log化后再观察下是否符合正态分布
  • 如果想统一处理一批数据变标准化 必须把这些之前已经正态化的数据提出
  • 正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果

对比原始数据与log化数据的分布

plt.figure(figsize=(16,8))
plt.suptitle('Transaction Values Distribution', fontsize=22)#添加总标题
plt.subplot(121)#画第一张子图 子图排列为2×2的矩阵 subplot(121)的位置相当于(1,1)位置
sub_plot_1 = sns.distplot(data_train['loanAmnt'])
sub_plot_1.set_title("loanAmnt Distribuition", fontsize=18) #设置图标标题
sub_plot_1.set_xlabel("") #设置x轴标签
sub_plot_1.set_ylabel("Probability", fontsize=15) #设置y轴标签

plt.subplot(122)
sub_plot_2 = sns.distplot(np.log(data_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)

金融风控训练营赛题理解(task 2)学习笔记

2.4 时间格式数据处理及查看

#转化成时间格式  issueDateDT特征表示数据日期离数据集中日期最早的日期(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')#字符串转换成日期  strftime:日期格式化成字符串
data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days 

to_datetime 以及 dt.days

一些时间序列的知识可以在我上传的文件资源查看,是以前学《利用python进行数据分析》时候做的笔记

#转化成时间格式
data_test_a['issueDate'] = pd.to_datetime(data_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
data_test_a['issueDateDT'] = data_test_a['issueDate'].apply(lambda x: x-startdate).dt.days
plt.hist(data_train['issueDateDT'], label='train');
plt.hist(data_test_a['issueDateDT'], label='test');
plt.legend();
plt.title('Distribution of issueDateDT dates');
#train 和 test issueDateDT 日期有重叠 所以使用基于时间的分割进行验证是不明智的

金融风控训练营赛题理解(task 2)学习笔记

2.5 掌握数据透视图

用pandas_profiling生成数据报告

print(tips[:5])
print(tips.pivot_table(['total_bill'],index=['time','smoker'],columns='day',margins=True,aggfunc='mean',fill_value=0))
#第一个参数是操作目标,index表示选取行指标,columns表示选取列指标,margins表示添加行列总计,就是图中的ALL,aggfunc表示进行的函数操作,fill_value=0表示用0替换图中的缺失值

金融风控训练营赛题理解(task 2)学习笔记

拓展一下crosstab交叉表

print(pd.crosstab([tips.time,tips.day],tips.smoker,margins=True)) #前两个参数是行和列

金融风控训练营赛题理解(task 2)学习笔记

2.6 用pandas_profiling生成数据报告

import pandas_profiling
pfr = pandas_profiling.ProfileReport(data_train)
pfr.to_file("./example.html")

由于不知道上面原因我生成不了报告,在下面贴一个其他码友的文章
python自动数据分析——pandas_profiling


三、学习问题与解答

对于代码的思考与解答已融入于第二点中


四、学习思考与总结

数据探索性分析是我们初步了解数据,熟悉数据为特征工程做准备的阶段,甚至很多时候EDA阶段提取出来的特征可以直接当作规则来用。可见EDA的重要性,这个阶段的主要工作还是借助于各个简单的统计量来对数据整体的了解,分析各个类型变量相互之间的关系,以及用合适的图形可视化出来直观观察

上一篇:2021-04-25


下一篇:广工大数协 阿里云天池 金融风控训练营-Task2