PDF 物理页索引 170
文件中的第 171 页 · 印刷页码:154
5.4.4 梯度下降的详细算法
本节内容需要读者具有一定的微积分基础。读者可跳过本节内容。在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数 $\operatorname { f } ( \mathbf { x } , \mathbf { y } )$ ,分别对x、y求偏导数,求得的梯度向量就是 $( \partial \mathbf { f } / \partial \mathbf { x } , \partial \mathbf { f } / \partial \mathbf { y } )$ ,简称 $\mathrm { g r a d f } ( \mathbf { x } , \mathbf { y } )$ 。对于在点 $\left( \mathbf { \boldsymbol { x } } _ { 0 } , \mathbf { \boldsymbol { y } } _ { 0 } \right)$ 的具体梯度向量就是 $( \partial \mathbf { f } / \partial \mathbf { x } _ { 0 } , \partial \mathbf { f } / \partial \mathbf { y } _ { 0 } )$ ,如果是3个参数的向量梯度,就是 $( \partial \mathbf { f } / \partial \mathbf { x } , \partial \mathbf { f } / \partial \mathbf { y }$ $\partial \mathbf { f } / \partial \mathbf { z } )$ ,以此类推。那么,这个梯度向量求出来有什么意义呢?从几何意义上讲,就是函数变化增加最快的地方。具体来说,对于函数 $\mathrm { f } ( \mathbf { \boldsymbol { x } } , \mathbf { \boldsymbol { y } } )$ ,在点 $( \mathbf { x } _ { 0 } , \mathbf { y } _ { 0 } )$ ,沿着梯度向量的方向,就是$( \partial \mathbf { f } / \partial \mathbf { x } _ { 0 } , \partial \mathbf { f } / \partial \mathbf { y } _ { 0 } )$ 的方向,是 $\operatorname { f } ( \mathbf { x } , \mathbf { y } )$ 增加最快的地方。或者说,沿着梯度向量的方向更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是 $( \partial \mathbf { f } / \partial \mathbf { x } _ { 0 } , \partial \mathbf { f } / \partial \mathbf { y } _ { 0 } )$ 的方向,梯度减小最快,也就更加容易找到函数的最小值。
梯度下降法的算法可以有代数法和矩阵法(也称向量法)两种表示,如果对矩阵分析不熟悉,则代数法更加容易理解。本节以代数法为例来讲解算法。
- 先决条件:确认优化模型的假设函数和误差函数
比如对于线性回归,假设函数表示为 $\scriptstyle \mathrm { h } _ { 0 } ( \mathrm { x } _ { 1 } , \mathrm { x } _ { 2 } , . . . , \mathrm { x } _ { \mathrm { n } } ) = \displaystyle \theta _ { 0 } + \theta _ { 1 } \mathrm { x } _ { 1 } + . . . + \theta _ { \mathrm { n } } \mathrm { x } _ { \mathrm { n } } ,$ 其中 $\Theta _ { \mathrm { i } } ( \mathrm { i } = 0 , 1 , 2 , . . . , \mathrm { n } )$ 为模型参数, $\mathrm { x _ { i } } ( \mathrm { i } = 0 , 1 , 2 , . . . , \mathrm { n } )$ 为每个样本的n个特征值。这个表示可以简化,我们增加一个特征 $\mathrm { x } _ { 0 } { = } 1$ ,这样 $\scriptstyle \mathrm { h _ { \boldsymbol { \Theta } } ( x _ { 0 } , x _ { 1 } , \ldots , x _ { n } ) = \sum \theta _ { i } x _ { i } }$ ,其中 $_ \mathrm { i = 0 \sim n }$ 。同样是线性回归,对应上面的假设函数,误差函数可以使用样本输出和假设函数的差取平方。
- 算法相关参数初始化
主要是初始化 $\theta _ { 0 } , \theta _ { 1 } , . . . , \theta _ { \mathrm { n } }$ ,以及算法终止距离ε和步长 $a _ { \circ }$ 在没有任何先验知识的时候,我可以将所有的 $\theta$ 初始化为0,将步长初始化为1。在调优的时候再优化。
3.算法过程
(1)确定当前位置的误差函数的梯度。在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。对于 $\theta _ { i }$ ,其梯度表达式为∂f/∂θi,其中函数f可以是均方差函数。
(2)用步长乘以误差(损失)函数的梯度得到当前位置下降的距离,即对应于前面登山例子中的某一步。
(3)确定是否所有 $\theta i$ 梯度下降的距离都小于ε,如果小于 $\varepsilon _ { \cdot }$ ,则算法终止,当前所有的 $\theta _ { i }$ $( \mathrm { i } { = } 0 , 1 , { \ldots } , \mathrm { n } )$ 即为最终结果。否则进入步骤4。
(4)更新所有的 $\theta ,$ 对于 $\theta i$ ,其更新表达式如下。更新完毕后继续转入步骤(1)。
$$
\theta _ { i } = \theta _ { i } - \frac { 2 r } { \top } \top \top \top \top \top \top
$$
在机器学习中,无约束优化算法除了梯度下降法以外,还有前面提到的最小二乘法,此外还有牛顿法和拟牛顿法。梯度下降法和最小二乘法相比,梯度下降法需要选择步长,而最小二乘法不需要。梯度下降法是迭代求解,最小二乘法是计算解析解。如果样本量不算很大,且存在解析解,最小二乘法比起梯度下降法有优势,计算速度很快。但是如果样本量很大,用最小二乘法由于需要求一个超级大的逆矩阵,这时就很难或者很慢才能求解了,使用迭代的梯度下降法比较有优势。梯度下降法和牛顿法/拟牛顿法相比,两者都是迭代求解,不过梯度下降法是梯度求解,而牛顿法/拟牛顿法是用二阶的海森矩阵的逆矩阵或伪逆矩阵求解。相对而言,使用牛顿法/拟牛顿法收敛更快,但是每次迭代的时间比梯度下降法长。
人工智能与大数据技术导论
154
PDF 物理页索引 171
文件中的第 172 页 · 印刷页码:155
5.5 模型的拟合效果
通过学习本节内容,我们将了解欠拟合和过拟合及其严重性,认识形成过拟合的原因,以及如何解决过拟合。
5.5.1 欠拟合与过拟合
在如图5-8所示的分类问题中,我们的目标是找到一个分类器,分割两种标签的数据。我们用肉眼不难看出,蓝色标签(圆圈)的点集中在图的右上区域,中间的图是最为合适的分类器。左图用一条直线分割平面,模型过于简单,对直线右侧的红色标签数据(叉叉)刻画较差,属于欠拟合(underfit);而右图则用了比较复杂的模型,对样本集的数据全部照顾,属于过拟合(overfit)。过拟合是参数过多,对训练集的匹配度太高、太准确,以至于在后面的预测过程中可能会导致预测值非常偏离合适的值,预测非常不准确。中间的图是合适的拟合。
欠拟合和过拟合都是应当尽可能避免的。欠拟合会让我们的模型产生较大的偏差(bias),这里的偏差是指我们的模型描绘的数据分布与数据的客观分布之间存在差异。欠拟合通常是因为我们使用了过于简单的模型,比如线性模型,或者训练的时间不够。而过拟合虽然将样本集的误差降到最低,但会使模型产生很大的方差(variance),方差大意味着当新的数据进来时,模型的预测准确率波动会比较大,虽然训练集预测能力很好,但对未知的测试集预测效果可能会很差。过拟合通常是因为我们的模型过于复杂。
事实上,在实际应用中,过拟合的问题远远多于欠拟合。在解决问题时,我们几乎总是要考虑和处理过拟合,但很少会遇到欠拟合。这是因为我们在训练模型时经常会采用过于复杂的模型,使用了太多的特征(features)来训练,对训练集的匹配度非常高(误差几乎为零),但是不能推广到其他未知数据上,也就是对于训练集之外的输入不能做出正确的预测。
第5章 模型
155
PDF 物理页索引 172
文件中的第 173 页 · 印刷页码:156
防止过拟合是机器学习中极其重要的一个问题,重要到后文几乎所有模型讲解中都会提到并给出防止过拟合的方法,可以说如果没有处理好过拟合,我们就会全盘皆输。过拟合是绝对值得我们花相当一部分时间去处理的。
5.5.2 过拟合的处理方法
当过拟合发生时,我们的模型对训练集数据的预测效果很好,但对测试集数据的预测效果较差。这是因为模型过于关注训练集的局部特征,从而记住了样本集的噪声,而这些噪声并不是数据分布的真实规律,所以出现了训练集和测试集准确率相差较大的情况。无论多优秀的模型,如果我们不去防止,都可能出现过拟合。通常有以下几种办法来处理过拟合问题。
(1)使用更多训练数据
引入更多训练数据通常会降低过拟合。训练数据的增加总是会为机器学习带来正面的作用,降低过拟合就是最大的好处之一。数据量越大,意味着模型训练得到的参数方差越小,模型越稳定,因此会降低数据集发生变化时模型效果的波动,从而降低过拟合。
虽然增大训练数据量是“首选”,但很多时候获得更多数据是很困难的。如果无法引入更多数据,我们仍然可以尝试这两种方法:第一种,将数据集中更多的数据用作训练数据,即加大训练集所占的比例;第二种,通过数据集增强(DataAugmentation)的方式从原始数据集中“获得”更多虚拟数据,如通过将原始图片旋转、镜像及色彩变换等技巧生成更多图片用作训练。
(2) 使用正则化
正则化是降低过拟合的一个主要技巧。正则化是通过改变误差(损失)函数,在误差函数原有的基础上加入惩罚项。惩罚项和参数的大小直接相关,当我们使用过多的参数时,这个惩罚项会变得很大,从而可以防止模型过于复杂。常见的正则化方法包括L1和L2正则化。有关这两种正则化方法会在后面的章节进行详细介绍。加入L1和L2惩罚项可以让部分参数值急剧变小或变成0,以达到“压缩”参数个数的作用。
(3) Early Stopping
EarlyStopping是指在迭代过程中提前结束迭代,从而防止过度训练的手段。训练时间过长,模型会越来越倾向于记住样本集的全部内容,而这会导致过拟合的发生。因此,我们可以在迭代训练的过程中随时观察误差(损失)函数的变化情况,如果发现在一段时间后模型效果没有显著提升,就停止训练。针对神经网络更多过拟合的解决方法也会在后面的章节系统性的介绍。
(4)使用集成算法
集成算法是指将多个简单模型进行平均的系统性方法。假设我们有10个模型,这10个模型单独运作都容易发生过拟合,但这10个模型平均之后则会降低过拟合的影响。就好比评委打分,1个人的打分经常是不稳定的,多个人投票或者取均值则会让评分变得更加公正、靠谱。
人工智能与大数据技术导论
156
PDF 物理页索引 173
文件中的第 174 页 · 印刷页码:157
这里读者可以先记住一句话来代表集成算法的思想,叫作“众人拾柴火焰高”。集成算法可以将多个基础算法结合在一起,并把“集体”的力量发挥到最大。
(5)减少特征的数量
减少特征的数量包括人工手动减少特征的数量和使用模型选择算法,我们会在后面的章节中讲到。
5.6 模型的评估与改进
通过上节的学习,我们知道为了防止过拟合,需要有效地利用验证集来选择表现最好的模型。我们顺着这个思路进入本节的学习:通过验证集评价、选取和改进模型。
5.6.1 机器学习模型的评估
要评价一个机器学习模型的表现,我们需要一个具体的指标来评估。一个确实的量化指标对我们评价和选择模型具有重要的参考意义。对于回归模型来说,常用的指标为MSE、MAE等,对于分类模型,常用指标包括准确率、精确率、召回率、F1-Score、ROC曲线和AUC等。下面我们来详细介绍这些概念。
- 分类模型的评估
绝大多数分类任务都是二分类任务(binary classificationproblem),即类别只有两种:0或1。对于一个二分类问题来说,根据预测值和真实值分类,无外乎出现表5-5所示的4种情况。
对于分类问题,最直观也是最简单的评价指标就是准确率(Accuracy),即样本中有多大比例被我们预测正确。准确率等于预测正确的样本数除以总样本数,即(TP+TN)/(TP+TN+FP+FN)。相对应的一个概念是错误率(Error/MisclassificationRate),或者叫误差率,是指我们预测错误的样本数所占的比例,误差率=1-准确率。
使用准确率或误差率作为评价指标的时候,意味着我们将两种分类类别平等对待。但现实中我们遇到的二分类任务中,通常两种分类类别并不像“性别为男或女”这样的对等关系,而是有正负之分。我们将某件事情发生、具有肯定性结果对应为类别1,或称为具有正值,比如药检呈阳性、天气预报会下雨、信用贷款会违约等。与之相对应的分类结果归为类别0,即事件未发生、具有否定性的结果。
当我们要差别对待类别0和类别1时,就需要懂得精确率、召回率等概念,这也是我们引
第5章 模型
157
PDF 物理页索引 174
文件中的第 175 页 · 印刷页码:158
入表5-5的原因。
精确率(Precision)的定义是所有我们预测为正的样本中确实为正值的比率。
$$
\frac { 1 } { 1 } \overrightarrow { A } _ { \vert A \vert } \overrightarrow { A } _ { \vert A } ^ { \vert } = \mathrm { T P / ( T P + F P ) }
$$
召回率(Recall)是指所有真实值为正的样本中被我们预测为正值的比率。
$$
\stackrel { \triangledown } { \scriptscriptstyle \perp } \left[ \boldsymbol { \mathrm { H } } \right] \stackrel { \scriptscriptstyle - 2 \vec { \alpha } } { \scriptscriptstyle + \cdot } = \mathrm { T P } / ( \mathrm { T P + F N } )
$$
F1-Score综合考虑精确率与召回率,等于二者的调和平均值,定义如下:
$$
\mathrm { F l - S c o r e } = 2 ^ { * } \mathrm { p r e c i s i o n ^ { * } r e c a l l / ( p r e c i s i o n + r e c a l l ) }
$$
精确率和准确率看似只在分母上有细微差别,其实表达的意思截然不同,它们反映了分类器性能的两个方面。之所以有两个概念,是因为不同问题中我们关注的侧重点不同。我们来看以下两个场景。
(1) 罪犯追踪
在人脸识别罪犯的案例中,通常我们会秉着“不错怪任何好人”的原则,希望我们识别出来的“罪犯”确实全部是真的罪犯。因此,我们要让精确率尽可能高,判断出的正值不能有失误。虽然这样做可能会使得一些嫌犯“逃脱”,但仍然是这个任务中可以接受的结果,总比错将好人当作犯人产生不必要的麻烦要好得多。
(2) 地震检测
对于地震的预测则恰恰相反,我们希望当地震真实发生时我们能预测出来,宁可100次误报95次,将5次地震全部预测到,而不要只预测10次,结果漏掉5次中的2次。在这个情形中,我们希望召回率越高越好,哪怕牺牲一定的精确率。
- 回归模型的拟合效果评估
相比分类模型,回归模型的评价指标则比较简单,最常使用的指标就是前面提到的MSE。回忆一下,MSE是估计值与真实值之差的平方和取均值再开平方根,用来量化预测值和真实值的偏离程度。除了MSE之外,有时也会用MAE(Mean AbsoluteError,平均绝对误差)。MAE是估计值与真实值之差的绝对值取均值。MAE看起来似乎比MSE更直观,但远不及MSE常用。这主要是因为MSE作为误差(损失)函数是可导的,方便通过求导来找最小值。
- 其他评价指标
除了衡量模型的准确度外,有时我们还需要关注计算能力相关的一些指标,比如运行时间、占用内存等。这些指标虽然重要,但通常不会作为优化的对象,而是作为一种“条件指标”进行约束,在该约束下使得我们要优化的指标(准确度)尽可能好。
5.6.2 机器学习算法与人类比较
随着机器学习越来越普及,人们逐渐开始将机器学习和人类的表现作比较。机器学习算法和人类的比较也成为越来越多机器学习学者研究的课题。这是因为最近几年随着机器学习算法变得越来越先进,特别是深度学习的兴起,机器学习在面临更多领域问题的时候表现出很高的可行性,并且可以和人类相提并论。比如拿图像识别来说,机器识别一个物体,给我们的感觉就像用人眼识别一样,几乎所有人类能辨识出来的东西机器也能办到,并具有和人类不相上下的准确率。同时,在建立机器学习系统时,通常通过高度机动性的工作流来实现,这比人类手工完成要高效得多。
人工智能与大数据技术导论
158
PDF 物理页索引 175
文件中的第 176 页 · 印刷页码:159
那么,机器学习和人类在做同一个任务时到底谁的准确率更高呢?事实上,目前机器学习之所以被广泛应用,正是因为它会表现得比人类更加优秀。理论和实践都证明,机器学习的准确率随着不断训练和改进会逐渐提升直至超过人类水平,但一旦越过人类水平,提升的速度将会显著放缓,直到达到一个“瓶颈”。这一“瓶颈”叫作“贝叶斯最优误差(BayesError)”,是这个任务准确率的理论最优值,无论用任何方式都无法超过这个水平。这个最优值会比人类水平稍高一点点,但通常达不到100%。比如在语音识别领域,由于语音中客观存在一定比率的噪声,所以无论是人类还是机器,都无法准确地听出这部分内容是什么,所以“最优准确率”并不是100%。
5.6.3 改进策略
只要机器学习算法准确率比人类水平低,我们就可以用以下策略来改进。
(1)使用更多人为标注的标签数据。
(2)手动进行误差分析。
(3)进行效果更好的bias-variance分析。
关于第三种策略,我们能够进行更好的bias-variance分析,是因为我们能够通过对比人类误差,决定改进的方向降低偏差还是降低方差。假设在一个识别猫的任务中,人类的误差率是0.5%,我们把这个误差近似看成“贝叶斯最优误差”。我们模型的训练误差是6%,而DevError是8%。训练误差和人类误差之间还有一定距离,说明我们应将重点放在降低误差的策略上,比如使用更高级的神经网络,或者训练更长时间。
假设另有一个难度较高的识别任务,比如识别一种具体的稀有猫科动物,在这项任务中,人类的误差率是5.5%。而假定我们模型的训练误差率仍为6%,DevError也依然为8%。训练误差与人类误差之间的差距仅有0.5%。在这种情况下,降低偏差的提升空间很小,因为我们很难把误差率降到5.5%以下。反而训练误差和DevError之间2%的间隔相对比较大,此时我们应该侧重于降低方差,而不是偏差。也就是说,我们应该尝试更多的防止过拟合的方法,比如采用正则化、使用更多训练数据等。
第5章 模型
159
PDF 物理页索引 176
文件中的第 177 页 · 印刷页码:160
以上三种改进方法,当机器学习算法准确率超过人类时都将无法实现。所以从人类水平到理论最优值,这一段路要比之前难走得多。
5.7 机器学习的实现框架
大数据、算法和并行计算能力构成了人工智能高速发展的三要素,海量的数据积累是基础。开源的机器学习平台能够让开发者将复杂的数据传输给已有的框架进行分析和处理,缩短了开发时间,提升了训练效果,极大地推动了AI技术的商业化进程。在本节中,我们将介绍两个用于AI开发的语言、框架和库。
5.7.1 Python
Python是数据科学家最常用的编程语言之一,也是机器学习的首选工具。这是因为Python内置了很多实用的library,很方便直接拿来用于解决机器学习的实际问题,后面要介绍的scikit-learn就是其中之一。
不熟悉编程的朋友们可能对library的概念不了解。我们知道,Python是写代码的工具,而library实际上就是预先写好的代码,可以直接用于应用,省去重复编写代码的过程。Library翻译成中文通常叫作“包”,调用library被称为“调包”。在Python中,数据科学家常用的library 如表 5-6所示。
对于初次接触编程或者Python的读者,我们推荐下载Anaconda。Anaconda集成了Python基本环境和上述所有常见包,安装方便,非常适合初学者使用。读者只需从Anaconda官网上免费下载其最新版本,就可以编写Python程序。本书中所有实例代码都可以在AnacondaPython中实现。
在Anaconda上,我们可以选择Spyder 进行代码的编写。Spyder是Python 的一款 IDE。如同其他编程语言一样,Python在编写代码时需要一个集成开发环境,IDE就是集成开发环境的缩写,它给用户提供了编程需要的图形化界面、编辑器、编译器、调试器等。打开Spyder,就可以看到输入代码的界面。
人工智能与大数据技术导论
160
PDF 物理页索引 177
文件中的第 178 页 · 印刷页码:161
5.7.2 scikit-learn
编写机器学习模型不容易,但使用机器学习模型非常简单,读者只需套用现有的框架即可。现有的框架可以是某种编程环境中的程序包,或者一款成熟的机器学习商业软件。scikit-learn是一个针对机器学习的强大Python库,主要用于构建模型,使用诸如Numpy、SciPy和Matplotlib等库构建,如图5-9所示,对于统计建模技术(如分类、回归、集群等)非常有效。scikit-learn的特性包括监督式学习算法、非监督式学习算法和交叉验证,官网地址是http://scikit-learn.org/。scikit-learn的优点是可以使用许多shell算法,提供高效的数据挖掘;缺点是不是最好的模型构建库,GPU使用不高效。
Python中有完备的机器学习库sklearn,它整合了现有的众多传统的机器学习模型,这些模型的算法已经在程序包中编写好,用户无须知道算法的原理,也无须懂得模型的含义,甚至无须会编程,即可调用程序包,执行并得到我们需要的结果。整个过程不过只是几行代码,就像把大象放到冰箱一样,只需三步。下面我们以Python为例,来看看它如何解决机器学习经典案例titanic沉船生存预测,如表5-7所示。
第5章 模型
161
PDF 物理页索引 178
文件中的第 179 页 · 印刷页码:162
人工智能与大数据技术导论
162
PDF 物理页索引 179
文件中的第 180 页 · 印刷页码:163
对于不熟悉模型的人,只需记住这几行代码,就可以完整地跑出这个模型。代码中并没有多少需要理解的部分或者需要预先掌握的知识,基本都是sklearn的预设格式。实际上,sklearn可以用于绝大多数传统机器学习模型,并且只需在这几行代码上稍作改动。
5.7.3 Spark MLlib
Apache的 Spark MLlib是一个具有高度拓展性的机器学习库,在Java、Scala、Python甚至R语言中都非常有用,因为它使用Python和R中类似NumPy这样的库,能够进行高效的交互。MLlib可以很容易地插入Hadoop工作流程中。它提供了机器学习算法,如分类、回归、聚类等。这个强大的库在处理大规模的数据时,速度非常快。SparkMLlib的官网地址是 https://spark.apache.org/mllib/。
SparkMLlib的优点是,对于大规模数据处理来说,非常快,可用于多种语言;缺点是,陡峭的学习曲线,仅Hadoop支持即插即用。
第5章 模型
163