从零开始机器学习-9 数据的表示——特征工程(上)
本文由 沈庆阳 所有,转载请与作者取得联系!
前言
我们先来回顾一下什么是特征。
特征(Feature)即机器学习中的输入变量。通过机器学习,我们可以得到定义了特征与标签之间关系的模型。
在传统的编程理念中,程序员往往关注点停留在代码身上。而在机器学习的项目中,工程师的关注点转移到表示(Representation)上面。即工程师通过添加、改进特征来调整模型。
在机器学习中,数据和特征决定了机器学习的上限,模型和算法只是逼近这个上限。特征工程即从原始数据中提取最大限度的特征以供模型使用。
从原始数据中映射到特征
假设我们得到的原始数据如下。
0:{
person_info:{
age:21
gender:'male'
career:'teacher'
...
}
}
上面我们获取了一个人的信息,其属于输入数据源的原始数据,而机器学习需要的输入是样本表示为实数矢量。为了将原始数据转换为特征矢量,我们需要运用到特征工程。通常在机器学习的项目中,特征工程要花费大量的时间。
通过特征工程,我们将原始数据映射到机器学习特征。(下述为机器学习特征矢量的举例,非对应上述原始数据)
[
21.0,
0.0,
5.31,
6.44,
0,
0,
...,
]
在映射的过程中,整数和浮点数作为原始数据不需要进行特殊的编码,因此可以对整数直接复制实值特征。
字符串映射的两种方法
而对于字符串的映射较为特殊,机器学习的模型无法通过字符串进行学习,因此我们需要对字符串进行一些特征工程的转化,将字符串转换为数字的形式。
与枚举型(Enumeration)有些类似,我们将职业(Career)想象成一个枚举型变量。枚举型变量实质上是用整形代替字符串,这点与特征工程处理字符串有类似,但不同。
Career{
Teacher,Student,Engineer,Agent,...
}
枚举型变量的Teacher对应的是0,Student对应的是1,Engineer对应的是2。
字符串映射:独热编码(One-Hot Encoding)
而在特征工程中,我们的Career不再是一个占据一个存储空间的整形变量,而是一个二元矢量。假设Career一共有20个职业,那么Career在特征矢量的表示下就是一个长度为20的一维数组。Teacher对应的是一维数组的第一个元素,Student对应的是一维数组的第二个元素,以此类推。当Career为Student时,第二个元素的值为1,其余值为0。当Career为Engineer时,第三个值为1,其余值为0。
这种映射方法叫做独热编码映射字符串。其基本步骤如下:
1、定义词汇表:将需要表示的字符串定义在一个词汇表中。对于Career特征,该词汇表包含所有样本中的Career职业。
2、独热编码:在创建完词汇表之后使用该词汇表创建一个独热编码,将指定字符串表示为二元矢量,该矢量的长度为词汇表中词汇的个数。该矢量只有一个元素为1,其余元素均为0。
独热编码适合特征的可能值较多的情况。
字符串映射:映射分类值(枚举)
在分类特征个数较少的情况下,我们使用映射分类值得方法。该方法与枚举型一致。
此外,机器学习模型也可以将单个字符串表示为多个布尔值得特征,如,
x1:是Teacher么?(True或False)
x2:是Student么?(True或False)
x3:是Engineer么?(True或False)
选用良好的特征
在将原始数据转为特征矢量之后,我们的关注点需要放在对特征矢量的选择上。
总的来说,良好的特征具有如下特点:
1、不存在或很少存在使用率低的离散特征值
2、特征具有清晰明确的含义
3、考虑到上游不稳定性
下面将会对这三个特点逐个解析。
避免使用率低的离散特征值
什么样的特征才叫使用率低的特征呢?
一个良好的特征值在数据集中出现大约5次及以上。只有这样,机器学习的模型才能学习这个特征值与标签之间的关系。大量的离散值相同的样本可以让模型了解不同设置中的特征,从而判断何时能对标签做出良好的预测。
以上文中讲到的Career为例,Career特征包含大量的样本,其中一个为Teacher。那么Career就是一个可取的特征。
反之,一个特征出现的次数很少,比如在person_info中加入person_id:51029302020XXXXX,那么person_id便不适合作为特征,因为这个值是唯一的,模型无法从这个特征中学到任何规律。
具有清晰明确的含义
良好的特征应该具有清晰且明确的含义。像是person_info中的age:21可以明确地知道这个人是21岁。
但如果将person_info中的age表示成这样age:3900192844(以分钟或是小时来计算年龄)怕是没人知道这个人几岁了,那么这个特征值便是糟糕的特征值。
在有些情况下,一些没有经过过滤的,来源不恰当的特征值也会导致特征混乱。像age:233。那么这个年龄明显超过了人类的最大年龄。
假设有一个特征值是一门考试的成绩,该特征是从0到100的浮点值。如果该特征值是落在0到100之间,那么这个特征值是良好的。如果一个样本没有参加考试,那么其特征值应该是多少呢?
一般编程的时候我们采用-1来表示这个值是奇异的。但是,在机器学习的项目中一定要杜绝这种表示方法!我们应该新建立一个特征,来表示这个特征值是否存在。
考虑到上游不稳定性
对于良好的特征,特征的定义不应该随着时间而变化。
清理数据
在准备数据集的时候,一些输入可能是会对模型学习结果产生不好影响的坏数据。比如在前面我们训练TensorFlow的Object Detection项目的时候,一个样本中对Pen的标注出现偏差,或是将茶杯标注成了Pen。在机器学习的时候,我们会花费大量的时间来挑除这样的坏样本来拯救数据集,因为即使存在少量的坏数据也会对一个大规模的数据集产生很大的影响,甚至是破坏整个数据集。
下一节,我们将会通过具体练习的实例来进行清理数据。
觉得写的不错的朋友可以点一个 喜欢♥ ~
谢谢你的支持!