探索性数据分析EDA

一、数据总体了解

基本汇总信息

head()         # 查看前5行数据(括号缺省值是5)

tail()            # 查看后5行数据(括号缺省值是5)

info()           #查看数据介绍(每个特征的基本信息)

describe()   #查看统计量(总数,平均值,方差)

shape         #样本个数和特征维度train.shape

columns     #查看特征名

当查看的数据太长了,中间的数据被省略了可以使用

特征太长,中间省略时加转置(.T):

如:head().T  

显示所有行/列以及设置value显示的长度

#设置value的显示长度为200,默认为50
pd.set_option('max_colwidth',200)
#显示所有列,把行显示设置成最大
pd.set_option('display.max_columns', None)
#显示所有行,把列显示设置成最大
pd.set_option('display.max_rows', None)

 

二、数据类型了解

特征一般分为类别特征和数值特征组成,数值型又分为连续型和离散型。

数值型特征本是可以直接入模的,但往往风控人员要对其做分箱,转化为WOE编码进而做标准评分卡等操作。从模型效果上来看,特征分箱主要是为了降低变量的复杂性,减少变量噪音对模型的影响,提高自变量和因变量的相关度。从而使模型更加稳定。
 

数值型特征

# 数值类型
numerical_feature = list(train.select_dtypes(exclude=['object']).columns)
numerical_feature

由于数值类型又可以分为连续变量、离散型变量和单值变量

# 连续型变量
serial_feature = []
# 离散型变量
discrete_feature = []
# 单值变量
unique_feature = []

for fea in numerical_feature:
    temp = train[fea].nunique()# 返回的是唯一值的个数
    if temp == 1:
        unique_feature.append(fea)
     # 自定义变量的值的取值个数小于10就为离散型变量    
    elif temp <= 10:
        discrete_feature.append(fea)
    else:
        serial_feature.append(fea)

连续型变量

查看某一个数值型变量的分布,查看变量是否符合正态分布,如果不符合正太分布的变量可以log化后再观察下是否符合正态分布。

正态化的原因:一些情况下正态非正态可以让模型更快的收敛,一些模型要求数据正态(eg. GMM、KNN),保证数据不要过偏态即可,过于偏态可能会影响模型预测结果。

可视化查看是否正态性。

#每个数字特征得分布可视化
f = pd.melt(train, value_vars=serial_feature)
g = sns.FacetGrid(f, col="variable",  col_wrap=3, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")

查看连续型变量的分布情况

import seaborn as sns
plt.figure(1 , figsize = (8 , 5))
sns.distplot(train.特征,bins=40)
plt.xlabel('特征')

 查看离散型变量的分布情况:

# 查看label的
import seaborn as sns
sns.kdeplot(train.loanAmnt[label[label==1].index], label='1', shade=True)
sns.kdeplot(train.loanAmnt[label[label==0].index], label='0', shade=True)
plt.xlabel('loanAmnt')
plt.ylabel('Density');

 查看annualIncome的分布情况:

plt.figure(1 , figsize = (8 , 5))
sns.distplot(train['annualIncome'])
plt.xlabel('annualIncome')

 离散型变量

离散型变量的类型数情况

for f in discrete_feature:
    print(f, '类型数:', train[f].nunique())

 可视化

import seaborn as sns
import matplotlib.pyplot as plt
df_ = train[discrete_feature]# 离散型变量
sns.set_style("whitegrid") # 使用whitegrid主题
fig,axes=plt.subplots(nrows=1,ncols=1,figsize=(8,10))# nrows=4,ncols=2,括号加参数4x2个图
for i, item in enumerate(df_):
    plt.subplot(4,2,(i+1))
    ax=sns.countplot(item,data = df_,palette="Pastel1")
    plt.xlabel(str(item),fontsize=14)   
    plt.ylabel('Count',fontsize=14)
    plt.xticks(fontsize=13)
    plt.yticks(fontsize=13)
    #plt.title("Churn by "+ str(item))
    i=i+1
    plt.tight_layout()
plt.show()

单值变量

单值变量表示该特征只有一种类别,对于数值全部都一样的特征,可以考虑直接删除

分类型特征

# 分类型特征
category_feature = list(filter(lambda x: x not in numerical_feature,list(train.columns)))
category_feature

分类型特征可视化呈现

df_category = train[['label']]

sns.set_style("whitegrid") # 使用whitegrid主题
color = sns.color_palette()
fig,axes=plt.subplots(nrows=1,ncols=1,figsize=(10,10))
for i, item in enumerate(df_category):
    plt.subplot(2,1,(i+1))
    #ax=df[item].value_counts().plot(kind = 'bar')
    ax=sns.countplot(item,data = df_category)
    plt.xlabel(str(item),fontsize=14)   
    plt.ylabel('Count',fontsize=14)
    plt.xticks(fontsize=13)
    plt.yticks(fontsize=13)
    #plt.title("Churn by "+ str(item))
    i=i+1
    plt.tight_layout()
plt.show()

统计一下每个类别的数量

for i in train[['label']]:
    print(train[i].value_counts())
    print()

三、标签的分布

查看标签是否平衡

若分问题中各类别样本数量差距太大,则会造成样本不均衡的问题。样本不均衡不利于建立与训练出正确的模型,且不能做出合理的评估。

label=train.isDefault             
label.value_counts()/len(label)

可视化

sns.countplot(label)

如果类别的比例差别很大,样本较不平衡,对于这种情况,考虑后续将进行采样等操作

标签和分类类别之间的分布关系

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)) 
# 目标变量为1时候grade的分布
train_loan_fr.groupby("grade").size().plot.bar(ax=ax1)
# 目标变量为0时候grade的分布
train_loan_nofr.groupby("grade")["grade"].count().plot.bar(ax=ax2)
# 目标变量为1时候employmentLength的分布
train_loan_fr.groupby("employmentLength").size().plot.bar(ax=ax3)
# 目标变量为0时候employmentLength的分布
train_loan_nofr.groupby("employmentLength")["employmentLength"].count().plot.bar(ax=ax4)
plt.xticks(rotation=90);

查看正负样本的数据差异

把数据集按正负样本分成两份,查看变量的分布差异

train_positve = train[train['isDefault'] == 1]
train_negative = train[train['isDefault'] != 1]
f, ax = plt.subplots(len(numerical_feature),2,figsize = (10,80))
for i,col in enumerate(numerical_feature):
    sns.distplot(train_positve[col],ax = ax[i,0],color = "blue")
    ax[i,0].set_title("positive")
    sns.distplot(train_negative[col],ax = ax[i,1],color = 'red')
    ax[i,1].set_title("negative")
plt.subplots_adjust(hspace = 1)

四、缺失值查看

如果缺失值过多会对整体的模型结果产生一定的影响,因此每次在建模之前都需要对数据的缺失值情况就行查看,若有缺失情况,需要在后续特征工程中进行填补

# 去掉标签
X_missing = train.drop(['isDefault'],axis=1)

# 查看缺失情况
missing = X_missing.isna().sum()
missing = pd.DataFrame(data={'特征': missing.index,'缺失值个数':missing.values})
#通过~取反,选取不包含数字0的行
missing = missing[~missing['缺失值个数'].isin([0])]
# 缺失比例
missing['缺失比例'] =  missing['缺失值个数']/X_missing.shape[0]
missing

可视化

# 可视化
(train.isnull().sum()/len(train)).plot.bar(figsize = (20,6),color=['#d6ecf0','#a3d900','#88ada6','#ffb3a7','#cca4e3','#a1afc9'])

 

五、异常值查看

在统计学中,如果一个数据分布近似正态,那么大约 68% 的数据值会在均值的一个标准差范围内,大约 95% 会在两个标准差范围内,大约 99.7% 会在三个标准差范围内。

def find_outliers_by_3segama(data,fea):
    data_std = np.std(data[fea])
    data_mean = np.mean(data[fea])
    outliers_cut_off = data_std * 3
    lower_rule = data_mean - outliers_cut_off
    upper_rule = data_mean + outliers_cut_off
    data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x < lower_rule else '正常值')
    return data
data_train = train.copy()
for fea in numerical_feature:
    data_train = find_outliers_by_3segama(data_train,fea)
    print(data_train[fea+'_outliers'].value_counts())
    print(data_train.groupby(fea+'_outliers')['isDefault'].sum())
    print('*'*10)

可视化

import matplotlib.pyplot as pl
plt.boxplot(train)

六、数据相关关系

查看各个特征与目标的相关系数.

train.corr()["isDefault"].sort_values()

可视化

f, ax = plt.subplots(1,1, figsize = (20,20))
cor = train[numerical_feature].corr()
sns.heatmap(cor, annot = True, linewidth = 0.2, linecolor = "white", ax = ax, fmt =".1g" )

特征间高相关

两两特征之间高于0.6的过滤

# 显示相关性高于0.6的变量
def getHighRelatedFeatureDf(corr_matrix, corr_threshold):
    highRelatedFeatureDf = pd.DataFrame(corr_matrix[corr_matrix>corr_threshold].stack().reset_index())
    highRelatedFeatureDf.rename({'level_0':'feature_x', 'level_1':'feature_y', 0:'corr'}, axis=1, inplace=True)
    highRelatedFeatureDf = highRelatedFeatureDf[highRelatedFeatureDf.feature_x != highRelatedFeatureDf.feature_y]
    highRelatedFeatureDf['feature_pair_key'] = highRelatedFeatureDf.loc[:,['feature_x', 'feature_y']].apply(lambda r:'#'.join(np.sort(r.values)), axis=1)
    highRelatedFeatureDf.drop_duplicates(subset=['feature_pair_key'],inplace=True)
    highRelatedFeatureDf.drop(['feature_pair_key'], axis=1, inplace=True)
    return highRelatedFeatureDf

getHighRelatedFeatureDf(train.corr(),0.6)

你可能感兴趣的:(数据科学,python,jupter,R)