2021-04-25

金融风控数据挖掘-Task2

一、学习知识点概要

初步认识python并且了解pandas、numpy、seaborn等数据挖掘中较为常用的库。

二、学习内容

1、导入数据分析及可视化过程需要的库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
import sklearn
import warnings
warnings.filterwarnings('ignore')
# 通过警告过滤器进行控制,忽略警告错误的输出。

2、读取文件

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

data_test_A=pd.read_csv('testA.csv')

# 通过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))
    #<class 'pandas.core.frame.DataFrame'>
    print(len(item))
    i+=1
    if i >= 4:   # 由于数据量过大,限制输出4条就跳出循环
        break
    #5
#     chunker表示将train分为五行每份的dataframe

3、数据集的总体了解

# shape读取行列
data_test_A.shape
data_train.shape
# columns返回列名
data_train.columns
#info()了解数据类型 
data_train.info()
# 查看各个特征的基本统计量
data_train.describe()
# numpy append 将一个数组附加到另一个数组的尾部
data_train.head(3).append(data_train.tail(3))
# 查看数据集中特征值缺失值以及唯一值等
# 简单理解为print(f'{}')花括号内可以使用函数
# pandas中isnull()判断缺失值
print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missing values.')

4、分析特征、处理特征

# 查找缺失率大于50%的特征
have_null_fea_dict = (data_train.isnull().sum()/len(data_train)).to_dict()
have_null_fea_dict
# pandas中to_dict()  返回字典词典
# DataFrame.to_dict (self, orient='dict',* into=)*                 --- 官方文档
# orient ='dict',是函数默认的,转化后的字典形式:{column(列名) : {index(行名) : value(值) )}}
have_null_fea_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()
# 查看训练集测试集中特征属性只有一值的特征
one_value_fea_train = [col for col in data_train.columns if data_train[col].nunique() <= 1]
one_value_fea_test_A = [col for col in data_test_A.columns if data_test_A[col].nunique() <= 1]
print(f'{one_value_fea_train}{one_value_fea_test_A}')
print(f'There are {len(one_value_fea_train)} columns in train dataset with one unique value.')
print(f'There are {len(one_value_fea_test_A)} columns in testA dataset with one unique value.')
# 查看特征的数值类型以及对象类型有哪些
# pandas select_dtypes
# DataFrame.select_dtypes(include=None, exclude=None)
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
numerical_fea
# filter()函数用于过滤序列,过滤掉不符合条件的元素,返回符合条件的元素组成新列表。
# filter(function,iterable)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
category_fea

5、数值型变量分析

# 数值型变量分析,数值型肯定是包括连续型变量和离散型变量的
# 划分数值型变量中的连续变量和离散型变量
# 过滤数值型类别特征
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_serial_fea
# 离散型
numerical_noserial_fea

6、分别对离散型和连续型变量进行分析

# 离散型
# pandas  value_counts() 一种查看表格某列中有多少个不同值的快捷方法,并计算每个不同值有在该列中有多少重复值,这里给出部分代码示例
data_train['term'].value_counts()#离散型变量
data_train['policyCode'].value_counts()#离散型变量,无用,全部一个值
data_train['n11'].value_counts()#离散型变量,相差悬殊
#连续型
# 每个数字特征得分布可视化
# col_wrap限制网格列的个数
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("")

7、非数值型变量

category_fea
data_train['grade'].value_counts()
data_train['earliesCreditLine'].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()

2021-04-25

# 根绝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()

2021-04-25

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

2021-04-25

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)     

2021-04-25

#转化成时间格式  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');

2021-04-25

# 掌握透视图,更好地了解数据
#透视图 索引可以有多个,“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、关于print(f’’)

简单理解为print(f’{}’)花括号内可以使用函数。

2、关于to_dict

pandas 中的to_dict 可以对DataFrame类型的数据进行转换。
pandas to_dict 的用法

3、关于pandas_profiling

文化水平有限,只能说这个库真的很厉害,几乎可以说它两行代码就能解决整个EDA的过程。

四、学习思考与总结

第一次使用jupyter进行python的学习,发现jupyter是一个很好的开发工具。只需要在Windows命令行输入jupyter notebook便可以在默认浏览器打开一个在线的IDE。jupyter的每个cell能够单独进行运算,非常适合于代码的调试,在熟悉快捷键后甚至不需要使用鼠标,对于python初学者而言十分友好。假如我们使用VScode开发一个完整的脚本,变量会随着代码执行的结束而从内存中释放,如果我们想看中间的变量或者结构,我们只能通过断点或者输出日志信息的方式进行调试,这样无疑是非常繁琐的,如果一个程序运行很多这种方式还可行,如果运行时间长达几个小时,这样我们调试一圈耗费的时间就太长了。而在jupyter notebook中我们可以把代码分隔到不同的cell里逐个进行调试,我们可以交互式地在不同cell里获取到我们想要测试的变量值和类型。它甚至支持Markdown,也就是说它的cell不仅支持代码的编写,也支持数学公式的编辑等等,还有类似于浏览器扩展的插件提供使用。

上一篇:金融风控-Task2学习笔记


下一篇:2021-04-25