天池-金融风控训练营-task2-数据分析

一、学习知识概要

主要介绍了eda可以从哪些方面入手:

1. 数据整体情况

多少行、多少列、各列的数据缺失情况(对存在缺失的列,可以查看缺失率)、各列的数据类型、各列的平均值等基本统计量、数据的首尾几行展示、各列取值去重后的数量。

2. 单变量分析-数据分布

查看数据分布需要按照数据类型进行分类,类别型变量、离散型数值型变量、连续型数值型变量。对于前两者,通过查看各类数量占比(表或柱状图的形式);对于后者,可以通过直方图进行可视化。

3. 多变量分析

此处主要是根据y值不同查看x某个特征的分布(通过绘图的方式);在逻辑回归模型训练之前需要计算特征之间的相关系数,以免入模变量存在多重共线性。

4. 其他

查看两个数据集时间分布,本文用到的两数据集上面日期有重叠。因此后续在使用train数据集进行训练集测试集划分时,基于时间的分割进行验证是不明智的。

二、学习内容

1. 数据总体了解:

1.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')

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

# 读取文件的部分(适用于文件特别大的场景)
# data_train_sample = pd.read_csv("data/train.csv",nrows=5)

#设置chunksize参数,来控制每次迭代数据的大小
i = 0  # 控制输出
chunker = pd.read_csv("data/train.csv",chunksize=5)
for item in chunker:
    print(type(item))
    #<class 'pandas.core.frame.DataFrame'>
    print(len(item))
    i+=1
    if i >= 4:   # 由于数据量过大,限制输出4条就跳出循环
        break
    #5

1.2 总体了解-数据集大小、数据缺失情况、数据类型;

# 总体了解

# 查看数据集的样本个数和原始特征维度
print('data_test_a.shape:{}'.format(data_test_a.shape))
print('data_train.shape:{}'.format(data_train.shape))
print('data_train.columns:\n{}'.format(data_train.columns))

# 通过info()来熟悉数据类型
data_train.info()

1.3 粗略查看数据集中各特征基本统计量;

# 总体粗略的查看数据集各个特征的一些基本统计量
data_train.describe()

# 查看数据样例
data_train.head(3).append(data_train.tail(3))

2. 缺失值和唯一值:

2.1 查看数据缺失值情况

# 查看缺失值
print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')

# 上面得到训练集有22列特征有缺失值,进一步查看缺失特征中缺失率大于50%的特征
# 发现没有缺失特征大于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:
        fea_null_moreThanHalf[key] = value
fea_null_moreThanHalf

# nan可视化
missing = data_train.isnull().sum()/len(data_train)
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()

 There are 22 columns in train dataset with missing values.

{}

2.2 查看唯一值特征情况

one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 1]
one_value_fea

 ['policyCode']

one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]
one_value_fea_test

 ['policyCode']

print(f'There are {len(one_value_fea)} columns in train dataset with one unique value.')
print(f'There are {len(one_value_fea_test)} columns in test dataset with one unique value.')

 There are 1 columns in train dataset with one unique value. There are 1 columns in test dataset with one unique value.

 # 总结

    47列数据中有22列都缺少数据,这在现实世界中很正常。‘policyCode’具有一个唯一值(或全部缺失)。有很多连续变量和一些分类变量。

3. 深入数据-查看数据类型

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

# 数值型变量
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)))

print(f'numerical_fea:\n{numerical_fea}\n')

print(f'category_fea:\n{category_fea}')

 numerical_fea:

['id', 'loanAmnt', 'term', 'interestRate', 'installment', 'employmentTitle', 'homeOwnership', 'annualIncome', 'verificationStatus', 'isDefault', 'purpose', 'postCode', 'regionCode', 'dti', 'delinquency_2years', 'ficoRangeLow', 'ficoRangeHigh', 'openAcc', 'pubRec', 'pubRecBankruptcies', 'revolBal', 'revolUtil', 'totalAcc', 'initialListStatus', 'applicationType', 'title', 'policyCode', 'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11', 'n12', 'n13', 'n14']

category_fea:

['grade', 'subGrade', 'employmentLength', 'issueDate', 'earliesCreditLine']

3.1 类别型数据

data_train['grade'].value_counts()

# data_train['subGrade'].value_counts()
# data_train['employmentLength'].value_counts()
# data_train['issueDate'].value_counts() # 贷款发放日期
# data_train['earliesCreditLine'].value_counts() #借款人最早报告的信用额度开立的月份
# data_train['isDefault'].value_counts()
# 单一变量分布可视化
plt.figure(figsize=(8, 8))
sns.barplot(data_train["employmentLength"].value_counts(dropna=False)[:20],
            data_train["employmentLength"].value_counts(dropna=False).keys()[:20])
plt.show()

3.2 数值型数据

#过滤数值型类别特征
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) 
            # 如果取值种类小于等于10的话,就认为是数值型类别特征
            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)

3.3 离散数值型数据

data_train['policyCode'].value_counts()#离散型变量,无用,全部一个值

data_train['n11'].value_counts()#离散型变量,相差悬殊,用不用再分析

data_train['n12'].value_counts()#离散型变量,相差悬殊,用不用再分析
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

3.4 连续数值型数据

#每个数字特征得分布可视化
# 这里画图估计需要10-15分钟
f = pd.melt(data_train, value_vars=numerical_serial_fea) # 类似于逆透视
# REF:https://blog.csdn.net/maymay_/article/details/80039677
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
# REF:https://blog.csdn.net/weixin_42398658/article/details/82960379

pd.melt用法参考:

Pandas 的melt的使用_数据分析-CSDN博客_pd.melt参数:pandas.melt(frame,id_vars=None,value_vars=None,var_name=None,value_name='value',col_level=None)frame:要处理的数据集。id_vars:不需要被转换的列名。value_vars:需要转换的列名,如果剩下的列全部都要转换,就不用写了。var_name和value_name是自定义设置对应...https://blog.csdn.net/maymay_/article/details/80039677sns.FacetGrid、g.map用法参考:

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

#Ploting Transaction Amount Values Distribution
plt.figure(figsize=(16,12))
plt.suptitle('Transaction Values Distribution', fontsize=22)
plt.subplot(221)
sub_plot_1 = sns.distplot(data_train['loanAmnt'])
sub_plot_1.set_title("loanAmnt Distribuition", fontsize=18)
sub_plot_1.set_xlabel("")
sub_plot_1.set_ylabel("Probability", fontsize=15)

plt.subplot(222)
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)

4. 数据间相关关系

4.1 特征和特征之间关系

4.2 特征和目标变量之间关系

# 首先查看类别型变量在不同y值上的分布
train_loan_fr = data_train.loc[data_train['isDefault'] == 1]
train_loan_nofr = data_train.loc[data_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))
data_train.loc[data_train['isDefault'] == 1] \
    ['loanAmnt'].apply(np.log) \
    .plot(kind='hist',
          bins=100,
          title='Log Loan Amt - Fraud',
          color='r',
          xlim=(-3, 10),
         ax= ax1)
data_train.loc[data_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)

# 绘制loanAmout在不同y值上的计数、总和
total = len(data_train)
total_amt = data_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=data_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 = (data_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)     

5. 时间格式数据处理及查看

#转化成时间格式  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')
data_train['issueDateDT'] = data_train['issueDate'].apply(lambda x: x-startdate).dt.days

#转化成时间格式
data_test_a['issueDate'] = pd.to_datetime(data_test_a['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 日期有重叠 所以使用基于时间的分割进行验证是不明智的

 train 和 test issueDateDT 日期有重叠 所以使用基于时间的分割进行验证是不明智的

三、学习问题与解答

1. -是否有必要,对每个变量都根据y值不同查看该特征的分布?

2. -日常操作中,分块读取数据的作用?

    -原理就是不一次性把文件数据读入内存中,而是分多次。  数据处理:1 用pandas处理大型csv文件 2 使用Pandas分块处理大文件 3 分块读取_wld的博客-CSDN博客_pandas分块读取csv在训练机器学习模型的过程中,源数据常常不符合我们的要求。大量繁杂的数据,需要按照我们的需求进行过滤。拿到我们想要的数据格式,并建立能够反映数据间逻辑结构的数据表达形式。 最近就拿到一个小任务,需要处理70多万条数据。我们在处理CSV文件时,经常使用的大熊猫,可以帮助处理较大的CSV文件。大熊猫中处理CSV文件的函数主要为read_csv() 状语从句:to_csv()这两个,其中read...https://blog.csdn.net/wld914674505/article/details/81431128

四、学习思考与总结

学习材料中,关于训练样本和预测样本日期分布的分析,对我来说是一个新鲜的做法,值得学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值