第六周PPT 下载密码:zgkq
本周主要讲解了如何设计机器学习系统和如何改进机器学习系统,包括一些模型选择的方法,模型性能的评价指标,模型改进的方法等。
目录
一、应用机器学习建议
1.决定下一步做什么
当你正在开发一个机器学习系统或者想改进机器学习系统的性能时,下一步需要做什么,接下来以线性回归预测房价的例子进行具体说明:
假设你用如下的线性回归代价函数通过训练已经得到了一组最优的参数,但是对于一些新样本,模型的预测效果并不是很好。
此时,你可以从以下几个方面进行尝试,以改进模型性能:
- 收集更多的训练样本(比较耗时,在特定情况下有用)
- 尝试使用更少的特征(当原始输入特征比较多时,可以从中选择一部分特征进行训练,缓解过拟合)
- 增加更多的特征(通过收集一些新的特征,比如原始房价数据集只有面积一个特征,可以通过一些渠道,收集一些其他影响房价的特征,如卧室数目,地理位置等等,耗时,不建议使用)
- 增加多项式特征(在原始输入特征的基础上,通过对这些特征进行组合,获取一些新的特征,如)
- 尝试减小正则化惩罚系数
- 尝试增大正则化惩罚系数
上述提及的这些建议并非全都有意义,接下来我们将学习一些机器学习诊断法,通过它来得到什么样的尝试对于改进模型性能是有意义的。
2.评估假设函数
当我们训练一个机器学习模型时,我们总期望预测值(假设函数的输出值)和真实值之间的误差越小越好,但这并不是一种好的做法,这样很容易产生过拟合。在训练集上无比精确,但是对于新样本却不灵了,泛化能力很差。
那我们该如何评价训练得到的假设函数呢?接下来以房价预测的例子进行演示:
当我们的原始输入特征只有面积时,通过增加多项式特征,我们训练得到了如下的假设函数:
这种情况下,我们可以通过可视化拟合的效果,来判断是否发生过拟合。但是这种方法,并不是通用的。
当我们的原始输入特征非常多时,假设有100个,此时是无法通过可视化的方法来判断是否发生过拟合的。我们需要使用一种评价假设函数的标准方法。
- 评价假设函数的标准方法
首先对原始的训练样本进行随机打乱,然后将其按比例分割为新的训练集和测试集,一般来说新的训练集占70%,测试集占30%。
对于线性回归:
首先通过新的训练集进行训练,最小化代价函数,得到一组最优的参数。
然后使用训练得到的在测试集上计算误差:
对于逻辑回归:
类似的,首先通过新的训练集进行训练,最小化代价函数,得到一组最优的参数。
然后使用训练得到的在测试集上计算误差:
不过对于分类问题,更常用的一种误差度量是0/1错误分类度量:
3.模型选择和训练、验证、测试集
正则化惩罚项系数的选择;增加多项式特征时,多项式的次数等这类问题,成为模型选择问题。
当模型确定时,可以使用上一小节的方法;对于模型选择问题,我们不能再像上一小节讲的那样,简单的把原始训练集分为新的数据集和测试集,而是应该把原始训练集分为3部分:新的训练集、验证集和测试集。
结下来还是通过预测房价的例子进行演示,假设输入特征只有面积,如果只使用这一个原始输入特征,拟合效果是很不理想的。这种情况下,我们一般通过增加多项式特征,再进行拟合。但是问题在于多项式特征的次数该怎么选?即应该选择一个怎么样的模型(假设).
根据之前讲的内容,我们可以这样做:
首先把所有可能的假设罗列出来,上图中的参数d代表多项式的次数。
然后对原始训练集进行分割,分为新的训练集和测试集,对这些假设分别在新训练集上进行训练,通过最小化训练集的代价,求得一组最优的参数,.
最后将分别带入测试集,计算测试误差,选择使测试误差最小的那组参数所对应的假设,作为最好的假设。并把这个最小的测试误差作为泛化误差。
但是这样做其实是不公平的,相当于你用测试集拟合了一个新的参数d,通过测试集来选择模型,又用该模型在测试集上计算泛化误差。这并不是一种好的做法。
对于这种模型选择问题,更科学的做法是,把原始训练集按比例分为新的训练集(60%),验证集(交叉验证集20%),测试集(20%)三部分:
训练、验证和测试集误差的计算:
对于模型选择问题,可以这样做:
首先把所有可能的假设罗列出来,上图中的参数d代表多项式的次数。
然后对这些假设分别在新训练集上进行训练,通过最小化训练集的代价,求得一组最优的参数,.
接着将分别带入验证集,计算验证误差,选择使验证误差最小的那组参数所对应的假设,作为最好的假设。比如,当d=4时,验证误差最小,此时我们的假设函数就是:
最后,将带入测试误差公式,得到测试误差,作为泛化误差,来评估该假设的效果。
综上,对于模型选择问题,用验证集选择模型,用测试集计算泛化误差,评估性能。
4.诊断偏差与方差
我们需要对机器学习模型进行判断,到底是高偏差还是高方差,以此来采用相应的改进措施。
高偏差和高方差
之前的课程中提到过,图1属于高偏差也就是欠拟合;图3属于高方差也就是过拟合。
对于不同的模型选择,首先训练得到一组参数,然后带入训练/验证误差的公式,得到训练/验证误差,并绘图,从而判断高偏差/方差。
-
上图的横坐标是假设函数多项式次数,也就是不同的模型选择
-
纵轴代表该假设下的误差
-
图中的两条曲线分别代表训练误差曲线和验证误差曲线
-
可以发现,当多项式次数比较低,模型的训练误差和验证误差都很大;随着次数的提升,训练误差不断减小,验证误差则是先减小后增大,验证误差最小的点对应最佳模型选择。
-
高偏差(欠拟合):训练误差和验证误差都很大,图中刚开始的那一部分;
-
高方差(过拟合):训练误差很小,而验证误差很大,图中最后的那一部分。
5.正则化和偏差、方差
从正则化的角度来看偏差和方差,之前课程的实验也做过,当我们选择不同的惩罚系数时,模型效果是会有显著的差异。
考虑如下的线性回归模型,及其代价函数(正则化):
当去不同值时,模型拟合效果如下:
图1,取10000,值很大,训练得到的参数都会非常接近0,假设函数将会是一个常数。此时为高偏差(欠拟合)。
图3,取0,值很小,相当于不做正则化,模型在训练集上的拟合效果会非常好,此时为高方差(过拟合)
图2,取值适中。
接下来讨论如何选择一个合适的:
是线性回归的假设函数,是带正则化的线性回归代价函数,接下里分别是在训练/验证/测试集上计算误差的公式。注意进行区分,之前我们没有考虑正则化,所以代价函数和计算训练误差的公式是一样的,现在由于加入了正则化所以对2者进行了区分。
注意先在训练集上最小化代价函数,求的最优的一组参数。然后再用该参数在训练/验证/测试集上根据公式计算相应的误差。
选择值也是一种模型选择问题,不同的对应不同的模型。和之前类似,我们一般通过尝试一组值,选出最佳的。
这组一般从0开始,逐渐小幅度递增,知道一个比较大的值,如上图所示,每次*2递增。
每个对应一个假设,然后对这些假设分别在训练集上进行训练,通过最小化训练集的代价,求得一组最优的参数,.
接着将分别带入验证集,计算验证误差,选择使验证误差最小的那组参数所对应的假设,作为最好的假设。比如,对应的假设。
最后,将该带入测试误差公式,得到测试误差,作为泛化误差,来评估该假设的效果。
综上,对于模型选择问题,用验证集选择模型,用测试集计算泛化误差,评估性能。
通过绘图的方式,查看值与方差/偏差的关系:
横轴代表不同的值,纵轴代表到误差。图中的曲线分别是训练误差和验证误差。
可以看到,随着的增大,训练误差越来越大;验证误差则是先减小后增大,验证误差最小的点,就是最优取值。
值比较小时,容易发生过拟合,高方差;
值比较大时,容易发生欠拟合,高偏差;
6.学习曲线
学习曲线可以帮助我们判断模型是高偏差还是高方差,非常重要。
学习曲线图像的横轴是训练样本数量,纵轴是误差,我们一般只画模型在训练集以及验证集上的误差曲线。
考虑下面这个例子,我们用2次函数拟合训练样本:
当样本比较少时,训练时可以做到完美拟合,所以此时的训练误差几乎是0,但随着训练样本的增加,模型要做到完美拟合就会变得越来越困难。所以随着训练样本的增加,训练误差是不断增大的。
而对于验证误差来说,少量样本训练的模型,泛化能力很差,所以样本数比较少时,验证误差非常大;但随着训练样本增加,将会拟合出比较合适的假设函数,模型的泛化能力会越来越好,相应的验证误差会随训练样本增加,不断减小。
反应在图像上,如下所示:
- 高偏差情况下的学习曲线
用一个简单的例子来说明:
当我们用直线拟合下图所示的数据时,很显然会出现高偏差的情况:
当样本数比较少时,假设只有1个,模型的泛化能力会非常差,所以刚开始验证误差会很大;随着训练样本的增加,模型的泛化能力会增强,验证误差会不断减小;但是样本增大到一定程度时,将会拟合出一条比较合适的直线,之后再增大样本数量,直线几乎不会变化,所以验证误差会趋于平缓。
对于训练误差,样本比较少时,模拟拟合的会非常完美,此时训练误差会很小;但是随着样本数量的增加,上图中的直线拟合会越来越困难,训练误差会越来越大;在高偏差的情况下,训练误差随着样本的增加,趋于平缓,接近验证误差。
综上,高偏差情况下的学习曲线如下图所示:
如果机器学习算法有高偏差,增加更多的训练样本,不会有一个更好的效果。
特点:验证误差随样本增加不断减小,并趋于平缓;训练误差随样本增加不断增大,最后也趋于平缓;并且二者非常接近,交界处对应的误差很大。
- 高方差情况下的学习曲线
用一个简单的例子来说明:
当我们用一个多项式次数非常高的假设函数来拟合下图的训练样本,很显然会出现高方差:
当训练样本比较少时,假设函数将会拟合的非常完美,训练误差几乎为0;但随着样本的增多,拟合完美会越来越困难,因此训练误差会逐渐增大。
当训练样本比较少时,不可能很好的拟合这么多模型参数,所以验证误差非常大;但随着样本增多,拟合效果会变好,模型的泛化能力也会提高,验证误差会随样本的增多而不断减小。
综上,高方差情况下的学习曲线如下所示:
如果机器学习算法有高方差,增加更多的训练样本,可以改进算法。
特点:验证误差随样本增加不断减小;训练误差随样本增加不断增大;但2者之间的间距比较大。
上述的学习曲线都非常理想,实际中可能还会有噪声,波动等,但大体形状差不多。绘制学习曲线,可以帮助我们判断学习算法是否出现了高方差/偏差。
7.决定接下来做什么
回到第一小节的那个例子,再来看一下那几个措施能解决的问题:
- 收集更多的训练样本(可以修正高方差的情况,如果画出学习曲线后,不是高方差,那么这样做是没有意义的)
- 尝试使用更少的特征(可以修正高方差的情况)
- 增加更多的特征(可以修正高偏差的情况,如果画出学习曲线后,不是高偏差,那么这样做纯属浪费时间)
- 增加多项式特征(可以修正高偏差的情况)
- 尝试减小正则化惩罚系数(可以修正高偏差的情况)
- 尝试增大正则化惩罚系数(可以修正高方差的情况)
神经网络与过拟合:
左图是一个小型神经网络,隐藏层少且隐藏层的神经元少;右图是一个大型神经网络,隐藏层比较多或隐藏层的神经元比较多。
小型网络参数更少,计算量比较小,但容易出现欠拟合;大型网络参数非常多,计算量很大(这个问题并不大),主要容易出现过拟合。实践证明,大型网络如果采取相应的防过拟合的手段,如正则化等等,性能将会比小型网络好非常多。
至于网络隐藏层数的选择,默认是一层;当然如果有更好的层数设计,可以采用多层,一般每层的神经元数相同。也可以多尝试一些层数,然后用之前讲多的模型选择方法,选一个最好的层数。
二、机器学习系统设计
1.确定执行的优先级
以建立垃圾邮件分类器为例进行演示,这是一个监督学习的问题。
- 用向量表示邮件
输入变量为邮件的特征;输出变量是标签,1代表是垃圾邮件,0代表不是。
我们可以人工选择100个单词作为字典,用一个100维的向量来表示邮件。如果邮件中的单词在字典中出现,则向量对应位置的分量,不考虑单词出现的次数,仅用0/1表示,那么就可以构建向量来表示邮件内容,作为机器学习算法的输入。
实际上,我们不会人工选择单词构成字典,而是在训练集中自动选择出现频率最高的(10000-50000)个单词构成字典,然后用一个维的特征向量来表示邮件。
- 想办法降低分类的错误率
收集更多的训练数据,但之前有讲过,这种方法并不总是有效,需要视情况而定。
为每个邮件构建更复杂的特征,比如生成特征时除了正文把邮件标题也考虑在内,一些垃圾邮件的特征会体现在标题中。
为邮件正文构建更复杂的特征,比如单词的单复数,discount和discounts是否应该看成一个单词;首字母大小、后缀,deal和Dealer是否应该看作一个单词;是否应该考虑标点符号,可能垃圾邮件中叹号会比较多。
构建更复杂的算法来检测邮件中的错误拼写,比如垃圾邮件发送者经常把一些容易被检测到的单词写错,如m0rtgage,med1cine,w4tches等,从而避免被检测到。
2.误差分析
- 建议方法
构建一个机器学习系统时,建议首先使用一个简单的算法快速实现,然后在验证集上测试他的性能,再逐步改进。
画出学习曲线,判断是存在高偏差还是高方差,然后以此来决定是否增加更多的数据,或构建更多特征。
误差分析:检查验证集上分错的样本(包括把非垃圾邮件分类为垃圾邮件,垃圾邮件分类为非垃圾邮件),观察这些分错的样本是否存在一些特征或规律,以此发现模型优缺点,进而进行改进。
- 误差分析例子
假设验证集有500个样本,,分类器分错了100个样本,此时你可以人工检查这100个错误:
首先分析这100个错分样本的类型,以及各自对应的数量,如下所示:
比如,关于卖药的邮件有12封,卖假货的邮件4封,钓鱼的邮件53封,其他邮件31封;通过以上分析,我们可以把重点放在钓鱼类的邮件上。
然后继续对钓鱼类的邮件进行分析,是否可以发现一些新的特征,能够使提高分类器的性能,比如这类邮件可能存在以下问题,并统计数量,如下所示:
比如,有5封邮件存在错误拼写,以逃避检测,但这个数量有些少,此时没必要花费额外的时间,去设计算法识别这个问题;但是有32封邮件存在一些不常用的标点,应该把关注重点放在这,设计一些包含标点的更复杂的特征,以此来提高分类器性能。
- 数值评估
在做垃圾邮件分类时,可能会遇到这种问题:
应不应该把discount,discounts,discounted,discounting看作是同一个单词,即是否看成一个特征。
在自然语言处理中会使用词干提取,在这种情况下,上述单词会被看作是同一个。但是词干提取有利有弊,这种方法通常指关注前几个字母,比如它可能会把universe/university看作一个单词,这显然不合理。
那么我们到底要不要使用词干提取?这时我们可以使用数值评估的方法:
首先使用词干提取,训练一个分类器,在验证集上计算它的错误率;然后不使用词干提取,训练一个分类器,在验证集上计算它的错误率。二者进行比较,哪个错误率低,就使用哪种方法。
类似的这种问题,还包括是否应该区分单词大小写,如mom和Mom是否应该看作一个单词,都可以使用上述数值评估的方法,选择一个合理的做法。
- 总结:
在开始一个机器学习问题时,首先快速实现一个简单的算法,尽管它的效果可能不太好;然后通过一些强有力的工具决定下一步做什么,可以第一步通过误差分析,来发现它出现了什么错误,以此来进行优化;第二步,如果你已经实现了一个简单的算法,并有一个数值评价指标,可以以此来验证你的一些想法,判断它对算法性能提高是否有帮助。这样可以让你尽快的确定你的算法应该放弃什么,包含什么。
3.不对称性分类的误差评估
之前我们一直在使用正确率或错误率来评价一个模型的性能,但这个指标并不是通用的,比如偏斜类问题。
首先回顾一下之前提到过的癌症分类的例子:
假设训练了一个逻辑回归模型进行癌症分类,代表患癌,代表没有癌症。在测试集上,发现仅有1%的错误率,按理说分类效果已经非常好了;但是实际上,病人中只有0.5%的人有癌症。那么此时1%的错误率就显得非常糟糕。
如果有一个程序他对于任何输入,输出都为0:
那么他的错误率也就只有0.5%,但是它总是预测没有癌症,那么一旦一个病人有癌症,这个分类器造成的后果是非常严重的,尽管它的错误率非常低。
对于这种偏斜类问题,即正负样本的比例悬殊,如患癌的概率是非常低的。此时用正确率或错误率来评价分类器就不再适用了。
- 查准率和召回率
对于偏斜类问题,使用查准率和召回率作为模型误差的评估指标。
代表稀有类别。
查准率:被分成正例的示例中,实际为正例的比例,如所有我们预测为患癌的病人中有多少比例真正患癌。
召回率:实际为正例的示例中,被分成正例的比例,如所有患癌的病人中,有多少比例被正确的预测为患癌。
查准率或召回率高的模型,被认为是一个好的模型。如之前总是预测为0的模型,他的准确率很高,但他的召回率却是0,所以他不是一个好模型。
4.查准率和召回率的权衡
查准率和召回率公式:
使用逻辑回归模型对癌症病人进行分类:
一般情况下,我们设置的分类阈值是0.5,对于这种偏斜类问题,我们可以从两个角度进行考虑:
- 首先,我们可能想只有在非常有把握的前提下,才会预测病人患癌。否则病人接受癌症治疗会非常痛苦。此时,我们可能会把分类阈值设置为0.7或0.9,即只有超过70%或90%的概率,我们才认为病人患癌。这种情况下,我们称模型具有高查准率、低召回率。
- 另一个角度,我们希望不遗漏任何一个患癌的病人,因为一旦遗漏了,病人不接受治疗,认为自己没病,后果将非常严重。此时,我们可能把分类阈值设置为0.3,即只要有超过30%的概率,我们就认为病人患癌。这种情况下,我们称模型具有低查准率、高召回率。
模型查准率和召回率的一般曲线(包含3种可能的曲线走向):
我们的问题是如何权衡模型的查准率和召回率,也就是如何设置一个合理的阈值:
- F1 Score
下面是一些不同的查准率和召回率数值:
如果简单对2者求平均的话,第三个数值将最高,但它却不是一个好的模型,当Recall=1时,意味着模型为把所有的病人预测为患癌,这显然是不对的。
所以,一般使用F1 Score来权衡查准和召回率:
F1 Score越高,模型性能越好:
5.机器学习数据
之前曾经告诫过大家,使用机器学习算法时,不要盲目的收集大量训练数据,因为大量的训练数据只会在某些情况下有用。
但是实践证明,在某种条件下,获取大量的训练数据会更好的得到一个性能良好的学习算法:
如果你的学习算法有很多参数,训练数据的特征非常充足(如果一个人类专家拿到这些特征,能做出很好的判断,证明特征比较充足),这种情况下如果有大量的训练数据,他的性能会非常好,如使用大型神经网络等。
三、编程作业