吴恩达机器学习课程笔记(八)-应用机器学习的建议

本节课内容:
1、介绍改进学习算法的几种方法,介绍训练集、验证集和测试集
2、高偏差与高方差问题的区分方法,及相应的解决方法
3、绘制学习曲线帮助判断高偏差与高方差问题

机器学习诊断法:通过执行一种测试,能够了解算法在哪里出了问题,这通常能告诉我们,想要改进一种算法的效果,什么样的尝试才是有意义的

评估假设

怎样判断一个假设是否过拟合?

对于下图的简单例子,我们可以画出假设函数h(x)然后观察,但对于一般情况,特征不止一个,还有包含很多特征的问题,想要通过画出假设函数来观察就变得很难甚至不可能了,因此需要另一种评价假设函数的方法

假设我们有一组训练样本,如下图所示,为了确保可以评价我们的假设函数,要将这些数据分为两部分。第一部分将成为训练集(training set),第二部分将成为测试集(test set),其中一种典型的分割方式是按照7:3的比例,70%的数据作为训练集,30%的数据作为测试集
一般来说,下标为test表示,这些样本来自测试集
另外一点,这里我们选择前70%的数据作为训练集,后30%的数据作为测试集,但如果这组数据有某种规律或顺序的话,最好是随机选择

一种典型的方法训练和测试学习算法

线性回归:
首先,需要对训练集进行学习得到参数θ,即最小化训练误差J(θ),这里使用训练集
接下来,计算测验误差,使用J_test来表示测试误差,然后把从训练集中学习得到的参数θ,放入J_test(θ)中计算测试误差,这实际上是测试集误差平方的平均值
这里是当我们使用线性回归和平方误差标准时,测试误差的定义

分类问题,比如逻辑回归:
训练和测试逻辑回归的步骤与之前所说的非常类似,首选使用训练集进行学习得到参数θ,再使用下图中J_test(θ)公式在测试集上计算测试误差
另一种形式的测试度量,更易于理解,叫做错误分类,也被称为0/1分类错误,0/1表示了预测分类正确或错误的情况,然后应用错误分类误差来定义测试误差,实际上就是假设函数错误标记的测试集中的样本

模型选择和训练、验证、测试集

在过拟合的情况中,学习算法即使对训练集拟合的很好,也并不代表它是一个好的假设,这也是为什么训练集的误差不能用来判断该假设对新样本的拟合好坏
更普遍的规律是,如果参数对某个数据集拟合的很好,那么用同一数据集计算得到的误差,比如训练误差,并不能很好的估计出实际的泛化误差,即该假设对新样本的泛化能力

模型选择

假设要选择能最好的拟合数据的多项式次数,这类似于在算法中加入一个参数d,表示多项式次数,所以除了参数θ,还有一个参数d,需要用数据集来确定
1、首先选择一个模型,然后最小化训练误差,这样会得到一个参数向量θ^((d)),表示用次数为d的 多项式模型拟合数据得到的参数
2、对所有这些模型求出测试集误差,即可以算出J_test(θ^((d) ))
3、为了从这些模型中选出最好的一个,要看哪个模型有最小的测试误差,假设对这个例子最终选择了五次多项式的模型

泛化能力检测

现在我们要使用最终的五次多项式模型,但它的泛化能力怎么样?
我们可以观察这个五次多项式模型对测试集的拟合情况,但问题是,这样做仍然不能公平的评估出这个模型的泛化能力,因为我们用测试集拟合了额外的参数d,又在测试集上评估假设模型

为解决在模型选择中出现的问题,我们通常会蚕蛹如下方法来评估假设:
给定一个数据集,将它分为三个部分,第一部分叫做训练集(training set),第二部分称为交叉验证集(cross validation set,简记为cv),有时候也叫验证集,最后一部分叫做测试集(test set),这些数据的典型分配比例是60%作为训练集,20%作为交叉验证集,20%作为测试集,这些比值可以稍微调整
一般来说,下标为cv表示,这些样本来自交叉验证集


再回到模型选择问题,我们要做的就是用交叉验证集来选择模型,而不是原来的测试集,最后再用测试集衡量或估计算法选出的模型的泛化误差

诊断偏差与方差

当运行一个学习算法,如果这个算法的表现不理想,那么多半是出现了两种情况,要么是偏差比较大,要么是方差比较大,换句话说,要么是欠拟合问题,要么是过拟合问题,这时候搞清楚是偏差问题还是方差问题或者两者都有关就很重要,因为弄清楚到底是哪方面的问题,就能很快找到有效的方法和途径来改进算法

欠拟合与过拟合

下图中的三种情况分别表示欠拟合、刚好、过拟合,其中第二种刚好的情况的泛化误差也是三种情况中最小的

我们沿用之前所使用的训练误差和验证误差的定义,分别是用训练集计算的和用交叉验证集计算的均方误差,接下来,画出训练误差和验证误差分别与多项式次数的关系的示意图,横坐标表示的是多项式的次数,纵坐标表示误差
随着多项式次数的增加,模型对训练集拟合的越来越好,图中粉色线表示训练误差与多项式次数的关系
再看验证误差,实际上如果观察测试误差的话,会得到和验证误差类似的结果:如果d=1,意味着用一个很简单的函数来拟合数据,也许不能很好的拟合训练集,会得到较大的验证误差;如果用中等大小次数的多项式来拟合时,会得到更小的验证误差,因为找到了能够更好的拟合数据的次数;如果次数d太大,那么我们又过拟合了数据,会得到较大的交叉验证误差。图中 红色线表示验证误差与多项式次数的关系

如何判断是高偏差问题还是高方差问题?

交叉验证误差比较大的情况对应着曲线的最左侧和最右侧,那么左侧这一端对应的就是高偏差的问题,需要一个较高的多项式次数来拟合数据,相反的,右侧这一端对应的就是高方差的问题,需要一个较小的多项式次数来拟合数据
这幅图也提示了我们如何区分这两种情况:具体地说,对于高偏差问题,也就是欠拟合现象,交叉验证误差和训练误差都会很大;对于高方差问题,也就是过拟合现象,训练误差会很小,而交叉验证误差会很大

正则化和偏差、方差

正则化参数λ对模型的影响

假设我们要对下图中的高阶多项式进行拟合,为了防止过拟合,要使用正则化,也就是试图通过正则化来让参数的值尽可能小,正则化项求和的范围照例是1到m,而非0到m,然后分析三种情况:
第一种情况是正则化参数λ很大,这种情况下所有的θ参数都将接近于0,h(x)将会等于或近似等于θ_0,因此我们最终得到的假设函数大致如下图中的图一所示,近似于一条水平的直线,因此这个假设处于高偏差,对数据集严重欠拟合
另一种极端情况是正则化参数λ很小,这种情况下要拟合一个高阶多项式的话,通常会出现过拟合的情况,也就是在拟合一个高阶多项式时,如果没有进行正则化,或者正则化程度很小时,通常会得到高方差、过拟合的结果,如下图中图三所示
只有当取一个大小适中的正则化参数λ,才能得到一组对数据拟合比较合理的θ参数值,如下图中图二所示

如何自动的选择出一个最合适的正则化参数λ的值?

假设在使用正则化的情形中,h_θ(x)为模型,J(θ)为学习算法的目标(代价函数),定义训练误差(J_train(θ))为另一种不同的形式,即训练集的平均平方和误差,不考虑正则化项,与此类似,定义交叉验证集误差(J_cv(θ))和测试误差(J_test(θ)),分别是交叉验证集和测试集上的平均平方和误差

自动选择正则化参数λ的值:
1、选取一系列想要尝试的λ值,以下图为例,选取12个不同的λ值(λ从0.01开始,以2倍速增长),得到12个不同的备选模型
2、选用第i个模型,最小化代价函数J(θ),得到某个参数向量θ,使用θ^((i)) 表示这个向量
3、对于所有的θ参数,用交叉验证集来评价它们,选取12个模型中,交叉验证误差最小的模型作为最终选择
4、观察最终选出的模型在测试集上的表现情况

J_train和J_cv与正则化参数λ的关系(分别对应训练集和交叉验证集)

当λ很小时,也就是几乎没有使用正则化,有很大的可能处于过拟合的情况,也就是对训练集拟合相对较好,即J_train很小,而J_cv很大
当λ很大时,很有可能处于高偏差、欠拟合的情况,也就是不能对训练集很好的拟合,即J_train很大,J_cv也很大
因此,当λ增大时,J_train增大(图中蓝色线),J_cv先减小后增大(图中粉色线),图中左端为高方差,右端为高偏差。同样的,总会有中间的某个λ值,表现的刚好合适,此时的训练误差和交叉验证误差都较小

学习曲线

绘制学习曲线

为了绘制学习曲线,通常会先绘制出J_train或J_cv关于参数m的函数,m表示训练集样本总数,m通常是一个常数,但我们需要减小训练集,限制只用10、20、30或40个训练样本,然后对于这些小的训练集画出训练误差,以及交叉验证误差

假设只有1个训练样本,假设用二次函数来拟合,由于只有一个训练样本,拟合的结果很明显会很好,其误差一定为0
假设有2个训练样本,二次函数也能很好的拟合,即使使用正则化,拟合的结果也会很好,如果不使用正则化,就能完美拟合
假设有3个训练样本,二次函数依然能很好的拟合
也就是说,当m=1,m=2,m=3时,如果不使用正则化,训练误差都会等于0;如果使用正则化,训练误差会稍大于0。因此,当训练样本容量m很小时,训练误差也会很小

再假设有4个训练样本,二次函数就不能对数据拟合的很好
假设有5个训练样本,二次函数的拟合结果就一般般了
当训练集越来越大的时候,要保证使用2次函数,对所有的样本拟合效果依然很好,就越来越困难
因此,随着训练集容量m的增大,不难发现平均训练误差在增大,如果画出这条曲线,会发现训练误差随着m的增大而增大(图中蓝色线)

对于交叉验证误差,当训练集很小时,泛化程度不会很好,也就是不能很好的适应新样本,因此这个假设不是一个理想的假设,只有使用更大的训练集时,才能得到一个能够更好拟合新数据的假设,因此交叉验证误差和测试误差都会随着训练集样本容量m的增大而减小(图中粉色线),因为使用的数据越多,越能获得更好的泛化表现

高偏差与高方差下的学习曲线

假设出现高偏差问题:
为了更清楚的解释这个问题,我们使用一个简单的例子来说明,也就是用一条直线来拟合数据,很显然直线不能很好的拟合数据
现在想象如果增大训练集样本容量会发生什么,不难发现最后还会得到类似的一条直线,也就是把样本容量扩大,这条直线也基本不会变化太大
所以如果绘制交叉验证误差,会得到图中蓝色线,最左端表示,训练样本很小时,表现相当不好,而当训练样本容量增大到某个值的时候,就会找到那条最有可能拟合数据的那条直线,此时即使继续增大训练样本容量,还会得到一条差不多的直线,也就是交叉验证误差或训练误差会很快变为水平而不再变化
如果绘制训练误差,会得到图中粉色线,训练误差一开始是很小的,而在高偏差的情况下,训练误差会逐渐增大,最后接近交叉验证误差,因为参数很少,而训练数据很多,当m很大时,训练误差和交叉验证误差会很接近
高偏差的问题可以由很高的交叉验证误差和训练误差反映出来
结论:如果一个学习算法有高偏差,随着我们增加训练样本,交叉验证误差不会明显下降了,所以如果学习算法处于高偏差的情形,那么选用更多的训练集数据,对于改善算法表现无益

假设出现高方差的问题:
假训练样本很少的情况,我们用很高次数的多项式来拟合,并假设使用很小的λ,最终会对这组数据拟合的很好,且这个函数会对数据过拟合,此时训练误差会很小
随着训练样本容量的增加,可能仍然会有些过拟合,但此时要对数据很好的拟合变得更加困难了,所以随着训练样本容量的增大,训练误差也会随之增大,因为训练样本越多的时候,就越难把数据集拟合的很好,但总的来说训练集误差还是很小(图中蓝色线)
对于交叉验证误差,在高方差的情形中,假设函数对数据过拟合,因此交叉验证误差将会一直很大(图中粉色线)
高方差问题的一个明显的特点就是,在训练误差和交叉验证误差之间,有一段很大的距离
总结:如果一个学习算法有高方差,如果我们考虑增加训练集的样本数,训练误差和交叉验证误差的学习曲线会相互靠近,因此可以预测,如果继续增大训练样本的数量,交叉验证误差将会一直下降,所以使用更多的训练数据,对改进算法是有帮助的

因此当要改进一个学习算法时,通常会画出学习曲线,可以更好的判断偏差或方差问题

决定接下来做什么

选择合适的方法改进算法

假设我们试图用正则化的线性回归拟合模型,发现并没有达到我们预期的效果,我们提出了很多改进算法的选择(如下图所示),怎么判断哪些方法有效呢?

1、获取更多的训练样本:对于解决高方差问题是有帮助的,但对解决高偏差问题不会有什么帮助
2、减少特征数量:对高方差时有效
3、选用更多的特征:通常是解决高偏差问题的一个方法
4、增加多项式特征:实际上属于增加特征,是另一种修正高偏差的方法
5、减小λ:修正高偏差
6、增大λ:修正高方差

神经网络的模型选择

当进行神经网络拟合时,可以选择相对比较简单的神经网络模型,比如只有很少甚至只有一个隐含层,并且只有少量的隐含单元,像这样简单的神经网络,参数不会很多,容易出现欠拟合的情况,这种小型神经网络的最大优势在于计算量较小
另一种情况是拟合较大型的神经网络结构,比如每层隐藏层的单元数很多,或者有很多隐藏层,这种比较复杂的神经网络参数较多,容易出现过拟合的情况,这种结构的一大劣势(也许不主要,但还是要考虑),就是当有大量神经元时,会有很大的计算量,但通常不构成问题。这种大型神经网络最主要的潜在问题,还是它更容易出现过拟合现象,通常越大型的网络性能越好,如果发生过拟合,可以使用正则化的方法来修正,一般来说,使用一个大型神经网络并用正则化来修正过拟合问题,通常比使用一个小型的神经网络效果更好。
最后还要选择隐藏层的层数,通常来说,使用一个隐藏层是比较合理的默认选项,但如果想要选择最合适的隐藏层层数,也可以试试把数据集分成训练集、验证集和测试集,然后训练一个隐藏层的网络,然后试试两个、三个隐藏层,然后看看哪个神经网络在交叉验证集上表现的最理想

课程资料

课程原版PPT-Advice for applying machine learning
练习内容和相关说明
相关数据ex5data1

python代码实现
ML-Exercise5.ipynb