数据预处理与缩放
序
之前我们在接触监督学习时了解到,有一些算法(譬如神经网络和SVM)对于数据的缩放非常敏感。因此,通常的做法是对数据集进行调节,使得数据表示更适合于这些算法。通常来说,这是对数据特征的一种简单的缩放和移动。
机器学习的理论实际上是起源于概率论与数理统计,接下来,我们来简单提几个相关概念,来帮助大家更好地理解接下来的要说的几种处理方法。
基础概念
中位数——对于一组数字来说,中位数指的是这样的数值x:有一半的数值小于x,另一半的数值大于x。如果数据集的数据个数是偶数,就取中间两个数值的平均数。
四分位数——按照四分之一的数据个数来划分数据集。较小四分位数指的是这样的数值x:有四分之一的数值小于x。较大四分位数指的是这样的数值x:有四分之一的数值大于x。
方差——衡量随机变量或一组数据的离散程度的度量。
异常值——在数据集之中的那些与众不同的数据点。
需要注意的是异常值并不一定是误差值或者错误值。譬如说想要统计某辆公交车上20名乘客的平均年龄,有一种情况就是其中19名乘客是处于20岁到30岁之间,但是有一名乘客的年龄是70岁,那么这名乘客的年龄就是属于与众不同的数据点,是异常值,而不是误差值。并且这个数值会影响最终的统计计算结果——拉高公交车上乘客的平均年龄。
预处理的四种类型
scikit-learn中一共提供了4种预处理方法,变换效果分别如上图所示,接下来,结合图像,我们来详细说一下这四种变换。PS:如果大家不喜欢下面的枯燥理论就直接跳过吧,说实话,我觉得只要会使用,知道用于什么地方就够了。
StandardScaler(标准化):确保每个特征的平均值为0,方差为1,使特征值都位于同一量级。但这种缩放不能保证特征任何特定的最大值和最小值。(我曾经在讲解神经网络的时候进行过标准化的人工处理,有源代码,感兴趣的朋友可以去看下,可以帮助大家更好地理解。)
RobustScaler(剔除异常值):RobustScaler也是一种标准化,工作原理与StandardScaler类似,确保每个特征的统计属性都处于同一范围。但是RobustScaler使用的是中位数和四分位数,而不是平均值和方差。这样RobustScaler会忽略与其它点有很大不同的数据点(异常值),减少异常值造成的麻烦。
MinMaxScaler(归一化):MinMaxScaler移动数据,使得所有特征都刚好位于0到1之间。对于二维数据集来说,所有的数据都包含在x轴0到1与y轴0到1组成的矩形中。(同样,我在讲解SVM的时候进行过归一化的人工处理,也有相关源代码。)
Normalizer(正则化,有些地方也叫做归一化):Normalizer用到的是一种完全不同的缩放方法。它对每个数据点进行缩放,使得特征向量的欧式长度等于1。通过上面的第四幅小图可以看出:它将一个数据点投射到半径为1的圆上(对于更高维度的情况是球面)。这意味着每个数据点的缩放比例都不相同。如果只有数据的方向(或角度)是重要的,而特征向量的长度无关紧要,那么通常会使用这种归一化。
应用数据转换
接下来我们用数据集胎儿健康分类和SVM算法来实际使用下,看看效果。(数据以及相关算法我们都在之前讲解的SVM中详细地讲过了,感兴趣的朋友可以点击超链接去看下,这里就不在赘述了。)
首先是导入数据:
1 |
|
划分训练集和测试集,并进行建模,精度评分:
1 |
|
结果如下所示:
接下来我们对数据进行缩放再进行建模评分,看看模型精度有什么变化:
1 |
|
可以看到模型精度较之前有了提升。
整个处理过程与之前算法训练模型类似。首先使用fit方法拟合缩放器(scaler),并将其应用于训练数据。然后为了应用刚刚学习的数据(即对训练数据进行实际缩放),我们使用缩放器的transform方法。最后为了将SVM应用到缩放后的数据上,还需要对测试集进行变换。
需要注意的是,为了让监督模型能够在测试集上运行,对训练集和测试集应用完全相同的变换是很重要的。因为刻度数值可以不一样,但是必须要保证测试集与训练集的数据分布是一样的(可以结合上面的散点图来看一下)。
替代方法
通常来说,想要在某个数据集上fit一个模型,然后再将其transform,是一个非常常见的过程。但是可以用比先调fit再调transform更高效的方法来计算。对于这种使用场景,所有具有transform方法的模型也都有一个fit_transform方法,代码如下所示:
1 |
|
虽然fit_transform不一定对所有模型都更加高效,但在尝试变换训练集时,使用这一方法仍然是很少的。PS:最主要是看起来上了点档次
小结
对于任何一种类型的数据集或者是一个算法来说,没有绝对正确的预处理算法。预处理方法,数据集与建模算法这三者之间永远都不会存在绑定关系。 譬如我们分别用SVM和神经网络来测试上述四种预处理算法,代码及结果如下所示:
SVM:
1 |
|
神经网络(MLP):
1 |
|
可以看出,对于同一个数据集应用不同的算法,选择的处理方法是不一样的。对于SVM来说,用标准化处理精度会高一些,而对于神经网络来说,用归一化处理效果会更好。而如果我们对其它数据集进行机器学习的话,那么就会存在其它的选择。所以对于一份没有接触过的数据集来说,如果时间允许的话,可以尝试各种各样的组合,来去搭建精度最高的模型。
最后,虽然数据缩放不涉及任何复杂的数学,但良好的做法仍是使用scikit_learn提供的缩放机制,而不是自己人工实现它们,因为即使在这些简单的计算中也容易犯错。
有很多地方做的不是很好,欢迎网友来提出建议,也希望可以遇到些朋友来一起交流讨论。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!