在之前的BLOG里,我们提出了遇到模型不理想的拟合问题,我们该干什么的困惑,并且一同学习了模型评估的数学方法。现在,就让我们从图像出发,再次审视我们的拟合问题,并找到该干什么的答案。

方差与偏差

当我们运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况,要么是偏差比较大,要么是方差比较大。换句话说出现的情况要么是欠拟合,要么是过拟合。那么这两种拟合问题哪个和偏差有关,哪个和方差有关或者是不是和两个都有关,搞清楚这一点非常重要。所以下面就让我们深入地探讨一下有关偏差和方差的问题。

假如我们有一些数据集,我们要用曲线去拟合它,就有可能出现欠拟合,刚刚好,过拟合的情况:

BV1.png

而通过之前的学习,我们已经掌握了训练集、验证集和测试集的概念,我们现在可以更好地理解偏差和方差的问题。具体来说,我们沿用之前所使用的训练集误差和验证集误差的定义,即对训练集数据进行预测或对验证集数据进行预测所产生的平均平方误差:

BV2.png

下面我们画图来具体看看。我们图像的横坐标表示的是多项式的次数,因此横坐标越往右的位置表示多项式的次数越大。所以左边代表的是比较简单的函数,右边代表的是比较复杂的函数:

BV4.5.png

让我们来把训练集误差和交叉验证集误差画在这个坐标中,我们先来画训练集误差,随着我们增大多项式的次数我们将对训练集拟合得越来越好,且当多项式次数很高时我们的训练误差就会很小甚至可能等于0;接下来我们再看交叉验证误差,我们知道如果多项式次数 d 很小的的话,就意味着我们用一个很简单的函数来拟合数据,此时我们不能很好地拟合训练集(欠拟合),所以此时我们的交叉验证误差较大;而如果我们用一个中等大小次数的多项式次数来拟合时,我们就会得到一个比较小的交叉验证误差,因为他有比较好的泛化性;而反过来如果多项式次数 d 太大,那么我们又过拟合了,我们又会得到一个较大的交叉验证误差:

BV3.png

因此我们画出来的图像就应该类似于上图。接着我们来看看如何判断我们的算法是处于高偏差的问题还是高方差的问题呢?其实我们只要分析我们图像的左右两端:

BV4.png

当交叉验证误差比较大时,我们可能是多项式的系数太低或太高,多项式系数太低时对应的就是高偏差的问题,而多项式系数太高对应的是高方差问题。这幅图也提示了我们怎样区分这两种情况。具体地说对于高偏差的情况,也就是我们常说的欠拟合的情况,我们发现交叉验证误差和训练误差 都会很大,因此如果我们的算法有偏差问题的话,那么训练集误差和交叉验证集误差都很大且两个误差可能很接近;相反如果如果的算法处于高方差的问题或者是是过拟合的情况,我们的 Jtrain 也就是训练误差会很小,这也就意味着我们对训练集数据拟合得非常好,但我们的的交叉验证误差会很大,往往会远远大于训练集误差。所以区分高偏差和高方差这两种不同情形的关键依据是,我们的训练误差。如果我们的算法处于高偏差的情况,那么我们的训练集误差会很大,因此我们的假设函数不能很好地拟合训练集数据;而当我们处于高方差的问题时,我们的训练误差通常会很小,并且远远小于交叉验证误差。

正则化与偏差方差

我们在刚刚那部分一起一起学习了偏差和方差的相关知识。我们这道正则化可以有效处理拟合问题,那正则化跟算法的偏差和方差又有什么关系呢?下面我们就来一起探讨这个问题。

假如我们要对下面这样的高阶多项式进行拟合,为了防止过拟合现象,我们要使用一个正则化项来让参数的值尽可能小:

BV5.png

正则化一般会出现三种情形:第一种情形是正则化参数 λ 取了过的的值,导致 θ1 θ2 θ3 等参数被大大惩罚,其结果是这些参数的值都将近似等于0,这假设模型 h(x) 的值将等于或者近似等于 θ0 因此我们最终得到的假设函数应该近似是一条平滑的直线,因此这个假设处于高偏差,对数据集欠拟合(underfit); 与之对应的另一种情况是 λ 值很小,在这种情况下如果我们要拟合一个高阶多项式的话,那么我们通常会处于高方差或者说过拟合(overfitting)的情况;只有当我们取一个中间大小的既不大也不小的 λ 值时我们才会得到一组合理的,对数据刚好拟合的 θ 参数值:

BV6.png

那么我们应该怎样选择出一个最合适的正则化参数 λ 呢?回顾一下,我们的模型和学习参数以及最优化目标是下面这样的,我们要最优化 J(θ) 来得到参数 θ:

BV5.png

让我们在使用正则化的情形中,继续定义 Jtrain(θ) 为另一种不同的形式的最优化目标,但不使用正则化项,它是训练集的平均误差平方和但不考虑正则化项;与此类似我们来定义交叉验证集误差和测试集误差和:

BV7.png

有了这几个误差后,下面就是我们自动选取正则化参数 λ 的方法。通常我们的做法是选取一系列想要尝试的 λ 值,通常会将步长设为 2 倍速度增长,直到一个比较大的值:

BV8.png

得到这12组模型后,我们要做的事情是选对于每个模型最小化我们的代价函数 J(θ) ,得到该模型的参数向量 θ,接下来我就可以用交叉验证集来评价这些假设和参数了。因此我可以得到十二个模型对应的假设函数,接着我们用交叉验证集来评价每一个模型对应的参数 θ 在交叉验证集上的平均误差平方和,然后我们选取这 12 个模型中交叉验证集误差最小的作为答案。最后如果我想看看该模型在测试集上的表现,我可以用经过学习得到的最佳模型来测出它对测试集的预测效果如何。再次重申,这里我们依然是用交叉验证集来拟合模型,这也是为什么我之前预留了一部分数据作为测试集的原因。这样我就可以用这部分测试集比较准确地估计出我的参数向量 θ 对于新样本的泛化能力。这就是模型选择在选取正则化参数 λ 时的应用。

最后我们来看看当我们改变正则化参数 λ 的值时,交叉验证集误差和训练集误差会随之发生怎样的变化:

BV10.png

如果 λ 的值很小,那也就是说我们几乎没有使用正则化,因此我们有很大可能处于过拟合;而如果 λ 的值取的很大的时候,那我们很有可能处于高偏差的问题。所以如果我们画出 Jtrain 和 Jcv 的曲线,就会发现当 λ 的值取得很小时,我们的函数对训练集的拟合相对较好,因为基本相当于没有使用正则化。所以当 λ 值很小时,我们最终能得到一个值很小的Jtrain。而如果 λ 的值很大时我们将处于高偏差问题,不能对训练集很好地拟合,因此我们的误差值可能位于很高的位置。而对于 Jcv 同样地,当 λ 的值很大或很小时,都不可能有较好的泛化能力,所以 Jcv 最小时, λ 的值应该处于一个比较中间的位置:

BV11.png

当然这里我们画的非常的理想化,对于真实的数据 最后得到的曲线可能比这看起来更凌乱,会有很多的噪点。但对某个实际的数据集都能或多或少能看出像这样的一个趋势。通过绘出这条曲线通过交叉验证集误差的变化趋势,我们就可以用自己选择出或者编写程序自动得出能使交叉验证集误差最小的那个点,然后选出那个与之对应的参数 λ 的值。这就是我们 λ 的自动选择方法。

学习曲线

到目前为止我们已经从不同角度认识了方差和偏差问题,接下来的这部分我们讲基于我们已经介绍过的所有这些概念,将它们结合起来建立我们的诊断法,也称为学习曲线。这种方法通常被用来诊断一个学习算法到底是处于偏差问题还是方差问题还是两者都有。下面我们就来一同看看吧!

绘制学习曲线往往非常有用,在改进和检验算法上都有独到的地方。为了绘制学习曲线,我们要关注的仍然是 Jtrain 和 Jcv 的图像:

BV2.png

我们要将其绘制成一个关于数据集大小 m 的函数图像,但你可能会好奇 m 不是一般都是常数吗?比如我有 100 组数据之类的。确实没错,但我们可以人为地限制我们数据集的使用,比如我只用 10 组 20 组之类的:

BV12.png

然后我们对于不同的数据组数,分别画出训练集误差和交叉验证集误差。我们来看看画出来是什么样子的。

假设我们的假设函数是一个二次函数,如果我们只有很少的训练样本,比如一个两个三个,我们的拟合效果会非常好,训练集误差都会是 0,而就算加上了正则化,我们的结果也会非常接近于 0.但随着我们样本数量的增加,想用二次函数达到比较完美的拟合就不太可能了。我们的训练集误差也在不断加大:

BV13.png

所以我们的 Jtrain 曲线是随着样本数量 m 的增大而增大的:

BV14.png

那交叉验证集的情况又是怎么样的呢?交叉验证误差就是在没有作为参数选取的数据上参数的误差。所以当我们选取的训练集比较小时,其泛化能力就很弱,即其交叉验证集误差就会比较大;而随着我们训练集大小的增加,我们的泛化能力也进一步增加,导致了我们交叉验证集误差的下降:

BV15.png

以上是没有拟合问题时反映出来的学习曲线,下面我们来看看在高偏差和高方差下学习曲线的变化。

首先我们先来看看高偏差的情况,这里我们选取一次函数作为例子。在只有五个数据点的情况下,我们得到了一个不怎么好的假设函数;并且随着数据集样本数量的增加,这个问题并没有得到改善。虽然很多的数据让我们拟合出了最好的直线,但是一条直线是无法比较好地反映我们的数据特征的:

BV16.png

所以我们的 Jtrain 曲线大概是下面这样,刚开始还是很低的,但随着 m 的增大慢慢升高到比较高:

BV17.png

那交叉验证集误差 Jcv 呢?刚开始数据点不多的时候还是很高的,随着数据点的增多,Jcv慢慢下降到最后与 Jtrain 非常接近:

BV18.png

这就是我们的学习算法处于高偏差是我们学习曲线的走势。而高偏差可以由很高的训练集误差和交叉验证集误差体现,也就是说就算样本再多,我们的训练集误差和交叉验证集误差都是很高的。所以在欠拟合也就是高偏差的问题下,增加训练数据并不能优化我们的学习算法!

接下来我们来看看当我们的学习算法处于高方差时得出的学习曲线。假如我们用一百次多项式来拟合,且正则化系数 λ 非常小时,当只有五个数据点时,我们的函数就可以对数据非常好的拟合;而当数据增多时,我们可能就越来越难比较好的拟合数据了:

BV19.png

所以我们的 Jtrain 曲线大概是下面这样,刚开始是很低的,但随着 m 的增大慢慢升高:

BV20.png

那交叉验证集误差 Jcv 呢?刚开始数据点不多的时候我们时过拟合,所以误差还是很高的,随着数据点的增多到达一个中等规模的时候,我们的Jcv慢慢下降但还是比Jtrain 大不少:

BV21.png

而处于高方差的一个典型特点就算在训练误差和交叉验证集误差中,还有着不小的差距。但如果我们考虑增加数据集也就是延长我们的图像,最后亦可以达到一个不错的效果。

我们以上画出的图像都是比较理想情况下的,真实数据反应的图像可能更加曲折一些。所以在改进算法之前,我们不妨先画出我们的学习曲线,看看到底是高方差高偏差还是两者都有,这对我们接下来要采取的步骤的选择尤其重要。

接下来要做的事

我们通过之前的板块已经学习了怎样评价一个学习算法,那么这些诊断法则怎样帮助我们判断哪些方法可能有助于改进学习算法的效果,而哪些可能是徒劳的呢。换句话说我们接下来要干什么?让我们再次回到最开始的例子,在那里寻找答案。

在我们之前的例子中,我们使用正则化的线性回归拟合模型,却发现该算法没有达到预期效果,我们提到我们有如下这些选择。那么如何判断哪些方法更可能是有效的呢?

第一种可供选择的方法是使用更多的训练集数据,这种方法对于高方差的情况是有帮助的。也就是说如果我们的模型不处于高方差问题,而是处于高偏差的时候,那么通过前面的学习曲线们已经知道获取再多的训练集数据也不会有太明显的帮助。所以要选择这第一种方法,我们应该先画出学习曲线,然后判断我们的模型是否至少有那么一点方差问题,也就是说你的交叉验证集误差是否比训练集误差大一些;

第二种方法是少选用几种特征,这同样是对高方差时有效。换句话说如果我们通过绘制学习曲线或者别的什么方法看出我们的模型处于高偏差问题,那么切记千万不要浪费时间试图从已有的特征中挑出一小部分来使用,因为我们已经发现高偏差的问题了,使用更少的特征不会有任何帮助。反过来如果我们发现从学习曲线或者别的某种诊断图中看出了高方差的问题,那么恭喜你花点时间挑选出一小部分合适的特征吧,这是把时间用在了刀刃上;

第三种方法是选用更多的特征,通常来讲尽管不是所有时候都适用,但增加特征数一般可以帮助解决高偏差问题。所以如果我们需要增加更多的特征时,一般是由于我们现有的假设函数太简单,我们才决定增加一些别的特征来让我们的假设函数更好地拟合训练集。类似地,增加更多的多项式特征实际上也是属于增加特征,因此也是用于修正高偏差问题。具体来说如果我们画出的学习曲线告诉我们处于高方差问题,那么采取这种方法就是浪费时间。

第四种方法是增大或减小我们的正则化系数 λ 。这种方法尝试起来很方便,而且我们已经知道减小 λ 可以修正高偏差,而增大 λ 的值可以解决高方差问题。这也是一种非常实用的方法。

最后我们来看看这些偏差方差和神经网络的联系。当我们在进行神经网络拟合的时候,我们需要选择神经网络模型。比如说一个相对比较简单的神经网络模型,可能只有一个隐藏层和比较少的隐藏单元,这样产出的参数就不会很多,很容易出现欠拟合问题。这种比较小型的神经网络其最大优势在于计算量较小:

BV22.png

与之相对的另一种情况是相对较大型的神经网络结, 要么隐藏层单元比较多,比如下图左边的神经网络的隐藏单元数就很多;要么隐藏层比较多,比如下图右边:

BV23.png

因此这种比较复杂的神经网络参数一般较多,也更容易出现过拟合问题。这种结构的一大劣势也许不是主要的但还是需要考虑的,那就是当网络中的神经元数量很多的时候计算量会较大。虽然有这个情况,但通常来讲这不是大问题。这种大型网络结构最主要的问题还是它更容易出现过拟合现象。事实上如果你经常应用神经网络,特别是大型神经网络的话,你就会发现越大型的网络性能越好,但如果发生了过拟合,就可能会产生不太好的假设。所以我们可以使用正则化的方法来修正过拟合。一般来说使用一个大型的神经网络并使用正则化来修正过拟合问题,通常比使用一个小型的神经网络效果更好,但主要可能出现的问题是计算量相对较大。

最后我们还需要选择隐藏层的层数,是应该用一个隐藏层呢,还是应该用三个呢?这时我们也可以试试把数据分割为训练集、验证集和测试集,然后使用交叉验证的方法比较一个隐藏层的神经网络,然后试试两个、三个隐藏层以此类推,然后看看哪个神经网络在交叉验证集上表现得最理想。这样我们就能比较好地选择我们神经网络的模型了。

结语

通过这篇BLOG,相信你已经对偏差和方差问题有所掌握了,限制你可以充分运用以上这些内容来判断哪些途径可能是有帮助的,而哪些方法可能是无意义的从而节省下大量时间。我希望这篇BLOG中提到的一些技巧,关于方差偏差以及学习曲线为代表的诊断法,能够真正帮助你更有效率地应用机器学习,让它们高效地工作。最后希望你喜欢这篇BLOG!

Last modification:March 5th, 2020 at 12:45 am
If you think my article is useful to you, please feel free to appreciate