基本汇总信息
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)