1、应用机器学习的建议
介绍偏差和方差问题,以及诊断该问题的学习曲线方法。在改进学习算法的表现时,你可以充分运用以上这些内容来判断哪些途径可能是有帮助的,哪些方法可能是无意义的。
过拟合检验
当我们确定学习算法的参数的时候,需要考虑选择参量来使训练误差最小化,有人认为得到一个非常小的训练误差一定是一件好事,但我们已经知道,仅仅是因为这个模型具有很小的训练误差,并不能说明它就一定是一个好的模型,它推广到新的训练集上是不适用的。
所以你该如何判断一个模型是否是过拟合的呢?对于单变量线性回归我们可以对假设函数进行画图,然后观察图形趋势。但对于特征较多的情况,可以将数据分成训练集和测试集(通常用70%的数据作为训练集,用剩下30%的数据作为测试集),很重要的一点是训练集和测试集均要含有各种类型的数据,通常我们要对数据进行“洗牌”,然后再分成训练集和测试集。
在通过训练集让我们的模型学习得出其参数后,对测试集运用该模型,我们有两种方式计算误差:①对于线性回归模型,我们利用测试集数据计算损失函数 ②对于逻辑回归模型,我们除了可以利用测试数据集来计算损失函数外,还可以用误分类比率(误分类个数/总数)
模型选择和交叉验证集
假设我们要在10个不同次数的二项式模型之间进行选择,显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,应该选择一个更能适应一般情况的模型。我们需要使用交叉验证集来帮助选择模型,即使用60%的数据作为训练集,用20%的数据作为交叉验证集,20%的数据作为测试集
模型选择的方法为:①使用训练集训练出10个模型 ②用10个模型分别对交叉验证集计算得出交叉验证误差(损失函数的值)③选取损失函数值最小的模型 ④用步骤3中选出的模型对测试集计算得出推广误差(损失函数的值),最终得到三个误差:训练误差、交叉验证误差、测试误差
诊断偏差和方差
当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大。换句话说,出现的情况要么是欠拟合,要么是过拟合问题。那么这两种情况,哪个和偏差有关,哪个和方差有关,或者是不是和两个都有关?搞清楚这一点非常重要,因为能判断出现的情况是这两种情况中的哪一种。理解有关偏差和方差的问题,能让我们弄清楚怎样评价一个学习算法,能够判断一个算法是偏差还是方差有问题,因为这个问题对于弄清如何改进学习算法的效果非常重要,高偏差和高方差的问题基本上来说是欠拟合和过拟合的问题。
我们通常会通过将训练集和交叉验证集的损失函数值error与多项式的次数d绘制在同一张图表上来帮助分析。①对于训练集,当d较小时,模型拟合程度更低,误差较大;随着d的增长,拟合程度提高,误差减小 ②对于交叉验证集,当d较小时,模型拟合程度低,误差较大;但是随着d的增长,误差呈现先减小后增大的趋势,转折点是我们的模型开始过拟合训练数据集的时候。
如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢?①训练集误差和交叉验证集误差近似时:偏差/欠拟合 ②交叉验证集误差远大于训练集误差时:方差/过拟

正则化和偏差方差
在我们在训练模型的过程中,一般会使用一些正则化方法来防止过拟合。但是我们可能会正则化的程度太高或太小了,即我们在选择λ的值时也需要思考与刚才选择多项式模型次数类似的问题。
我们选择一系列的想要测试的λ值,通常是0-10之间的呈现2倍关系的值(如0、0.01、0.02、0.04、0.08、0.16、0.32、0.64、1.28、2.56、5.12、10,共12个)。我们同样把数据分为训练集、交叉验证集和测试集。
使用λ的方法:①使用训练集训练出12个不同程度正则化的模型 ②用12个模型分别对交叉验证集计算的出交叉验证误差 ③选择得出交叉验证误差最小的模型 ④运用步骤3中选出模型对测试集计算得出推广误差,我们也可以同时将训练集和交叉验证集模型的损失函数值与λ的值绘制在一张图表上:当λ较小时,训练集误差较小(过拟合)而交叉验证集误差较大;随着λ的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加
学习曲线
学习曲线是将训练集误差和交叉验证集误差作为训练集实例数量m的函数绘制的图表,我经常使用学习曲线来判断某一个学习算法是否处于偏差、方差问题。学习曲线是学习算法的一个很好的合理检验,即如果我们有100行数据,我们从1行数据开始,逐渐学习更多行的数据。思想是:当训练较少行数据的时候,训练的模型将能够非常完美地适应较少的训练数据,但是训练出来的模型却不能很好地适应交叉验证集数据或测试集数据。

如何利用学习曲线识别高偏差/欠拟合?在高偏差/欠拟合的情况下,增加数据到训练集不一定能有帮助。比如用一条直线来拟合数据,无论训练集有多么大,验证集、训练集误差都不会有太大改观
如何利用学习曲线识别高方差/过拟合?在高方差/过拟合的情况下,增加更多数据到训练集可能可以提高算法效果。比如我们用一个个非常高次的多项式模型,并且正则化非常小,当交叉验证集误差远大于训练集误差时,往训练集增加更多数据可以提高模型的效果。
总结
我们已经介绍了怎样评价一个学习算法,我们讨论了模型选择、偏差和方差的问题,那么这些诊断法则怎样帮助我们判断:哪些方法可能有助于改进学习算法的效果,而哪些可能是徒劳的呢?①用于解决高偏差的方法:获得更多的特征、增加多项式特征、减少正则化程度λ ②用于解决高方差的方法:获得更多的训练实例、尝试减少特征的数量、增加正则化程度λ
比如神经网络的方差和偏差:①使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,计算代价小 ②使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。
对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络,后选择交叉验证集代价最小的神经网络。
练习
2、机器学习系统的设计
以一个垃圾邮件分类算法为例进行讨论,介绍在设计复杂的机器学习系统时,你将遇到的主要问题,同时我们会试着给出一些关于如何巧妙构建一个复杂的机器学习系统的建议,这可能在构建大型的机器学习系统时能帮你节省大量的时间。
构建一个学习算法的推荐方法
(1)决定如何选择并表达特征向量
为了解决垃圾邮件分类问题,可以选择一个由100个最常出现在垃圾邮件中的词所构成的列表,根据这些词是否有在邮件中出现,来获得我们的特征向量(出现为1,不出现为0),尺寸为100×1
思考:为了构建这个分类算法,我们可以做很多事,比如:①收集更多的数据,让我们有更多的垃圾邮件和非垃圾邮件的样本 ②基于邮件的路由信息开发一系列复杂的特征 ③基于邮件的正文信息开发一系列复杂的特征,包括考虑截词的处理 ④为探测刻意的拼写错误(把watch 写成w4tch)开发复杂的算法。在上面这些选项中,非常难决定应该在哪一项上花费时间和精力,这时可以通过下面的方法来决定到底用什么方法。
(2)构建一个简单的可以快速实现的算法,并评估它
每当我研究机器学习的问题时,最多花一天时间就把结果搞出来,即便效果不好。然后通过交叉验证来检验数据,画出学习曲线,通过画出学习曲线、检验误差来找出你的算法是否有高偏差和高方差的问题(知道应该把时间花在什么地方来优化算法,而不是仅仅凭直觉)。在这样分析之后,再来决定用更多的数据训练,或者加入更多的特征变量是否有用。
(3)误差分析
除了画出学习曲线之外,一件非常有用的事是误差分析,也就是当我们在构造垃圾邮件分类器时,我会看一看我的交叉验证数据集,然后亲自看一看哪些邮件被算法错误地分类。通过这些被算法错误分类的垃圾邮件与非垃圾邮件,你可以发现某些系统性的规律:什么类型的邮件总是被错误分类、分类器对哪一组邮件的预测误差最大。思考怎样能改进分类器,比如发现是否缺少某些特征,记下这些特征出现的次数,记录下错误拼写出现了多少次,异常的邮件路由情况出现了多少次等,然后从出现次数最多的情况开始着手优化。
误差分析并不总能帮助我们判断应该采取怎样的行动。有时我们需要尝试不同的模型,然后进行比较,在模型比较时,用数值来判断哪一个模型更好更有效,通常我们是看交叉验证集的误差。在我们的垃圾邮件分类器例子中,对于“我们是否应该将discount/discounts/discounted/discounting处理成同一个词?”如果这样做可以改善我们算法,我们会采用一些截词软件。误差分析不能帮助我们做出这类判断,我们只能尝试采用和不采用截词软件这两种不同方案,然后根据数值检验的结果来判断哪一种更好。
因此,当你在构造学习算法时总会尝试很多新想法,实现出很多版本的学习算法,如果每次你实践新想法时都要手动地检测这些例子,看看表现差还是表现好,那么这很难让你做出决定,到底是否使用词干提取?是否区分大小写?但是通过一个量化的数值评估,通过这个数字得知误差是变大还是变小了,通过这个数值能帮你判断你的想法是否提高了算法表现。所以我强烈推荐在交叉验证集上来实施误差分析,而不是在测试集上。
样本不平衡时的误差度量
上一节我提到了误差分析,以及设定误差度量值的重要性。需要注意的一件事是关于样本不平衡的问题,它表现为我们的训练集中有非常多的同一种类的实例,只有很少或没有其他类的实例。比如用算法预测某人是否患病,训练集中只有0.5%的实例是患病的,如果都预测没病则正确率也有99.5%,此时误差的大小不能视为评判算法效果的依据,应该用查准率(Precision)和查全率(Recall)来评估模型。
我们将算法预测的结果分成四种情况:①正确肯定(True Positive,TP):预测为真,实际为真 ②正确否定(True Negative,TN):预测为假,实际为假 ③错误肯定(False Positive,FP):预测为真,实际为假 ④错误否定(False Negative,FN):预测为假,实际为真

查准率=TP/(TP+FP)。比如在所有我们预测有病的人群中,实际有病的占比,越高越好。
查全率=TP/(TP+FN)。比如在所有实际有病的人中,成功预测有病的占比,越高越好。如果预测所有人没有患病的话,查全率为0
在很多应用中,我们希望能够保证查准率和召回率的相对平衡。①如果我们提高查准率,即在非常确信的情况下预测人生病,减少错误预测的情况,就用比0.5更大的阈值,这样会增加未能成功预测患病的情况;②如果我们提高查全率,尽可能地让所有可能患病的人都得到进一步检查和诊断,就用比0.5更小的阈值,这样会增加错误预测患病的情况。
我们希望有一个帮助我们选择这个阀值的方法。一种方法是计算F1值,其计算公式为:$F1Score:2\frac{PR}{P+R}$,我们选择使得F1值最高的阀值。