表示 (Representation):特征工程

在传统编程中,关注重点是代码。在机器学习项目中,关注点转移到表征上。也就是说,开发者可以通过添加和改进特征来调整模型。

将原始数据映射到特征

图 1 左侧表示来自输入数据源的原始数据,右侧表示特征向量,该矢量是构成数据集中样本的一组浮点值。 特征工程是指将原始数据转换为特征向量。进行特征工程预计需要大量时间。

许多机器学习模型必须将特征表示为实数向量,因为特征值必须乘以模型权重。

原始数据通过一个称为特征工程的过程映射到特征向量。

图 1. 特征工程将原始数据映射到机器学习特征。

映射数值

整数和浮点数据不需要特殊编码,因为它们可以与数字权重相乘。如图 2 所示,将原始整数值 6 转换为特征值 6.0 非常简单:

可直接从原始数据复制的地图项示例

图 2. 将整数值映射到浮点值。

映射分类值

分类特征具有一组离散的可能值。例如,可能有一个名为 street_name 的功能,其中包含以下选项:

{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}

由于模型无法将字符串与学习到的权重相乘,因此我们使用特征工程将字符串转换为数值。

为此,我们可以定义一个从特征值(我们将其称为可能值的词汇)到整数的映射。由于世界上的每条街道并非都会出现在我们的数据集中,因此我们可以将所有其他街道划分到一个包罗的“其他”类别,称为 OOV(词汇表外)分桶

使用这种方法,我们可以将街道名称映射到数字,如下所示:

  • 将 Charleston Road 映射到 0
  • 将 North Shoreline Boulevard 映射到 1
  • 将 Shorebird Way 映射到 2
  • 将 Rengstorff Avenue 映射到 3
  • 将其他所有内容 (OOV) 映射到 4

但是,如果我们将这些索引数字直接纳入模型中,将会施加一些可能存在问题的限制:

  • 我们将学习适用于所有街道的单一权重。例如,如果我们了解到 street_name 的权重为 6,那么对于 Charleston Road,我们会将其乘以 0,对于 North Shoreline Boulevard 则乘以 1,对于 Shorebird Way 则乘以 2,依此类推。假设有一个使用 street_name 作为特征来预测房价的模型。根据街道名称对价格进行线性调整的可能性不大,此外,这会假设您已根据平均房价对街道进行排序。我们的模型需要灵活地为每条街道学习不同的权重,这些权重将添加到使用其他特征估算的价格中。

  • 我们没有考虑 street_name 可能具有多个值的情况。例如,许多房屋位于两条街道的拐角处,如果它包含单个索引,则无法在 street_name 值中对该信息进行编码。

要消除这两个约束,我们可以为模型中的每个分类特征创建一个二元向量来表示值,如下所示:

  • 对于适用于样本的值,将相应矢量元素设为 1
  • 将所有其他元素都设为 0

该向量的长度等于词汇表中的元素数。当单个值为 1 时,该表示法称为独热编码;当多个值为 1 时,这种表示法称为多热编码

图 3 展示了特定街道 Shorebird Way 的独热编码。在二元矢量中,代表 Shorebird Way 的元素的值为 1,而代表所有其他街道的元素的值为 0

映射字符串值 (

图 3. 通过独热编码映射街道地址。

此方法可以有效地为每个特征值(例如街道名称)创建一个布尔变量。在这里,如果房屋位于 Shorebird Way 上,则只有 Shorebird Way 的二元值才为 1。因此,该模型仅使用 Shorebird Way 的权重。

同样,如果房屋位于两条街道的拐角处,则将两个二元值设为 1,并且模型会使用它们各自的权重。

稀疏表示法

假设您的数据集中有 100 万个不同的街道名称,您想要将其添加为 street_name 的值。如果明确创建一个包含 100 万个元素的二元向量,其中只有 1 个或 2 个元素为 true,那么在处理这些向量时,就存储时间和计算时间而言,这种做法的效率非常低下。在这种情况下,一种常用的方法是使用 稀疏表示法,其中仅存储非零值。在稀疏表示法中,仍然会为每个特征值学习独立的模型权重,如上所述。