2.1 学习目标
1、学习如何对数据集整体概况进行分析,包括数据集的基本情况(缺失值,异常值)
2、学习了解变量间的相互关系、变量与预测值之间的存在关系
完成相应学习打卡任务
2.2 分析内容
- 1、数据总体的了解
一般查看数据的纬度,数据类型,基本了解一下数据各个统计量说的啥,对此有一个大概的了解 - 2、查看数据缺失和唯一值
- 3、深入了解数据的类型。每一个特征是连续的还是离散的。对此要有了解
- 4、分析各个特征之间的关系,和目标变量的关系。
2.3 分析过程
导入相关的库
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('./train.csv') data_test_a = pd.read_csv('./testA.csv')
data_test_a.shape data_train.shape
这里的特征列太长,可以使用T进行转置:
data_train.describe().T
实时对比数据内容
data_train.head().append(data_train.tail())
data_train.isnull().any().sum()
上面得到训练集有22列特征有缺失值,进一步查看缺失特征中缺失率大于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
具体的查看缺失特征及缺失率
# nan可视化 missing = data_train.isnull().sum()/len(data_train) missing = missing[missing > 0] missing.sort_values(inplace=True) missing.plot.bar()
one_value_fea = [col for col in data_train.columns if data_train[col].nunique() <= 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)))
数值型变量分析,数值型肯定是包括连续型变量和离散型变量的,找出来 划分数值型变量中的连续变量和离散型变量
#过滤数值型类别特征 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)
了解离散型变量,这里建议去查看一下这两组数据
data_train[ 'policyCode'].value_counts()#离散型变量
数值连续型变量分析可视化。
这里melt方法比较重要,数据透视表和使用方格可视化。由于本文篇幅可能过于长,不在详述。想要了解可以翻找我的博客
#每个数字特征得分布可视化 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在观察。
- 正态Transaction并可视化
#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)
变量分布可视化:
单一变量可视化
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()
- 根据Y值不同可视化特征分布
查看类别型变量在不同y值上的分布:
rain_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')['employm entLength'].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
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)
时间格式数据处理及查看
#转化成时间格式 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 日期有重叠 所以使用基于时间的分割进行验证是不明智的
#透视图 索引可以有多个,“columns(列)”是可选的,聚合函数aggfunc最后是被应用到了变量“values”中你所列举的项目上。 pivot = pd.pivot_table(data_train, index=['grade'], columns=['issueDateDT'], values=['loanAmnt'], aggfunc=np.sum) pivot
最后可以使用这行命令生成数据报告,这个非常棒的,我也是第一次使用,但生成的比较慢
import pandas_profiling pfr = pandas_profiling.ProfileReport(data_train) pfr.to_file("./example.html")
注意
如果没有pandas_profiling这个模块可以是使用
conda install pandas_profiling
安装一下即可
本次任务二学习到不少知识,文章中如有不足之处,感谢指出,一定迅速改正。