广工大数协 阿里云天池 金融风控训练营 - Task2 数据分析

本学习笔记为阿里云天池龙珠计划Docker训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/activity/promotion/aicampdocker

一、学习知识点概要

  1. 学习如何对数据集整体概况进行分析,包括数据集的基本情况(缺失值,异常值)

  2. 学习深入数据-查看数据类型

  3. 学习了解变量间的相互关系、变量与预测值之间的存在关系

  4. 学习用pandas_profiling生成数据报告


二、学习内容

2.1  数据总体了解

1.读取数据集并了解数据集大小,原始特征维度

#读取文件(需要先下载数据集)
data_train = pd.read_csv('train.csv')
data_test_a = pd.read_csv('testA.csv')
#查看数据集的样本个数和原始特征维度
data_test_a.shape
data_train.shape
data_train.columns

*读取文件的拓展知识:

  • pandas读取数据时相对路径载入报错时,尝试使用os.getcwd()查看当前工作目录。

  • TSV与CSV的区别:

    • 从名称上即可知道,TSV是用制表符(Tab,'\t')作为字段值的分隔符;CSV是用半角逗号(',')作为字段值的分隔符;

    • Python对TSV文件的支持: Python的csv模块准确的讲应该叫做dsv模块,因为它实际上是支持范式的分隔符分隔值文件(DSV,delimiter-separated values)的。 delimiter参数值默认为半角逗号,即默认将被处理文件视为CSV。当delimiter='\t'时,被处理文件就是TSV。

  • 读取文件的部分(适用于文件特别大的场景)

    • 通过nrows参数,来设置读取文件的前多少行,nrows是一个大于等于0的整数。

    • 分块读取

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

2.通过info熟悉数据类型

data_train.info()

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.')
#进一步查看缺失特征中缺失率大于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()

2.查看唯一值特征情况

one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 1]
one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]
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.')

2.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)))
#过滤数值型类别特征
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)

1.数值连续型变量分析

#每个数字特征得分布可视化
# 这里画图估计需要10-15分钟
f = pd.melt(data_train, value_vars=numerical_serial_fea)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
  • 查看某一个数值型变量的分布,查看变量是否符合正态分布,如果不符合正太分布的变量可以log化后再观察下是否符合正态分布。

  • 如果想统一处理一批数据变标准化 必须把这些之前已经正态化的数据提出

  • 正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。

#绘制交易金额值分布图
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)

2.非数值类别型变量分析

category_fea
data_train['**'].value_counts() #'**'指各个非数值类别型变量名

总结:

  • 图表是概括原始信息最便捷的方式

  • 同一份数据集,在不同的尺度刻画上显示出来的图形反映的规律是不一样的

2.4  变量分布可视化

1.单一变量分布可视化

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()

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

#首先查看类别型变量在不同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)
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)

2.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

2.6  透视图

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

2.8  用pandas_profiling生成数据报告

import pandas_profiling

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

三、学习问题与解答

Q1:在导入pandas_profiling包时,运行’import pandas_profiling‘语句报错:未定义名称“Pandas_Profiling”。

原因是未下载Pandas_Profiling包,尝试运行了'pip install pandas-profiling'命令,又出现了pandas包不匹配的问题,需要对pandas的版本进行升级,升级后再次运行'pip install pandas-profiling'命令就可以了。

Q2:在最后生成数据报告时,进度一直为0,且运行一段时间后,总是提示服务器连接错误。

未找到解决方法。


四、学习思考与总结

在拿到数据后,我们首先要进行的就是数据探索性分析(EDA),它可以有效的帮助我们熟悉数据集、了解数据集,初步分析特征间的相互关系以及特征与目标变量之间的关系,并且对数据进行初步处理,以便使数据集的结构和特征让接下来的预测问题更加可靠。在这个阶段中,我们需要对数据进行清洗,如处理缺失值和异常值,还需要将各个变量间的关系进行可视化,绘制特征分布图,后续所有的阶段都需要在EDA的基础上进行,可见其重要性。

你可能感兴趣的:(广工大数协 阿里云天池 金融风控训练营 - Task2 数据分析)