task2—数据分析

前一部分我们对一些分类指标等一些预备知识进行了学习,接下来我们要进行的是探索性的数据分析(EDA)。
EDA是我们进行数据挖掘非常重要的一步,做的好的EDA可以让我们对数据作出更准确的分析,一方面是让我们了解整个数据集,包括缺失值,异常值,变量间的练习等,另一方面也是为我们之后的特征工程做好准备。

查看数据集的列数据

train.columns

Index([‘id’, ‘loanAmnt’, ‘term’, ‘interestRate’, ‘installment’,
‘grade’,
‘subGrade’, ‘employmentTitle’, ‘employmentLength’, ‘homeOwnership’,
‘annualIncome’, ‘verificationStatus’, ‘issueDate’, ‘isDefault’,
‘purpose’, ‘postCode’, ‘regionCode’, ‘dti’, ‘delinquency_2years’,
‘ficoRangeLow’, ‘ficoRangeHigh’, ‘openAcc’, ‘pubRec’,
‘pubRecBankruptcies’, ‘revolBal’, ‘revolUtil’, ‘totalAcc’,
‘initialListStatus’, ‘applicationType’, ‘earliesCreditLine’, ‘title’,
‘policyCode’, ‘n0’, ‘n1’, ‘n2’, ‘n2.1’, ‘n4’, ‘n5’, ‘n6’, ‘n7’, ‘n8’,
‘n9’, ‘n10’, ‘n11’, ‘n12’, ‘n13’, ‘n14’],
dtype=‘object’)

项目Value
电脑$1600
手机$12
导管$1
Column 1Column 2
‘id’贷款清单分配的唯一信用证标识
‘loanAmnt’贷款金额
#‘term’贷款期限
‘interestRate’贷款利率
‘installment’分期付款金额
‘grade’贷款等级
‘subGrade’贷款等级之子级
‘employmentTitle’就业职称
‘employmentLength’就业年限
‘homeOwnership’借款人在登记时提供的房屋所有权状况
‘annualIncome’年收入
‘verificationStatus’验证状态
‘issueDate’贷款发放的月份
‘purpose’借款人在贷款申请时的贷款用途类别
‘postCode’借款人在贷款申请中提供的邮政编码的前3位数字
‘regionCode’地区编码
‘dti’债务收入比
‘delinquency_2years’借款人过去2年信用档案中逾期30天以上的违约事件数
‘ficoRangeLow’借款人在贷款发放时的fico所属的下限范围
‘ficoRangeHigh’借款人在贷款发放时的fico所属的上限范围
‘openAcc’借款人信用档案中未结信用额度的数量
‘pubRec’贬损公共记录的数量
‘pubRecBankruptcies’公开记录清除的数量
‘revolBal’信贷周转余额合计
‘revolUtil’循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额
‘totalAcc’借款人信用档案中当前的信用额度总数
 还可以通过数据分析的基本python语句对数据集进行分析了解
#通过info()来熟悉数据类型
train.info()
#总体粗略的查看数据集各个特征的基本统计情况
train.describe()

查看缺失值

print(f'There are {data_train.isnull().any().sum()} columns in train dataset with missingvalues.')
have_null_fea_dict=(train.isnull().sum()/len(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

查看具体缺失及缺失率

missing=train.isnull().sum()/len(train)
missing=missing[missing >0]
missing.sort_values(inplace=True)
missing.plot.bar()

Alt

了解哪些列存在“nan”,并可以把nan的个数打印,主要的目的在于nan存在个数是否 真的很大,
如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化;
如果nan存在的过多,可以考虑删除查看训练集测试集中特征属性只有一值的特征

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

47列数据中有22列都缺少数据,在现实生活中很正常,policycode具有一个唯一值(或全部缺失) 有很多连续变量和一些分类变量。

  • 1、特征一般都是由类别型特征和数值型特征组成 。
  • 2、类别型特征有时具有非数值关系,有时也具有数值关系。比如‘grade’中的等级A,B,C等,是否只是单纯的 分类,还是A优于其他要结合业务判断。
  • 3、数值型特征本是可以直接入模的,但往往风控人员要对其做分箱,转化为WOE编码进而做标准评分卡等操作。 从模型效果上来看,特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度。从而使模型更加稳定。
numerical_fea=list(train.select_dtypes(exclude=['object']).columns)
category_fea=list(filter(lambda x: x not in numerical_fea,list(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(train,numerical_fea)

对数据离散量进行分析

离散量如下,将离散量名称名进行替换就可以得出离散量:

'term',
 'homeOwnership',
 'verificationStatus',
 'isDefault',
 'initialListStatus',
 'applicationType',
 'policyCode',
 'n11',
 'n12'
train['term'].value_counts()

数值连续性变量分析
每个数字特征的分布可视化

f=pd.melt(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")

Alt

1、查看某一个数值型变量的分布,查看变量是否符合正态分, 如果不符合正太分布的变量可以log化后再观察下是否符合正态分布。
2. 如果想统一处理一批数据变标准化 必须把这些之前已经正态化的数据提出。

# ploting transaction amount values distribution
plt.figure(figsize=(16,12))
plt.suptitle('Transaction values dictribution',fontsize=22)
plt.subplot(221)

sub_plot_1=sns.distplot(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(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)

Alt

非数值类别型变量分析,方法同上:

'grade', 'subGrade', 'employmentLength', 'issueDate', 'earliesCreditLine'
train['grade'].value_counts()
plt.figure(figsize=(8,8))
sns.barplot(train["employmentLength"].value_counts(dropna=False)[:20],
            train["employmentLength"].value_counts(dropna=False).keys()[:20])
plt.show()

Alt

train_loan_fr=train.loc[train["isDefault"]==1]
train_loan_nofr=train.loc[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_fr.groupby("employmentLength")["employmentLength"].count().plot(kind="barh",ax=ax4,title="Count of employmentLength non-fraud")
plt.show()

Alt

查看连续型变量在不同y值上的分布

fig,((ax1,ax2))=plt.subplots(1,2,figsize=(15,6))
train.loc[train['isDefault']==1]\
    ['loanAmnt'].apply(np.log)\
    .plot(kind='hist',
         bins=100,
         title='Log Loan Amt-Fraud',
         color='r',
         xlim=(-3,10),
         ax=ax1)
train.loc[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)

Alt

total=len(train)
total_amt=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=train)
# 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=(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)

Alt

时间格式数据处理及查看

# 转化成时间格式
train['issueDate']=pd.to_datetime(train['issueDate'],format='%Y-%m-%d')
startdate=datetime.datetime.strptime('2007-06-01','%Y-%m-%d')
train['issueDateDT']=train['issueDate'].apply(lambda x: x-startdate).dt.days
# 转化成时间格式
test['issueDate']=pd.to_datetime(test['issueDate'],format='%Y-%m-%d')
startdate=datetime.datetime.strptime('2007-06-01','%Y-%m-%d')
test['issueDateDT']=test['issueDate'].apply(lambda x: x-startdate).dt.days
plt.hist(train['issueDateDT'],label='train');
plt.hist(test['issueDateDT'],label='test');
plt.legend();
plt.title('Distribution of issueDateDT dates');
# train 和issueDateDT日期由重叠,所以使用基于时间的分割进行验证是不明智的

Alt

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页