# FDE 读 Géron 的 Hands-On ML，应从第 2 章读起

> 名字最乏味的 notebook，教会你在做任何决定前先锁好测试集，让交给客户的数字站得住。

原文: https://fdetimes.net/zh/books-courses/hands-on-machine-learning-geron-chapter-2/

全书共有 19 个 notebook，第二个的名字最枯燥：end_to_end_machine_learning_project。除了本章全部示例代码和习题答案，它还包含一个名为“Create a Test Set”的小节，以及一行设定随机种子的代码，确保每次重新运行都得到完全相同的结果。

对前线部署工程师（FDE）来说，这一章应该最先读。在客户现场，第一周很少从选择模型架构开始，而是从一个数据文件和一个评测数字开始，这个数字迟早需要你出面辩护。

第 2 章教的，就是如何让这个数字站得住。

## 哪本书，哪个仓库？

这本书是 Aurélien Géron 所著的《Hands-on Machine Learning with Scikit-Learn, Keras and TensorFlow》，由 O'Reilly 出版，目前是第三版。华盛顿与李大学（Washington and Lee University）图书馆的资源指南也把它列入推荐的机器学习书目。

最好的学习方式是使用 GitHub 上的官方仓库 `ageron/handson-ml3`。据作者介绍，该仓库收录第三版的示例代码和习题答案，目标是用 Python 讲授机器学习的基础知识。

第 2 章的 notebook 包含本章全部示例代码和答案。所以学习方法是逐个单元格运行，而不是像读小说那样从头读到尾。

## 为什么测试集是 FDE 的问题？

scikit-learn 官方文档把留出一部分数据作为测试集，描述为监督学习实验中的常见做法。随之而来的规则很简短：绝不用测试数据做任何关于模型的决策，也绝不在测试数据上调用 `fit`。

听起来理所当然。但客户催着要结果的时候，恰恰最容易跳过这条规则。

scikit-learn 把后果称为数据泄漏：构建模型时用到了真正预测时无法获得的信息。评测数字看起来很漂亮，生产环境中的模型却不是这样。

**要点:** 只有当测试集从未参与任何模型决策时，评测数字才值得信任。

## 一家有 50,000 个订单的配送公司

假设一家配送公司交给你 50,000 个订单，请你预测哪些会延误。会泄漏的做法是：先查看全部 50,000 行，根据刚才看到的内容挑选特征，在整个数据集上做归一化，最后才按 80/20 划分。

这两个错误都违反了 scikit-learn 的规则。看过那 10,000 行测试数据之后再选特征，等于用测试数据做模型决策；在整个数据集上做归一化，等于在测试数据上调用 `fit`。

由这条规则可以推出，安全的做法是在预处理之前划分，最好在开始探索数据、挑选特征之前就划分。

跳过这一步，你会拿出一个好看的数字，结果下一周模型在新订单上的表现差得多。客户那边力推这个项目的人，会第一个丢面子。

干净的做法是一开始就划分，把 10,000 行测试数据锁起来，预处理步骤只在 40,000 行训练数据上拟合。像 notebook 里那样设定随机种子，同事重新运行时就能得到完全相同的划分。

第 2 章的 notebook 用分层划分来创建测试集，并指出用 scikit-learn 做一次这样的划分要简洁得多。假设 5% 的订单会延误，即 2,500 个。分层划分会让两边都保持 5% 的比例，测试集里大约有 500 个延误订单，而不会因为偶然因素发生偏斜。

但订单是有日期的。scikit-learn 警告，打乱按时间排序的数据很容易得到过拟合的模型和虚高的验证分数。`TimeSeriesSplit` 工具的做法正相反：用过去训练，用未来测试，训练集随时间逐步扩大。

对这家配送公司来说，用最近一个月作为测试集通常更诚实。这一点要和客户商定，因为只有他们知道模型会在什么时候、用于什么目的。

## 谁该读，按什么顺序读？

如果你是没有 ML 经验、正转向 FDE 工作的软件工程师，就从第 2 章开始。运行 notebook，先自己做习题，再打开答案。Keras 和 TensorFlow 部分可以等到真有客户需要时再看。

如果你已经是 ML 工程师，就把第 2 章当作检查清单快速过一遍。问题不在于你是否知道这些步骤，而在于客户施压时你是否仍然一步不落地执行。

## 哪三个观点值得记住？

第一，划分必须可复现：设了种子，任何人重新运行都会得到同样的数字。第二，在预处理之前划分，不让测试数据左右任何决策，绝不在测试集上 fit。

第三，划分方式必须适合数据：存在稀有类别时用分层划分，模型要预测未来时按时间划分。

自测方法：在运行创建测试集的单元格之前，写一句话说明你为什么这样划分。如果把书中的数据换成上面那 50,000 个订单，这句话依然成立，你就真正读懂了第 2 章。

如果你正准备申请 FDE 岗位，可以在目标行业的公开数据集上重做第 2 章，并放到 GitHub 上。当岗位描述提到“end-to-end”或“model evaluation”时，一份清楚说明你如何划分测试集、为什么这样划分的 README，比任何自我描述都更有说服力。

神经网络能吸引客户的注意，但留住客户信任的，是一个你从未碰过的测试集。

**本周动手试试:**

- 克隆 ageron/handson-ml3 仓库，自己从头到尾运行第 2 章的 notebook。先做习题，再打开答案。
- 选一个你想进入的行业的公开数据集，先划出测试集，再在上面重做第 2 章的步骤。
- 为这个 notebook 写一份三句话的 README，说明你如何划分测试集、为什么这样划分，然后在简历中附上链接。

## 信源

- [Machine Learning Notebooks, 3rd edition (ageron/handson-ml3 README)](https://github.com/ageron/handson-ml3)

- [Machine Learning Notebooks, 3rd edition (ageron/handson-ml3 README)](https://github.com/ageron/handson-ml3/blob/main/README.md)

- [02_end_to_end_machine_learning_project.ipynb (ageron/handson-ml3)](https://raw.githubusercontent.com/ageron/handson-ml3/main/02_end_to_end_machine_learning_project.ipynb)

- [Additional Resources – GenAI (W&L LibGuides)](https://libguides.wlu.edu/GenAI/AdditionalResources)

- [Cross-validation: evaluating estimator performance (scikit-learn docs)](https://scikit-learn.org/stable/modules/cross_validation.html)

- [Common pitfalls and recommended practices (scikit-learn docs)](https://scikit-learn.org/stable/common_pitfalls.html)
