赞
踩
1. 熟悉了解整个数据集的基本情况,例如缺失值,异常值。
a. 读取数据集并了解数据集大小,原始特征维度;
b. 通过info熟悉数据类型;
c. 粗略查看数据集中各特征基本统计量;
d. 查看数据缺失值情况
e. 查看唯一值特征情况
f. 查看数据类型
·类别型数据
·数值型数据
·离散数值型数据
·连续数值型数据
2. 了解变量间的相互关系、变量与预测值之间的存在关系。
a. 特征和特征之间关系
b. 特征和目标变量之间关系
c. 用pandas_profiling生成数据报告
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')
import pandas.util.testing as tm
data_train = pd.read_csv('./train.csv')
data_test_a = pd.read_csv('./testA.csv')
a. 设置nrows参数 ,只读取前多少行
1 data_train_sample = pd.read_csv("./train.csv",nrows=5)
b. 设置chunksize参数,来控制每次迭代数据的大小
chunker = pd.read_csv("./train.csv",chunksize=5)
for item in chunker:
print(type(item))
#<class 'pandas.core.frame.DataFrame'>
print(len(item))
#5
data_train.head(3).append(data_train.tail(3))
print(data_test_a.shape)
#(200000, 48)
print(data_train.shape)
#(800000, 47)
print(data_train.columns)
#Index(['id', 'loanAmnt', 'term', 'interestRate'···],
#dtype='object')
data_train.info()
data_train.describe()
查看缺失值
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.
进一步查看缺失特征中缺失率大于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可视化)
如果nan存在的个数很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,如果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]
one_value_fea_test = [col for col in data_test_a.columns if data_test_a[col].nunique() <= 1]
one_value_fea
#['policyCode']
one_value_fea_test
#['policyCode']
特征一般都是由类别型特征和数值型特征组成。
类别型特征有时具有非数值关系,有时也具有数值关系。
特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度。从而使模型更加稳定。
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)))
data_train.grade #查看grade
利用value_counts()等函数反应特征属性的分布。
图表是概括原始信息最便捷的方式。
1. 划分连续变量和分类变量
def get_numerical_serial_fea(data,feas):
numerical_serial_fea = []
numerical_noserial_fea = []
for fea in feas:
temp = data[fea].nunique() #查看该序列(axis=0/1对应着列或行)的不同值的数量
if temp <= 10: #经验判断?
numerical_noserial_fea.append(fea) #noserial
continue
numerical_serial_fea.append(fea) #serial
return numerical_serial_fea,numerical_noserial_fea
numerical_serial_fea,numerical_noserial_fea = get_numerical_serial_fea(data_train,numerical_fea)
numerical_noserial_fea
#['term', 'homeOwnership', 'verificationStatus', 'isDefault', 'initialListStatus', 'applicationType', 'policyCode',
'n11',
'n12']
2. 数值类别型变量分析
data_train['term'].value_counts() # 3 606902 # 5 193098 # Name: term, dtype: int64 data_train['homeOwnership'].value_counts() # 0 395732 # 1 317660 # 2 86309 # 3 185 # 5 81 # 4 33 # Name: homeOwnership, dtype: int64 # 离散型变量,无用,全部一个值 data_train['policyCode'].value_counts() # 离散型变量,相差悬殊,用不用再分析 data_train['n11'].value_counts()
1、pandas.DataFrame.nunique返回的是唯一值的个数,不返回这个唯一值;
2、value_counts()查看表格某列中有多少个不同值,并计算每个不同值有在该列中有多少重复值;
3、unique()是以数组形式(numpy.ndarray)返回列的所有唯一值(特征的所有唯一值)
# 每个数字特征得分布可视化
# pd.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")
# 报错
# 1、ValueError: could not convert string to float: 'scott'
# 2、RuntimeError: Selected KDE bandwidth is 0. Cannot estiamte density.
# 参考https://stackoverflow.com/questions/61440184/who-is-scott-valueerror-in-seaborn-pairplot-could-not-convert-string-to-floa
# 将seaborn 0.10.0更新至0.10.1后解决
查看变量是否符合正态分布,如果不符合正太分布的变量可以log化后再观察是否符合正态分布。
统一处理一批数据变标准化前,必须把之前已经正态化的数据提出。
#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)
category_fea
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()
根据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()
# groupby可以免去循环
# groupby('a')['b'].c().d()
# 数据根据a进行分组后,选择b属性(列),得到一个series(每组都有一个series,可以用unstack将每一组变成每一行),进行c、d等操作
# []中可以是连续属性的数据,也可以是离散的
# 参考https://www.jianshu.com/p/42f1d2909bb6
查看连续型变量在不同y值上的分布
# df.at[a,b]定位到a,b位置的元素
# df.loc[a,b]显示索引,a为index切片,b为columns列名,a、b都可以为列表
# [a,b]也可以为[a][b]
# 传入:表示所有行/列
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)) # 1代表行,2代表列,所以一共有2个图,1代表此时绘制第一个图 plt.subplot(121) plot_tr = sns.countplot(x='isDefault',data=data_train) # sns.countplot画出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() #.get_height() plot_tr.text(p.get_x()+p.get_width()/2.,height + 3, '{:1.2f}%'.format(height/total*100), ha="center", fontsize=15) #.text;.get_x();.get_width() 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)
#转化成时间格式 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_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 # 时间处理函数pandas.to_datetime(arg,errors ='raise',utc = None,format = None,unit = None ) # 如果数据里有时间出错的格式,errors='coerce' # 转化成时间格式 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)
# index是层次字段,可以逐层次添加
# values筛选需要计算的数据
import pandas_profiling
pfr = pandas_profiling.ProfileReport(data_train)
pfr.to_file("./example.html")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。