PDF 物理页索引 260
文件中的第 261 页 · 印刷页码:244
解决数据不均匀的方法就是在创建训练集和验证集之前,先把数据打乱(数据预处理阶段)。这就防止了源数据集可能有序排列而造成的问题。把上述代码中的这两行注释去掉,然后依次运行代码。
最后结果如图8-42所示。验证数据也看上去像个加州地图了。数据预处理和数据集分割看上去合理了。
人工智能与大数据技术导论
244
PDF 物理页索引 261
文件中的第 262 页 · 印刷页码:245
下面我们使用所有特征变量来训练线性回归模型。输入函数如下,把数据集的数据导入TensorFlow 模型中。
下面的代码配置所有的特征列为一个单独的函数:
下面是模型训练函数:
第8章 TensorFlow
245
PDF 物理页索引 262
文件中的第 263 页 · 印刷页码:246
人工智能与大数据技术导论
246
PDF 物理页索引 263
文件中的第 264 页 · 印刷页码:247
第8章 TensorFlow
247
PDF 物理页索引 264
文件中的第 265 页 · 印刷页码:248
相关结果如图8-43、图8-44所示。
在结果图上,比较了训练数据和验证数据的根均方误差(Root MeanSquaredError,RMSE)。下面我们来看一下在测试数据集上的模型的表现:
工智能与大数据技术导论
248
PDF 物理页索引 265
文件中的第 266 页 · 印刷页码:249
特征工程
在现实世界中,我们拿到的数据可能是数据库记录、文本文件或其他形式。我们必须从各种各样的数据源中提取数据,然后根据这些数据创建特征向量。从原始数据中提取特征的过程称为特征工程。从事机器学习的专业人员将花费超过一半的时间在特征工程方面。
8.4.1 数值型数据
接下来,我们了解一下特征工程是如何发生的,也就是说,怎么从原始数据(RawData)中提取特征。如果某个记录本来就是一个数字,例如房子的房间数量,我们可以直接把这个值对应到一个特征向量(feature vector)中,如图8-46所示。
249
PDF 物理页索引 266
文件中的第 267 页 · 印刷页码:250
8.4.2 字符串数据和 one-hot 编码
机器学习模型是针对数值型数据进行训练,但是模型不能从字符串数据中学习。如果我们面对的是一个字符串,比如地址中的街名(长安街),那么我们该怎么办呢?这时候就需要特征工程把字符串数据转化为数值型数据。如果见到的是字符串值,我们通常可以使用独热(one-hot)编码,将其转化为特征向量。独热编码针对我们可能见到的每个字符串都提供了一个唯一的数字。例如“长安街”,我们就指定为1,其他就为0。我们可以将这个独热编码用作表示字符串的特征向量。独热编码要求:只有一个字符串值为1,其他都为0。
8.4.3 枚举数据(分类数据)
分类(categorical)特征具有一些枚举数据,即一个离散数据的集合。比如,一个性别的特征可能只包含三个值:{“男”,“女”,“未知”}。我们可能想到把这些数据编码为0、1、2。但是,在机器学习模型中,一般情况下,把每个分类数据表示为一个单独的布尔值。在上面的性别例子中,模型可能使用3个不同的布尔特征。
$\mathbf { X } _ { 1 } \mathbf { : }$ 是男的?
$\mathbf { \boldsymbol { x } } _ { 2 } { : }$ 是女的?
• $\mathrm { X } _ { 3 } \dot { : }$ 未知?
8.4.4 好特征
那么,什么样的特征才是好特征呢?首先,一个特征应具有非零值,并且特征值在数据集中至少出现5次或更多次。这样模型才能了解这个特征值和标签之间的关系。如果一个特征在具有非零值的情况下出现的次数十分少,或仅出现过一次,恐怕就不是一个值得使用的好特征,应该在预处理步骤中过滤掉。比如,房屋类型特征变量,针对某个具体的房屋类型,样本数据有很多。那么,房屋类型特征可能是一个好的特征。再比如,房屋编号可能是一个差的特征,因为每个房屋编号可能只有一个样本数据,那么模型就无法从房屋编号上学到什么东西。
其次,特征应具有清晰明显(直接)的意义。这样一来,我们就可以方便地进行有效的检查。例如,以年为单位来计算一座房子的年龄要远远好于以秒为单位来计算。这方便以后排除错误和进行推理。例如,我们定义一个特征,作用是告诉我们一座房子上市了多少天才出售。有些工程师喜欢用特殊值-1来表示这座房子从未上市出售过。对于机器学习来说,这不是一个好的设计。好的主意是定义一个指示型特征,让这个特征采用布尔值,以便表示是否已定义“上市出售天数”特征。借助这种方式,原来的特征“上市出售天数”可以保持0\~n的自然单位。
人工智能与大数据技术导论
250
PDF 物理页索引 267
文件中的第 268 页 · 印刷页码:251
还有,特征值不应随时间发生变化。这一点回到了数据的平稳性这一概念。
8.4.5 数据清洗
对于机器学习而言,预先了解源数据是至关重要的。我们不能将机器学习当作一个黑盒子,把数据丢进去,却不检查数据,就盼着能够获得好结果,这种做法并不妥当。有时,我们要监控一段时间内的数据。数据源昨天情况很好,并不意味着明天情况也会很好。有时,数据集中的有些数据可能并不可靠。因此,我们能做的就是,使用直方图或散点图以及各种排名指标将数据直观地显示出来,查看数据的统计信息(如最大/最小值、均值等)。我们写一些代码查找重复值和缺失值,查找不正确的标签数据和特征值,然后将它们清除出数据集。
在选取特征时应考虑排除离群值。例如,在加利福尼亚州的住房数据中,如果我们创建一个合成特征,例如人均房间数,即房间总数除以人口总数,那么对于大多数城市街区,我们都会得到介于每人0到3或4个房间的相对合理的值。如果出现高达50的值,这样的值就太不正常了,是一个离群值。再比如,年龄数据为200,这个可能是一个离群值。此时,我们或许可以为特征设置上限或转换特征,以便去掉这些不理性的离群值。这就是数据清洗的工作。还有一种数据清洗的标准化方法是将特征数据(比如1000到8000)缩放(scale)至给定的最小值与最大值之间,通常是0与1之间。
我们来看一个具体的例子。图8-47的左图描述了roomsPerPerson特征的数据分布。roomsPerPerson指一个区域内每人所占用的房间数。大多数特征数据集中在1和2之间,看上去比较合理。但是也有50的数据。为了减少离群值的影响,我们使用1og函数把特征值缩放了,如图8-47的右图所示。
虽然log缩放函数帮了一些忙,但是还有离群值。我们修剪最大值到4,如图8-48所示。
第8章 TensorFlow
251
PDF 物理页索引 268
文件中的第 269 页 · 印刷页码:252
“修剪最大值到 $4 ^ { \dprime \dprime }$ 的意思是所有超过4的值都变成4(不是把这些数据扔掉)。可以看到图8-48在4那里有一个突起。尽管如此,缩小的特征数据集更好了。
8.4.6分箱(分桶)技术
我们还可以考虑另一种技术,那就是分箱(bin,也叫分桶)技术。如果要探讨纬度对加利福尼亚州住房价格的影响,我们发现并不存在由北向南的可直接映射到住房价格上的线性关系(见图8-49)。在维度34附近是洛杉矶,在维度38附近是旧金山。但是在某个特定纬度范围内,却往往存在很强的关联。因此,我们能做的就是,将由北向南的纬度划分成11个不同的小分箱(见图8-50),每个小分箱可以是一个布尔特征。针对这些小分箱,每个维度数值都会变成一个布尔值,此时我们就可以使用独热编码。现在,如果映射到洛杉矶附近的特定分箱中,那么基本上会得到一个1,或者映射到旧金山的特定分箱中,也会得到一个1;而在其他任何地区,都会得到一个0。使用11个特征有点复杂,所以我们可以使用一个11元素的向量。比如,维度37.4附近就是[0,0,0,0,0,1,0,0,0,0,0]。借助这种方式,我们的模型可以将部分非线性关系映射到模型中。
人工智能与大数据技术导论
252
PDF 物理页索引 269
文件中的第 270 页 · 印刷页码:253
8.4.7 特征工程实例
在前面一节中,我们在例子代码中用到了所有的特征变量。本节将尝试使用尽可能少的特征变量来达到一样的效果。特征变量少,用的系统资源也少,系统代码也易于维护。下面的代码首先装载样本数据:
定义了2个预处理函数,一个是预处理特征数据;另一个是预处理标签数据:
第8章 TensorFlow
253