1. 获取和读取数据集
比赛数据分为训练数据集和测试数据集。两个数据集都包括每栋房子的特征,如街道类型、建造年份、房顶类型、地下室状况等特征值。这些特征值有连续的数字、离散的标签甚至是缺失值“na”。只有训练数据集包括了每栋房子的价格,也就是标签。我们可以访问比赛网页下载这些数据集。
我们将通过pandas库读入并处理数据。在导入本节需要的包前请确认已安装pandas库,否则请参考下面的代码注释。
解压后的数据位于../../data目录,它包括两个csv文件。下面使用pandas读取这两个文件。
训练数据集包括1460个样本、80个特征和1个标签。
测试数据集包括1459个样本和80个特征。我们需要将测试数据集中每个样本的标签预测出来。
让我们来查看前4个样本的前4个特征、后2个特征和标签(SalePrice):
可以看到第一个特征是Id,它能帮助模型记住每个训练样本,但难以推广到测试样本,所以我们不使用它来训练。我们将所有的训练数据和测试数据的79个特征按样本连结。
2. 预处理数据
我们对连接数值的特征做标准化(standardization):设该特征在整个数据集上的均值为,标准差为。那么,我们可以将该特征的每个值先减去再除以得到标准化后的每个特征值。对于缺失的特征值,我们将其替换成该特征性的均值。
接下来将离散数值转成指示特征。举个例子,假设特征MSZoning里面有两个不同的离散值RL和RM,那么这一步转换将去掉MSZoning特征,并新加两个特征MSZoning_RL和MSZoning_RM,其值为0或1。如果一个样本原来在MSZoning里的值为RL,那么有MSZoning_RL=1且MSZoning_RM=0。
可以看到这一步转换将特征数从79增加到了331。
最后,通过values属性得到NumPy格式的数据,并转换NDArray方便后面的训练。
3.训练模型
我们使用一个基本的线性回归模型和平方损失函数来训练模型。
下面定义比赛用来评价模型的对数均方根误差。给定预测值和对应的真实标签,它的定义为
对数均方根误差的实现如下。
下面的训练函数跟本章中前几节的不同在于使用了Adma优化算法。相对之前使用的小批量随机梯度下降,它对学习率相对不那么敏感。我们将在之后的“优化算法”一章里详细介绍它。
4. K折交叉验证
我们在“模型选择、欠拟合和过拟合”一节中介绍了K折交叉验证。它将被用来选择模型设计并调节超参数。下面实现了一个函数,它返回一个第i折交叉验证时所需要的训练和验证数据。
在K折交叉验证中我们训练K次并返回训练和验证的平均误差。
5. 模型选择
我们使用一组未经调优的超参数并计算交叉验证误差。可以改动这些超参数来尽可能减小平均测试误差。
有时候会发现一组参数的训练误差可以达到很低,但是在K折交叉验证上的误差可能反而较高。这种现象很可能是由过拟合造成的。因此,当训练误差较低时,我们要观察K折交叉验证上的误差是否也响应降低。
6. 预测并在Kaggle提交结果
下面定义预测函数。在预测之前,我们会使用完整的训练数据集来重新训练模型,并将预测结果存成提交所需要的格式。
设计好模型并调好超参数之后,下一步就是对测试数据集上的房屋样本做价格预测。如果我们得到与交叉验证时差不多的训练误差,那么这个结果很可能是理想的,可以在Kaggle上提交结果。