首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

机器学习数据预处理方法与技巧系统讲解

「文末高能」

编辑 | 哈比

数据预处理,可以说是数据挖掘过程中的一个最重要的步骤, “garbage in, garbage out” 非常适用于形容数据挖掘和机器学习,输入的数据烂,输出的模型效果也会很烂。

数据的采集过程中通常会出现一些不可避免的失误,无论是人工录入、通过传感器获得还是从网页上爬取的数据,都会需要对这些错误进行一些处理。

最常见的错误包括缺失值不规则的格式(通常出现在从网页上爬取的数据中,主要需要使用正则表达式处理,本文不做介绍)、数据噪声(如:传感器采集数据过程中产生的噪声)、异常值(如:收入:-15元,或身高:1688cm)。

数据预处理并不是一种算法模型,更像实战中用到的 trick。

数据预处理招无定法,不可以用同样的过程来对不同类型的数据集进行预处理,甚至对于类型相同,但数据采集过程有细微区别的两个数据集,使用完全相同的数据预处理流程,效果可能都会有极大的不同。

因此,这个 Chat 并非教授给你一种数据预处理的定式,而是把数据预处理的方法及思路分解,从而让你在自己进行数据处理的时候以这些方法为基础,将其拼接扩展,根据手中拿到的数据集的具体情况,来制定不同的数据预处理方法。

接下来,我将数据预处理的技巧分解成一个个小的点来展示,以便你在需要进行数据预处理的时候,可以浏览一遍,以便找到灵感。

数据预处理最基础的作用,就是去除数据中的噪声、异常值,纠正不一致。所以,数据预处理(data preprocessing)通常在狭义上也被称为数据清洗

然而真正影响到模型效果的,并不只是这些,下面我将列举出在数据集中常见的对模型有影响的问题,并提出解决它们的方法与思路,并且还会列出其他对于模型好坏有极大影响的预处理方法。

一、特征间的量级差异

量级差距即特征间的范围不同,比如以下两个特征就会有量级的差距。

如果你是使用如决策树,可以无视此问题,因为数据间的量级差异对(决策)树模型(tree-based model)无影响。

因为 tree-based model 如 CART、GBDT 等,是根据每个特征的划分增益进行分枝决策,所以每次判断仅针对一个特征进行分割判断,所以可以无视特征间的量级差距,不会对模型的决策造成任何影响。

然而,数据的量级对除了树模型外的大多数模型都有很大的影响。

例如,某数据集包含 2 个特征 x1、x2,如果使用 kNN 算法,k 值为 1,对绿色个点进行预测,如下图所示。那么,与绿色的点最靠近的就是蓝色的 ×。

然而如果把 x1 的量级扩大 10 的六次方倍呢?如下图,与绿色点最接近的居然变成了红色的圆圈!所以,数据间量级的变换,将导致模型结果的大大不同!

同理,对于线性模型(如 SVM/ 感知机等等),如下图,如果按照原数据 (左图) 进行判断,SVM 的分割决策线应该是平行于 x1 轴,然而如果将 x1 轴的数据放大,分割决策线会与 x 轴则会成 45 度角。

解决方法:数据标准化

数据标准化(data normalization)就是将不同的特征按比例缩放,使之落入一个特定的区间。其中最典型的就是数据的归一化处理,即将数据统一映射到 [0,1] 区间上。

而且归一化除了让数据的量级变得相同外,还有另一个好处,就是当使用如神经网络等算法时,归一化的数据通常能够更快的收敛。

数据标准化方法有多种,不同的标准化方法,对数据集的影响都不同,在数据标准化方法的选择上,还没有通用的法则可以遵循。下面,为常见的数据标准化方法:

1. 极大极小规范化(MinMaxScaler)

(压缩至 [0,1]),每个数据都减去最小的值,再除以极差。

2. 方差规范化(StandardScaler)

压缩至约 [-1, 1],每个数据减去均值,再除以标准差。

理论上,要将所有的特征都进行标准化,否则特征见量级不同,对模型的影响会有差距。当然,也可以根据经验,适当增加或者减少 某些特征的量级。

二、异常值(outlier)

异常值,通常也可以理解为噪声,几乎对于所有的模型,异常值都会有影响。如下图,加入了一个异常值后,可能整个模型都会被改变。

异常值的常用检测方法:极差、中间四分位数极差、标准差。

首先,将数据根据某一特征的值的大小进行排序。

然后可计算下列几个数值:

极差:数据集的最大值和最小值的差;

百分位数:第 n 个百分位数是指 n% 的数据项位于或低于 x;

四分位数:第一个四分位数 Q1(第 25 个百分位数),第三个四分位数 Q3,中间四分位数极差(IQR)即 Q3 - Q1。

如果极差远大于 IQR,则说明存在很可能存在异常值,那么可以对异常值进行处理。

标准差同理,如果标准差过大,也可判断出存在异常值。

异常值的解决方法:

1. 百分位法

只留数值百分位数为 1 至 99 间的数据,这样就会避免异常值,比如在 Python 中的 numpy 可以轻易实现这个功能:

importnumpyasnpimportpandasaspdUPPERBOUND, LOWERBOUND = np.percentile(x, [1,99])y = np.clip(x, UPPERBOUND, LOWERBOUND)pd.Series(y).hist(bins=30)

2. 改变范围

将特征的数值变换到另外的空间中,这种方式可以让极大的异常值缩小,使他们对模型的影响变小,通常可用的空间变换函数为:

(1)Log 变换:

x = np.log(1+x)

(2)取小于 1 的方根:

x = np.sqrt(x+2/3)

三、缺失值

缺失值是经常存在的,产生的原因不多解释,缺失值的影响更不必多解释,下面来说解决办法。

1. 平均值 / 中位数 / 众数代替法

这三种就不多说了,都是很基础很简单的方法。

2. 插值法

常见的包括牛顿插值、拉格朗日插值等等,由于公式太多,本 chat 篇幅有限,就不具体讲解了,网上有很多具体实现的代码。

3. 聚类法

使用如 k-mean/kNN 等聚类方法,对存在缺失数据的点的特征值进行预测。

四、分类特征问题

考虑以下这个分类特征:

[“China”,”Japan”, “America”, “German”]

如果使用大多数机器学习算法,需要将该特征用数字表示,而不能直接使用字符串,因为至少计算会更高效,所以可以将其特征转换为

[0, 1, 2, 3]

然而,转化为数字表示后,直接用在模型中是不合适的。因为,模型会认为数据是有序的,也就是 “China”

为了解决上述问题,其中一种可能的解决方法是采用独热编码(One-Hot Encoding)。

One-Hot 编码,又称一位有效编码,其方法是使用 N 位状态寄存器来对 N 个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。

例如:

自然状态码为:0,1,2,3,4,5

独热编码为:000001,000010,000100,001000,010000,100000

可以这样理解,对于每个特征,如果它有 m 个可能值,那么经过独热编码后,就变成了 m 个二元特征。并且,这些特征互斥,每次只有一个激活。因此,数据会变成稀疏的。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180202B047SI00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券