DataWhale Task2 EDA数据探索

 代码部分全都用Anaconda 中的Jupyter notebook 完成~

一、读取数据

1.1 设置jupyter nootbook 显示

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity='all'

import pandas as pd 
pd.set_option('display.max_rows',10000)
pd.set_option('display.max_columns',10000)

1.2 调包

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import warnings
warnings.filterwarnings('ignore')

1.3 读取数据

#训练集
df_train=pd.read_csv('train.csv')
df_train.shape
df_train.head(1)
#测试集
df_test=pd.read_csv('testA.csv')
df_test.head(1)
df_test.shape

在这里插入图片描述

二、数据描述

这里主要是描述训练集的数据状态~因为后续建模是针对训练集部分!

2.1 查看数据类型

df_train.info()

在这里插入图片描述
在这里插入图片描述

2.2 总体粗略的查看数据集各个特征的一些基本统计量

df_train.describe() #查看连续变量的基本统计量
df_train.describe(include='O') #查看分类变量的基本统计量
df_train.describe(include='all') #查看全部变量的基本统计量

【截图变量不完整!】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 查看数据的缺失值情况

print(f'There are {df_train.isnull().any().sum()} columns in train dataset with missing values.' )#显示有多少列有缺失值
df_train.isnull().sum()/df_train.shape[0] #显示每个变量的缺失值比例

在这里插入图片描述
查看缺失值比例大于50%的变量

have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict() #先把变量缺失比例转化为字典
fea_null_moreThanHalf = {} #建立一个空字典
for key,value in have_null_fea_dict.items(): #遍历变量缺失值字典
    if value > 0.5: #判断缺失比例是否大于50%
        fea_null_moreThanHalf[key] = value #大于50%添加到空字典中

在这里插入图片描述
没有变量缺失值比例大于50%~

具体的查看缺失特征及缺失率

missing=df_train.isnull().sum()/len(df_train) #查看缺失值比例
missing=missing[missing>0] #选出有缺失值的变量
missing.sort_values(inplace=True) #把有缺失值变量按照比例排序,默认升序
missing.plot.bar() #画出直方图

在这里插入图片描述

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

2.4 查看变量是否存在唯一值情况

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

one_value_fea=[col for col in df_train.columns if df_train[col].nunique() <=1]  #列表中for循环,需要学习!
one_value_fea
print(f'There are {len(one_value_fea)} columns in train dataset with one unique value.')

在这里插入图片描述

  • 总结:
    47列数据中有22列都缺少数据,‘policyCode’具有一个唯一值(或全部缺失)。有很多连续变量和一些分类变量。

三、变量分析

3.1查看特征的数值类型有哪些,对象类型有哪些

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

这里需要学习两个之前没用过的函数:
1、select_dtypes 链接地址,百度找到一个用法
2、filter 详细用法链接地址

3.2 数值型变量分析,数值型肯定是包括连续型变量和离散型变量的,找出来

  • 划分数值型变量中的连续变量和离散型变量
def get_numerical_serial_fea(data,feas): #定义函数
    numerical_continue_fea=[] #数值型-连续型
    numerical_category_fea=[] #数值型-离散型
    for fea in feas:
        temp=data[fea].nunique()
        if temp<=10: #判断变量数值型类别是否小于10个
            numerical_category_fea.append(fea)
            continue
        else:
            numerical_continue_fea.append(fea)
    return numerical_continue_fea,numerical_category_fea

numerical_continue_fea,numerical_category_fea=get_numerical_serial_fea(df_train,numerical_fea)
numerical_continue_fea
numerical_category_fea

在这里插入图片描述
注意:
这里注意一下循环中continue和break的区别。continue是跳出循环中跳过,进入下次循环。break是跳出此次所有循环,以一个实例感受一下区别
continue

for i in range(8):
    if i==5:
        continue
    else:
        print(i)

在这里插入图片描述
break

for i in range(8):
    if i==5:
        break
    else:
        print(i)

在这里插入图片描述

3.2.1 数值类别型变量分析
for i in numerical_category_fea:
    print(i)
    print(df_train[i].value_counts())
    print('\n')

在这里插入图片描述

总结:

  • policyCode:离散型变量,无用,全部一个值
  • n11:离散型变量,相差悬殊,用不用再分析,0的数量为729682
  • n12:离散型变量,相差悬殊,用不用再分析,0的数量为757315
3.2.2 数值连续型变量分析
  • 数值型-连续型变量可视化
f=pd.melt(df_train,value_vars=numerical_continue_fea)
g=sns.FacetGrid(f,col="variable", col_wrap=2, sharex=False, sharey=False)
g=g.map(sns.distplot,"value")

在这里插入图片描述
这里注意可视化操作的两个函数,以前没有用过,附上链接
一个是pandas.melt() pd.melt()用法
另一个是 sns.FacetGrid sns.FaceGrid()函数用法

3.3 非数值型变量分析

for i in category_fea:
    print(i)
    print(df_train[i].value_counts())
    print('\n')

在这里插入图片描述
查看一下每一个非数值型变量有多少个类别~

for i in category_fea:
    print(i)
    print(df_train[i].nunique())
    print('\n')

在这里插入图片描述

总结:

  • subGrade类别多,35个类别
  • issueDate类别多,139个,earliesCreditLine类别多,720个,因为它们是时间变量,需要进一步处理~

3.4 变量分布可视化

注意: 关于数据可视化部分,是自己的弱项,基本不会,需要多学习~

3.4.1 单一变量分布可视化
#就业年限可视化
plt.figure(figsize=(8,8))
sns.barplot(df_train['employmentLength'].value_counts(dropna=False)[:20], df_train['employmentLength'].value_counts(dropna=False).keys()[:20]) #这里取得是前20个类
plt.show()

在这里插入图片描述

3.4.2 根据绝y值不同可视化x某个特征的分布
  • 首先查看类别型变量在不同y值上的分布
train_loan_fr = df_train.loc[df_train['isDefault'] == 1] #有欺诈的人群
train_loan_nofr = df_train.loc[df_train['isDefault'] == 0]  # 无欺诈的人群
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')
plt.show()

在这里插入图片描述

  • 其次查看连续型变量在不同y值上的分布
fig, ((ax1, ax2)) = plt.subplots(1, 2, figsize=(15, 6))
df_train.loc[df_train['isDefault'] == 1]['loanAmnt'].apply(np.log) .plot(kind='hist', bins=100,
          title='Log Loan Amt - Fraud',
          color='r',
          xlim=(-3, 10),
         ax= ax1)
df_train.loc[df_train['isDefault'] == 0] \
    ['loanAmnt'].apply(np.log) \
    .plot(kind='hist',
          bins=100,
          title='Log Loan Amt - Not Fraud',
          color='b',
          xlim=(-3, 10),
         ax=ax2)

在这里插入图片描述

total = len(df_train)
total_amt = df_train.groupby(['isDefault'])['loanAmnt'].sum().sum()  #贷款金额
plt.figure(figsize=(12,5))
plt.subplot(121)##1代表行,2代表列,所以一共有2个图,1代表此时绘制第一个图。
plot_tr = sns.countplot(x='isDefault',data=df_train)#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 = (df_train.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)   

在这里插入图片描述

3.5 时间变量查看及处理

  • 训练集中衍生一个新的时间变量
#转化成时间格式  issueDateDT特征表示数据日期离数据集中日期最早的日期(2007-06-01)的天数
df_train['issueDate'].min() # 日期最早的日期 2007-06-01
df_train['issueDate'] = pd.to_datetime(df_train['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
df_train['issueDateDT'] = df_train['issueDate'].apply(lambda x: x-startdate).dt.days #衍生了一个新变量  issueDateDT特征表示数据日期离数据集中日期最早的日期(2007-06-01)的天数
  • 测试集中衍生一个新的时间变量
#转化成时间格式 【测试集】
df_test['issueDate'] = pd.to_datetime(df_test['issueDate'],format='%Y-%m-%d')
startdate = datetime.datetime.strptime('2007-06-01', '%Y-%m-%d')
df_test['issueDateDT'] = df_test['issueDate'].apply(lambda x: x-startdate).dt.days
  • 可视化
plt.hist(df_train['issueDateDT'], label='train');
plt.hist(df_test['issueDateDT'], label='test');
plt.legend();
plt.title('Distribution of issueDateDT dates');
#train 和 test issueDateDT 日期有重叠 所以使用基于时间的分割进行验证是不明智的

在这里插入图片描述

3.6 透视图

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

贴一个详细讲解透视表的链接!
pd.pivot_table用法

总结:嗯,用到了一些自己之前没有用过的函数,对EDA的流程也有了一个清晰的理解~继续加油

补充:
1、安装库的镜像,加一个链接 python安装库镜像/清华/豆瓣等等
2、
在这里插入图片描述

安装pandas_profiling一直出错,没有安装成功,还没有找到原因,迫不及待想看到数据报告呢~继续探索!
【更新,隔了2天再次启动Jupyter,调用pandas_profiling竟然成功了,神奇,哈哈】

pandas_profiling 会形成数据的一个网页版报告,有数据的形状,变量,以及对每一个变量的具体报告,具体报告截图所示:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值