4.3 数据预处理
我们正在处理的数据训练得越好,最终可能得到的结果也就越好。这个过程的第一步称为数据预处理(data preprocessing),(至少)有3种不同的形式:
- 数据格式化:数据的格式可能不适合我们使用,例如,可能以专有文件格式提供数据,而我们最喜欢使用的机器学习算法却不理解这种格式。
- 数据清洗:数据可能包含无效记录或者缺失记录,它们需要清除或者删除。
- 数据采集:对于我们特定目的来说,数据可能太大了,这就迫使我们对数据进行智能采集。
数据预处理后,我们就可以开始实际的特征工程了:变换预处理数据以适应我们特定的机器学习算法。这一步通常涉及3个可能过程中的一个或者多个:
- 缩放(scaling):通常,某些机器学习算法要求数据在一个通用的范围内,如零均值和单位方差。缩放就是将所有特征(可能有不同的物理单元)放入一个通用取值范围的过程。
- 分解(decomposition):通常,数据集有很多我们无法处理的特征。特征分解是将数据压缩成数量更少、信息更丰富的数据分量的过程。
- 聚合(aggregation):有时,可以将多个特征组合成一个更有意义的特征。例如,一个数据库可能包含登录到基于Web系统的每个用户的日期和时间。根据不同的任务,通过简单地计算每个用户的登录次数,可以更好地表示这些数据。
让我们更深入地看看其中一些过程。
4.3.1 特征标准化
标准化(standardizing)是指将数据按比例缩放到零均值和单位方差的过程。这是许多机器学习算法的共同需求,如果单个特征不能满足这一需求,那么这些算法的性能可能会很糟糕。我们可以手动标准化我们的数据,每个数据点减去所有数据的均值(μ)再除以数据的方差(σ);即对于每个特征x,我们可以计算(x–μ)/σ。
另外,scikit-learn在其preprocessing模块中提供了这个过程的一个简单实现。
让我们考虑一个3×3的数据矩阵X,它表示3个数据点(行),其中每个数据点有3个任意选择的特征值(列):
然后,利用scale函数可以实现对数据矩阵X的标准化:
我们通过再次检查均值和方差来验证缩放的数据矩阵X_scaled确实是标准化的。标准化特征矩阵每一行的均值应该是(接近)0:
请注意,上面代码中的axis=0表示行。图4-2有助于更好地理解这一点。
图4-2 标准化特征矩阵示例
同样,标准化特征矩阵的每一行的方差应该是1(与使用std检查标准差为1相同):
4.3.2 特征归一化
与标准化类似,归一化(normalization)是将单个样本缩放到一个单位范数的过程。相信你知道范数表示一个向量的长度,可以用不同的方式定义范数。在第3章中我们讨论了其中的两个范数:L1范数(或者曼哈顿距离)和L2范数(或者欧氏距离)。
在scikit-learn中,我们的数据矩阵X可以使用normalize函数进行归一化,L1范数由norm关键字指定:
类似地,可以通过指定norm='12'来计算L2范数:
4.3.3 将特征缩放到一个范围
将特征缩放到零均值和单位方差的另一种方法是使特征位于给定的最小值和最大值之间。通常,这些值是0和1,这样就可以将每个特征的最大绝对值缩放到单位大小。在scikit-learn中,这可以使用MinMaxScaler来实现:
默认情况下,数据将被缩放到0到1之间。通过向MinMaxScaler构造函数传递一个关键字参数feature_range,我们可以指定各种范围:
4.3.4 特征二值化
最后,我们可能会发现自己不太关心数据的准确特征值,只想知道某个特征值是否存在。通过对特征值进行阈值化,可以实现数据的二值化。让我们快速回顾一下特征矩阵X:
假设这些数字表示我们银行账户中的数千美元。如果一个人的账户超过0.5万美元,我们就认为他是个富人,用1来表示。否则,就用0表示。这类似于用threshold=0.5对数据进行阈值处理:
结果是一个完全由1和0组成的矩阵。
4.3.5 缺失数据的处理
特征工程中另一个常见需求是缺失数据的处理。例如,我们可能有这样一个数据集:
大多数机器学习算法不能处理Not a Number(NAN)值(Python中的nan)。因此首先我们必须用一些恰当的填充值替换所有nan值。这就是缺失值的估算。
scikit-learn提供了3种不同的策略来估算缺失值:
- mean:用矩阵一个指定轴上的平均值(默认axis=0)替换所有的nan值。
- median:用矩阵一个指定轴上的中值(默认axis=0)替换所有的nan值。
- most_frequent:用矩阵一个指定轴上的最频繁值(默认axis=0)替换所有的nan值。
例如,可以用下列方法调用mean估算:
用填充值替换这两个nan值,该填充值等于沿相应列计算的平均值。通过计算第1列(没有计算第1个元素X[0,0])的平均值,并将这个值与矩阵中的第1个元素(X2[0,0])进行比较,我们可以复查数学计算的正确性:
类似地,median策略依赖于相同的代码:
让我们再来复查一下这个数学运算。这次,我们不再计算第1列的平均值,而是计算中值(不包括X[0,0]),我们将结果与X3[0,0]进行比较。我们发现这两个值是相同的,这使我们相信,估算与预期一致: