机器学习基础---机器学习诊断法
一:决定下一步做什么
在懂机器学习的人当中依然存在着很大的差距,一部分人确实掌握了怎样高效有力地运用这些学习算法。而另一些人可能没有完全理解怎样运用这些算法。因此总是把时间浪费在毫无意义的尝试上。
应该是确保你在设计机器学习的系统时,你能够明白怎样选择一条最合适、最正确的道路。
因此,将介绍一些实用的建议和指导,帮助怎样进行选择。
具体来讲,重点关注的问题是假如你在开发一个机器学习系统,或者想试着改进一个机器学习系统的性能,你应如何决定接下来应该选择哪条道路?
为了解释这一问题,我想仍然使用预测房价的学习例子,假如你已经完成了正则化线性回归,也就是最小化代价函数J的值:
假如,在你得到你的学习参数以后,如果你要将你的假设函数放到一组新的房屋样本上进行测试,假如说你发现在预测房价时产生了巨大的误差,现在你的问题是要想改进这个算法,接下来应该怎么办?
实际上你可以想出很多种方法来改进这个算法的性能:
1.其中一种办法是使用更多的训练样本。具体来讲,也许你能想到通过电话调查或上门调查来获取更多的不同的房屋出售数据。遗憾的是,我看到好多人花费了好多时间想收集更多的训练样本。他们总认为,要是我有两倍甚至十倍数量的训练数据,那就一定会解决问题的是吧?但有时候获得更多的训练数据实际上并没有作用。在后面,将解释原因。我们应该避免把过多的时间浪费在收集更多的训练数据上。
2.另一个方法,你也许能想到的是尝试选用更少的特征集。因此如果你有一系列特征比如x_1,x_2,...,x_n等等,也许你可以花一点时间从这些特征中仔细挑选一小部分来防止过拟合。
3.也许你需要用更多的特征,也许目前的特征集,对你来讲并不是很有帮助。你希望从获取更多特征的角度来收集更多的数据。
4.也可以尝试增加多项式特征的方法,
5.考虑其他方法减小或增大正则化参数入的值。
我们列出的这个单子,上面的很多方法都可以扩展开来扩展成一个六个月或更长时间的项目。遗憾的是,大多数人用来选择这些方法的标准是凭感觉的,也就是说,大多数人的选择方法是随便从这些方法中选择一种。
比如他们会说“噢,我们来多找点数据吧”,然后花上六个月的时间收集了一大堆数据,
然后也许另一个人说:“好吧,让我们来从这些房子的数据中多找点特征吧”。
很多人花了至少六个月时间来完成他们随便选择的一种方法。
而在六个月或者更长时间后,他们很遗憾地发现自己选择的是一条不归路。
幸运的是,有一系列简单的方法能让你事半功倍,排除掉单子上的至少一半的方法,留下那些确实有前途的方法。
同时也有一种很简单的方法,只要你使用,就能很轻松地排除掉很多选择,从而为你节省大量不必要花费的时间。
最终达到改进机器学习系统性能的目的。
假设我们需要用一个线性回归模型来预测房价,当我们运用训练好了的模型来预测未知数据的时候发现有较大的误差,我们下一步可以做什么?
获得更多的训练实例——通常是有效的,但代价较大,下面的方法也可能有效,可考虑先采用下面的几种方法:
1.尝试减少特征的数量
2.尝试获得更多的特征
3.尝试增加多项式特征
4.尝试减少正则化程度入
5.尝试增加正则化程度入
我们不应该随机选择上面的某种方法来改进我们的算法,而是运用一些机器学习诊断法来帮助我们知道上面哪些方法对我们的算法是有效的。
“诊断法”的意思是:
这是一种测试法,你通过执行这种测试,能够深入了解某种算法到底是否有用。
这通常也能够告诉你,要想改进一种算法的效果,什么样的尝试,才是有意义的。
在后面我们将介绍具体的诊断法,但我要提前说明一点的是,这些诊断法的执行和实现,是需要花些时间的,有时候确实需要花很多时间来理解和实现,但这样做的确是把时间用在了刀刃上,因为这些方法让你在开发学习算法时,节省了几个月的时间。因此,在接下来,将先来介绍如何评价你的学习算法。
在此之后,我将介绍一些诊断法,希望能让你更清楚。在接下来的尝试中,如何选择更有意义的方法。
二:评估假设
介绍一下怎样用学过的算法来评估假设函数。将以此为基础来讨论如何避免过拟合和欠拟合的问题。
(一)过拟合问题
当我们确定学习算法的参数的时候,我们考虑的是选择参量来使训练误差最小化,有人认为得到一个非常小的训练误差一定是一件好事,但我们已经知道,仅仅是因为这个假设具有很小的训练误差,并不能说明它就一定是一个好的假设函数。而且我们也学习了过拟合假设函数的例子,所以这推广到新的训练集上是不适用的。
(二)评估假设函数过拟合---画图(不太可能)
对于这个简单的例子,我们可以对假设函数h(x)进行画图,然后观察图形趋势,
但对于特征变量不止一个的这种一般情况,还有像有很多特征变量的问题,想要通过画出假设函数来进行观察,就会变得很难甚至是不可能实现。
(三)评估假设函数过拟合---标准方法(测试集评估)
为了确保我们可以评价我们的假设函数(为了检验算法是否过拟合),我们将数据分成训练集和测试集,通常用70%的数据作为训练集,用剩下30%的数据作为测试集。很重要的一点是训练集和测试集均要含有各种类型的数据,通常我们要对数据进行“洗牌”,然后再分成训练集和测试集(下标test表示数据来自于测试集)。
测试集评估在通过训练集让我们的模型学习得出其参数后,对测试集运用该模型,我们有两种方式计算误差:
1.对于线性回归模型,首先,我们需要对训练集进行学习得到参数θ(就是最小化训练误差J(θ)---使用的70%训练数据来定义得到的),接着计算出测试误差J_test(θ),把从训练集中学习得到的参数θ放入J_test(θ)中,来计算测试误差---计算出假设函数的平方误差(当然还有其他误差计算方法)。
2.对于逻辑回归模型,训练和测试逻辑回归的步骤和上面类似。除了代价函数(计算误差)的实现:
当然对于逻辑回归,我们还有另外一种形式的测试度量,可能更易于理解---错误分类(0/1分类错误)
此时我们的假设,能够正确对样本y进行分类。然后我们就能应用错误分类误差来定义测试误差:
上面式中,实际上就是获取我们的假设函数标记错误的那部分测试集中的样本求平均。
三:模型选择和训练、验证、测试集
假如你想确定对于一个数据集最合适的多项式次数,怎样选用正确的特征来构造学习算法?或者假如你需要正确选择学习算法中的正则化参数lambda?应该如何做呢?这些问题我们称之为模型选择问题。对于这一问题的讨论中,我们还将提到不仅是把你的数据分为:训练集和测试集,而且是如何将数据分为三个数据组:
也就是训练集、验证集和测试集
下面需要了解含义,以及如何使用它们进行模型选择。
(一)过拟合问题
在前面的学习中,我们已经多次接触到过拟合现象。在过拟合的情况中学习算法在适用于训练集时表现非常完美,但这并不代表此时的假设也很完美。更普遍地说,这也是为什么训练集误差通常不能正确预测出该假设是否能很好地拟合新样本的原因。
具体来讲,如果你把这些参数集,比如theta1 theta2等等,调整到非常拟合你的训练集。那么结果就是你的假设会在训练集上表现地很好。但这并不能确定当你的假设推广到训练集之外的新的样本上时,预测的结果是怎样的。是不能作为实际的泛化误差的。不能说明你的假设对于新样本的效果。
(二)模型选择问题
假设我们要在10个不同次数的二项式模型之间进行选择:
我们从测试集中选取最小测试误差项:比如这里我们选择了d=5这一项
这一过程目前看来还比较合理。那么现在,我确定了我使用我的假设也就是这个五次函数模型。现在我想知道这个模型能不能推广到新的样本。我们可以观察这个五次多项式假设模型对测试集的拟合情况。但这里有一个问题是这样做仍然不能公平地说明我的假设推广到一般时的效果。其原因在于我们选择了一个能够最好地拟合测试集的参数d的值及多项式的度。
即我们选择了一个参数d的值,我们选择了一个能够最好地拟合测试集的参数d的值。因此,我们的参数向量theta(5)在拟合测试集时的结果,也就是对测试样本预测误差时,很可能导致一个比实际泛化误差更完美的预测结果。
因为是找了一个最能拟合测试集的参数d,因此我再用测试集来评价我的假设,就显得不公平了。因为我已经选了一个能够最拟合测试集的参数。所以对于测试样本的预测效果不能公平地估计出这个假设对于未知的新样本的预测效果如何。
意思大概是训练集用来决定theta,测试集用来确定模型,所以评估泛化应该用新的集合
为了调整这个评价假设时模型选择的问题,我们通常会采用如下的方法来解决:
如果我们有这样的数据集,我们不要将其仅仅分为训练集和测试集两部分,而是分割为三个部分:
第一部分和之前一样,也是训练集
然后第二部分数据,我们将其称为交叉验证集(Cross validation),有时也把交叉验证直接称为验证集。
交叉验证:”把一组数据分为多份,然后每次取一份作为验证组,其他组用来训练。每一份都担任过一次验证组之后(循环一遍),算总体的平均误差。
然后最后这部分数据我们依然称之为测试集
那么最典型的比例是分配三组数据:将整个数据的60%分给训练集,然后20%作为验证集,20%作为测试集(比值可以稍微进行调整)
上面我们定义了训练集、验证集、测试集。下面同样的,我们可以定义训练误差、交叉验证误差和测试误差。
现在由验证集选出最合适的假设函数,由测试集给出泛化评价。
模型选择步骤:
1. 使用训练集训练出10个模型
2. 用10个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
3. 选取代价函数值最小的模型
4. 用步骤3中选出的模型对测试集计算得出推广误差(代价函数的值)
如果泛化误差大到接收不了就改进模型。
四:诊断偏差和方差
当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大。
换句话说,出现的情况要么是欠拟合,要么是过拟合问题。那么这两种情况,哪个和偏差有关,哪个和方差有关,或者是不是和两个都有关?
搞清楚这一点非常重要,因为能判断出现的情况是这两种情况中的哪一种。其实是一个很有效的指示器,指引着可以改进算法的最有效的方法和途径。
(一)偏差、方差概念
- 偏差(bias):偏差衡量了模型的预测值与实际值之间的偏离关系。通常在深度学习中,我们每一次训练迭代出来的新模型,都会拿训练数据进行预测,偏差就反应在预测值与实际值匹配度上,比如通常在keras运行中看到的准确度为96%,则说明是低偏差;反之,如果准确度只有70%,则说明是高偏差。
- 方差(variance):方差描述的是训练数据在不同迭代阶段的训练模型中,预测值的变化波动情况(或称之为离散情况)。从数学角度看,可以理解为每个预测值与预测均值差的平方和的再求平均数。通常在深度学习训练中,初始阶段模型复杂度不高,为低方差;随着训练量加大,模型逐步拟合训练数据,复杂度开始变高,此时方差会逐渐变高。---所以过拟合会导致方差增大
(二)偏差和方差图像结合
这是一张常见的靶心图。可以想象红色靶心表示为实际值,蓝色点集为预测值。在模型不断地训练迭代过程中,我们能碰到四种情况:
- 低偏差,低方差:这是训练的理想模型,此时蓝色点集基本落在靶心范围内,且数据离散程度小,基本在靶心范围内;
- 低偏差,高方差:这是机器学习面临的最大问题,过拟合了。也就是模型太贴合训练数据了,导致其泛化(或通用)能力差,若遇到测试集,则准确度下降的厉害;
- 高偏差,低方差:这往往是训练的初始阶段;
- 高偏差,高方差:这是训练最糟糕的情况,准确度差,数据的离散程度也差。
(三)欠拟合、恰好、过拟合
高偏差和高方差的问题基本上来说是欠拟合和过拟合的问题。
我们通常会通过将训练集和交叉验证集的代价函数误差与多项式的次数绘制在同一张图表上来帮助分析:
对于训练集,当d较小时,模型拟合程度更低,误差较大;随着d的增长,拟合程度提高,误差减小。
对于交叉验证集,当d较小时,模型拟合程度低,误差较大;但是随着d的增长,误差呈现先减小后增大的趋势,转折点是我们的模型开始过拟合训练数据集的时候。
如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢?根据上面的图表,我们知道:
训练集误差和交叉验证集误差近似时:偏差/欠拟合---多项式次数d太小,我们应该适当增大
交叉验证集误差远大于训练集误差时:方差/过拟合---多项式次数d太大,我们应该适当减小
五:正则化和偏差、方差
正则化可以有效的防止过拟合,但是正则化和算法的偏差和方差又有什么关系呢?
探讨一下偏差和方差的问题,讨论一下两者之间是如何相互影响的,以及和算法的正则化之间的相互关系
(一)线性回归正则化
1.当我们设置入较大时,比如入=1000,这时θ_1,...,θ_m都将受到很大的惩罚。所以θ_1,...,θ_m几乎都等于0.这时H_θ(x)≈θ_0
因此这个假设处于高偏差,对数据集严重欠拟合。
2.与之对应的另一种情况是,如果我们的lambda值很小,比如说lambda的值等于0的时候,在这种情况下,如果我们要拟合一个高阶多项式的话,那么此时我们通常会处于过拟合的情况。
3.只有当我们取一个中间大小的,既不大也不小的lambda值时,我们才会得到一组合理的,对数据刚好拟合的theta参数值
(二)如何自动地选择出一个最合适的正则化参数入?
h_θ(x)是我们的模型,J(θ)是我们的目标。我们使用正则化处理目标代价函数J(θ)获得参数。
正则是为了梯度下降的优化,和真值的误差本身不包括正则。所以我们后面对于训练集、验证集、测试集的误差求解不需要包含正则项
主要就是在选取入值之后,对于每个入值(获取参数集之后),都用(不再有正则项)使用训练集获取模型、验证集得到最小验证误差项、测试集进行测试评估。
我们选择一系列的想要测试的入值,通常是 0-10之间的呈现2倍关系的值:
使用交叉验证集来拟合参数,用测试集估计参数对新样本的泛化能力。
选择入的方法步骤:
1.使用训练集训练出12个不同程度正则化的模型
2.用12个模型分别对交叉验证集计算的出交叉验证误差
3.选择得出交叉验证误差最小的模型
4.运用步骤3中选出模型对测试集计算得出推广误差。评估对新样本的泛化能力
我们也可以同时将训练集和交叉验证集模型的代价函数误差与λ的值绘制在一张图表上:
• 当入较小时,训练集误差较小(过拟合)而交叉验证集误差较大--高方差
• 随着入的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加---高偏差
注意:训练集误差是指内部数据集与模型的拟合程度(所以当入小的时候,模型虽然是过拟合,但是与原来训练集的拟合程度还是不错的),验证集误差是指新的数据集与原始模型的平均误差平方和(当入过小或者过大,都会导致误差太大)。
六:学习曲线
学习曲线就是一种很好的工具,我经常使用学习曲线来判断某一个学习算法是否处于偏差、方差问题或者两者都有。学习曲线是学习算法的一个很好的合理检验(sanity check)。学习曲线是将训练集误差和交叉验证集误差作为训练集实例数量(m)的函数绘制的图表。
(一)训练集误差
训练集误差(假设的平均误差),随着m增大而增大:
当m很小,即当训练样本很少的时候,对每一个训练样本,都能很容易的拟合到很好,所以训练误差将会很小。反之,当m逐渐增大,那么想对每一个训练样本都做到很好的拟合,就变得困难了。训练集误差就会越来越大
(二)交叉验证集误差
交叉验证集误差就是在新的数据集(用于验证的那20%)上的误差。
当训练集很小的时候,泛化程度不会很好(不能很好的适应新的样本)。
当训练集很大的时候,才能够更好的拟合数据的假设函数。因此验证集误差和测试集误差都会随着训练集样本容量m的增加而减小。因为你使用的数据越多,你越能获得更好地泛化表现。(或者说对新样本的适应能力更强)
因此,数据越多越能拟合出合适的假设
注意:这里我们的验证集误差存在下界---因为我们是先有数据的假设函数,然后增加样本数量去拟合假设函数,所以很有可能当我们增加数量后也会存在下界的情况(具体看下面讲解)
(三)高偏差(欠拟合)下的学习曲线---预测值与实际值之间的偏离程度
1.当m较小时:
2.当我们增大样本容量时:对于这组数据这是拟合得最好得直线,当我们增大样本容量后,直线拟合得越来越好---即J_cv逐渐减小
但是只是一条直线来减小拟合是不可能对这组数据进行很好得拟合。所以当我们给出交叉验证集误差随着m得增大得图像时,会发现,误差会随着m增大逐渐减小,但是会存在一个下界。
同样训练误差一开始也是很小的,而在高偏差的情况下,你会发现训练集误差会逐渐增大,最后接近交叉验证误差:
这是因为你的参数很少,但当m很大的时候,数据太多。此时训练集和交叉验证集的预测效果将会非常接近,这就是当你的学习算法处于
高偏差情形时学习曲线的大致走向。
最后补充一点:高偏差的情形反映出的问题是交叉验证集和训练集误差都很大。也就是说,你最终会得到一个值比较大Jcv和Jtrain
这也得出一个很有意思的结论:如果一个学习算法有很大的偏差,那么当我们选用更多的训练样本时,对于改善算法没有太大作用。
所以,能够看清你的算法正处于高偏差的情形,是一件很有意义的事情。因为这样可以让你避免把时间浪费在收集更多的训练集数据上,因为再多的数据也是无意义的
(四)高方差(过拟合)下的学习曲线---预测值变化波动情况
1.训练误差---当训练样本越多的时候,就越难把训练集数据拟合得更好。但总的来说训练集误差还是很小得
2.交叉验证误差---过拟合下(泛化能力很差),验证误差将会一直很大,尽管随着样本增大,但是总的来说还是很大。
其特点是:在训练误差和交叉验证误差之间有一段很大的差距。
当我们增大样本数量时,训练误差会增大,而验证误差会减少。所以高方差下,增大样本数量还是有用的。
七:下一步做什么
我们已经介绍了怎样评价一个学习算法,我们讨论了模型选择问题,偏差和方差的问题。那么这些诊断法则怎样帮助我们判断,哪些方法可能有助于改进学习算法的效果,而哪些可能是徒劳的呢?
(一)六种选择解决高方差、偏差
让我们再次回到最开始的例子,在那里寻找答案,这就是我们之前的例子。回顾 一 中提出的六种可选的下一步,让我们来看一看我们在什么情况下应该怎样选择:
1. 获得更多的训练实例——解决高方差
2. 尝试减少特征的数量——解决高方差
3. 尝试获得更多的特征——解决高偏差
4. 尝试增加多项式特征——解决高偏差
5. 尝试减少正则化程度λ——解决高偏差
6. 尝试增加正则化程度λ——解决高方差
高方差---过拟合
高偏差---欠拟合
(二)回顾神经网络中的偏差和方差
使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代价较小。
使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。
通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。
对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络, 然后选择交叉验证集代价最小的神经网络。
关于方差、偏差,以及学习曲线为代表的诊断法能够真正帮助你更有效率地应用机器学习,让它们高效地工作。