Press "Enter" to skip to content

机器学习基础系列(2)——数据预处理

本文系PWN2WEB原创,转载请说明出处

 

机器学习算法最终学习结果的优劣取决于 数据质量 和数据中蕴含的 有用信息数量, 对数据的处理对模型高效性起到了巨大的作用。

 

一 缺失数据的处理

 

数据采集过程中的错误导致缺失值的出现,我们无法忽略这些缺失值,所以我们需要对这些缺失值进行处理。

 

首先我们构造一个csv文件来举例说明问题的所在。

 

构造如下的CSV文件:

 

read_csv函数是将CSV格式数据读取到pandas的数据框(DataFrame)中
StringIO仅仅起到演示作用:如果我们的数据是存储在硬盘上的CSV文件,就可以通过此函数以字符串的方式从文件中读取数据,并将器转换成DataFrame的格式赋值给csv_data

0x01 方法一 —— 缺失值的特征或样本删除

 

最简单的方法就是直接删除缺失数据,可以使用的方法是dropna, 即df.dropna()

 

 

可以看到,该函数默认删除行,如果需要删除列的话则需要加上一个参数axis:

 

 

axis=1表示删除含NaN的列,0表示删除具备NaN值的行

 

 

此函数还有其他几个参数:

dropna(how=’all’)   丢弃一行的所有列全为NaN的

dropna(thresh=4)   丢弃没有达到至少四个非NAN值的行

dropna(subset=[‘C’])    删除NaN值出现在特定的列的行

 

0x02   缺失数据填充

 

一般来说直接删除是整列或整行是不行的,会丢失很多珍贵的数据,这种情况下我们可以使用不同的 插值技术, 最常用的是 均值插补 通过 数据集中其他训练的数据 来估计缺失值,我们使用 Impute 类实现

 

均值插补一般是用计算行或列的平均值来进行插补,如下图及代码,这里axis=1,是计算每行除缺失值的其他所有数字和的均值,并填入。

 

axis=0则就是计算每列的平均值。

 

同时,参数strategy可以有median和most_frequent,根据特定情况具体应用

 

这里,Imputer为转换器类API,常用的两个方法是fit和transform,二者区别见此文: https://blog.csdn.net/weixin_38278334/article/details/82971752

 

二   处理类别数据

 

真实情况下,经常会出现一个或多个类别数据的特征列。在讨论类别数据时,又可以进一步将他们划分为 标称特征 和 有序特征, 有序特征可以理解为类别的值时有序的或者时可以排序的。标称特征则不具备排序的特性。讨论这个问题前我们先构造数据集:

 

 

0x01 有序特征的映射

 

一般来说,为了确保算法可以有效、高效的使用有序特征,我们需要将字符串转换为整数,通常情况下需要我们手动构造映射:

 

 

0x02 类标的编码

 

上一小节我们提到了对有序特征的映射,仔细想想,其实这些数字的顺序并不是很有意义,只要是一一对应即可,那幺这里有个小技巧:

 

 

classmapping1通过枚举的方式(enumerate),这里我解释一下这个class_mapping1后面字典的代码是什幺个原理,

 

首先,np.unique( ) 函数,转自( https://blog.csdn.net/u012193416/article/details/79672729 ):

 

 

那就是说,将 将df1中的classlabel这个标的所有值去除重复值取出来

 

 

然后是我们的enumerate函数,这个函数主要是将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列

 

 

然后我们回过头来看label:idx这个东西,我们先看这个

 

 

这个map对应的是   label:数字 , 但是label:idx这种写法就是将字典的键值对转换成这种表达方式

 

最后就是for idx,label in 这句话就是将idx,label组合并分别赋值

 

上面两种方案太麻烦了,使用LabelEncoder类可以更加方便的完成对类标的整数编码工作

 

 

0x03 标称特征上的one-hot编码

 

用上面的方法去标识标称特征往往会出现如blue=1 > red=0这种情况,然而blue和red是无法比较的,这种情况下我们就要用到one-hot编码了

 

具体可参考:

 

https://zhuanlan.zhihu.com/p/35287916

 

https://www.imooc.com/article/35900

 

我简要说明一下,举例:{红,黄,蓝},{男,女},{东,西,南,北}、

 

首先,红黄蓝,一个特征三个类别,那就是N=3,就用三位数表示:100红 010黄 001蓝

 

其次,男女,一个特征两个类别,那就是N=2,就用两位数表示:10男  01女

 

东西南北以此类推。当一个样本为[男 黄 女 蓝 北]时,就直接按顺序把对应的编码放进去就行了:[1,0,     0,1,0,     0,1,     0,0,1,     0,0,0,1] 。这样的化会让特征空间很大,一般会结合PCA使用,我们后面会说到。

 

三  训练集和测试集划分

 

这部分虽就简单的几行代码,但是需要注意的有很多
选取UCI的葡萄酒数据举例,一共13个特征,下面第二个cell的第二行,是将numpy数组的第2-13个特征赋值给X,第一个类标特征赋值给y。这里简要介绍一下,df_wine.iloc[:, 1:]这个东西,逗号前的那个冒号,意味着第几条到第几条数据传给X,因为是冒号,那幺就是所有。逗号后的1:,是第几个到第几个的特征赋值。

 

 

之后,我们要70:30划分数据集和测试集(即上图种的0.3),实际应用中,我们 基于数据大小 划分数据集,一般是60:40, 70:30,80:20,对于非常庞大的数据集,那就是90:10或者99:1了,然而,测试集不能太小,否则就会对泛化误差的估计将会越不准确。

 

四 将特征的值缩放到相同的区间

 

特征缩放的定义是特征缩放就是标准化数据特征的范围,从而使得每个特征的范围有可比性,比如将取值范围处理为0到1之间。

 

将特征缩放到相同的区间有 归一化 和 标准化 两个常用方法。

 

归一化:一般是缩放到[0,1]区间,为 最小-最大缩放 的一个特例

 

from sklearn.preprocesing import MinMaxScaler
mms = MinMaxScaler()

 

标准化:可以将均值设为0,方差设为1,使得特征列的值呈标准正态分布,易于权重的更新。

 

from sklearn.preprocessing import StandardScaler
stdsc = StandardScaler()

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注