2.6 选择和训练模型
最后!你构建了问题、获取了数据并对其进行了探索、对训练集和测试集进行了采样,还编写了预处理流水线来自动清洗数据并为机器学习算法准备了数据。现在是时候选择和训练机器学习模型了。
2.6.1 在训练集上训练和评估
好消息是,多亏了之前的所有这些步骤,现在一切都变得很简单了!你决定开始训练一个非常基本的线性回归模型:
完毕!你现在有了一个有效的线性回归模型。你在训练集上进行尝试,查看前五个预测值并将它们与标签进行比较:
好吧,它能正常工作,但并非总是如此。第一个预测相差甚远(超过200 000美元!),而其他预测则更好:后两个相差约25%,最后两个相差不到10%。请记住,你选择使用了RMSE作为性能度量,所以你想使用Scikit-Learn的mean_squared_error()函数测量此回归模型在整个训练集上的RMSE,将squared参数设置为False:
这总比没有好,但显然不是一个很好的分数:大多数地区的median_housing_values在120 000~265 000美元之间,因此68 628美元的典型预测误差确实不是很令人满意。这是模型欠拟合训练数据的样例。发生这种情况时,可能意味着这些特征没有提供足够的信息来做出良好的预测,或者模型不够强大。正如我们在第1章中看到的,解决欠拟合的主要方法是选择更强大的模型,为训练算法提供更好的特征,或者减少对模型的约束。该模型未正则化,这排除了最后一个选项。你可以尝试添加更多特征,但首先你想尝试一个更复杂的模型,看看它是如何工作的。
你决定尝试DecisionTreeRegressor,因为这是一个相当强大的模型,能够在数据中发现复杂的非线性关系(决策树在第6章中有更详细的介绍):
现在模型已经训练完毕,你可以在训练集上对其进行评估:
等等,什么!一点错误都没有?这个模型真的可以完美无缺吗?当然,更有可能的是模型对数据严重过拟合了。你怎么能确定?正如你之前看到的,在准备好启动你有信心的模型之前,不要接触测试集,因此你需要使用一部分训练集进行训练,另一部分用于模型验证。
2.6.2 使用交叉验证进行更好的评估
评估决策树模型的一种方法是使用train_test_split()函数将训练集拆分为较小的训练集和验证集,然后针对较小的训练集训练你的模型并针对验证集对其进行评估。这需要一些努力,但不会太困难,而且效果会很好。
一个很好的替代方法是使用Scikit-Learn的k折交叉验证功能。以下代码将训练集随机拆分为10个不重叠的子集,称为折叠,然后对决策树模型进行10次训练和评估,每次选择不同的折叠进行评估,并使用其他9次折叠进行训练。结果是一个包含10个评估分数的数组:
Scikit-Learn的交叉验证功能期望效用函数(越大越好)而不是代价函数(越低越好),因此评分函数实际上与RMSE相反。这是一个负值,因此你需要切换输出的符号来获得RMSE分数。
让我们看看结果:
现在决策树看起来不像之前那么好了。事实上,它的表现似乎与线性回归模型几乎一样差!请注意,交叉验证不仅可以让你获得模型性能的估计值,还可以测量该估计值的精确程度(即标准差)。决策树的RMSE约为66 868,标准差约为2061。如果你只使用一个验证集,你就不会获得此信息。但是交叉验证是以多次训练模型为代价的,所以它并不总是可行的。
如果你为线性回归模型计算相同的指标,你会发现平均RMSE为69 858,标准差为4182。所以决策树模型的表现似乎比线性模型稍微好一点,但由于严重的过拟合,两种模型差异很小。我们知道存在过拟合问题,因为训练误差很低(实际上为零)而验证误差很高。
现在让我们尝试最后一个模型:RandomForestRegressor。正如你将在第7章中看到的那样,随机森林的工作原理是在特征的随机子集上训练许多决策树,然后对它们的预测进行平均。由许多其他模型组成的此类模型称为集成:它们能够提高基础模型(在本例中为决策树)的性能。代码与之前的代码大致相同:
让我们看看分数:
哇,这好多了:随机森林看起来非常适合这项任务!但是,如果你训练RandomForest并在训练集上测量RMSE,你会发现RMSE大约为17 474:这要低得多,这意味着仍然存在相当多的过拟合。可能的解决方案是简化模型、对其进行约束(即对其进行正则化),或者获取更多的训练数据。然而,在你更深入地研究随机森林之前,你应该尝试来自不同类别机器学习算法的许多其他模型(例如,几个具有不同内核的支持向量机,可能还有一个神经网络),而不要花太多时间调整超参数。目标是选择一些(2~5个)有前途的模型。