数值数据的特征预处理
特征预处理是数据挖掘中最重要的步骤。在这篇文章中,我将向你介绍特征预处理的概念,它的重要性,不同的机器学习模型下的数值特征的不同特征预处理技术。
模型的质量在很大程度上取决于输入模型的数据。当从数据挖掘过程中收集数据时,会丢失一些数据(我们将其称为丢失值)。此外,它很容易受到噪音的影响。这都导致低质量数据的结果,正如你可能已经听说过的,模型的好坏取决于它所训练的数据。
这就是特征预处理的由来,特征预处理将原始数据转换为机器学习模型可用的数据。
不同类型的机器学习模型
首先,让我们看看机器学习模型的不同类别。这里,我们将模型分为两种类型:
- 基于树的模型:基于树的模型是一种监督学习模型,能够在捕捉复杂非线性关系的同时提供高精度和稳定性。基于树的决策树模型有随机森林模型和梯度增强决策树模型。
- 非树模型:所有其他监督学习模型都属于非树模型的范畴。线性模型、K近邻模型和神经网络是基于非树模型的一些例子。
不同的数据类型或特征
一个数据集可以包含各种数据类型或特征。以下是一些最常见的数据类型:
- 数值特征
- 分类特征和顺序特征
- 日期和时间
- 文本
- 图像
不同的数据类型和不同的机器学习模型需要不同类型的特征预处理。一些预处理方法对于所有数据类型都是通用的。
数值数据的特征预处理
数值数据有测量或计数的意义。数值数据的例子包括雇员的工资、年龄和拥有的房屋数量。数值数据可以进一步分为两种类型:离散型和连续型。在上面的例子中,一个员工的工资是连续的数据,一个人的年龄和拥有的房屋数量是离散的数据。
让我们研究一下来自Kaggle的SF salary数据集中旧金山市的员工工资数据。
在这个数据集中,特征BasePay, OvertimePay, OtherPay, TotalPay, TotalPayBenefits和Year是数值特征。
让我们选择一个特征并对其进行探索性数据分析。
这里是TotalPay特征的直方图。
从上图中我们可以看出,数据的分布是巨大的。值的范围从0到50,000左右。
如果我们使用panda中的describe()函数看数据分布,我们得到:
count 148654.000000
mean 74768.321972
std 50517.005274
min -618.130000
25% 36168.995000
50% 71426.610000
75% 105839.135000
max 567595.430000
Name: TotalPay, dtype: float64
为了有效地使用该特征,我们需要使用以下任何一种方法对该特征进行预处理。
1. 特征缩放(归一化)
特征缩放是一种对数据的自变量或特征范围进行归一化的方法。它通常被称为标准化。与基于树的模型相比,特征缩放对非树模型的影响更大。因此,如果你想使用非基于树的模型获得良好的结果,你应该考虑规范化你的数值特征。
有不同的方法来归一化特征。以下是一些常见的例子:
- Rescaling (Min-Max归一化):这是一种最简单的归一化,将特征重新划分为[0,1]范围。
下面是使用sklearn库中的MinMaxScaler函数在python中执行Min-Max归一化的代码片段。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
TotalPayReshaped = df.TotalPay.as_matrix().reshape(-1, 1)
df.TotalPay = scaler.fit_transform(TotalPayReshaped)
df.hist(figsize=(15,6), column=[‘TotalPay’])
对TotalPay特征进行Min-Max归一化后使用describe()查看的结果如下。我们可以看到TotalPay的最小值是0,最大值是1。
count 148654.000000
mean 0.132673
std 0.088905
min 0.000000
25% 0.064742
50% 0.126792
75% 0.187354
max 1.000000
Name: TotalPay, dtype: float64
- Standardization (Z-score归一化):在这种归一化中,对一个特征进行缩放,使其均值为零,方差为1。
让我们对原始的TotalPay特征执行Z-score归一化。下面是使用sklearn库中的StandardScaler函数在python中执行此类归一化的代码片段。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
TotalPayReshaped = df.TotalPay.as_matrix().reshape(-1, 1)
df.TotalPay = scaler.fit_transform(TotalPayReshaped)
df.hist(figsize=(15,6), column=[‘TotalPay’])
对TotalPay特征进行Z-score归一化后的结果如下。我们可以看到,TotalPay的均值接近于0,标准差为1。
count 1.486540e 05
mean -2.707706e-15
std 1.000003e 00
min -1.492304e 00
25% -7.640884e-01
50% -6.615046e-02
75% 6.150586e-01
max 9.755700e 00
Name: TotalPay, dtype: float64
2. 离群值删除
在统计学中,离群点是一个与其他观测值距离较远的观测点。 --维基百科
有时,通过从数据中删除离群值,可以显著提高机器学习模型的性能。对于非基于树的模型也是如此。另一方面,基于树的模型对离群值具有较强的鲁棒性。
下面的代码片段将从TotalPay特征中删除1%的数据。
x = df.TotalPay
UPPERBOUND, LOWERBOUND = np.percentile(x, [1,99])
y = np.clip(x, UPPERBOUND, LOWERBOUND)
pd.DataFrame(y).hist()
去除离群值后使用describe()查看TotalPay特征的结果如下。
count 148654.000000
mean 74502.923277
std 49644.336571
min 286.971000
25% 36168.995000
50% 71426.610000
75% 105839.135000
max 207015.797400
Name: TotalPay, dtype: float64
3. 排序变换
基于非树的模型可以从秩变换中获益。如果你没有时间手动处理离群值,这是一种非常方便的技术。当变量是标称变量时,排序变换特别有用,在标称变量中,不同值之间的顺序比值更重要。
可以使用scipy库中的rankdata方法将特征值转换为对应排序后的索引。
4. 对数变换
当你希望降低数据的可变性时,对数变换是另一种常用的技术。对数变换的另一个流行用法是当数据分布高度倾斜时。
下面是用Python执行对数变换的代码片段。
df['LogTotalPay'] = np.log(1 df.TotalPay)
对TotalPay特征执行对数变换后使用describe()的结果如下。值的范围从最小值-618.130和最大值567595.43更改为最小值0.00和最大值13.25。通过对这个特征执行对数变换,我们已经减少了数据中的方差,即原始特征的标准差约为50,500,而对数变换特征的标准差为1.41。
count 148653.000000
mean 10.739295
std 1.413888
min 0.000000
25% 10.495993
50% 11.176446
75% 11.569692
max 13.249166
Name: LogTotalPay, dtype: float64
在本文中,我讨论了为什么特征预处理被认为是数据挖掘过程中的一个重要步骤。我列出了数据集中不同类型的特征,并简要讨论了基于树和非基于树的模型。然后,通过代码示例和直方图图,详细阐述了数值特征常用的特征预处理技术,包括归一化、离群点去除和对数变换等。
你最常用什么预处理技术来处理数值特征?为什么?请在下面的评论中留下你的想法。
欢迎关注磐创博客资源汇总站:http://docs.panchuang.net/
欢迎关注PyTorch官方中文教程站:http://pytorch.panchuang.net/