《机器学习算法竞赛实战》学习笔记3.数据探索

本文以kaggle入门赛House Prices为例
如何确保自己准备好竞赛使用的算法模型?如何为数据集选择最合适的算法?如何定义可用于算法模型的特征变量?数据探索可以帮助回答以上三点。
一般而言,数据探索可以分为三个部分:

  1. 首先是赛前数据探索,帮助我们对数据有个整体性的认识,并发现数据中存在的问题,比如缺失值、异常值和数据冗余等
  2. 其次是竞赛中的数据探索,通过分析数据发现变量的特点,帮助提取有价值的特征,这里可以从单变量、多变量和变量分布进行分析
  3. 最后是模型的分析,可以分为重要性分析和结果误差分析,帮助我们从结果发现问题,并进一步优化
数据探索
数据初探
分析思路
分析方法
明确目的
变量分析
单变量分析
多变量分析
模型分析
学习曲线
特征重要性分析
误差分析

1.数据初探

赛前数据探索,主要包含分析思路、分析方法和明确目的。

1.1分析思路

在实际竞赛中,最好使用多种探索思路和方法来探索每个变量并比较结果。在完全理解数据集后,就可以进入数据预处理阶段和特征提取阶段了,以便根据所期望的业务结果转换数据集。此步骤的目标是确信数据集已准备好应用于机器学习算法

1.2分析方法

数据探索的分析主要采用以下方法:

  • 单变量可视化分析:提供原始数据集中每个字段的摘要统计信息
  • 多变量可视化分析:用来了解不同变量之间的交互关系
  • 降维分析:有助于发现数据中特征变量之间方差最大的字段,并可以在保留最大信息量的同时减少数据维度。
    可以检查每个变量的分布,定义一些丢失值,最终找到替换它们的可能方法

1.3明确目的

在竞赛中跳过数据探索阶段可能会导致数据倾斜、出现异常值和过多的缺失值,产生以下糟糕结果:

  • 生成不准确的模型
  • 在错误的数据上生成精确的模型
  • 为模型选择错误的变量
  • 资源的低效利用,包括模型的重建

数据探索阶段必须要明确:

  1. 数据集基本情况:比如数据有多大,每个字段各是什么类型
  2. 重复值、缺失值和异常值:去除重复值,缺失值是否严重,缺失值是否有特殊含义,如何发现异常值
  3. 特征之间是否冗余:可以通过特征间相似性特征来找出冗余特征
  4. 是否存在时间信息:当存在时间信息时,通常要进行相关性、趋势性、周期性和异常点的分析,同时有可能涉及潜在的数据穿越问题
  5. 标签分布:对于分类问题,是否存在类别分布不均衡。对于回归问题,是否存在异常值,整体分布如何,是否需要进行目标转换
  6. 训练集与测试集的分布:是否有很多在测试集中存在的特征字段在训练集中没有
  7. 单变量/多变量分布:熟悉特征的分布情况,以及特征和标签的关系

数据探索最基本的步骤之一是获取对数据的基本描述,通过获取对数据的基本描述从而获得对数据的基本感觉。以下方法有助于我们认识数据:

  • DataFrame.describe():查看数据的基本分布,具体是对每列数据进行统计,统计值包含频次、均值、方差、最小值、分位数、最大值等。
  • DataFrame.head(n):可以直接加载数据集的前n行,n默认为5
  • DataFrame.shape:得到数据集的行列情况
  • DataFrame.info():可以快速获得对数据集的简单描述,比如每个变量的类型、数据集的大小和缺失值情况。

下面通过一段代码展示nunique和缺失值的情况:

stats = []
for col in train.columns:
    stats.append((col,#Feature:特征
                  train[col].nunique(),#unique_value:每个特征的唯一值的个数
                  train[col].isnull().sum()*100/train.shape[0],#Percentage of missing values:该特征缺失值占比  shape[0]:行数 shape[1]:列数
                  train[col].value_counts(normalize=True,dropna=False).values[0]*100,#dropna 丢弃
                  train[col].dtype))#type 类型
    stats_df = pd.DataFrame(stats,columns=['Feature','unique_value','Percentage of missing values','Percentage of values in the biggest category','type'])
stats_df.sort_values('Percentage of missing values',ascending=False)[:10] #以缺失率进行值排序 降序排序

结果
数据的基本分布上图展示了经过上述代码生成的数据基本信息,我们从中找到特殊变量进行细致分析,这里选择nunique值低和缺失值多的变量进行观察。一般而言,nunique为1是不具备任何意义的,表示所有值都一样,不存在区分性,需要进行删除。可以发现有些变量的缺失值很多,比如缺失比例达到95%以上,我们可以考虑将其删除。
用柱状图的形式可以更加直观地展示变量的缺失值分布情况,以下为变量缺失值可视化图的具体生成代码:

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

Pandas中的inplace参数
是否在原对象的基础上进行操作
inplace=True:不创建新对象,直接在原对象上修改
inplace=False:创建并返回修改后的新对象,原对象不变
默认情况下为False
变量的缺失值分布

2.变量分析

2.1单变量分析

单变量可以分为标签、连续型和类别型

1.标签

标签是最重要的变量,首先应当观察标签的分布情况
对于房屋价格预测,其标签SalePrice为连续型变量,基本信息生成代码:

train['SalePrice'].describe()

对标签SalePrice的基本描述
通过可视化的方式更细致地观察SalePrice的分布情况

import scipy.stats as st
plt.figure(figsize=(9, 8))
sns.distplot(train['SalePrice'], color='b', bins=100, hist_kws={'alpha': 0.4})#alpha参数表示填充颜色深度,取值0~1

SalePrice的分布情况可见,SalePrice呈偏离正态分布,属于向右倾斜类型,存在峰值状态,一些异常值在500000以上。我们最终会想办法去掉这些异常值,得出能够让算法模型很好学习的、符合正态分布的变量。
下面对SalePrice进行对数转换,并生成可视化图
在这里插入图片描述

import scipy.stats as st
from scipy.stats import norm#norm正态分布
plt.figure(figsize=(9, 8))
sns.distplot(np.log(train['SalePrice']), color='b', bins=100, fit=norm,hist_kws={'alpha': 0.4})

matplotlib中 figsize=(a,b) 表示设置图形的大小,a为图形的宽, b为图形的高,单位为英寸

seaborn中的 displot参数

sns.distplot(a,#观察数据。如果是具有name属性的Series对象,则该名称将用于标记数据轴。
 bins=None, #matplotlib hist()的参数,或None。可选参数。直方图bins(柱)的数目,若填None,则默认使用Freedman-Diaconis规则指定柱的数目
 hist=True, #是否绘制(标准化)直方图
 kde=True,#kde: 控制是否显示核密度估计图,默认为True
 rug=False,#是否在支撑轴上绘制rugplot()图默认为false
 fit=None, #fit: 设定函数图像,与原图进行比较 控制拟合的参数分布图形,能够直观地评估它与观察数据的对应关系(图中黑色为曲线为正态分布)
 hist_kws=None,#{hist,kde,rug,fit} _kws:字典  底层绘图函数的关键字参数
 kde_kws=None,
 rug_kws=None,
 fit_kws=None,
 color=None,#绘制除了拟合曲线之外的所有内容的颜色
 vertical=False,#如果为True,则观察值在y轴上,即水平横向的显示
 norm_hist=False,#布尔值,可选参数。True,则直方图的高度显示密度而不是计数。如果绘制KDE图或拟合密度,则默认为True。

 axlabel=None,#axlabel: 设置x轴的label
 label=None,#字符串,可选参数。图形相关组成部分的图例标签
 ax=None)#可选参数。若提供该参数,则在参数设定的轴上绘图。


2.连续型

类似于标签的查看方式,这里主要使用直方图这种可视化方式观察值的分布、每个值出现的频率等。以下为连续型变量的分布可视化的生成代码:

df_num = train.select_dtypes(include = ['float64', 'int64'])
df_num.hist(figsize=(16, 20), bins=50, xlabelsize=8, ylabelsize=8)

接着进行更加科学的分析,首先是相关性分析。
注意:相关性分析只能比较数值间特征,所以对于字母或字符串特征,需要先进行编码,并将其转换为数值,然后再看有什么关联。
在实际竞赛中,相关性分析可以很好地过滤掉与标签没有直接关系的特征。


正相关和负相关

  • 正相关:如果一个特征增加导致另一个特征增加,则它们呈正相关。值1表示完全正相关
  • 负相关:如果一个特征增加导致另一个特征减少,则它们呈负相关。值-1表示完全负相关

多重线性
现在假设特征A和特征B完全正相关,这意味着这两个特征值包含高度相似的信息,信息几乎没有或完全没有差异。这称为多重线性,因为两个特征包含几乎相同的信息。


在搭建或训练模型时,如果同时使用这两个特征,可能其中一个会是多余的。我们应尽量消除冗余特征,因为它会使训练时间变长,同时影响其他优势
以下代码为生成有关SalePrice的相似性矩阵图

corrmat = train.corr() #corrmat 相关性矩阵
f, ax = plt.subplots(figsize=(20, 9))
sns.heatmap(corrmat, vmax=0.8, square=True)

相似性矩阵seaborn.heatmap——将矩形数据绘制为颜色编码矩阵

seaborn.heatmap(data,#矩形数据集可以强制转换为ndarray格式数据的2维数据集。如果提供了Pandas DataFrame数据,索引/列信息将用于标记列和行。
 vmin=None,#浮点型数据,可选参数。用于锚定色彩映射的值,否则它们是从数据和其他关键字参数推断出来的。
 vmax=None,#同上
 cmap=None,#matplotlib 颜色条名称或者对象,或者是颜色列表,可选参数。从数据值到颜色空间的映射。 如果没有提供,默认值将取决于是否设置了“center”。
 center=None,#浮点数,可选参数。 绘制有色数据时将色彩映射居中的值。 如果没有指定,则使用此参数将更改默认的cmap。
 robust=False,#布尔值,可选参数。如果是True,并且vmin或vmax为空,则使用稳健分位数而不是极值来计算色彩映射范围。
 annot=None,#布尔值或者矩形数据,可选参数。如果为True,则在每个热力图单元格中写入数据值。 如果数组的形状与data相同,则使用它来代替原始数据注释热力图。
 fmt='.2g',#字符串,可选参数。添加注释时要使用的字符串格式代码。
 annot_kws=None, #字典或者键值对,可选参数。当annot为True时,ax.text的关键字参数。
 linewidths=0, #浮点数,可选参数。划分每个单元格的行的宽度。
 linecolor='white', #颜色,可选参数   划分每个单元的线条的颜色。
 cbar=True, #布尔值,可选参数。 描述是否绘制颜色条。
 cbar_kws=None, #字典或者键值对,可选参数。  fig.colorbar的关键字参数。
 cbar_ax=None, #matplotlib Axes,可选参数。用于绘制颜色条的轴,否则从主轴获取。
 square=False, #布尔值,可选参数。   如果为True,则将坐标轴方向设置为“equal”,以使每个单元格为方形。
 xticklabels='auto', #“auto”,布尔值,类列表值,或者整形数值,可选参数。如果为True,则绘制数据框的列名称。如果为False,则不绘制列名称。如果是列表,则将这些替代标签绘制为xticklabels。如果是整数,则使用列名称,但仅绘制每个n标签。如果是“auto”,将尝试密集绘制不重叠的标签。
 yticklabels='auto', 
 mask=None,# 布尔数组或者DataFrame数据,可选参数。 如果为空值,数据将不会显示在mask为True的单元格中。 具有缺失值的单元格将自动被屏蔽。
 ax=None, #matplotlib Axes,可选参数。  绘制图的坐标轴,否则使用当前活动的坐标轴。
 **kwargs)#其他关键字参数。 所有其他关键字参数都传递给ax.pcolormesh

从生成的相似性矩阵中,可以找出与房价相关性最强的变量,其中OverallQual(总评价)、GarageCars(车库)、TotalBsmtSF(地下室面积)、GrLivArea(生活面积)等特征与SalePrice呈正相关

从相似性矩阵中,我们还能发现变量之间的关系,如何利用相似性矩阵进行分析就成为了关键

3.类别型

数据探索的目的是为了帮助我们了解数据并且构建有效特征。
比如,我们找到了与标签有着强相关的特征,那么就可以围绕着这个强相关特征进行一系列的扩展,具体可以进行交叉组合,比如强相关加弱相关、强相关加强相关等组合,挖掘更高维度的潜在信息。

首先,观察类别型变量的基本分布情况,即观察每个属性的频次。根据频次,我们不仅可以发现热点属性和极少出现的属性,还可以进一步分析出现这些情况的原因,比如淘宝网的女性用户多于男性,主要是因为平台在服饰和美妆业务方面拥有强大的影响力。这是从业务角度考虑,自然也有可能是数据采样的原因。

对部分类别变量的分布进行可视化展示

df_not_num = train.select_dtypes(include = ['O'])
fig, axes = plt.subplots(round(len(df_not_num.columns) / 3), 3, figsize=(12, 30))

for i, ax in enumerate(fig.axes):
    if i < len(df_not_num.columns):
        ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=45)
        sns.countplot(x=df_not_num.columns[i], alpha=0.7, data=df_not_num, ax=ax)

fig.tight_layout()

类别型变量的基本分布

2.2多变量分析

单变量分析太过于单一,不足以挖掘变量之间的内在联系,获取更加细粒度的信息,所以有必要进行多变量分析。分析特征变量与特征变量之间的关系有助于构建更好的特征,同时降低构建冗余特征的概率值。
此处选用本赛题中需要特别关注的特征变量进行分析
从相似性矩阵中,我们已知房屋评价与SalePrice呈正相关。进一步扩展分析,通过可视化来考虑房屋评价和房屋位置是否存在某种联系。

plt.style.use('seaborn-white')
type_cluster = train.groupby(['Neighborhood','OverallQual']).size()
type_cluster.unstack().plot(kind='bar',stacked=True, colormap= 'PuBu', figsize=(13,11),  grid=False)
plt.xlabel('OverallQual', fontsize=16)
plt.show()

不同房屋位置的评价分布条状图上图为不同房屋位置的评价分布条状图,我们可发现颜色越深代表评价越高。NoRidge、NridgHt和StoneBr都有不错的评价

再进一步看看不同位置房屋的SalePrice

var = 'Neighborhood'
data = pd.concat([train['SalePrice'], train[var]], axis=1)
f, ax = plt.subplots(figsize=(26, 12))
fig = sns.boxplot(x=var, y="SalePrice", data=data)
fig.axis(ymin=0, ymax=800000);

不同房屋位置对应的SalePrice箱型图
高评价位置对应高SalePrice,说明房屋位置评价与房屋售价有比较强的相关性。除了通过这样的分析证明原始特征与SalePrice强相关外,还可以通过分析来构建新的特征。
既然房屋位置和房屋评价的组合能够出现更高售价的房屋,那么我们可以构造这两个类别特征的交叉组合特征来进行更细致的描述,也可以构造这个组合特征下的房屋均价等。

3.模型分析

1.1 学习曲线

学习曲线是机器学习中被广泛使用的效果评估工具,能够反映训练集和验证集在训练迭代中的分数变化情况,帮助我们快速了解模型的学习效果。我们可以通过学习曲线来观察模型是否过拟合,通过判断拟合程度来确定如何改进模型

学习曲线广泛应用于机器学习中的模型评估,模型会随着训练迭代逐步学习(优化其内部参数),例如神经网络模型。这时用于评估学习的指标可能会最大化(分类准确率)或者最小化(回归误差),这也意味着得分越高(低)表示学习到的信息越多(少)。

以下是学习曲线图中观察到的一些常见形状

1.欠拟合学习模型

欠拟合是指模型无法学习到训练集中数据所展现的信息,这里可以通过训练损失的学习曲线来确定是否发生欠拟合。在通常情况下,欠拟合学习曲线可能是一条平坦的线或者有着相对较高的损失,也就表明该模型根本无法学习训练集

2.过拟合学习模型

过拟合是指模型对训练集学习得很好,包括统计噪声或训练集中的随机波动。过拟合的问题在于,模型对于训练数据的专业化程度越高,对新数据的泛化能力就越差,这会导致泛化误差增加。泛化误差的增加可以通过模型在验证集上的表现来衡量。如果模型的容量超出了问题所需的容量,而灵活性又过多,则会经常发生这种情况。如果模型训练时间过长,也会发生过拟合。

1.2 特征重要性分析

通过模型训练可以得到特征重要性。对于树模型(如LightGBM和XGBoost),通过计算特征的信息增益或分裂次数得到特征的重要性得分。对于模型LR和SVM,则是使用特征系数作为特征重要性得分,例如LR(逻辑回归),每个特征各对应一个特征系数w,w越大,那么改特征对模型预测结果的影响就会越大,就可以认为该特征越重要。我们假定特征性得分和特征系数w都是在衡量特征在模型中的重要性,都可以起到特征选择的作用。

1.3 误差分析

误差分析是通过模型预测结果来发现问题的关键。
一般而言,回归问题中看预测结果的分布,分类问题中看混淆矩阵等。

在真实问题中,误差分析会更加细致。比如,在进行一个用户违约预估的二分类任务中,验证集结果中有200个错误分类样本,进一步分析发现有70%的错误分类样本是由于大量特征缺失而导致的误判,这时就需要调整,既可以通过挖掘更多能够描述这些误判样本的特征信息帮助增强模型的预测能力,还可以在模型训练中赋予这些误判样本更高的权重。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值