将原始数据映射到特征称之为特征工程。之前看到一句话,说特征工程决定了神经网络的上限,而模型则是如何逼近这个上限。这句话还是有一定道理的。
机器学习模型是根据浮点值进行训练,因此整数和浮点原始数据并不需要特殊编码。
对于字符串文中给出了独热码的方式。用过mnist应该对独热码的概念都挺熟悉。
文中已经介绍的很清晰了,这里不再介绍了。
避免很少使用的离散特征值。良好的特征值应该在数据中出现5次以上。
“大量离散值相同的样本可让模型有机会了解不同设置中的特征,从而判断何时可以对标签很好地做出预测。”
相反如果某个特征的值出现很少甚至只出现一次,则模型无法根据该特征进行预测。
特征最好具有清晰明确的含义,即每个特征对于项目中的任何人来说都具有清晰明确的含义。
不要将神奇值与实际数据混为一谈。
为解决神奇值的问题,需将该特征转换为两个特征:
一个特征只存储质量评分,不含神奇值。
一个特征储存布尔值,表示是否提供了上面的特征。
我们还要考虑上游的不稳定性(特征的定义不应随时间变化)。
“苹果树结出的果子有品相上乘的,也有虫蛀坏果。而高端便利店出售的苹果是 100% 完美的水果。从果园到水果店之间,专门有人花费大量时间将坏苹果剔除或给可以挽救的苹果涂上一层薄薄的蜡。作为一名机器学习工程师,您将花费大量的时间挑出坏样本并加工可以挽救的样本。即使是非常少量的“坏苹果”也会破坏掉一个大规模数据集。”
首先文中给出的方法是缩放特征值:
缩放指的是将浮点特征值从自然范围(例100~900)转化为标准范围(例0~1或-1~1)。如果某个特征集只包含一个特征,那么缩放的好处几乎没有。但是如果有很多特征那么就会有以下优势:
帮助梯度下降法更快收敛。
帮助避免Nan值陷阱。
帮助模型为每个特征确定合适的权重。如果没有进行特征缩放,则模型会对范围较大的特征投入过多精力。
文中给出了2个缩放的方法:
第一种是将特征中的最大值最小值映射到较小的范围。
另一种是Z得分 scaledvalue = (value - mean)/stddev
除了缩放我们还要处理极端离群值。
我们再看加利福尼亚住房数据集。我们之前创建了rooms_per_person的特征。
import pandas as pd
df = pd.read_csv('california_housing_train.csv')
rooms_per_person = df['total_rooms']/df['population']
print(rooms_per_person.describe())
我们看到max值有55.2222。我们现在想办法降低离群值的影响。
rooms_per_person = np.log(df['total_rooms']/df['population']+1)
这里我们是取的对数(因为最小值小于1,如果我们不加上1,结果则会有负数)。
最后将大于4的值设置为4
def f(x):
return min(x, 4)
k = []
j = map(f, rooms_per_person)
for i in j:
k.append(i)
rooms_per_person.iloc[::] = k
print(rooms_per_person.describe())
我们再来看纬度,在原文给的图中我们能看到纬度和房屋相对普及率的关系。
我们可以将其分为多段来看,这里我们称为对纬度进行分箱:
关于分箱边界:
“为了简单起见,我们在纬度样本中使用整数作为分箱边界。如果我们需要更精细的解决方案,我们可以每隔 1/10 个纬度拆分一次分箱边界。添加更多箱可让模型从纬度 37.4 处学习和维度 37.5 处不一样的行为,但前提是每 1/10 个纬度均有充足的样本可供学习。
另一种方法是按分位数分箱,这种方法可以确保每个桶内的样本数量是相等的。按分位数分箱完全无需担心离群值。”
清查:
至此为止,我们都是假设数据是可靠的。现实中数据往往是不可靠的原因有以下一种或多种:
- 遗漏值。 例如,有人忘记为某个房屋的年龄输入值。
- 重复样本。 例如,服务器错误地将同一条记录上传了两次。
- 不良标签。 例如,有人错误地将一颗橡树的图片标记为枫树。
- 不良特征值。 例如,有人输入了多余的位数,或者温度计被遗落在太阳底下。
一旦检测到存在问题,我们应该将其从数据集中移除,我们可以很轻松的检测遗漏值和重复样本(通过pandas库)。
然而检测不良特征值和标签可能比较棘手。
除了检测各个不良样本之外,您还必须检测集合中的不良数据。直方图是一种用于可视化集合中数据的很好机制。此外,收集如下统计信息也会有所帮助:
- 最大值和最小值
- 均值和中间值
- 标准偏差
以上我们均可以用pandas和matplotlab来处理, pandas中查看这些值的方法为 df.describe(). 直方图则是plt.hist()
了解数据
遵循以下规则:
- 记住您预期的数据状态。
- 确认数据是否满足这些预期(或者您可以解释为何数据不满足预期)。
- 仔细检查训练数据是否与其他来源(例如信息中心)的数据一致。
像处理任何任务关键型代码一样谨慎处理您的数据。良好的机器学习依赖于良好的数据。
这章还挺重要的,大部分内容都是搬运原文,原文生成的直方图这里并没有给出(因为下一章是编程练习),感兴趣的可以自己画一下。