# 5. 你的开发集和测试集

让我们回到前面提到的猫图片检测的例子：你运行一个手机应用，用户可以上传很多东西到你的应用。你想自动的找到含猫的图片。

你的团队通过从不同网站下载带有毛的图片（正样本）和不含猫的图片（负样本）得到了一个很大的训练集。他们把数据集按照70%/30%分成训练集和测试集。通过使用这些数据，他们建立了一个在训练集和测试集都能表现良好的猫检测器。

但是当你部署这个检测器到你的手机应用上的时候，你发现它的性能表现非常糟糕！

![](https://726924510-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LATGeHOwfM9im7p_Lly%2F-LAVPbG-y-iFK71zwoMJ%2F-LAVPcF0pt4ngGYhDM3Y%2F5.1.jpg?generation=1524183501682889\&alt=media)

发生了什么呢？

你会发现用户上传的图片与你的训练集使用的图片有着不同的外观：用户通常上传使用手机拍摄的照片，往往会出现分辨率低、模糊不清并且光线不足。因为你的训练集/测试集使用的照片是从一些较为专业的网站下载的，你的算法不能很好的推广到你关心的图片分布上：你关心的是手机拍摄的图片。

在现代大数据时代到来之前，机器学习中通常会使用随机的分配70%/30%来分割训练集和测试集。这种做法可以工作的很好，但是当越来越多的应用实践中训练集的分布（从专业网站下载的图片）和实际中你关心的分布（手机应用上传的图片）不一致的时候，这种做法就比较糟糕了。

我们通常定义：

* **训练集（Training set） ——** 你运行你的学习算法的数据集。
* **开发集（Dev（development） set）——** 用于调整参数，选择特征和作出其他关于算法决定的数据集，有时也叫交叉验证集。
* **测试集（Test set） ——** 该数据集用于评估算法性能，但是不用对使用什么算法或参数做任何决定。

一旦你定义了开发集和测试集，你的团队将会尝试很多想法，比如设置不同的学习算法参数，来看哪种效果最好。开发集和测试集可以使你的团队快速的查看你的算法效果如何。

换句话说，**设置开发集和测试集的目的是引导你的团队走向机器学习系统最重要的变化。**

所以，应该做以下事情：选择能够反映你将来要获取并且希望能做好的数据集来作为开发集和测试集。

换句话说，你的测试集不应该是简单的从可用数据集中抽取30%，尤其是当你期望的数据集（手机拍摄的图片）与你的训练集（专业网站下载的图片）不同的时候。

如果你的手机应用还没有上线，你可能没有用户，同时也很可能没有一些能够反映你需要做的好的实际分布的数据。但是你可以尝试近似这个。例如，你让你的朋友们来拍一些猫的照片并且发送给你。一旦你的手机应用上线，你就可以使用用户数据来更新你的开发集和测试集。

如果你没有办法来近似获取你将来期望可能获得的数据，或许你也可以使用这些专业网站的图片。但是你要清醒的记得，这个系统不会泛化的好。

这需要去判断决定在开发集和测试集上投入多少资金。但不要假定你的训练集与测试集的分布相同。试着去挑选能够反映你最终想要表现的良好的测试集，而不是你恰好有可以对应的测试集可以用。
