机器学习算法评估实战
上QQ阅读APP看书,第一时间看更新

1.1 训练集和测试集的选择

对于分类问题的线下评估,训练集和测试集的选择是必不可少的步骤。

训练集,就是用于训练算法(模型)的数据集合,算法通过对训练集的学习和挖掘,来“培养”自己的“智慧”。

测试集,就是开发人员用于验证算法学习效果的数据集合。

通常测试集和训练集同属于一个完整的数据集合,开发人员通过不同的选择策略选择训练集和测试集,让它们发挥各自的作用。

构建训练集和测试集必须遵守以下两个原则。

(1)一致性

一致性即测试集的数据分布要和训练集保持一致,包括“特征数量”和“每个特征的数值分布”两个方面。

(2)完整性

完整性即测试集的数据数量和数据分布必须能够完整反映模型的真实指标,并且能够产生有统计意义的结果。

我们通过开源的鸢尾花数据集来对理论知识进行解释。该数据集中的鸢尾花品种有3类,分别为setosa、versicolor和virginica。分类依赖的特征有4个,分别为萼片长度、萼片宽度,花瓣长度、花瓣宽度。

下面的数据集是鸢尾花数据集的一小部分,前4列分别对应4个特征,最后一列代表鸢尾花的品种,也就是分类标签。

5.1,3.5,1.4,0.2, Iris-setosa
4.9,3.0,1.4,0.2, Iris-setosa
4.7,3.2,1.3,0.2, Iris-setosa
4.6,3.1,1.5,0.2, Iris-setosa
5.0,3.6,1.4,0.2, Iris-setosa
……
7.0,3.2,4.7,1.4, Iris-versicolor
6.4,3.2,4.5,1.5, Iris-versicolor
6.9,3.1,4.9,1.5, Iris-versicolor
5.5,2.3,4.0,1.3, Iris-versicolor
6.5,2.8,4.6,1.5, Iris-versicolor
……
6.3,3.3,6.0,2.5, Iris-virginica
5.8,2.7,5.1,1.9, Iris-virginica
7.1,3.0,5.9,2.1, Iris-virginica
6.3,2.9,5.6,1.8, Iris-virginica
6.5,3.0,5.8,2.2, Iris-virginica
……

我们先通过这个数据集来解释一下什么是训练集和测试集的一致性。

假设训练集为:

5.1,3.5,1.4,0.2, Iris-setosa
4.9,3.0,1.4,0.2, Iris-setosa
4.7,3.2,1.3,0.2, Iris-setosa

7.0,3.2,4.7,1.4, Iris-versicolor
6.4,3.2,4.5,1.5, Iris-versicolor
6.9,3.1,4.9,1.5, Iris-versicolor

6.3,3.3,6.0,2.5, Iris-virginica
5.8,2.7,5.1,1.9, Iris-virginica
7.1,3.0,5.9,2.1, Iris-virginica
6.3,2.9,5.6,1.8, Iris-virginica
6.5,3.0,5.8,2.2, Iris-virginica

假设测试集为:

4.6,3.1,1.5,0.2, Iris-setosa
5.0,3.6,1.4,0.2, Iris-setosa

5.5,2.3,4.0,1.3, Iris-versicolor
6.5,2.8,4.6,1.5, Iris-versicolor

这种划分方法会导致样本分布不一致,因为测试集中根本没有virginica这个品种的样本,无法检验virginica的分类效果。

还有一种划分方法也会导致样本分布不一致。

假设我们现在需要解决的是一个二分类问题,训练集和测试集的拆分效果如下。

假设训练集为:

5.4,3.9,1.7,0.4, Iris-setosa
4.6,3.4,1.4,0.3, Iris-setosa
5.0,3.4,1.5,0.2, Iris-setosa
4.4,2.9,1.4,0.2, Iris-setosa
4.9,3.1,1.5,0.1, Iris-setosa

7.0,3.2,4.7,1.4, Iris-versicolor
6.4,3.2,4.5,1.5, Iris-versicolor
6.9,3.1,4.9,1.5, Iris-versicolor
5.5,2.3,4.0,1.3, Iris-versicolor
6.5,2.8,4.6,1.5, Iris-versicolor

假设测试集为:

5.1,3.2,1.4,0.2, Iris-setosa
4.9,3.3,1.4,0.2, Iris-setosa
4.7,3.2,1.4,0.2, Iris-setosa

6.4,3.2,4.5,1.5, Iris-versicolor
6.4,3.1,4.5,1.5, Iris-versicolor
6.5,3.2,4.5,1.5, Iris-versicolor

我们可以看到,在测试集中,setosa的每个样本的花瓣长度值都是1.4,花瓣宽度值都是0.2,这会导致花瓣长度和花瓣宽度这两个特征的值在测试集中的分布和在训练集中的分布严重不一致。当花瓣长度值不等于1.4,或者花瓣宽度值不等于0.2时,模型的分类效果如何我们就无从得知了。像这样的数值分布不够多样化的训练集和测试集的划分方法,也是不可取的。

另外,如果训练集有4个特征,而测试集中少了某一个特征,会导致特征不一致,同样无法反映模型的真实效果。

下面我们来解释一下构建数据集的第二个原则——完整性。

在鸢尾花数据集中,每种类型的鸢尾花都有50个样本,完整的鸢尾花数据集共有150个样本,这在机器学习场景中属于小规模的数据集。一般样本数量小于10万的时候,我们将训练集和测试集划分的数量比例保持在6∶4~8∶2都是可以的;如果样本数量巨大,训练集和测试集的样本数量比例就相对没有那么重要,只要它们都能完整且一致地反映数据的真实分布就可以。对鸢尾花数据集来说,训练集和测试集的样本数量比例在7∶3左右就比较合适。

训练集和测试集的选择方法有很多,下面我们来介绍几种常用且可靠的方法。

(1)留出法

留出法是比较简单也比较常用的方法,即从全集S 中选择一定比例的样本作为测试集C ,剩下的作为训练集T 。选择时可以将数据集随机打乱排序,然后取其中若干比例(如前30%)的样本作为测试集,剩下的是训练集;或者直接从全集S 中无放回地随机抽样,直到达到一定比例为止,抽出来的样本作为测试集,剩下的样本作为训练集。

留出法的优点是操作简单,使用几行代码即可完成;缺点是当样本数量较少时,留出法的随机性可能无法保证测试集和训练集的一致性,也无法保证测试集的完整性。

(2) K 折交叉验证法

K 折交叉验证法是指将全集S 分为数量均等的K 份,每次选择其中的K −1份作为训练集,剩下的1份作为测试集,然后对这K 份不同的训练集和测试集依次进行K 轮实验,通过对每次实验的结果取均值和标准差来判断模型的效果。

如果K 值是10,那么训练集和测试集的比例就是9∶1;如果K 值是5,那么训练集和测试集的比例就是4∶1。

以3折交叉验证法为例,将全集S 平均分为A B C 共3个子集。每次实验对应的训练集和测试集如表1.1所示。

表1.1 3折交叉验证法

训练集

测试集

A B

C

B C

A

A C

B

K 折交叉验证法相对留出法的优点是它的多轮验证机制。K 折交叉验证法通过对每次验证的结果求均值和标准差,能够有效地消除某一次验证时样本分布不均衡带来的估计偏差。

(3)采样法

采样法(boost trapping)与留出法的不同点在于,采样法是有放回地采样,然后把n(n>0) 次采样后仍未被选中的样本作为测试集。

那么问题来了,为什么是将n 次采样后仍未被选中的样本作为测试集呢?如果仍未被选中的样本数量为0怎么办?

这里涉及一个数学问题,即对一个集合,如果有放回地采样n(n>0) 次,那么一个样本在n 次采样之后仍没被选中的概率是多少?

我们用极限的思维来求解。即求解n 趋于正无穷时\underset{n\to +\infty }{\mathop{\lim }}\,{{(1-1/n)}^{n}} 的值。

根据重要极限公式有:

\lim _{n \rightarrow+\infty}\left[\left(1+\frac{1}{-n}\right)^{(-n)}\right]^{-1}=\mathrm{e}^{-1}=1 / \mathrm{e}

(1-1)

1/e约等于0.368,接近1/3(0.33),也就是说n 次采样之后仍然有1/3左右的样本不会被抽到。我们通过上文可以知道,将这个比例的样本数量作为测试集是相对合理的。

采样法也引入了样本选择的随机性,它会像留出法一样有一定的样本采样偏差,但是由于随机的过程更复杂,因此在小样本集合中划分测试集时,其一致性和完整性效果一般要优于留出法。

(4)交叉验证集+测试集法

还有一种比较经典的选择方法,是由机器学习领域专家吴恩达在他的课程中提出的,即交叉验证集 + 测试集的方法。这种方法主要用于模型选择,但是在模型评估方面也会给我们一定的启发。他的模型选择的基本步骤如下:

1)使用训练集训练出n 个模型;

2)用n 个模型分别对交叉验证集进行计算,得出交叉验证误差(代价函数值);

3)选取代价函数值最小的模型;

4)用步骤3) 中选出的模型对测试集进行计算,得出推广误差(代价函数值)。

我们在评估模型的过程中也可以借鉴这种方法,先按留出法选取全集S 的一部分(20%左右)作为测试集T ,再将剩下的80%看作一个小的全集S^{\prime} ,对集合S^{\prime} 按照K 折交叉验证的方式分成训练集和交叉验证集。接下来通过交叉验证集初步验证模型的效果,最后用测试集进一步模拟评估模型上线后的真实效果。

为什么在训练集和测试集之间还要加入一个验证集呢?这里需要解释两个概念。

第一个概念是超参数,大家都知道,机器学习模型有很多自带的学习参数,比如线性回归的变量权重\boldsymbol w 和偏置项b ,而超参数则是人工设定的、对模型的学习效率和学习效果起到影响作用的参数,这些参数不需要模型自己学习,而需要在训练的过程中不断进行人工调整。比如神经网络的隐藏层层数、每层的节点数量,还有树模型的深度、叶子节点的个数等。验证集存在的第一个作用就是帮助我们调整这些超参数。

如果用测试集优化这些超参数,模型会逐渐过拟合,过拟合的含义我们会在第2章详细介绍,这里可以暂时理解为模型对新数据的学习过于刻板,缺乏广泛适用性。这就是我们要介绍的第二个概念——信息泄露,通俗来说就是模型已经通过我们调整过的参数感知到了测试集的信息,等于对模型的测试提前“泄题”,于是测试集的测试结果将会比模型真实效果偏好。验证集的第二个作用就是信息隔离,在调整超参数的过程中,泄露的只是验证集的信息,测试集的信息仍然保存完好,从而能够得到更真实的模型效果。

如果你只选择一个训练集、一个验证集,就会导致虽然最后在测试集上表现得可以,但是泛化性不好。因此,我们需要用交叉验证集帮助调参,再用测试集进行模型效果的验证。