金融风控训练营task2-赛题理解学习笔记

一、学习知识点概要

文章目录

    • 一、学习知识点概要
    • 二、学习内容
      • 1. 导入数据分析及可视化过程需要的库
      • 2. 读取文件
        • 2.1 拓展知识
      • 3. 基本常用函数
        • 3.1 查看数据集的样本个数和原始特征维度
        • 3.2 查看数据集中特征缺失值,唯一值等
      • 4. 特征的类型
        • 4.1 特征类型:
      • 5. 变量分布可视化
        • 5.1 单一变量分布可视化
        • 5.2 根据y值不同可视化x某个特征的分布
      • 6. 时间格式数据处理及查看
      • 7. 透视图
      • 8. 用pandas_profiling生成数据报告
    • 三、学习问题和解答
    • 四、学习思考与总结

二、学习内容

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

2. 读取文件

2.1 拓展知识

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

  • SV与CSV的区别:

    • SV是用制表符(Tab,’\t’)作为字段值的分隔符;CSV是用半角逗号(’,’)作为字段值的分隔符
  • 读取文件的部分

    • 通过nrows参数,来设置读取文件的前多少行(不包括列名),nrows是一个大于等于0的整数。
      pd.read_csc("train.csv",nrows=5)

    • 分块读取

      • read_csv 和 read_table 有一个 chunksize 参数,用以指定一个块大小(每次读取多少行),返回一个可迭代的 TextFileReader 对象。
      #设置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
      >>> 
      <class 'pandas.core.frame.DataFrame'>
      5
      <class 'pandas.core.frame.DataFrame'>
      5
      <class 'pandas.core.frame.DataFrame'>
      5
      <class 'pandas.core.frame.DataFrame'>
      5
      

3. 基本常用函数

3.1 查看数据集的样本个数和原始特征维度

  • describe默认统计数值型数据的各个(特征)统计量 : data_train.describe()
  • append将截取得数据拼在一起data_train.head(3).append(data_train.tail(3))

3.2 查看数据集中特征缺失值,唯一值等

3.2.1 查看缺失值

print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')
>>> There are 22 columns in train dataset with missing values.
#上面得到训练集有22列特征有缺失值
  • df.isnull() 是元素级别的判断,可以用来查看每个单元格是否缺失(与sina()没有区别),isnull生成的是所有数据的true/false矩阵
  • isnull().any(),是列级别的判断,只要该列有为空或者NA的元素,就为True,否则False
    • 使用all就是全部非缺失值,如果是any就是至少有一个不是缺失值
  • isnull().sum(),将列中为空的个数统计出来

3.2.2 进一步查看缺失特征中缺失率大于50%的特征

have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict()
fea_null_moreThanHalf = {
     } 
#生成列名为key其缺失率为value的字典,包括缺失率为0的列
for key,value in have_null_fea_dict.items():
    if value > 0.5:
        fea_null_moreThanHalf[key] = value

fea_null_moreThanHalf
>>> {
     }

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

# nan可视化
missing = data_train.isnull().sum()/len(data_train)
#同样返回所有列名及其缺失值但不是字典
missing = missing[missing > 0]
#去掉没有数据缺失的
missing.sort_values(inplace=True)
#排序
missing.plot.bar()
#画出柱状图
image-20210426162734266
  • 默认缺失的值类型全为np.nan,上面的示例帮助我们总想了解哪些列存在“nan”,并且可以把nan的个数打印。若nan个数很多则可以考虑将这一列删除。
  • 此外,我们可以进行横向比较,某些样本数据的大部分列是缺失的,且在样本足够的情况下可以考虑将其删除

【补充】

  • inplace参数:作用为 是否在原对象基础上进行修改

    • inplace = True:不创建新的对象,直接对原始对象进行修改;
    • inplace = False:对数据进行修改,创建并返回新的对象承载其修改结果,原对象不变
    • 默认是false
    • inplace的值只有这两个
  • 画图

    • figsize=() 用来表示figure 的大小为宽、长(单位为inch)
    • 直方图hist
      • hist函数:查看df中所有值列的直方图
      • plot函数:df[‘col’].plot(kind = ‘hist’);
    • 柱状图 bar / 横向 barh
      • df[‘col’].value_counts().plot(kind = ‘bar’);
      • value_counts()是按数量多少排序的
    • 饼状图 pie
      • df[‘col’].value_counts().plot(kind = ‘pie’, figsize = (8,8));
    • 散点图 scatter
      • 一整个df的:pd.plotting.scatter_matrix(df, figsize=(15,15)); 该函数还会展示每个变量的直方图
      • 单独的散点图:df.plot(x = ‘col1’, y = ‘col2’, kind = ‘scatter’);
    • 箱线图 box

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

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]
# one_value_fea,one_value_fea_test 返回的值都是['policyCode'],所以这一列参考价值不大,可去掉

4. 特征的类型

4.1 特征类型:

  • 类别性特征
  • 数值型特征
    • 连续型
    • 离散型

(为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度,进行特征分箱,将其转化为WOE编码进而做标准评分卡等操作)

(1)根据类型选择列

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)))
# category_fea这个list就是filter函数筛选出来的结果

(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)
            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)离散型变量分析(节选)

data_train['term'].value_counts()#离散型变量
>>> 
3    606902
5    193098
Name: term, dtype: int64
data_train['policyCode'].value_counts()#离散型变量
>>>
1.0    800000
Name: policyCode, dtype: int64
#无用,只有一个值
data_train['policyCode'].value_counts()#离散型变量
>>>
1.0    800000
Name: policyCode, dtype: int64
#相差悬殊,用不用再分析

(4)数值连续型变量分析

#每个数字特征得分布可视化
# 这里画图估计需要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),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。
#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)

Text(0, 0.5, ‘Probability’)

金融风控训练营task2-赛题理解学习笔记_第1张图片

【绘图说明】

  1. figure语法
figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)
  • num:图像编号或名称,数字为编号 ,字符串为名称
  • figsize:指定figure的宽和高,单位为英寸
  • dpi:参数指定绘图对象的分辨率,即每英寸多少个像素
  • facecolor:背景颜色
  • edgecolor:边框颜色
  • frameon:是否显示边框
  1. subplot语法(创建单个子图)
subplot(nrows,ncols,sharex,sharey,subplot_kw,**fig_kw)
  • nrows: subplot的行数
  • ncols: subplot的列数
  • sharex: 所有subplot应该使用相同的x轴刻度(调节xlim将会影响所有subplot)
  • sharey: 所有subplot应该使用相同的y轴刻度(调节ylim将会影响所有subplot)
  • subplot_kw: 用于创建各subplot的关键字字典
  • **fig_kw: 创建figure时的其他关键字,如plt.subplots(2,2,figsize=(8,6))

subplot可以规划figure划分为n个子图,但每条subplot命令只会创建一个子图 ,参考下面例子。

import numpy as np  
import matplotlib.pyplot as plt  
x = np.arange(0, 100)  
#作图1
plt.subplot(221)  
plt.plot(x, x)  
#作图2
plt.subplot(222)  
plt.plot(x, -x)  
 #作图3
plt.subplot(223)  
plt.plot(x, x ** 2)  
plt.grid(color='r', linestyle='--', linewidth=1,alpha=0.3)
#作图4
plt.subplot(224)  
plt.plot(x, np.log(x))  
plt.show()  

  1. subplots语法(创建多个子图)

参数与上面相似


(5)非数值类别型变量分析

同上,对"grade","subGrade"等采用value_counts()

5. 变量分布可视化

5.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()
金融风控训练营task2-赛题理解学习笔记_第2张图片

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

5.2.1 首先查看类别型变量在不同y值上的分布

train_loan_fr = data_train.loc[data_train['isDefault'] == 1]
train_loan_nofr = data_train.loc[data_train['isDefault'] == 0]

【注释】

  • 对于pd.loc和pd.iloc
    • loc通过行和列的名字获取值
    • iloc通过下标获取值
      金融风控训练营task2-赛题理解学习笔记_第3张图片
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()
png

5.2.2 其次查看连续型变量在不同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)

png

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)
金融风控训练营task2-赛题理解学习笔记_第4张图片

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

#转化成时间格式  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_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 日期有重叠,所以使用基于时间的分割进行验证是不明智的

金融风控训练营task2-赛题理解学习笔记_第5张图片

7. 透视图

掌握透视图可以让我们更好的了解数据

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

8. 用pandas_profiling生成数据报告

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

三、学习问题和解答

  1. 涉及到可视化知识点的部分很多概念都是新接触到的,为了吃下实例的代码,需要一个个方法、函数去查,并且作适当补充
  2. 后半部分的分布可视化和时间格式数据还有很多看不懂的地方,有请教同学,也有上网找相应的知识点看,但还是一知半解

四、学习思考与总结

1.初步接触了EDA探索性数据分析,主要学到的东西有对数据进行特征分析以及可视化的相关内容

2.taks02 对比 task01 已经开始接触有技术含量的东西,现在只是学习打卡阶段,应该要及时落实笔记里面还没有完全看懂的知识点,切忌囫囵吞枣。

3.要学会并且懂得剖析代码,多查多记多思考!时间上要抓紧,即使任务ddl前打卡完成了也要多巩固再学习。

参考文献:
[1]pandas 柱状图_python-pandas | 画图

[2]【Python】 【绘图】plt.figure()的使用

[3]阿里云天池笔记

你可能感兴趣的:(金融风控训练营task2-赛题理解学习笔记)