什么是特征工程?
图 1 左侧表示来自输入数据源的原始数据,右侧表示特征矢量,也就是组成数据集中样本的浮点值集。 特征工程指的是将原始数据转换为特征矢量。进行特征工程预计需要大量时间。
许多机器学习模型都必须将特征表示为实数向量,因为特征值必须与模型权重相乘。
特征工程中的映射
映射数值
整数和浮点数据不需要特殊编码,因为它们可以与数字权重相乘。如图 2 所示,将原始整数值 6 转换为特征值 6.0 并没有多大的意义
映射分类值
分类特征具有一组离散的可能值。例如,可能有一个名为 street_name 的特征,其中的选项包括:
由于模型不能将字符串与学习到的权重相乘,因此我们使用特征工程将字符串转换为数字值。
要实现这一点,我们可以定义一个从特征值(我们将其称为可能值的词汇表)到整数的映射。世界上的每条街道并非都会出现在我们的数据集中,因此我们可以将所有其他街道分组为一个全部包罗的“其他”类别,称为 OOV(词汇表外)分桶。
通过这种方法,我们可以按照以下方式将街道名称映射到数字:
- 将 Charleston Road 映射到 0
- 将 North Shoreline Boulevard 映射到 1
- 将 Shorebird Way 映射到 2
- 将 Rengstorff Avenue 映射到 3
- 将所有其他街道 (OOV) 映射到 4
不过,如果我们将这些索引数字直接纳入到模型中,将会造成一些可能存在问题的限制:我们没有将 street_name 可能有多个值的情况考虑在内。例如,许多房屋位于两条街道的拐角处,因此如果模型包含单个索引,则无法在 street_name 值中对该信息进行编码。
要去除这两个限制,我们可以为模型中的每个分类特征创建一个二元向量来表示这些值,如下所述: - 对于适用于样本的值,将相应向量元素设为 1。
- 将所有其他元素设为 0。
该向量的长度等于词汇表中的元素数。当只有一个值为 1 时,这种表示法称为独热编码;当有多个值为 1 时,这种表示法称为多热编码。
图 3 所示为街道 Shorebird Way 的独热编码。在此二元矢量中,代表 Shorebird Way 的元素的值为 1,而代表所有其他街道的元素的值为 0。
该方法能够有效地为每个特征值(例如,街道名称)创建布尔变量。采用这种方法时,如果房屋位于 Shorebird Way 街道上,则只有 Shorebird Way 的二元值为 1。因此,该模型仅使用 Shorebird Way 的权重。
同样,如果房屋位于两条街道的拐角处,则将两个二元值设为 1,并且模型将使用它们各自的权重。
良好特征的特点
- 避免很少使用的离散特征值
- 最好具有清晰明确的含义
- 实际数据内不要掺入特殊值
- 考虑上游不稳定性
清理数据
缩放特征值
缩放是指将浮点特征值从自然范围(例如 100 到 900)转换为标准范围(例如 0 到 1 或 -1 到 +1)。如果某个特征集只包含一个特征,则缩放可以提供的实际好处微乎其微或根本没有。不过,如果特征集包含多个特征,则缩放特征可以带来以下优势:
- 帮助梯度下降法更快速地收敛。
- 帮助避免“NaN 陷阱”。在这种陷阱中,模型中的一个数值变成 NaN(例如,当某个值在训练期间超出浮点精确率限制时),并且模型中的所有其他数值最终也会因数学运算而变成 NaN。
- 帮助模型为每个特征确定合适的权重。如果没有进行特征缩放,则模型会对范围较大的特征投入过多精力。
您不需要对每个浮点特征进行完全相同的缩放。即使特征 A 的范围是 -1 到 +1,同时特征 B 的范围是 -3 到 +3,也不会产生什么恶劣的影响。不过,如果特征 B 的范围是 5000 到 100000,您的模型会出现糟糕的响应。
处理极端离群值
下面的曲线图表示的是加利福尼亚州住房数据集中称为 roomsPerPerson 的特征。roomsPerPerson 值的计算方法是相应地区的房间总数除以相应地区的人口总数。该曲线图显示,在加利福尼亚州的绝大部分地区,人均房间数为 1 到 2 间。不过,请看一下 x 轴。
将特征值限制到 4.0 并不意味着我们会忽略所有大于 4.0 的值。而是说,所有大于 4.0 的值都将变成 4.0。这就解释了 4.0 处的那个有趣的小峰值。尽管存在这个小峰值,但是缩放后的特征集现在依然比原始数据有用。
分箱
在数据集中,latitude 是一个浮点值。不过,在我们的模型中将 latitude 表示为浮点特征没有意义。这是因为纬度和房屋价值之间不存在线性关系。例如,纬度 35 处的房屋并不比纬度 34 处的房屋贵 35/34(或更便宜)。但是,纬度或许能很好地预测房屋价值。
为了将纬度变为一项实用的预测指标,我们对纬度“分箱”,如下图所示:
分箱之后,我们的模型现在可以为每个纬度学习完全不同的权重。
清查
截至目前,我们假定用于训练和测试的所有数据都是值得信赖的。在现实生活中,数据集中的很多样本是不可靠的,原因有以下一种或多种:
- 遗漏值。 例如,有人忘记为某个房屋的年龄输入值。
- 重复样本。 例如,服务器错误地将同一条记录上传了两次。
- 不良标签。 例如,有人错误地将一颗橡树的图片标记为枫树。
- 不良特征值。 例如,有人输入了多余的位数,或者温度计被遗落在太阳底下。
一旦检测到存在这些问题,您通常需要将相应样本从数据集中移除,从而“修正”不良样本。要检测遗漏值或重复样本,您可以编写一个简单的程序。检测不良特征值或标签可能会比较棘手。
除了检测各个不良样本之外,您还必须检测集合中的不良数据。直方图是一种用于可视化集合中数据的很好机制。此外,收集如下统计信息也会有所帮助:
- 最大值和最小值
- 均值和中间值
- 标准偏差