38-机器学习40讲

开篇词 | 打通修炼机器学习的任督二脉

你好，我是王天一，我在“机器学习 40 讲”欢迎你的到来！

在上一季的专栏中，我与你一起走马观花地浏览了学习人工智能所需要的基础数学、当前流行的深度学习、以及其他可能实现智能的技术路径。广义的人工智能概念可以说包罗万象，其中每一个细分的子领域发展到今天都值得大书特书。40 篇文章的篇幅绘出的人工智能轮廓就像是一幅低分辨率的全景画，覆盖广度的同时必然难以兼顾深度。

正因如此，新一季的专栏内容将聚焦于人工智能大问题里的一个小目标——机器学习。在新进展层出不穷的今日，机器学习依然占据着人工智能的核心地位，迅猛的发展势头也让现在的机器学习领域充斥着各种听起来狂拽酷炫的新玩意儿。但阳光之下再无新事，再炫目的技术归根结底都是基本模型与方法在具体领域问题上的组合，而理解这些基本模型与方法才是掌握机器学习，也是掌握任何一门学问的要义所在。

既然机器学习领域的文献论著已经汗牛充栋，这个专栏和它们的区别又在哪里呢？在我看来，是融会贯通的系统性。不少关于机器学习的文献虽然深入阐释了不同模型的原理，但对它们之间的关联却缺少清晰的解释，从而使内容的组织流于模型展览，仿佛一串没能串成项链的珍珠宝石。实际上，所有模型就像龙生九子一样，都是从基本模型出发，根据不同改进方法衍生出来。所以，这个专栏最重要的任务就是帮助你把握不同模型之间的内在关联，让你形成观察机器学习的宏观视角，找准进一步理解与创新的方向。

在内容上，“机器学习”分为 3 个模块。

第一个模块是机器学习概观，介绍机器学习中超脱于具体模型和方法之上的一些共性问题，将从概率的两大派别开始。众所周知，概率在机器学习中扮演着核心角色，而频率学派与贝叶斯学派对概率迥异的认知也将机器学习一分为二，发展出两套完全不同的理论体系。正所谓兼听则明偏听则暗，理解机器学习时应该看到这同一枚硬币的两面，以获得完整的认知。除此之外，本模块还涵盖了计算学习等机器学习的理论问题，以及关于模型和特征的一些实验主题。

第二个模块将讨论频率学派发展出的机器学习理论——统计学习。统计机器学习的核心是数据，它既从数据中来，利用不同的模型去拟合数据背后的规律；也到数据中去，用拟合出的规律去推断和预测未知的结果。统计学习中最基础的模型是线性回归，几乎所有其他模型都是从不同角度对线性回归模型做出的扩展与修正。因此，在这个模块中，我将以线性模型为主线，和你一起浏览它的万千变化，观察从简单线性回归到复杂深度网络的发展历程。

第三个模块将讨论贝叶斯学派发展出的机器学习理论——符号学习，也就是概率图模型。和基于数据的统计学习相比，基于关系的图模型更多地代表了因果推理的发展方向。贝叶斯主义也需要计算待学习对象的概率分布，但它利用的不是海量的具体数据，而是变量之间的相关关系、每个变量的先验分布和大量复杂的积分技巧。在这个模块中，我将围绕概率图模型中的表示、推断、学习三大问题展开介绍，认识贝叶斯面纱下的机器学习。

除了理论之外，在介绍模型时我还会穿插一些基于 Python 语言的简单实例以加强理解。这些实例会应用诸如 Scikit-Learn 和 PyMC 等比较成熟的第三方库，通过调用现成的类来实现不同模型的功能。Python 语言的一大优势就是功能丰富又强大的第三方库，将它们束之高阁未免暴殄天物。在快速实现的基础上再进一步深入钻研核心代码，也是比较合理的学习路径。

理解机器学习绝不是简单地了解几个时髦概念，而是要将前沿和基础融会贯通，从中发现贯穿学科发展的脉络。这个专栏不是乾坤大挪移这种水平的内功心法，但如果能打通你修炼机器学习的任督二脉，它的价值就实现了。

我已做好准备，在接下来的三个多月里，和你分享我所理解的机器学习。也请你告诉我，你为什么要学习机器学习？你希望通过这个专栏得到哪些收获呢？

与君共勉！

01 | 频率视角下的机器学习

在“人工智能基础课”中我曾提到，“概率”（probability）这个基本概念存在着两种解读方式，它们分别对应着概率的频率学派（Frequentist）和贝叶斯学派（Bayesian）。而解读方式上的差异也延伸到了以概率为基础的其他学科，尤其是机器学习之中。

根据机器学习领域的元老汤姆·米切尔（Tom M. Mitchell）的定义，机器学习（machine learning）是一门研究通过计算的手段利用经验来改善系统自身性能的学科。

现如今，几乎所有的经验都以数据的形式出现，因而机器学习的任务也就变成了基于已知数据构造概率模型，反过来再运用概率模型对未知数据进行预测与分析。如此一来，关于概率的不同认识无疑会影响到对模型的构建与解释。

可在概率的应用上，频率学派和贝叶斯学派的思路呈现出天壤之别，这种思维上的差异也让两派的拥护者势同水火，都视另一方为异端邪说。正因如此，在这个专栏的前两篇文章中，我将首先和你理清频率学派与贝叶斯学派对概率的不同观点，为接下来从不同的角度理解机器学习的各种算法打下扎实的基础。

下面这个流传已久的笑话，不经意间对频率学派和贝叶斯学派的区别给出了形象的解释：有个病人找医生看病，医生检查之后对他说：“你这病说得上是九死一生，但多亏到我这里来看了。不瞒你说，在你之前我已经看了九个得一同样病的患者，结果他们都死了，那你这第十个就一定能看得好啦，妥妥的！”

如果病人脑子没事，肯定就从这个糊涂医生那里跑了。显然，医生在看待概率时秉持的是频率主义的观点，但却是个蹩脚的频率主义者。之所以说他是频率主义者，是因为他对九死一生的理解就是十次手术九次失败一次成功；说他蹩脚则是因为他不懂频率学派的基础，区区九个病人就让他自以为掌握了生死的密码。

归根到底，频率学派口中的概率表示的是事件发生频率的极限值，它只有在无限次的独立重复试验之下才有绝对的精确意义。在上面的例子中，如果非要从频率的角度解释“九死一生”的话，这个 10% 的概率只有在样本容量为无穷大时才有意义。因此即使“九死一生”的概率的确存在，它也不能确保第十个病人的康复。

在频率学派眼中，当重复试验的次数趋近于无穷大时，事件发生的频率会收敛到真实的概率之上。这种观点背后暗含了一个前提，那就是概率是一个确定的值，并不会受单次观察结果的影响。

将一枚均匀的硬币抛掷 10 次，结果可能是 10 次都是正面，也可能 10 次都是反面，写成频率的话就对应着 0% 和 100% 这两个极端，代表着最大范围的波动。可如果将抛掷次数增加到 100 次，出现正面的次数依然会发生变化，但波动的范围更可能会收缩到 40% 到 60% 之间。再将抛掷次数增加到 1000，10000 的话，频率波动的现象不会消失，但波动的范围会进一步收缩到越来越小的区间之内。

基于以上的逻辑，把根据频率计算概率的过程反转过来，就是频率统计估计参数的过程。频率统计理论的核心在于认定待估计的参数是固定不变的常量，讨论参数的概率分布是没有意义的；而用来估计参数的数据是随机的变量，每个数据都是参数支配下一次独立重复试验的结果。由于参数本身是确定的，那频率的波动就并非来源于参数本身的不确定性，而是由有限次观察造成的干扰而导致。

这可以从两个角度来解释：一方面，根据这些不精确的数据就可以对未知参数的精确取值做出有效的推断；另一方面，数据中包含的只是关于参数不完全的信息，所以从样本估计整体就必然会产生误差。

统计学的核⼼任务之一是根据从总体中抽取出的样本，也就是数据来估计未知的总体参数。参数的最优估计可以通过样本数据的分布，也就是采样分布（sampling distribution）来求解，由于频率统计将数据看作随机变量，所以计算采样分布是没有问题的。确定采样分布之后，参数估计可以等效成一个最优化的问题，而频率统计最常使用的最优化方法，就是最大似然估计（maximum likelihood estimation）。

回忆一下最大似然估计，它的目标是让似然概率最大化，也就是固定参数的前提之下，数据出现的条件概率最大化。这是频率学派估计参数的基本出发点：一组数据之所以能够在单次试验中出现，是因为它出现的可能性最大。而参数估计的过程就是赋予观测数据最大似然概率的过程。这可以通过下面这个简单的例子来说明：

“如果观测到的数据 θiθi 是真实值 θθ 和方差为 σ2σ2，但形式未知的噪声 eiei 的叠加，那么如何得出 θθ 的最优估计值？”

要用最大似然估计解决这个问题，首先就要对似然概率进行建模，建模中的一个重要假设是假定未知形式的噪声满足高斯分布。这不仅在统计学中，在其他学科里也是一个常用的假设。

从理论上说，在功率有限的条件下，高斯噪声的信源熵最大，因而带来的不确定性也就越大，换句话说，这是最恶劣的噪声；从实践上说，真实的噪声通常来源于多个独立的物理过程，都具有不同的概率分布，中心极限定理告诉我们，当噪声源的数目越来越多时，它们的叠加就趋近于高斯分布，因而高斯噪声就是对真实情况的一个合理的模拟。

在高斯噪声的假设下，每个观测数据 θiθi 所满足的概率分布就可以写成

p(θi|θ)=12πσ2−−−−√exp[−(θi−θ)22σ2]p(θi|θ)=12πσ2exp⁡[−(θi−θ)22σ2]

这实际上就是采样分布。计算所有数据的概率分布的乘积，得到的就是似然函数（likelihood function）

L(θ|θ)=∏i=1Np(θi|θ)L(θ|θ)=∏i=1Np(θi|θ)

求解似然函数的对数，就可以将乘法运算转换为加法运算

logL=−12∑i=1N[log(2πσ2)+(θi−θ)22σ2]log⁡L=−12∑i=1N[log⁡(2πσ2)+(θi−θ)22σ2]

令对数似然函数的导数为 0，就求出了使似然概率最大的最优估计

θ^=1N∑i=1Nθiθ^=1N∑i=1Nθi

不知道你有没有在上面的公式中发现一个问题：虽然真实值 θθ 是个固定值，但估计值 θ^θ^ 却是数据的函数，因而也是个随机变量。

这一点其实很好理解，因为估计值本质上是利用数据构造出来的函数，既然数据是随机分布的，估计值肯定也是随机的。这意味着如果每次估计使用的数据不同，得到的估计值也不会相同。那么如何来度量作为随机变量的估计值和作为客观常量的真实值之间的偏差呢？置信区间（confidence interval）就是频率学派给出的答案。

置信区间的意义在于划定了真值的取值范围，真实的参数会以一定的概率 αα 落入根据样本计算出的置信区间之内。当然，这里的概率还是要从频率的角度来解读：从同一个总体中进行 100 次采样可以得到 100 个不同的样本，根据这 100 个不同的样本又可以计算出 100 个不同的置信区间。在这么多个置信区间之中，包含真值的有多少个呢？100×α100×α 个，剩下的 100×(1−α)100×(1−α) 个置信区间就把真值漏掉了。这有点像乱枪打鸟：每一枪都乱打一梭子，打了 100 枪之后统计战果，发现打下来 100×α100×α 只鸟。如果把参数的真实值比喻成鸟，那么每一枪轰出的一梭子子弹就是置信区间。显然，置信区间的上下界和估计值一样，也是随机变量。

总结起来，频率主义解决统计问题的基本思路如下：参数是确定的，数据是随机的，利用随机的数据推断确定的参数，得到的结果也是随机的。

这种思路直接把可能的参数空间压缩成为一个点：参数本身可能满足这样或者那样的概率分布，但一旦试验的条件确定，参数表现出来的就是一个固定的取值，让所有的概率分布都失去了意义。这就像说即使上帝真的掷骰子，但从骰子脱手那一刻起，它的点数就不再受上帝的控制，也就变成了确定不变的取值。频率主义者关注的就是这个真实存在的唯一参数，通过计算它对数据的影响来实现估计。

将频率主义“参数确定，数据随机”的思路应用在机器学习当中，得到的就是统计机器学习（statistical learning）。统计机器学习的做法是通过对给定的指标（比如似然函数或者均方误差）进行最优化，来估计模型中参数的取值，估计时并不考虑参数的不确定性，也就是不考虑未知参数的先验分布。和参数相关的信息全部来源于数据，输出的则是未知参数唯一的估计结果，这是统计机器学习的核心特征。

受噪声和干扰的影响，观测数据并不是未知参数的准确反映，因此如何衡量估计结果的精确程度就成为统计机器学习中的一个关键问题。损失函数（loss function）直接定义了模型性能的度量方式，其数学期望被称为风险（risk），风险最小化就是参数估计的依据和准则。但风险的计算并不能一蹴而就：估计最优参数需要计算风险，计算风险时需要在数据的概率分布上对损失函数进行积分，可表示数据的分布又需要依赖未知参数的精确取值。这就给频率主义出了一个无解的问题：风险函数是没有办法精确求解的。

为了解决这个问题，统计机器学习引入了经验风险（empirical risk），用训练数据的经验分布替换掉原始表达式中数据的真实分布，借此将风险函数转化成了可计算的数值。在真实的学习算法中，无论是分类问题中的误分类率，还是回归问题的中的均方误差，都是经验风险的实例，而所谓的最优模型也就是使经验风险最小化（empirical risk minimization）的那个模型。

今天我和你分享了频率学派对概率、统计学和机器学习的认识方式，其要点如下：

频率学派认为概率是随机事件发生频率的极限值；

频率学派执行参数估计时，视参数为确定取值，视数据为随机变量；

频率学派主要使用最大似然估计法，让数据在给定参数下的似然概率最大化；

频率学派对应机器学习中的统计学习，以经验风险最小化作为模型选择的准则。

有了这些理论之后，如何在实际问题中应用频率主义的统计学呢？这里有一个非常好的例子，来源于 Nature Biotechnology 第 22 卷第 9 期上的论文《什么是贝叶斯统计学》（What is Bayesian statistics）。

在这个例子中，Alice 和 Bob 在进行一场赌局，先得到 6 分者获胜。判断得分的方式有一些特别：在赌局开始之前，荷官在赌桌上扔一个小球，在这个球停止的位置做个标记。显然，这个标记的位置是随机的。赌局开始后，荷官继续扔球，如果球停到标记的左侧，则 Alice 得分；反之停到标记右侧，则 Bob 得分，这就是赌局的计分规则。那么问题来了：在这样的规则下，Alice 现在以 5:3 领先 Bob，那么 Bob 反败为胜的概率是多大呢？

要计算 Bob 获胜的概率，必须要借助一个参数，那就是 Alice 得分的概率，不妨将它设为 pp，那么 Bob 得分的概率就是 1−p1−p。概率 pp 取决于标记在赌桌上的位置，由于位置本身是随机的，pp 也就在 [0, 1] 上满足均匀分布。按照频率主义的观点，在这一场赌局中，pp 有固定的取值，并可以通过已有的得分结果来估计。估计出 pp 后就可以进一步计算 Bob 获胜的概率。这个问题就作为今天的思考题目，你可以计算一下。

但是，这个问题并没有到此为止。如果跳出频率主义的限制，把 pp 的概率分布引入到计算之中，又会得到什么样的结果呢？

请加以思考并发表你的观点。

02 | 贝叶斯视角下的机器学习

在上一篇文章中，我向你介绍了频率学派对概率、统计和机器学习的理解。今天则要转换视角，看一看贝叶斯学派解决这些问题的思路。

还记得那个“九死一生”的例子吗？对其中 90% 的概率更直观、也更合理的解释是生病之后生还的可能性。之所以说频率主义的解释牵强，是因为没有哪个人能倒霉到三番五次地得这个病。当多次独立重复试验不可能实现时，就不存在从频率角度解读概率的理论基础。

虽然上面的这个例子不见得严谨，却可以用来描述频率学派的问题：对于所有的“一锤子买卖”，也就是不包含随机变量的事件来说，频率学派对概率的解读都是不成立的。

为了解决频率主义的问题，贝叶斯学派给出了一种更加通用的概率定义：概率表示的是客观上事件的可信程度（degree of belief），也可以说成是主观上主体对事件的信任程度，它是建立在对事件的已有知识基础上的。

比方说，当一个球迷提出“明天皇家马德里战胜拉斯帕尔马斯的概率是 86%”的时候，可以理解成他对皇马获胜有 86% 的把握程度，要是买球的话自然就会在独胜上下出重注（其实贝叶斯概率正是来源于对赌博的分析）。

除了对概率的置信度解释之外，贝叶斯学派中的另一个核心内容是贝叶斯定理（Bayes' theorem），用来解决“逆向概率问题”（inverse probability problem）。

听名字就知道，逆向概率和前向概率是对应的：假定数据由一个生成模型给出，前向概率是在已知生成过程的前提下来计算数据的概率分布和数字特征，逆向概率则是在已知数据的前提下反过来计算生成过程的未知特性。贝叶斯定理的数学表达式可以写成

P(H|D)=P(D|H)⋅P(H)P(D)P(H|D)=P(D|H)⋅P(H)P(D)

式中的 P(H)P(H) 被称为先验概率（prior probability）；P(D|H)P(D|H) 被称为似然概率（likelihood probability）；P(H|D)P(H|D) 被称为后验概率（posterior probability）。

抛开乱七八糟的符号，贝叶斯定理同样可以从贝叶斯概率的角度加以解读：所谓先验概率是指根据以往经验和分析得到的概率，可以视为假设 H 初始的可信程度；与假设 H 相关的数据 D 会作为证据出现，将数据纳入考虑范围后，假设 H 的可信程度要么会增强要么会削弱。但不管增强还是削弱，得到的结果都是经过数据验证的假设的可信程度，这就是后验概率。

贝叶斯定理的意义正是在于将先验概率和后验概率关联起来，刻画了数据对于知识和信念的影响。

纳粹德国的宣传部长保罗·约瑟夫·戈培尔有句名言：“如果你说的谎言范围够大，并且不断重复，人民终会开始相信它。”从贝叶斯定理的角度看，这句话是有科学依据的空穴来风。本来谎言的先验概率 p(lie)p(lie)，也就是初始的可信度接近于 0，而 p(lie¯)=1−p(lie)p(lie¯)=1−p(lie) 接近于 1。可问题的关键在于似然概率——戈培尔这句话的核心是被宣传对象对将谎言说成真理的宣传的信任。宣传对象相信宣传者不说假话，意味着似然概率 p(brainwash|lie)p(brainwash|lie) 较大，同时 p(brainwash|lie¯)p(brainwash|lie¯) 较小。这样一来，经过宣传之后，谎言成立的后验概率就可以写成

p(lie|brainwash)=p(lie)⋅p(brainwash|lie)p(lie)⋅p(brainwash|lie)+p(lie¯)⋅p(brainwash|lie¯)p(lie|brainwash)=p(lie)⋅p(brainwash|lie)p(lie)⋅p(brainwash|lie)+p(lie¯)⋅p(brainwash|lie¯)

稍作分析就不难发现，只要 p(brainwash|lie)>0.5p(brainwash|lie)>0.5，谎言的后验概率就会大于先验概率。更重要的是，本次宣传得到的后验概率 (lie|brainwash)(lie|brainwash) 将作为下次宣传的先验概率 p(lie)p(lie) 出现。于是，在后验概率与先验概率不断迭代更新的过程中，p(lie|brainwash)p(lie|brainwash) 将持续上升，谎言也就越来越接近真理了。

将贝叶斯定理应用到统计推断中，就是贝叶斯主义的统计学。频率统计理论的核⼼在于认定待估计的参数是固定不变的常量，⽽⽤来估计的数据是随机的变量。贝叶斯统计则恰恰相反：它将待估计的参数视为随机变量，用来估计的数据反过来是确定的常数，讨论观测数据的概率分布才是没有意义的。贝叶斯统计的任务就是根据这些确定的观测数据反过来推断未知参数的概率分布。

相对于频率主义的最大似然估计，贝叶斯主义在参数估计中倾向于使后验概率最大化，使用最大后验概率估计（maximum a posteriori estimation）。

频率学派认为观测数据之所以会出现是因为它出现的概率最大，因此最可能的参数就是以最大概率生成这一组训练数据的参数。最大后验估计则是将频率学派中“参数”和“数据”的角色做了个调换：参数本身是随机变量（服从先验分布），有许多可能的取值，而不同取值生成这一组观测数据（服从似然分布）也是不同的。因而最大后验概率推断的过程就是结合参数自身的分布特性，找到最可能产生观测数据的那个参数的过程。

贝叶斯定理告诉我们，后验概率正比于先验概率和似然概率的乘积，这意味着后验概率实质上就是用先验概率对似然概率做了个加权处理。频率主义将参数看成常量，那么似然概率就足以描述参数和数据之间的关系。贝叶斯主义则将参数看成变量，因此参数自身的特性也会影响到参数和数据之间的关系。先验概率的作用可以用下面的例子来说明（本例来自 David JC MacKay, Information Theory, Inference, and Learning Algorithms, Example 2.3）

“Jo 去进行某种疾病的检查。令随机变量 aa 表示 Jo 的真实健康状况，a=1a=1 表示 Jo 生病，a=0a=0 表示 Jo 没病；令随机变量 bb 表示 Jo 的检查结果，b=1b=1 表示阳性，b=0b=0 表示阴性。已知检查的准确率是 95%，也就是此病患者的检查结果 95% 会出现阳性，非此病患者的检查结果 95% 会出现阴性，同时在 Jo 的类似人群中，此病的发病率是 1%。如果 Jo 的检查结果呈阳性，那么她患病的概率是多大呢？"

直观理解，“检查的准确率是 95%”似乎说明了 Jo 患病的概率就是 95%，可事实真是这样吗？根据贝叶斯定理，患病概率可以写成

p(a=1|b=1)=p(b=1|a=1)⋅p(a=1)p(b=1|a=1)⋅p(a=1)+p(b=1|a=0)⋅p(a=0)p(a=1|b=1)=p(b=1|a=1)⋅p(a=1)p(b=1|a=1)⋅p(a=1)+p(b=1|a=0)⋅p(a=0)

式中的 p(b=1|a=1)=0.95p(b=1|a=1)=0.95 就是似然概率，p(a=1)=0.01p(a=1)=0.01 则是先验概率。不难求出，Jo 患病的真正概率，也就是后验概率只有 16%!

为什么会出现这样的情况呢？对于频率学派来说，Jo 要么生病要么没病，概率的推演是在这两个确定的前提下分别进行的，所以似然概率就足以说明问题。可是阳性检查结果既有真阳性也有假阳性，两者的比例是不同的。虽然真阳性基本意味着生病，但由于先验概率较小（1%），它在所有的阳性结果中依然是少数（16%）。相比之下，假阳性结果凭借其比较大的先验概率（99%），占据了阳性结果的大部分（84%）。这个例子说明抛开先验概率谈论似然概率，是没有多少说服力的。

不难看出，先验信息在贝叶斯统计中占据着相当重要的地位。可问题在于先验信息从哪里来？

先验信息是在使用数据之前关于分析对象的已有知识，可当这种已有知识并不存在时，就不能对先验做出合理的建模。事实上，指定先验分布的必要性正是贝叶斯学派被频率学派的诟病之处，因为先验分布不可避免地会受到主观因素的影响，这与统计学立足客观的出发点背道而驰。这中间的哲学思辨在此不做探讨，你只需要知道即使包含某些主观判断，先验信息也是贝叶斯主义中不可或缺的核心要素。

当已有的知识实在不足以形成先验信息时，贝叶斯主义的处理方式是引入无信息先验（noninformative prior），认为未知参数取到所有取值的可能性都是相等的，也就是满足均匀分布。由于此时的先验概率是个常数，这个先验概率也被称为平坦先验（flat prior）。在平坦先验之下，最大后验估计和最大似然估计是等效的。

不知道你还记不记得上一篇文章末尾的例子？如果从频率主义出发，可以用最大似然估计求出 Alice 得分的概率 p^=5/8p^=5/8，而 Bob 赢得赌局的概率就是他连得三分的概率 (1−p^)3≈0.0527(1−p^)3≈0.0527。

可是在贝叶斯主义看来，事情并没有这么简单，因为已有的投球结果并不能给出关于得分位置的可靠信息，5:3 的领先可能意味着 Alice 有较大的得分概率，也可能意味着 Bob 虽有有较大的得分概率却走了背字。因而在贝叶斯学派看来，处理未知参数 pp 的方式不应该是武断地把它看成一个常数，而是应该从变量的角度去观察，考虑它在 [0, 1] 上所有可能的取值，再计算在所有可能的取值下 Bob 获胜概率的数学期望，从而消除 pp 的不确定性对结果的影响。

在这样的思想下，Bob 获胜的概率就可以写成

E=∫01(1−p)3P(p|A=5,B=3)dpE=∫01(1−p)3P(p|A=5,B=3)dp

利用贝叶斯定理可以将上式中的条件概率写成

P(p|A=5,B=3)=P(A=5,B=3|p)P(p)∫01P(A=5,B=3|p)P(p)dpP(p|A=5,B=3)=P(A=5,B=3|p)P(p)∫01P(A=5,B=3|p)P(p)dp

在这个式子中，先验概率 P(p)P(p) 是在观察到数据之前 pp 的分布，因而是未知的。但由于 pp 服从均匀分布，所以是个常数，也就不会对 P(p|A=5,B=3)P(p|A=5,B=3) 产生影响。另一方面，P(A=5,B=3|p)P(A=5,B=3|p) 可以用二项分布计算，其数值等于 8!/(5!3!)p5(1−p)38!/(5!3!)p5(1−p)3。将这一结果代入 EE 的表达式，可以得到

E=∫01p5(1−p)6dp∫01p5(1−p)3dp=0.0909E=∫01p5(1−p)6dp∫01p5(1−p)3dp=0.0909

显然，这与最大似然估计得到的结果是不同的。但这个结果却符合频率主义的阐释：如果用蒙特卡洛法（Monte Carlo method）进行数值仿真的话，你会发现这个 0.0909 才是符合真实情况的概率。

将贝叶斯定理应用到机器学习之中，完成模型预测和选择的任务，就是贝叶斯视角下的机器学习。由于贝叶斯定理大量涉及各种显式变量与隐藏变量的依赖关系，通常用概率图模型来直观地描述。贝叶斯主义将未知参数视为随机变量，参数在学习之前的不确定性由先验概率描述，学习之后的不确定性则由后验概率描述，这中间不确定性的消除就是机器学习的作用。

与频率主义不同的是，贝叶斯学习的输出不是简单的最优估计值 θ^θ^，而是关于参数的概率分布 p(θ)p(θ)，从而给出了更加完整的信息。在预测问题中，贝叶斯学习给出的也不仅仅是一个可能性最大的结果，而是将所有结果及其概率以概率分布的形式完整地呈现出来。

除了在预测中提供更加完备的信息之外，贝叶斯学习在模型选择上也有它的优势。在贝叶斯主义看来，所谓不同的模型其实就是不同概率分布的参数化表示，使用的参数也有它们自己的先验分布，但所有模型的共同点是它们都能生成训练数据集，而模型选择的任务就是从这些概率分布中挑出一个最好的。

这里的“好”的标准就是数据和模型的符合程度，也叫可信度（model evidence）。可信度实际上就是归一化的似然函数 p(D|M)p(D|M)，表示的是模型 MM 生成数据 DD 的条件概率。当不同复杂度模型的经验风险接近的时候，就可以利用可信度来筛选模型了。

既然贝叶斯主义能够提供更加完整的信息，为什么迟迟没有取代频率主义成为主流呢？这就不得不说贝叶斯方法的缺点了：一是对未知变量的积分运算会导致极高的计算复杂度（computation complexity），这从 Alice 和 Bob 打赌的例子中就可以看出；二是对先验分布的设定（prior specification）包含一定的主观性，因而一直不招老派的统计学家待见。正是这两个原因限制了贝叶斯方法的广泛应用。

今天我和你分享了贝叶斯学派对概率、统计学和机器学习的认识方式，其要点如下：

贝叶斯学派认为概率是事件的可信程度或主体对事件的信任程度；

贝叶斯学派执行参数估计时，视参数为随机变量，视数据为确定取值；

贝叶斯学派主要使用最大后验概率法，让参数在先验信息和给定数据下的后验概率最大化；

贝叶斯学派对应机器学习中的概率图模型，可以在模型预测和选择中提供更加完整的信息。

在这两篇文章中，我和你探讨了频率主义和贝叶斯主义这两个解决概率问题的基本思路，它们也是以后理解不同机器学习方法的基础。虽然两种观点各执一词，争论得不可开交，但两者更像是一枚硬币的两面，在思想方法上没有根本性的对立，各种频率主义下的统计学习方法也可以通过贝叶斯来解释。将两种方法论融会贯通才是理解机器学习的正确思路。

最后再回到 Alice 和 Bob 赌局的例子，基于贝叶斯主义的方法得到了符合频率学派解释的结果，基于频率主义的最大似然估计反而做出了错误的判断，那么你是怎么看待频率学派的错误呢？

欢迎发表你的观点。

03 | 学什么与怎么学

男孩还是女孩？这是个问题！

在中国人的生活中，生男生女可谓兹事体大，多少幸福与烦恼都因此而起。那么有没有办法提前做出准确的预测呢？当然有啦！通常在怀孕 4 个月时，胎儿的性别就可以通过 B 超得到准确的判断了，所以只要问一问医生轻松搞定。但是出于职业道德和执业法规的要求，医生一般是不会透露胎儿性别的。想要在怀孕的早期判断，终归还是要依赖祖辈流传下来的经验。

可祖辈的经验多了去了，流传最广的可能就是“酸儿辣女”：如果准妈妈突然爱喝柠檬水说明怀了个男孩；突然爱吃老干妈就说明怀了个女孩。可实际上，“酸儿辣女”只是一种互文的说法，表达的是怀孕对饮食口味的影响，想要以此为据预测胎儿的性别纯属无稽之谈。相比之下，另一条经验还更靠谱一些：准妈妈的肚子如果是尖形，则胎儿很可能是个男孩；肚子是圆形的话就更可能是个女孩。至少在我个人的生活经验之中，这条规则的准确率超过了 80%。

剥去所有的伦理道德外延，所谓的“生男生女”完全可以看成一个纯粹的科学问题。虽然说胎儿性别不可能以决定性的方式影响母体的物理特征，但终究会有一定的参考价值。通俗说就是虽说男孩肚子尖女孩肚子圆一定不会以 100% 的概率发生，但 70% 的置信度恐怕还是有的，这相比于纯属瞎猜的对半概率就是个不小的进步，也就意味着肚子形状的特征提供了一定的信息。除此之外，胎儿性别还可能对母体的其他变化产生一些不起眼但确实存在的影响，比如说民间流传的脚部浮肿或者肚脐突出，这些变化都可以作为预测胎儿性别的特征来看待。

除了肉眼可见的物理特征外，更精确的特征是医学上的定量指标。相关的具体信息在这里我就不班门弄斧了。但可以确定的是，胎儿的性别势必会对母体的内分泌特性产生不同的影响，从而在指标上体现出不同趋势的变化。而这些怀孕早期的指标变化反过来又可以为倒推胎儿性别提供有力的证据，从而实现“生男还是生女”的预测。

那么问题来了，能不能通过机器学习来解决这个问题呢？

能不能用机器学习来解决，要从下面这几个角度来分析。首先，预测胎儿的性别不是预测婴儿的活动，没人能知道婴儿的下一声啼哭会发生在什么时候，即使你知道他的血压肺活量脉搏等所有的生理指标，还是没有办法去预测。但胎儿的性别不一样，它可以体现出一些切实的规律，也就是某些特征会表现出固定的变化趋势，蕴含着明显的规律性，这种规律性被称为“模式”（pattern）。

机器学习能够解决的问题必然会包含某些显式或者隐式的模式，没有模式的问题就不能通过机器学习解决。完全随机的问题是不可能被求解，也不可能被学习的，就像我们永远也没法预测示波器下一时刻的本底噪声一样。

一提到模式，你可能会一下子联系到另一个专业词汇——模式识别（pattern recognition）。模式识别和机器学习实际上有大量的共通之处，严格地将两者区分开来既没方法也没必要。如果非要找到些不同的话，模式识别是被更广泛地应用在计算机视觉（computer vision）等专门领域之中的专门概念，工程上的意义更浓一些。如果说机器学习侧重于将预先设定的准确率等指标最大化，那模式识别就更注重于潜在模式的提取与解释。

是不是有潜在模式的问题都能够被机器所学习呢？也不尽然。流体力学的研究之中有不少复杂困难的问题，但机器学习也没有成为这个学科的主流方法，这意味着机器学习并不适用于易编程问题的解释。一个具有解析解的问题是完全不需要机器学习的。即使一个一次方程组中有一万个方程，每个方程中又有一万个未知数，这个看似复杂的问题本质上也无非就是个矩阵求逆，只是矩阵的规模比较大而已。如果将机器学习运用到这种问题上，那就是杀鸡用牛刀了。

退一步讲，即使问题本身没有解析解，要是能够通过数值计算的方法解决，而不涉及明显的优化过程的话，也无需机器学习的使用。在流体力学中，仿真是最常用的研究方法，大量的参数与繁冗的边界条件给计算带来了超高的复杂度。但在这样的问题中，机器学习即使被应用，可能也不会发挥出良好的效果，因为这在本质上依然是对等式方程的求解。就像“能用钱解决的问题都不是问题“一样，能用纯计算解决的问题也不是（需要先进方法的）问题。

回到“生男还是生女”这个例子，你可能听说过所谓的“清宫图”——一个依据孕妇年龄和怀孕月份预测生育的表格。可是如果生男生女真的能靠简单的查表操作解决的话，它怎么会直到今天还困扰着为人父母的年轻人呢？正是因为这个问题没有那么简单，机器学习才有大展拳脚的用武之地。

最后，用机器学习解决问题还需要一个条件，就是大量的可用数据（data）。没有数据支撑的机器学习方法就是巧妇难为无米之炊。这是由于问题中的模式可不会像秃子头上的虱子那么明显，一方面，输出结果会受到多个输入特征的共同影响，另一方面，特征与特征之间通常也不是完全独立的，而是存在着相互作用。因此，要精确地描绘出输入与输入、输入与输出之间的定量关系，大量的数据是不可或缺的。

总结起来，什么样的问题才能通过机器学习来解决呢？首先，问题不能是完全随机的，需要具备一定的模式；其次，问题本身不能通过纯计算的方法解决；再次，有大量的数据可供使用。对于满足这三个条件的问题，机器学习的过程就可以用下图来表示

﻿﻿机器学习的过程

（图片来自 Yaser S. Abu-Mostafa, et al., Learning from Data A Short Course, 图 1.9）

在这张图中，目标函数不是通常意义上的正确率等指标，而是指问题的模式，也就是机器学习要发现的对象。这里的目标函数并不具备简单的解析式形式，不能精确求解，只能从不同的角度去近似。近似的方式是什么呢？针对训练数据的特点做出各种不同的假设（线性模型、多项式模型 ⋯⋯），再在假设空间（hypothesis space）或者假设集合（hypothesis set）中找到与数据的符合度最高的假设——寻找最佳假设的过程就是学习的过程。机器学习的任务，就是使用数据计算出与目标函数最接近的假设，或者说拟合出最精确的模型 。

在不同的机器学习任务中，无论是数据类型还是学习方式都会有所区别，由此就可以从不同的角度对机器学习加以简单的分类。

还是以“生男生女”为例，如果真的要依据医学指标进行预测的话，那么输入的特征可能既包括像 hcg 激素水平这样有明确意义的数字指标，也可能是 B 超图像这类需要进一步提取转化的原始资料，甚至还可能包括身份证号和病历编号这类每个人独有的信息。

在机器学习中，这三类特征分别被命名为具体特征（concrete feature）、原始特征（raw feature）和抽象特征（abstract feature），在解决实际问题时，具体特征可以直接使用，原始特征通常需要转换成具体特征，抽象特征就需要根据实际情况加以取舍。

看完了输入特征，再来看看输出结果。在第一季“人工智能基础课”中我曾提到，根据输出结果的不同，可以将机器学习的方法分成分类算法（classification）、回归算法（regression）和标注算法（tagging）三类。

显然，“生男生女”是个典型的二分类问题（binary classification），分类的结果只有两种，要么正类要么负类。二分类问题是最基础，也是最核心的分类问题，可以在它的基础上进一步解决多分类问题的求解。

如果训练数据中的每组输入都有其对应的输出结果，这类学习任务就是监督学习（supervised learning），对没有输出的数据进行学习则是无监督学习（unsupervised learning）。监督学习具有更好的预测精度，无监督学习则可以发现数据中隐含的结构特性，起到的也是分类的作用，只不过没有给每个类别赋予标签而已。无监督学习可以用于对数据进行聚类或者密度估计，也可以完成异常检测这类监督学习中的预处理操作。直观地看，监督学习适用于预测任务，无监督学习适用于描述任务。

最后，不同算法的学习策略也有差异。大部分算法是集中处理所有的数据，也就是一口气对整个数据集进行建模与学习，并得到最佳假设。这种策略被称为批量学习（batch learning）。和批量学习相对应的是在线学习（online learning）。在在线学习中，数据是以细水长流的方式一点点使用，算法也会根据数据的不断馈入而动态地更新。当存储和计算力不足以完成大规模的批量学习时，在线学习不失为一种现实的策略。

在学校中，老师可以通过将学生代入学习过程，引导学生主动提问来加强学习效果。这种策略应用在机器学习中就是主动学习（active learning）。主动学习是策略导向的学习策略，通过有选择地询问无标签数据的标签来实现迭代式的学习。当数据的标签的获取难度较高时，这种方法尤其适用。

今天我和你分享了机器学习所解决的问题特点，以及学习中使用的不同策略，其要点如下：

机器学习适用于解决蕴含潜在规律的问题；

纯算数问题无需使用机器学习；

机器学习需要大量数据来发现潜在规律；

从输入空间、输出空间、数据标签、学习策略等角度可以对机器学习进行分类。

最后要说明的是，本文中所使用的“生男生女”一例，其作用仅限于解释机器学习这一概念，并无任何其他寓意。如有有意设计算法解决此问题者，一切衍生后果请自行承担（笑）。

机器学习、模式识别、数据挖掘（data mining）、甚至人工智能，这些概念经常被视为等同，不做区分地加以使用。可是它们真的一样吗？希望你能自己研究每个概念的内涵与外延，深入理解它们的区别和联系。

欢迎发表你的观点。

04 | 计算学习理论

无论是频率学派的方法还是贝叶斯学派的方法，解决的都是怎么学的问题。但对一个给定的问题到底能够学到什么程度，还需要专门的计算学习理论（computational learning theory）来解释。与机器学习中的各类具体算法相比，这部分内容会略显抽象。

学习的目的不是验证已知，而是探索未知，人类和机器都是如此。对于机器学习来说，如果不能通过算法获得存在于训练集之外的信息，学习任务在这样的问题上就是不可行的。

下图就是来自于加州理工大学教授亚瑟·阿布 - 穆斯塔法（Yaser S. Abu-Mostafa）的课程 Learning from Data 中的一个例子：假设输入 xx 是个包含三个特征的三维向量，输出 yy 则是二元的分类结果，训练集中包含着五个训练数据，学习的任务是预测剩下的三个测试数据对应的分类结果。

学习任务示意图（图片来自 Yaser S. Abu-Mostafa, et. al., Learning from Data）

横线上方为训练数据，下方为待估计的分类结果，f1f1~f8f8 代表所有可能的映射关系。

预测三个二分类的输出，总共就有 23=823=8 种可能的结果，如上图所示。可在这穷举出来的 8 个结果里，到底哪个是符合真实情况的呢？遗憾的是，单单根据这 5 个输入数据其实是没有办法确定最适合的输出结果的。输出结果为黑点可能对应所有只有 1 个特征为 1 的输入数据（此时三个测试数据的结果应该全是白点）；也可能对应所有奇偶校验和为奇数的输入数据（此时三个测试数据的结果应该是两白一黑）；或者还有其他的潜在规律。关于这个问题唯一确定的结果就是不确定性：不管生成机制到底如何，训练数据都没有给出足以决定最优假设的信息。

既然找不到对测试数据具有更好分类结果的假设，那机器学习还学个什么劲呢？别忘了，我们还有概率这个工具，可以对不同假设做出定量描述。虽然不能对每个特定问题给出最优解，但概率理论可以用来指导通用学习问题的求解，从而给出一些基本原则。

不妨想象一下这个问题：一个袋子里有红球和白球，所占比例分别是 μμ 和 1−μ1−μ。在这里，作为总体参数的 μμ 是个未知量，其估计方法就是从袋子里抽出若干个球作为样本，样本中的红球比例 νν 是可以计算的，也是对未知参数 μμ 最直接的估计。

但是，用 νν 来近似 μμ 有多高的精确度呢？

直观看来，两者的取值应该相差无几，相差较大的情况虽然不是不可能发生，但是希望渺茫。在真实值 μ=0.9μ=0.9 时，如果从袋子中抽出 10 个球，你可以利用二项分布来计算一下 ν≤0.1ν≤0.1 的概率，由此观察 νν 和 μμ 相差较大的可能性。

直观的印象之所以准确，是因为背后存在科学依据。在概率论中，有界的独立随机变量的求和结果与求和数学期望的偏离程度存在一个固定的上界，这一关系可以用 Hoeffding 不等式（Hoeffding's Inequality）来表示。在前面的红球白球问题中，Hoeffding 不等式可以表示为

P[|ν−μ|>ϵ]≤2e−2ϵ2NP[|ν−μ|>ϵ]≤2e−2ϵ2N

这个式子里的 ϵϵ 是任意大于 0 的常数，NN 是样本容量，也就是抽出的球的数目。

Hoeffding 不等式能够说明很多问题。首先，它说明用随机变量 νν 来估计未知参数 μμ 时，虽然前者的概率分布在一定程度上取决于后者，但估计的精度只和样本容量 NN 有关；其次，它说明要想提高估计的精度，最本质的方法还是增加样本容量，也就是多采一些数据，当总体的所有数据都被采样时，估计值也就完全等于真实值了。反过来说，只要样本的容量足够大，估计值与真实值的差值将会以较大的概率被限定在较小的常数 ϵϵ 之内。

红球白球的问题稍做推广，就是对机器学习的描述。把装球的袋子看成数据集，里面的每个球就都是一个样本，球的颜色则代表待评估的模型在不同样本上的表现：红球表示模型输出和真实输出不同；白球表示模型输出和真实输出相同。这样一来，抽出来的所有小球就表示了训练数据集，真实值 μμ 可以理解成模型符合实际情况的概率，估计值 νν 则表示了模型在训练集上的错误概率。

经过这样的推广，Hoeffding 不等式就变成了对单个模型在训练集上的错误概率和在所有数据上的错误概率之间关系的描述，也就是训练误差和泛化误差的关系。它说明总会存在一个足够大的样本容量 NN 使两者近似相等，这时就可以根据模型的训练误差来推导其泛化误差，从而获得关于真实情况的一些信息。当训练误差 νν 接近于 0 时，与之接近的泛化误差 μμ 也会接近于 0，据此可以推断出模型在整个的输入空间内都能够以较大的概率逼近真实情况。可如果小概率事件真的发生，泛化误差远大于训练误差，那只能说是运气太差了。

按照上面的思路，让模型取得较小的泛化误差可以分成两步：一是让训练误差足够小，二是让泛化误差和训练误差足够接近。正是这种思路催生了机器学习中的“概率近似正确”（Probably Approximately Correct, PAC）学习理论，它是一套用来对机器学习进行数学分析的理论框架。在这个框架下，机器学习利用训练集来选择出的模型很可能（对应名称中的“概率”）具有较低的泛化误差（对应名称中的“近似正确”）。

如果观察PAC 可学习性（PAC learnable）的数学定义（这里出于可读性的考虑没有给出，大部分机器学习教材里都会有这个定义），你会发现其中包含两个描述近似程度的参数。描述“近似正确”的是准确度参数 ϵϵ，它将模型的误差水平，也就是所选模型和实际情况之间的距离限制在较小的范围内；描述“概率”的是置信参数 δδ，由于训练集是随机生成的，所以学好模型只是以 1−δ1−δ 出现的大概率事件，而并非 100% 发生的必然事件。

如果问题是可学习的，那需要多少训练数据才能达到给定的准确度参数和置信参数呢？这要用样本复杂度来表示。样本复杂度（sample complexity）是保证一个概率近似正确解所需要的样本数量。可以证明，所有假设空间有限的问题都是 PAC 可学习的，其样本复杂度有固定的下界，输出假设的泛化误差会随着样本数目的增加以一定速度收敛到 0。

但是在现实的学习任务中，并非所有问题的假设空间都是有限的，像实数域上的所有区间、高维空间内的所有超平面都属于无限假设空间。如何判断具有无限假设空间的问题是否是 PAC 可学习的呢？这时就需要 VC 维登场了。VC 维（Vapnik-Chervonenkis dimension）的名称来源于统计学习理论的两位先驱名字的首字母，它是对无限假设空间复杂度的一种度量方式，也可以用于给出模型泛化误差在概率意义上的上界。

想象一下，如果要对 3 个样本进行二分类的话，总共有 23=823=8 种可能的分类结果。当所有样本都是正例或都是负例时，是不需要进行区分的；可当样本中既有正例又有负例时，就需要将两者区分开来，让所有正例位于空间的一个区域，所有负例位于空间的另一个区域。区域的划分方式是由模型来决定，如果对于 8 种分类结果中的每一个，都能找到一个模型能将其中的正负例完全区分，那就说明由这些模型构成的假设空间就可以将数据集打散（shatter）。

数据集打散示意图（图片来自维基百科）

上图就是一个利用线性模型打散容量为 3 的数据集的例子。其实对于 3 个数据来说，所有对分类结果的划分本质上都是把其中的某两个点和另外一个区分开来，而完成这个任务只需要一条直线，而无需更加复杂的形状。可以证明，线性模型可以对任何 3 个不共线的点进行划分，也就是将这个数据集打散。

可是一旦数据集的容量增加到 4，线性模型就没法把它打散了。容量为 4 的数据集总共有 16 种类别划分的可能，但线性模型只能区分开其中的 14 种，不能区分开的是什么呢？就是异或问题的两种情况，也就是红色图示中的特例。要将位于对角线位置的正例和负例区分开来，要么用一条曲线，要么用两条直线，单单一条直线是肯定做不到的。

在打散的基础上可以进一步定义 VC 维。假设空间的 VC 维是能被这个假设空间打散的最大集合的大小，它表示的是完全正确分类的最大能力。上面的例子告诉我们，对于具有两个自由度的线性模型来说，它最多能打散容量为 3 的集合，其 VC 维也就等于 3。如果假设空间能打散任意容量的数据集，那它的 VC 维就是无穷大了。一个具有无穷 VC 维的假设空间是 y=sin(kx)y=sin(kx)，你可以思考一下这背后的原因。

从可学习性的角度来看，一旦假设空间的 VC 维有限，就可以通过调整样本复杂度来使训练误差以任意的精度逼近泛化误差，使泛化误差和训练误差足够接近。这个性质取决于模型的特性，与学习方法、目标函数、数据分布都没有关系，因而是通用的。从这个结论出发就可以得到，任何 VC 维有限的假设空间都是 PAC 可学习的。

在维度有限的前提下，VC 维的大小也会影响模型的特性。较小的 VC 维虽然能够让训练误差和泛化误差更加接近，但这样的假设空间不具备较强的表达能力（想想上面线性模型的例子），训练误差本身难以降低。反过来，VC 维更大的假设空间表达能力更强，得到的训练误差也会更小，但训练误差下降所付出的代价是训练误差和泛化误差之间更可能出现较大的差异，训练集上较小的误差不能推广到未知数据上。这其实也体现了模型复杂度和泛化性能之间的折中关系。

由于 VC 维并不依赖于数据分布的先验信息，因此它得到的结果是个松散的误差界（error bound），这个误差界适用于任意分布的数据。要是将数据的分布特性纳入可学习性的框架，复杂性的指标就变成了Rademacher 复杂度（Rademacher complexity）。

函数空间的经验 Rademacher 复杂度（empirical Rademacher complexity）描述函数空间和随机噪声在给定数据集上的相关性，这里的随机噪声以 Rademacher 变量（Rademacher variable）的形式出现，它以各 50% 的概率取 ±1±1 这两个值。如果存在多个数据集，而每个数据集中的数据都是对同一个概率分布的独立重复采样，那么对每个数据集的经验 Rademacher 复杂度求解数学期望。得到的就是“没有经验的”Rademacher 复杂度，它表示了函数空间在给定的数据分布上拟合噪声的性能。

看到这里你可能不明白了，学得好好的为什么要去拟合噪声呢？其实引入 Rademacher 复杂度的初衷是刻画训练误差和泛化误差之间的区别。泛化误差是没办法计算的，只能想方设法地去近似，而交叉验证就是最常用的近似手段。如果将容量为 mm 数据集等分成训练集 S1S1 和验证集 S2S2，那训练误差与泛化误差之差就可以写成

ES1(h)−ES2(h)=2m[∑xi∈S1e(h,xi)−∑xi∈S2e(h,xi)]ES1(h)−ES2(h)=2m[∑xi∈S1e(h,xi)−∑xi∈S2e(h,xi)]

其中 hh 表示待评价的假设。显然，当 xixi 落入 S1S1 时，损失函数 e(⋅)e(⋅) 的系数为 1；当 xixi 落入 S2S2 时，损失函数 e(⋅)e(⋅) 的系数为 -1。如果用随机变量 σiσi 对 ±1±1 的系数进行建模的话，上面的式子就可以改写称

ES1(h)−ES2(h)=2m[∑iσie(h,xi)]ES1(h)−ES2(h)=2m[∑iσie(h,xi)]

如果把 σiσi 看成 Rademacher 变量，那这个式子就是 Rademacher 复杂度。到这儿就不难理解 Rademacher 复杂度的含义了。在已知的数据分布下，Rademacher 复杂度既可以表示函数空间的复杂度，也可以用来计算泛化误差界，其数学细节在这儿就不做介绍了。

今天我和你分享了计算学习理论的一些最主要的概念，并没有深入数学细节。这是评估机器学习的理论基础，也是机器学习理论研究的主要对象，其要点如下：

Hoeffding 不等式描述了训练误差和泛化误差之间的近似关系；

PAC 学习理论的核心在于学习出来的模型会以较大概率接近于最优模型；

假设空间的 VC 维是对无限假设空间复杂度的度量，体现了复杂性和性能的折中；

Rademacher 复杂度是结合了先验信息的对函数空间复杂度的度量。

和各种具体的模型相比，计算学习理论充斥着各种各样的抽象推导，其内容也显得比较枯燥无味。那么关于学习理论的研究对解决实际问题到底具有什么样的指导意义呢？

欢迎发表你的观点。

05 | 模型的分类方式

机器学习学的是输入和输出之间的映射关系，学到的映射会以模型的形式出现。从今天开始，我将和你聊聊关于模型的一些主题。

大多数情况下，机器学习的任务是求解输入输出单独或者共同符合的概率分布，或者拟合输入输出之间的数量关系。从数据的角度看，如果待求解的概率分布或者数量关系可以用一组有限且固定数目的参数完全刻画，求出的模型就是参数模型（parametric model）；反过来，不满足这个条件的模型就是非参数模型（non-parametric model）。

参数模型的优点在于只用少量参数就完整地描述出数据的概率特性，参数集中的每个参数都具有明确的统计意义。你可以回忆一下常用的典型概率分布，离散变量的二项分布 B(n,p)B(n,p) 只包含两个参数，分别代表独立重复试验的次数和每次试验中事件发生的概率；连续变量的正态分布 N(μ,σ)N(μ,σ) 也是只包含两个参数，分别代表着随机变量的均值和方差。所以在参数模型的学习中，算法的任务就是求出这些决定概率特性的参数，只要参数确定了，数据的统计分布也就确定了，即使未知的数据无穷无尽，我们也可以通过几个简单的参数来确定它们的性质。

为什么在参数模型中，有限的参数就能够描述无限的数据呢？想必你已经发现，这样的便捷来自于超强的先验假设：所有数据符合特定类型的概率分布。在实际的学习任务中，我们并非对问题一无所知，通常会具有一定的先验知识。先验知识并不源于对数据的观察，而是先于数据存在，参数模型恰恰就是先验知识的体现与应用。

先验知识会假定数据满足特定的先验分布，学习的过程就是利用训练数据估计未知参数的过程，一旦得出未知参数的估计结果，训练数据就完成了它的历史使命，因为这些估计出来的参数就是训练数据的浓缩。在这个过程中，先验知识确定了假设空间的取值范围，学习算法（比如最大似然估计或是最大后验概率估计）则在给定的范围内求解最优化问题。

参数模型虽然简单实用，但其可用性却严重依赖于先验知识的可信度，也就是先验分布的准确程度。如果说训练数据和测试数据确实满足二项分布或者正态分布，那么学习算法只需付出较小的计算代价就可以从假设空间中习得一个较好的模型。可如果先验分布本身就不符合实际，那么不管训练数据集的体量多大，学习算法的性能多强，学习出来的结果都会与事实真相南辕北辙，背道而驰。

先贤孔子早在两千年前就告诉了我们一个朴素的道理：“知之为知之，不知为不知，是知也。”当对所要学习的问题知之甚少的时候，不懂装懂地搞些先验分布往数据上生搬硬套就不是合理的选择，最好的办法反而是避免对潜在模型做出过多的假设。这类不使用先验信息，完全依赖数据进行学习得到的模型就是非参数模型。

需要注意的是，“非参数模型”不是“无参数模型”，恰恰相反，非参数模型意味着模型参数的数目是不固定的，并且极有可能是无穷大，这决定了非参数模型不可能像参数模型那样用固定且有限数目的参数来完全刻画。在非参数模型中不存在关于数据潜在模式和结构化特性的任何假设，数据的所有统计特性都来源于数据本身，一切都是“所见即所得”。和参数相比，非参数模型的时空复杂度都会比参数模型大得多。但可以证明的是，当训练数据趋于无穷多时，非参数模型可以逼近任意复杂的真实模型，这给其实用性添加了一枚重量级的筹码。

参数模型和非参数模型的区别可以通过下面这个实例来简单地体现：假定一个训练集中有 99 个数据，其均值为 100，方差为 1。那么对于第 100 个数据来说，它会以 99% 的概率小于哪一个数值呢？

使用参数模型解决这个问题时，可以假设所有数据都来自于同一个正态分布 N(μ,σ)N(μ,σ)。利用训练数据构造关于正态分布均值和标准差的无偏估计量，可以得到相应的估计值 μ^=100,σ^=1μ^=100,σ^=1。如此就不难计算出，新数据会以 99% 的概率小于 102.365，其意义是均值加上 2.365 倍的标准差，这就是参数模型计算出的结果。

可是对于非参数模型而言，它并不关心这些数据到底是来源于正态分布还是指数分布还是均匀分布，只是做出所有数据来源于同一个分布这个最基础的假设。在这个假设之上，99 个训练数据和 1 个测试数据是一视同仁的。如果把它们视为一个整体，那么在测试之前，所有数据的最大值可能是其中的任何一个。正因如此，测试数据有 1% 的可能性比之前的 99 个都要好，也就是有 99% 的可能性小于训练数据中的最大值。

归根结底，非参数模型其实可以理解为一种局部模型，就像战国时代每个诸侯国都有自己的国君一样，每个局部都有支配特性的参数。在局部上，相似的输入会得到相似的输出，而全局的分布就是所有局部分布的叠加。相比之下，参数模型具有全局的特性，所有数据都满足统一的全局分布，这就像履至尊而制六合得到的扁平化结构，一组全局分布的参数支配着所有的数据。

从数据分布的角度看，不同的模型可以划分为参数模型和非参数模型两类。如果将这个划分标准套用到模型构造上的话，得到的结果就是数据模型（data model）和算法模型（algorithm model）。相比于参数对数据分布的刻画，这种分类方式更加侧重于模型对数据的拟合能力和预测能力。

2001 年，著名的统计学家莱奥·布雷曼（Leo Breiman）在《统计科学》（Statistical Science）的第 16 卷第 3 期发表了论文《统计模型：两种思路》（Statistical Modeling: The Two Cultures），提出了数据模型和算法模型的区分方法。

作为一个统计学家，布雷曼看重的是学习算法从数据中获取有用结论和展示数据规律的能力。从这一点出发，他将从输入 xx 到输出 yy 的关系看成黑盒，数据模型认为这个黑盒里装着一组未知的参数 θθ，学习的对象是这组参数；算法模型则认为这个黑盒里装着一个未知的映射 f()˙f()˙，学习的对象也是这个映射。

不难看出，数据模型和算法模型实际上就是另一个版本的参数模型和非参数模型。数据模型和参数模型类似，都是通过调整大小和颜色把一件固定款式的衣服往模特身上套，即使给高大威猛的男模套上裙子也没关系——没见过苏格兰人吗？算法模型和非参数模型则是调了个个儿，充分发挥量体裁衣的精神，目标就是给模特穿上最合身的衣服，至于红配绿或是腰宽肩窄什么的都不在话下——只要穿着舒服，还要什么自行车？

如果说参数模型与非参数模型的核心区别在于数据分布特征的整体性与局部性，那么数据模型和算法模型之间的矛盾就是模型的可解释性与精确性的矛盾，这可以通过两种模型的典型代表来解释。

数据模型最典型的方法就是线性回归，也就是将输出结果表示为输入特征的线性加权组合，算法通过训练数据来学习权重系数。线性回归的含义明确而清晰的含义：输入数据每个单位的变化对输出都会产生同步的影响，影响的程度取决于这个特征的权重系数，不同特征对结果的贡献一目了然。

可问题是，如何确定输入与输出之间真实的对应关系是否满足特定的假设呢？当某个数据模型被以先验的方式确定后，学习的对象就不再是输入输出之间的作用机制，而是这个数据模型本身。绝大部分数据模型都有简明的解释方式，可如果简单模型不能充分体现出复杂作用机制（比如医学数据或经济数据）时，它的预测精度就会不堪入目。这种情况下，再漂亮的解释又有什么意义呢？

处在可解释性的坐标轴另一端的是大名鼎鼎的随机森林算法，这是个典型的算法模型，其原创者正是前文所提到的布雷曼。随机森林是一种集成学习方法，构成这座森林的每一颗树都是决策树，每一棵决策树都用随机选取数据和待选特征构造出来，再按照少数服从多数的原则从所有决策树的结果中得到最终输出。

决策树本身是具有较好可解释性的数据模型，它表示的是几何意义上对特征空间的划分，但是精确度却不甚理想。随机森林解决了这个问题：通过综合使用建立在同一个数据集上的不同决策树达到出人意料的良好效果，在很多问题上都将精确度提升了数倍。但精确度的提升换来的是可解释性的下降。每个决策树对特征空间的单独划分共同织成一张剪不断理还乱的巨网，想要理解这张巨网背后的语义无异于水中望月、雾里看花。

从学习方法上看，上面提到的两种划分方式具有相同的本质。此外，还有另一种针对学习对象的划分方式，那就是生成模型和判别模型之分。简单地说，生成模型（generative model）学习的对象是输入 xx 和输出 yy 的联合分布 p(x,y)p(x,y)，判别模型学习的则是已知输入 xx 的条件下，输出 yy 的条件分布 p(y|x)p(y|x)。两个分布可以通过贝叶斯定理建立联系。

生成模型和判别模型的区别可以这样来理解：假如我被分配了一个任务，要判断一个陌生人说的是什么语言。如果用生成模型来解决的话，我就需要把这个老外可能说的所有语言都学会，再根据他的话来判定语言的种类。但可能等我学完这些语言时，这个陌生人都说不出话了。可是用判别模型就简单多了，我只需要掌握不同语言的区别就足够了。即使不会西班牙语或者德语的任何一个单词，单凭语感也可以区分出这两种语言，这就是判别模型的优势。

针对生成模型和判别模型的利弊，支持向量机的奠基者弗拉基米尔·瓦普尼克（Vladimir Vapnik）有句名言：“（解决分类问题）应该直截了当，不要用兜圈子的方式，搞一个更难的问题（比如求解似然概率）做为中间步骤”。一般来说，生成模型的求解更加复杂，当数据量趋于无穷大时，渐进条件下的精确性也更差，但其收敛的速度更快，在较少数据的训练后就可以收敛到错误的下界。相比之下，判别模型的形式更加简单，在分类问题上的表现也更出色，却不能提供关于数据生成机制的信息。有些情况下，生成模型和判别模型会成对出现。例如在分类问题中，朴素贝叶斯和逻辑回归就是一对生成 - 判别分类器。

今天我和你分享了对机器学习模型不同的分类方法，其要点如下：

不同的学习思路对应假设空间中不同的建模方式与学习方法；

参数模型和非参数模型的区别体现的是全局普适性和局部适用性的区别；

数据模型和算法模型的区别体现的是可解释性和精确性的区别；

生成模型和判别模型的区别体现的是联合分布和条件分布的区别。

当下，参数模型还是机器学习的主流，非参数模型无论在应用范围上还是性能表现上都要略逊一筹。可随着大数据概念的出现，更多更复杂的数据无疑会给参数的拟合带来更大的挑战。在这样的背景下，非参数模型有没有可能发挥更大的作用呢？

欢迎发表你的看法。

06 | 模型的设计准则

上学时你一定过学习新知识的经历：首先要结合老师的讲解进行消化理解，接着要做些练习题找到问题并加强巩固，最后通过考试来检验学习的最终效果。机器学习需要根据问题特点和已有数据确定具有最强解释性或预测力的模型，其过程也可以划分为类似于“学习 - 练习 - 考试”这样的三个阶段，每个阶段的目标和使用的资源可以归纳如下：

模型拟合（model fitting）：利用训练数据集（training set）对模型的普通参数进行拟合；

模型选择（model selection）：利用验证数据集（validation set）对模型的超参数进行调整，筛选出性能最好的模型；

模型评价（model assessment）：利用测试数据集（test set）来估计筛选出的模型在未知数据上的真实性能。

接下来的三篇文章将分别围绕模型处理这三个阶段展开论述，首先将从模型拟合开始。

虽然模型拟合的任务是计算未知的参数，但它还要解决一个更重要的问题，就是在拟合参数前确定模型的形式，或者说到底要拟合哪些参数。模型拟合本身只是简单的数学问题，交给计算机就可以万事大吉，可模型设计却颇有门道，涉及到更多的思考：一方面，模型的合理性很大程度上取决于待解决问题本身的特征；另一方面，模型的复杂度也要和问题的复杂度相匹配。在机器学习中，对这两个基本准则的理解催生了两个基本的规律，分别是无免费午餐定理和奥卡姆剃刀原则。

“天下没有免费的午餐”是人尽皆知的俗语，这朴素的道理在机器学习中同样适用。通俗地说，无免费午餐（No Free Lunch, NFL）定理证明了任何模型在所有问题上的性能都是相同的，其总误差和模型本身是没有关系的。

这样的结论好像有些反直觉：既然大家谁都不比谁好，那关于机器学习算法和模型不计其数的研究又有什么意义呢？其实这种想法误解了 NFL 定理的一个核心前提，也就是每种问题出现的概率是均等的，每个模型用于解决所有问题时，其平均意义上的性能是一样的。

所有模型在等概率出现的问题上都有同样的性能，这件事可以从两个角度来理解：一是从模型的角度来看，如果单独拿出一个特定的模型来观察的话，这个模型必然会在解决某些问题时误差较小，而在解决另一些问题时误差较大；二是从问题的角度来看，如果单独拿出一个特定的问题来观察的话，必然有某些模型在解决这些问题时具有较高的精度，而另一些模型的精度就没那么理想了。

如果把不同模型看成一个班级里的不同学生，不同问题看成考试时的不同科目，NFL 定理说的就是在这个班里，所有学生期末考试的总成绩都是一样的，既然总成绩一样，每一科的平均分自然也是一样的。这一方面说明了每个学生都有偏科，数学好的语文差，语文好的数学差，如果数学语文都好，那么英语肯定更差；另一方面也说明了每个科目的试题都有明显的区分度，数学有高分也有低分，语文有高分也有低分，不会出现哪一科上大家都是 90 分或者大家都是 30 分的情形。

NFL 定理最重要的指导意义在于先验知识的使用，也就是具体问题具体分析。机器学习的目标不是放之四海而皆准的通用模型，而是关于特定问题有针对性的解决方案。因此在模型的学习过程中，一定要关注问题本身的特点，也就是关于问题的先验知识。这就像学习数学有学习数学的方法，这套方法用来学习语文未必会有良好的效果，但它只要能够解决数学的问题就已经很有价值了。脱离问题的实际情况谈论模型优劣是没有意义的，只有让模型的特点和问题的特征相匹配，模型才能发挥最大的作用。

相比于 1995 年提出的 NFL 定理，奥卡姆剃刀可谓历史悠久，它诞生于公元 14 世纪圣方济各会修士奥卡姆的威廉笔下。在机器学习的场景下，奥卡姆剃刀（Occam's Razor）可以理解为如果有多种模型都能够同等程度地符合同一个问题的观测结果，那就应该选择其中使用假设最少的，也就是最简单的模型。尽管越复杂的模型通常能得到越精确的结果，但是在结果大致相同的情况下，模型就越简单越好。

奥卡姆剃刀是人类思维的一种直观的体现，你我在不经意间都会用到它：当看到 1，2，4，8 这几个数时，对下一个出现的数字，你的第一反应一定是 16，因为这一系列数字里蕴含的最简单的规律是等比数列关系，而不是什么包含十几二十个参数的高阶多项式，这个复杂的结果直接被头脑中的那把剃刀无意识地砍掉了。

在科学方法中，奥卡姆剃刀对简单性的偏好并非逻辑上不可辩驳的金科玉律，它更多的是基于可证伪性的标准。一个问题存在多个可接受的模型，其中的每一个都可以演化出无数个更为复杂的变体，其原因在于可以把任何解释中的错误归结于某种特例的出现，将这个特例纳入模型就可以避免原来错误的发生。更多特例的引入无疑会降低模型的通用性和可解释性，把薄薄的教材变成厚重的词典，这就是奥卡姆剃刀偏爱简单模型的原因。

本质上说，奥卡姆剃刀的关注点是模型复杂度。机器学习学到的模型应该能够识别出数据背后的模式，也就是数据特征和数据类别之间的关系。当模型本身过于复杂时，特征和类别之间的关系中所有的细枝末节都被捕捉，主要的趋势反而在乱花渐欲迷人眼中没有得到应有的重视，这就会导致过拟合（overfitting）的发生。反过来，如果模型过于简单，它不仅没有能力捕捉细微的相关性，甚至连主要趋势本身都没办法抓住，这样的现象就是欠拟合（underfitting）。

过拟合也好，欠拟合也罢，都是想避免却又无法避免的问题。在来自真实世界的数据中，特征与类别之间鲜有丁是丁卯是卯的明确关系，存在的只是在诸多特征织成的罗网背后若即若离、若隐若现的相关性。用较为简单的模型来模拟复杂的数据生成机制，欠拟合的发生其实是不可避免的。可欠拟合本身还不是更糟糕的，更糟糕的是模型虽然没有找到真正的相关性，却自己脑补出一组关系，并把自己的错误的想象当做真实情况加以推广和应用，得到和事实大相径庭的结果——其实就是过拟合。

模型复杂度与拟合精度之间的关系可以这么来理解：过于简单的模型就像给三五百人一起上大课，不管听课的学生水平如何参差不齐，上课的内容都固定不变，或者变化很小。这种教学的效果一定不好：水平高的学生不用听也会，水平差的学生听了也不会，就像欠拟合的模型在训练集上都没有良好的表现，更遑论泛化性能了。

相比之下，过于复杂的模型则是一对一的闭门辅导，针对每个学生不同的问题做出不同的解答，数学不好的补数学，语文不好的补语文。这样因材施教的教学效果固然优良，却因为它的针对性而没法推广，就像过拟合的模型能够在训练集上表现优异，却因为针对性过强，同样不具备良好的泛化性能。

模型的复杂度也可以从误差组成的角度一窥端倪。在“人工智能基础课”的第一季中曾介绍过，模型的误差包括三个部分：偏差（bias），方差（variance）和噪声（noise）。

三者中的噪声也叫作不可约误差（irreducible error），体现的是待学习问题本身的难度，并不能通过模型的训练加以改善。噪声来源于数据自身的不确定性，如果按照 y=x+ϵ,ϵ N(0,σ)y=x+ϵ,ϵ N(0,σ) 生成数据，并对生成的数据进行线性拟合的话，高斯噪声的方差 σ2σ2 就属于不可约误差。噪声的方差 σ2σ2 越大，线性拟合的难度也就越高。

除了噪声之外，偏差和方差都与模型本身有关，两者对误差的影响可以用误差的偏差 - 方差分解（bias-variance decomposition）来表示。偏差的含义是模型预测值的期望和真实结果之间的区别，如果偏差为 0，模型给出的估计的就是无偏估计。但这个概念是统计意义上的概念，它并不意味着每个预测值都与真实值吻合。方差的含义则是模型预测值的方差，也就是预测值本身的波动程度，方差越小意味着模型越有效。抛开噪声不论，模型的误差就等于偏差的平方与方差之和。

偏差和方差之间的折中与模型自身的特性息息相关。偏差来源于模型中的错误假设，偏差过高就意味着模型所代表的特征和分类结果之间的关系是错误的，对应着欠拟合现象；方差则来源于模型对训练数据波动的过度敏感，方差过高意味着模型对数据中的随机噪声也进行了建模，将本不属于特征 - 分类关系中的随机特性也纳入到模型之中，对应着过拟合现象。

根据上面的理解，就不难得到结论：理想的模型应该是低偏差低方差的双低模型，就像一个神箭手每次都能将箭射进代表 10 环的红心之内；应该避免的模型则是高偏差高方差的双高模型，这样的箭手能射得箭靶上到处窟窿，却没有一个哪怕落在最外层的圆圈里。更加实际的情形是偏差和方差既不会同时较低，也不会同时较高，而是在跷跷板的两端此起彼伏，一个升高另一个就降低。

一般说来，模型的复杂度越低，其偏差也就越高；模型的复杂度越高，其方差也就越高。比较简单的模型像是个斜眼的箭手，射出的箭都在远离靶心的 7 环的某一点附近；比较复杂的模型则是个心理不稳定的箭手，本来是 9 环水平却一下射出 10 环一下射出 8 环。对模型复杂度的调整就是在偏差 - 方差的折中中找到最优解，使得两者之和所表示的总误差达到最小值。这样的模型既能提取出特征和分类结果之间的关系，又不至于放大噪声和干扰的影响。

今天我和你分享了在设计机器学习的模型时，需要考虑的一些共性问题，其要点如下：

无免费午餐定理说明模型的选取要以问题的特点为根据；

奥卡姆剃刀说明在性能相同的情况下，应该选取更加简单的模型；

过于简单的模型会导致欠拟合，过于复杂的模型会导致过拟合；

从误差分解的角度看，欠拟合模型的偏差较大，过拟合模型的方差较大。

在实际应用中，欠拟合和过拟合是不太可能同时被抑制的，现实的考量是“两害相权取其轻”。那么你认为是应该优先控制欠拟合还是过拟合呢？

欢迎发表你的观点。

07 | 模型的验证方法

模型本身及其背后学习方法的泛化性能（generalization performance），也就是模型对未知数据的预测能力，是机器学习的核心问题。可在一个问题的学习中，往往会出现不同的模型在训练集上具有类似的性能，这时就需要利用模型验证来从这些备选中做出选择。

由于模型的泛化性能和它的复杂度是直接挂钩的，所以模型验证的任务就是确定模型的复杂度以避免过拟合的发生。原则上说，模型验证应该使用专门的验证数据集。可是当数据集的容量较小，不足以划分成三个部分时，验证集和测试集就可以合二为一，共同来完成对模型的选择和评价。

估计泛化性能时，最重要的依据就是模型在训练数据集上的精度（accuracy）。定性而论，模型在训练集上的精度不能太低。由于模型的拟合和评价都是在相同的训练集上完成的，因此用训练误差去估计测试误差，得到的必然是过于乐观的结果。如果在训练集上都达不到较高的精度的话，模型本身的假设就很可能存在问题（比如用线性模型来建模平方关系的数据），从而导致较大的偏差，这样的模型很难指望它在真实数据上具有良好的表现。

可另一方面，训练数据集上的正确率也不是“低低益善”，因为过低的正确率往往是欠拟合的征兆。训练数据集中的数据量一定是有限的，这些数据共同构成了高维空间上一个点集。只要模型的参数足够多，形式足够复杂，就必定可以构造出经过所有数据点的曲线或者曲面，在训练集上得到 100% 的正确率。显然，这样的模型对训练数据的拟合能力过强，不可能具备良好的泛化特性。

过拟合现象（图片来自维基百科）

上图就是一个典型的过拟合例子：黑点代表的离散数据可以看成是满足线性关系的原始数据和随机噪声的叠加，受噪声的影响，即使是生成数据的直线也不能完全拟合数据，总归存在一定的残留误差。如果要将残留误差降低为 0，在训练集上取得 100% 的正确率，得到的拟合结果就是龙飞凤舞的蓝色曲线。虽然这个多项式模型完美地覆盖了所有数据点，但它所代表的数据生成方式显然和黑色直线并不接近。此时，过高的训练集正确率反而与对模型优良泛化性能的追求背道而驰。

既然训练误差太高了不行，太低了也不行，那么究竟到什么程度才算合适呢？关于训练误差和泛化误差的关系，《统计学习基础》（Elements of Statistical Learning）从理论上给出了略显晦涩的解释。在这里我尝试加以解读。

分析的出发点是误差的分解理论：误差包括噪声、偏差和方差三部分。当模型的训练过程结束后，在训练集上就可以计算出模型 f^f^ 的训练误差，在测试集上则可以计算出模型的泛化误差。由于训练数据是已知的，验证数据是未知的，两者之间并不存在交集，所以泛化误差也被称为样本外误差（extra-sample error）。

可随后，作者们又引入了一个新的概念，叫样本内误差（in-sample error），这个概念的核心在于刻画噪声的影响。训练集的数据中既包含由潜在的概率分布所决定的确定部分，也包含受噪声干扰产生的随机部分。在训练过程中，模型 f^f^ 将不可避免地把噪声的一部分随机特性也纳入建模的范畴。如果考虑噪声的影响，那么即使当训练数据的自变量不变，它的因变量也会受发生变化。从这个角度来理解，训练数据集就是一个样本，它对应的总体是自变量固定时因变量所有可能的取值。利用样本训练出的模型 f^f^ 在样本上的表现和在总体上的表现之间的差值，就是所谓的样本内误差。

看到这里你可能发现了，这个样本内误差纯粹是统计学家想象出来的概念。但好在经过一番处理之后，对测试误差的估计可以转化成对样本内误差的估计，让这个概念终于找到了它能够发光发热的场景。进一步简化的话，由于训练误差是已知的，所以对样本内误差的估计又可以转化成对它和训练误差之间的差值的估计，这个差值在《统计学习基础》中被称为乐观度（optimism）。

对于线性模型等特殊形式的模型，乐观度可以以解析式来表示，并且直接取决于模型中参数的数目，这时就可以根据赤池信息量准则（Akaike Information Criterion, AIC）或者贝叶斯信息量准则（Bayesian Information Criterion, BIC）来指导模型选择。说白了，在这个理论框架下，模型选择就是计算有效参数的数目。

上面的理论估计虽然严谨，却也太过复杂。在工程上处理误差时哪里需要这喋喋不休的推导，直接用数据模拟就什么都出来了。更通用的验证方法是直接估计样本外误差，估计的手段则是数据的重采样（re-sampling），充分利用有限的数据来估算模型的泛化性能，这也是实际应用中的惯常技巧。

模型在验证集上的性能是模型选择和评估的依据。无论使用什么样的重采样策略，验证集都需要满足一个基本要求，就是不能和训练集有交集。模型本身就是在训练集上拟合出来的，如果再用相同的数据去验证的话，这种既当运动员又当裁判员的做法就缺乏说服力了。所以在划分时，最基本的原则就是确保训练集、验证集和测试集三者两两互不相交。

除了互不相交之外，另一个需要注意的问题是训练 / 验证 / 测试中样例分布的一致性，也就是三个集合中正例和负例的比例应该大致一致，避免在数据集之间出现不平衡。如果训练集和验证集中的样例分布相差较大，这种分布差异将不可避免地给性能的估计带来偏差，从而模型选择造成影响。

做老师的都知道，一次考试中的学生成绩应该是近似满足正态分布的，所以在评估教学效果时，学生样本的构成就至关重要：如果选的都是成绩较好的学生，那他们在自习室自学的效果可能还比上课更好；如果选的都是成绩较差的学生，那即使老师再苦口婆心掰开揉碎也可能白费功夫。这两种情况的共同特点就是都不能真实反映教学质量。只有当学生样本的构成也是两头尖中间宽的纺锤形时，评估的结果才能忠实于实际情况，具有参考价值。

想要充分利用有限的数据，必须在训练集和验证集的划分方式，或者说验证数据的抽取方式上做些门道。最简单直接的方法就是随机采样出一部分数据作为训练集，再采样出另一部分作为验证集，这种方法就是留出法（hold-out）。如果机器学习过程不使用验证步骤，那么这种划分方式就相当于拿出大部分数据做训练，剩下的全部留做测试，这也是“留出”这个名称的含义。

留出法的一个问题是它所留出的、用于模型验证的数据是固定不变的。即使在满足分布一致性的条件下，训练集和验证集的划分方式也并不是唯一的。把所有 ID 为奇数的数据作为训练集和把所有 ID 为偶数的数据作为训练集，进行模型评估的结果肯定有所区别。通过留出法计算出来的泛化误差本质上也是个随机变量，单次留出得到的估计结果就相当于对这个分布进行一次采样，这单次采样的结果没办法体现出随机变量的分布特性。正因如此，在使用留出法时一般采用多次随机划分，在不同的训练 / 验证集上评估模型性能再取平均值的方式，以此来得到关于泛化误差更加精确的估计。

将留出法的思想稍做推广，就可以得到常用的kk 折交叉验证法（kk-fold cross validation）。kk 折交叉验证将原始数据集随机划分为 kk 个相同大小的子集，并进行 kk 轮验证。每一轮验证都选择一个子集作为验证集，而将剩余的 k−1k−1 个子样本用作训练集。由于每一轮中选择的验证集都互不相同，每一轮验证得到的结果也是不同的，kk 个结果的均值就是对泛化性能的最终估计值。

>kk 折交叉验证示意图（k=4k=4）（图片来自维基百科）

kk 折交叉验证中 kk 值的选取直接决定估计结果的精确程度。较小的 kk 值意味着更少的数据被用于训练模型，这将导致每一轮估计得到的结果更加集中，但都会偏离真正的泛化误差，也就是方差较小而偏差较大。随着 kk 的不断增加，越来越多的数据被用在模型拟合上，计算出的泛化误差也会越来越接近真实值。但由于训练数据的相似度越来越高，训练出来的模型也就越来越像，这就会导致在不同的验证集上产生较大的方差。

kk 折交叉验证一个特例是 kk 等于原始数据集的容量 NN，此时每一轮中只有一个样本被用做测试，不同轮次中的训练集则几乎完全一致。这个特例被称为留一法（leave-one-out）。留一法得到的是关于真实泛化误差的近似无偏的估计，其结果通常被认为较为准确。但它的缺点是需要训练的模型数量和原始数据集的样本容量是相等的，当数据量较大时，使用留一法无疑会带来庞大的计算开销。

除了 kk 折交叉验证之外，另一种模型验证的方法是自助采样（bootstrap）。在学习概率论时你肯定计算过这样的问题：一个袋子里有红球若干白球若干，从中抽出一个球查看颜色后放回或不放回，再次抽出一个红球 / 白球的概率是多少。前面提到的 kk 折交叉验证执行的就是典型的不放回的重采样，在同一轮验证中某个样本要么出现在训练集，要么出现在验证集，两者必居其一。

相比之下，自助采样执行的则是有放回的重采样。如果使用自助采样生成训练集的话，需要每次随机从原始数据集中随机抽取一个样本并拷贝到训练集中，将这个样本放回到原始数据集，再重复以上的步骤。这种放回重采样的方式会导致某些数据可能在同一轮验证中多次出现在训练集内，而另一些数据可能从头到尾都没有参与到模型的训练当中。在每一轮次的自助采样中，没有被采到的样本会作为测试数据使用。

自助采样原理示意图（图片来自https://dzone.com/articles/machine-learning-validation-techniques）

模型验证是模型原型设计的最后完善。一旦完成了模型验证，模型就不能再做调整了。这就像对陶土模型做出最后的修饰定型，至于入窑烧制的效果如何就完全听天由命，出来的成品品相不佳就只能狠心摔碎。同样的道理，即使验证之后的模型在测试集上的表现再差，也只能打掉牙往肚子里咽。若非要调整不可，就只能重启炉灶了。

今天我和你分享了模型验证的实现思路和具体方法，其要点如下：

模型验证的作用是选择最佳模型并确定其性能；

对数据的重采样可以直接实现对样本外误差，也就是泛化误差的估计；

kk 折交叉验证是无放回的重采样方法；

自助采样是有放回的重采样方法。

在机器学习中，参数（parameter）和超参数（hyperparameter）是两个不同的概念。模型的参数是对模型的内部描述，超参数则是对模型的外部描述。对于多项式模型 f(x)=∑i=0Nαixif(x)=∑i=0Nαixi 来说，所有的 αiαi 都是需要拟合的参数，而多项式的最高次数 NN 则是超参数。模型的验证实际上就是通过调整模型超参数来控制模型复杂度，从而找到一组预测能力最强的模型参数。

关于参数和超参数之间的关系，你可以查阅相关的文献，并在这里留下你的理解。

08 | 模型的评估指标

用训练数据集拟合出备选模型的参数，再用验证数据集选出最优模型后，接下来就到了是骡子是马牵出来溜溜，也就是模型评估的阶段了。模型评估中使用的是测试数据集，通过衡量模型在从未出现过的数据上的性能来估计模型的泛化特性。为简便起见，我将以二分类任务为例来说明度量模型性能的不同指标。

二分类任务是最重要也最基础的机器学习任务，其最直观的性能度量指标就是分类的准确率。给定一组训练数据，算法不可能完全正确地划分所有实例，而是会将一部分正例误判为反例，也会将一部分反例误判为正例。分类正确的样本占样本总数的比例是精度（accuracy），分类错误的样本占样本总数的比例是错误率（error rate），两者之和等于 1。

在现实生活中，二分类任务的一个实际应用就是疾病的诊断。你可以回忆一下在“贝叶斯视角下的机器学习”中提到的例子：“Jo 去进行某种疾病的检查。已知检查的准确率是 95%，也就是此病患者的检查结果 95% 会出现阳性，非此病患者的检查结果 95% 会出现阴性，同时在 Jo 的类似人群中，此病的发病率是 1%。如果 Jo 的检查结果呈阳性，那么她患病的概率是多大呢？”

这个例子就是一个典型的二分类问题。根据之前的分析结果，即使 Jo 的检查结果呈现阳性，她患病的概率也只有 16%，如果一个庸医完全按照检查结果判定的话，每 6 个病人里他就要误诊 5 个！（这又是频率主义直观的看法）但是需要注意的是，错误的分类不仅包括假阳性这一种情况，假阴性也要考虑在内——也就是确实生病的患者没有被检查出来的情形，假阳性和假阴性共同构成所有的误分类结果。

那么在 Jo 的例子中，出现假阴性的可能性有多大呢？同样令随机变量 aa 表示 Jo 的真实健康状况，a=1a=1 表示 Jo 生病，a=0a=0 表示 Jo 没病；令随机变量 bb 表示 Jo 的检查结果，b=1b=1 表示阳性，b=0b=0 表示阴性。由此可以计算出 Jo 的检查结果呈阴性，但是她患病的概率

p(a=1|b=0)=p(b=0|a=1)⋅p(a=1)p(b=0|a=1)⋅p(a=1)+p(b=0|a=0)⋅p(a=0)p(a=1|b=0)=p(b=0|a=1)⋅p(a=1)p(b=0|a=1)⋅p(a=1)+p(b=0|a=0)⋅p(a=0)

=0.05×0.010.05×0.01+0.95×0.99=0.053%=0.05×0.010.05×0.01+0.95×0.99=0.053%

可以看出，虽然这个检查容易把没病的人误诊成有病，但把有病的人误诊成没病的概率是极低的。这符合我们一贯的认知：在现实中，假阳性无非就是给患者带来一些不必要的精神压力，通常不会产生更加严重的后果；可假阴性却可能让患者错过最佳的治疗时机，一旦发现便为时已晚。因此，在医学检查中本着“宁可错判，不能放过”的原则，对假阴性的要求比对假阳性的要求更加严格。

不光是在医学中，在很多情况下将正例误判为反例和将反例误判为正例的代价都是不同的，这也是数理统计将分类错误分为一类错误和二类错误的原因。为了更清楚地体现出不同的错误类型的影响，机器学习采用了混淆矩阵（confusion matrix），也叫列联表（contingency table）来对不同的划分结果加以区分。

混淆矩阵（图片来自维基百科）

如上图所示，在混淆矩阵中，所有测试样例被分为真正例（true positive, TP）、假正例（false positive, FP）、假反例（false negative, FN）、真反例（true negative, TN）四大类。真正例和真反例容易理解，假正例指的是样例本身是反例而预测结果是正例，也就是假阳性；假反例指的是样例本身是正例而预测结果是反例，也就是假阴性。

这样的分类能够对机器学习模型的性能做出更加精细的刻画，查准率（precision）和查全率（recall）就是两个具体的刻画指标。

查准率 PP 也叫正例预测值（positive predictive value），表示的是真正例占所有预测结果为正例的样例的比值，也就是模型预测结果的准确程度，写成数学表达式是

P=PPV=TPTP+FPP=PPV=TPTP+FP

查全率 RR 也叫真正例率（true positive rate, TPR），表示的是真正例占所有真实情况为正例的样例的比值，也就是模型对真实正例的判断能力，写成数学表达式是

R=TPR=TPTP+FNR=TPR=TPTP+FN

通俗地说，查准率要求把尽可能少的真实负例判定为预测正例，查全率则要求把尽可能少的真实正例判定为预测负例。

一般情况下，查准率和查全率是鱼和熊掌不可兼得的一对指标。使用比较严苛的判定标准可以提高查准率，比如医学上对青光眼的诊断主要依赖于眼压值，将诊断阈值设定得较高可以保证所有被诊断的患者都是真正的病人，从而得到较高的查准率。可这样做会将症状不那么明显的初期患例都划分为正常范畴，从而导致查全率的大幅下降。

反过来，如果将眼压的诊断阈值设定得较低，稍有症状的患者都会被诊断为病人。这样做固然可以保证真正的病人都被确诊，使查全率接近于 100%，但确诊的病例中也会包含大量的疑似患者，指标稍高的健康人也会被误诊为病人，从而导致查准率的大幅下降。

将查准率和查全率画在同一个平面直角坐标系内，得到的就是 P-R 曲线，它表示了模型可以同时达到的查准率和查全率。如果一个模型的 P-R 曲线能够完全包住另一个模型的曲线，就意味着前者全面地优于后者。可是更普遍的情况是有些模型查全性能较优，而另一些模型查准性能较优，这就需要根据任务本身的特点来加以选择了。

除了 P-R 曲线外，另一个对机器学习模型性能进行可视化的方式是受试者工作特征曲线（receiver operating characteristic curve），简称ROC 曲线。ROC 这个名字来源于曲线的原始用途：判断雷达接收到的信号到底是敌机还是干扰。在机器学习中，这样的场景就演化为所有的样例共同符合一个混合分布，这个混合分布由正例和反例各自服从的单独概率分布叠加组成。此时二分类模型的任务就是确定新来的样本究竟来源于哪个分布。数据中的随机变化在分类器中体现为阈值动态取值的随机变化，分类器的性能则取决于两个概率分布之间的分离程度。

ROC 曲线描述的是真正例率和假正例率之间的关系，也就是收益（真正例）与代价（假正例）之间的关系。所谓的假正例率（false positive rate, FPR）等于假正例和所有真实反例之间的比值，其数学表达式为

FPR=FPFP+TNFPR=FPFP+TN

ROC 空间将 FPR 定义为 XX 轴，TPR 定义为 YY 轴。给定一个二元分类模型和它的阈值，就能计算出模型的 FPR 和 TPR，并映射成由 (0, 0)、(0, 1)、(1, 0)、(1, 1) 四个点围成的正方形里。在这个正方形里，从 (0, 0) 到 (1, 1) 的对角线代表了一条分界线，叫作无识别率线，它将 ROC 空间划分为左上／右下两个区域。

无识别率线描述的是随机猜测的模型，以 0.5 的概率将新来的实例判定为正例，这种模型的 TPR 和 FPR 是处处相等的。在无识别率线左上方，所有点的 TPR 都大于 FPR，意味着分类结果优于二选一的随机猜测；而在无识别率线右下方，所有点的 TPR 都小于 FPR，意味着分类结果劣于随机猜测。完美的模型体现在 ROC 空间上的 (0, 1) 点：FPR=0FPR=0 意味着没有假正例，没有负例被掺入；TPR=1TPR=1 意味着没有假负例，没有正例被遗漏。也就是说，不管分类器输出结果是正例还是反例，都是 100% 完全正确。

不同类型的模型具有不同的 ROC 曲线。决策树这类模型会直接输出样例对应的类别，也就是硬分类结果，其 ROC 曲线就退化为 ROC 空间上的单个点。相比之下，朴素贝叶斯这类输出软分类结果，也就是属于每个类别概率的模型就没有这么简单了。将软分类概率转换成硬分类结果需要选择合适的阈值，每个不同的阈值都对应着 ROC 空间上的一个点，因此整个模型的性能就是由多个离散点连成的折线。下图给出了 ROC 曲线和 P-R 曲线的示意图，你可以直观感受一下两者的区别。

﻿典型的 ROC 曲线（左）与 P-R 曲线（右）

（图片来自https://blogs.msdn.microsoft.com/andreasderuiter/2015/02/09/using-roc-plots-and-the-auc-measure-in-azure-ml/）

ROC 曲线可以用来衡量习得模型的性能。模型的 ROC 曲线越靠近左上方，其性能就越好。和 P-R 曲线一样，如果一个模型的 ROC 曲线能够完全包住另一个模型的曲线，那么前者的性能就优于后者。但大多数情况下，模型之间并不存在全方位的碾压性优势，自然不会出现 ROC 曲线完全包含的情形。这时要评估不同模型性能的话，就需要 ROC 曲线下面积的概念。

ROC 曲线下面积（Area Under ROC Curve）简称 AUC。由于 AUC 的计算是在 1×11×1 的方格里求面积，因此其取值必然在 0 到 1 之间。对于完全靠蒙的无识别率线来说，其 AUC 等于 0.5，这样的模型完全没有预测价值。一般来说，通过调整模型的阈值，可以让模型的最优 AUC 大于 0.5，达到比随机猜测更好的判别效果。如果模型的 AUC 比 0.5 还小，这样的模型可以通过求解其镜像，也就是将分类结果反转来获得优于随机猜测的结果。

但 ROC 曲线的意义不仅限于求解面积，它还可以提供其他的信息。不同性能的算法对应着 ROC 空间上不同的点，如果能够确定所有样例中真实正例的比例 pospos 和真实负例的比例 1−pos1−pos，那么模型的精度就可以表示为 pos⋅TPR+(1−pos)⋅(1−FPR)pos⋅TPR+(1−pos)⋅(1−FPR)。根据这个数量关系可以得出，虽然不同的模型具有不同的 TPRTPR 和 FPRFPR，但它们的精度是可以相等的。在 ROC 空间上，这些精度相同的模型都落在同一条斜率为 (1−pos)/pos(1−pos)/pos，也就是负例与正例比值的直线上，这样的直线就被称为等精度线（iso-accuracy lines）。

由此，正例和负例的比例就可以作为已知的先验信息指导模型的选择。如果正例和负例的比例约为 2:1，那就可以在 ROC 空间上作一条斜率为 1/2 且经过 (0, 1) 的直线，并向右下方平行移动。当平移的直线与 ROC 曲线相交时，交点所对应的模型就是适用于这个先验信息的最优模型。此时最优模型的精度是多少呢？就是交点所在直线的截距，也就是和 TPRTPR 轴的交点。

今天我和你分享了对机器学习模型不同的性能度量方法，其要点如下：

在二分类任务中，模型性能度量的基本指标是精度和错误率，两者之和为 1；

混淆矩阵是个 2×22×2 的性能度量矩阵，其元素分别是真正例、假正例、假反例和真反例的数目；

P-R 曲线表示的是查准率和查全率之间的关系，曲线在点 (1, 1) 上达到最优性能；

ROC 曲线表示的是真正例率和假正例率之间的关系，曲线在点 (0, 1) 上达到最优性能。

关于模型性能的评估我想给你推荐一位学者，他就是英国布里斯托尔大学的彼得·弗拉克（Peter Flach）。这位教授在模型评估研究，尤其是 ROC 曲线分析上的造诣颇深，你可以在他的著作《机器学习》（Machine Learning）第 2 章和论文中领会模型评估中蕴藏的信息，这一定会让你受益匪浅。

对比 P-R 图和 ROC 曲线会发现一个有趣的现象，那就是当类别的平衡性，也就是数据中正例和负例的比例发生改变时，这种变化不会给 ROC 曲线带来变化，却会让 P-R 曲线产生明显的改变，为什么会出现这种现象呢？

你可以思考一下，并在这里分享你的观点。

09 | 实验设计

和其他科学学科一样，机器学习也会借助实验获取关于目标的信息。宏观来看，实验的设计与分析正在逐渐脱离具体问题的限定，有成为一门独立学科的趋势。不管是物理学还是经济学，对实验的处理都存在着一些共性的准则。在本篇文章中，我就和你简单谈谈机器学习中有关实验设计与分析的一些原则性问题。

在讨论实验设计之前，先得知道实验设计到底是怎么回事。实验设计（experimental design），或者叫设计实验（designed experiment），指的是在实验之前制定详细的实验计划，确定实验目标并选择待研究的过程因子（process factor）。精心挑选的实验设计可以在给定资源的条件下使实验获得的信息量最大化，让实验结果最大程度地接近真实结果。实验设计需要人为改变一个或多个过程因子，以观察这种变化对一个或多个因变量的影响，其目的是分析获得的数据以产生有效和客观的结论。

在现有的关于机器学习的文献中，对设计实验部分的讨论似乎并不多见，其原因在于这部分工作已经由他人代劳，而不需要放在机器学习的应用层面来解决。在各种各样的图像识别竞赛中，无论是训练集还是测试集都是预先给定的，其中的每张图片都有精确的标注。看起来，设计实验似乎是一项蓝领工作，它被处理高大上算法的白领工作给人为地屏蔽了。可真实情况是什么呢？通过人工数据训练出来的算法，在真实世界中的行为可能完全不同，从“人工智能”变成“人工智障”只是捅破一层窗户纸这么简单。

设计实验绝非简单的蓝领工作，它甚至比机器学习本身更加注重策略的作用。机器学习的目标是模拟数据的内在生成机制，取得较低的泛化误差和较强的预测精度。对数据生成机制的学习是建立在足量数据的基础上的，因此机器学习需要的数据多多益善，不会对数据提出这样那样的要求。即使是类别不平衡或者属性有缺失值，机器学习对这些非完美的数据也会来者不拒。这就像一个给啥吃啥的傻小子，只要能填饱肚子就无欲无求了。

相比之下，在设计实验中，数据都是经过精挑细选的，最重要的特性就是平衡（balance）。一般来说，“平衡”意味着对于数据来说，每个特征可能的取值个数都是相同的，而对于特征来说，每个取值上的数据比例也是要近似相同的。这种平衡保证了每个特征对结果都会产生同等程度的影响，从而回避了特征和因子之间的偏好关系。这就像个讲究生活品质的人，不仅要填饱肚子，还要通过口味和营养的搭配吃得美味、吃得健康。这在实验中就表现为精确衡量不同因子对实验结果的影响。

设计实验要完成的任务是对整个机器学习过程的优化。影响作为一个过程，而不单单是一个模型的机器学习的因子是多种多样的，其中最基本的因子就是选用的模型形式。当解决一个分类问题时，主成分分析（通常作为预处理方法出现）、KK 近邻和神经网络都是可用的模型。当模型确定后，模型的超参数（hyperparameter）就是下一个可控因素，主成分分析中主成分的个数 dd、KK 近邻算法中 KK 的取值，神经网络中隐藏层的数目 nn 都属于超参数。超参数会对模型的性能和复杂度产生直接的影响，在不同的超参数配置下，模型训练所得到的参数和性能也会有所区别。

实验中因子的设置取决于实验的目的。如果想要比较不同算法在同一个问题上的性能，算法的类别就是因子；如果要测试固定的算法在不同问题上的性能，算法的超参数就是因子；如果要用算法来区别数据集的数据质量，那么不同的数据集也是因子。设计实验时，要将发生影响的所有因子全部纳入考虑范围并加以调节，从而实现对学习过程的系统性优化。

当实验中的因子数目比较多时，如何唯一地确定单个因子的影响就需要一些技巧。你一定听说过控制变量法，这是最简单的实验设计技法之一，它通过将其余变量设置为固定值来观察单一因素的影响效果，以及其背后的因果关系。在机器学习中，这种方法被称为一次一因子（one factor at a time），它首先为所有因子都设定一个基线值，再在其他因子保持在基线水平的前提下令单个因子波动，观察它对学习性能的影响。

在应用控制变量变量法时需要注意的是，它暗含着一个较强的假设，就是不同因子之间相互独立，互不影响。这个假设在实际的学习任务中显然并不总是成立的，埃塞姆·阿帕丁（ Ethem Alpaydin）在他的《机器学习导论》（Introduction to Machine Learning, 3rd Edition）中提到，在主成分分析的预处理与 KK 近邻分类的级联算法中，主成分数目的每个选择都给后面的 KK 近邻定义出一个全新的输入空间，这会使 KK 近邻的最优超参数出现变化——在 10 维输入中计算出的最优近邻数目未必适用于 15 维的输入。

如果在每次实验中不是控制单个因子，而是让所有的因子一起变化来发现它们之间的协同关系，这就是因子设计（factorial design）的方法。因子设计关注的是不同因子之间系统化的变化对学习效果的影响，它的一个特例是全因子实验（full factorial experiment），也叫完全交叉设计（fully crossed design）。在全因子实验中，每个因子都有有限个离散的取值，实验则覆盖了所有因子所有取值的所有可能组合。如果总共有 3 个因子，每个因子的取值数目分别是 3/4/5，那么全因子实验的执行次数就是 3×4×5=603×4×5=60。

全因子实验不仅能够研究每个因子对因变量的影响，还能发现因子之间相互作用对因变量的影响，它可以进一步被看成是连续实验（sequential experimentation）的一个阶段。在待分析的因子数目较多时，连续实验体现出来的就是“粗调 + 微调”的处理方式。它首先执行全因子实验，但只给每个因子赋予较少的可能取值。这种广撒网的做法能够评判所有因子的重要程度，确定哪些是对学习结果影响较大的活跃因子并保留下来，剩下的不活跃的因子就会被放弃。接下来，连续实验会聚焦活跃因子，通过增加取值数目并进行精细的微调来精确刻画它们之间的关系，以及对因变量的影响方式，进而优化学习的设置。

在对筛选出的少量因子进行微调时，可以使用响应面方法（response surface methodology）来降低计算开销。微调的目的是找到最优的因子取值，在不可能对所有取值都计算出性能指标的情况下，通过插值的方法来拟合出因子和性能之间的响应面就是一种更容易操作的办法。在得到的响应面上寻找最值，找到的就是最优的因子取值。

响应面通常被设定为二次曲面，用来拟合初始曲面的数据通常取在因子的基线附近。在初始曲面上找到的因子最优值被应用到学习模型之中，得到的结果作为一个新样本被添加到初始曲面里面，然后继续对响应曲面进行拟合和优化，直到得到的最优结果没有明显的改进为止。

响应曲面其实可以看成一种替代模型。替代模型（surrogate model）是对真实模型的逼近，以数据驱动的自底向上的方法构建，目标是尽可能地模拟真实模型的行为。如果机器学习中的因子较多的话，它们之间的关系可能就是无法用解析式来描述的复杂关系，替代模型就是对这种复杂关系的拟合，就像机器学习训练模型来拟合输入特征和输出结果之间的关系那样。

今天我和你分享了机器学习中实验设计的一些基本原则，其要点如下：

实验设计的任务是观察一个或多个因子对实验结果的影响；

机器学习中，实验设计中的因子包括算法类型、超参数、数据集等；

连续实验可以用来评估多个因子对实验的影响；

响应面方法通过二次曲面的拟合寻找可变因子的最佳取值。

本篇中提到的实验设计类似于机器学习中的模型调参，只不过调参调的是模型内部的参数，而实验设计调的是模型外部的因子。在实际中通常没有得到应有的重视。那么在机器学习的实践中，你是否专门关注过这个过程，又或者掉进过实验设计的坑里，还是历练出什么独门绝技呢？

欢迎分享你的观点。

10 | 特征预处理

华盛顿大学教授、《终极算法》（The Master Algorithm）的作者佩德罗·多明戈斯曾在 Communications of The ACM 第 55 卷第 10 期上发表了一篇名为《机器学习你不得不知的那些事》（A Few Useful Things to Know about Machine Learning）的小文，介绍了 12 条机器学习中的“金科玉律”，其中的 7/8 两条说的就是对数据的作用的认识。

多明戈斯的观点是：数据量比算法更重要。即使算法本身并没有什么精巧的设计，但使用大量数据进行训练也能起到填鸭的效果，获得比用少量数据训练出来的聪明算法更好的性能。这也应了那句老话：数据决定了机器学习的上限，而算法只是尽可能逼近这个上限。

但多明戈斯嘴里的数据可不是硬件采集或者软件抓取的原始数据，而是经过特征工程处理之后的精修数据，在他看来，特征工程（feature engineering）才是机器学习的关键。通常来说，原始数据并不直接适用于学习，而是特征筛选、构造和生成的基础。一个好的预测模型与高效的特征提取和明确的特征表示息息相关，如果通过特征工程得到很多独立的且与所属类别相关的特征，那学习过程就变成小菜一碟。

特征的本质是用于预测分类结果的信息，特征工程实际上就是对这些信息的编码。机器学习中的很多具体算法都可以归纳到特征工程的范畴之中，比如使用 L1L1 正则化项的LASSO 回归，就是通过将某些特征的权重系数缩小到 0 来实现特征的过滤；再比如主成分分析，将具有相关性的一组特征变换为另一组线性无关的特征。这些方法本质上完成的都是特征工程的任务。

但是今天，我将不会讨论这些，而是把关注点放在算法之外，看一看在特征工程之前，数据的特征需要经过哪些必要的预处理（preprocessing）。

特征缩放（feature scaling）可能是最广为人知的预处理技巧了，它的目的是保证所有的特征数值具有相同的数量级。在有些情况下，数据中的某些特征会具有不同的尺度，比如在电商上买衣服时，身高和体重就是不同尺度的特征。

假设我的身高 / 体重是 1.85 米 /64 公斤，而买了同款衣服的两个朋友，1.75 米 /80 公斤的穿 L 号合适，1.58 米 /52 公斤的穿 S 号正好。直观判断的话，L 码应该更合适我。可如果把（身高，体重）的二元组看作二维空间上的点的话，代表我自己的点显然和代表 S 码的点之间的欧式距离更近。如果电商不开眼的话，保不齐就会把 S 码推荐给我。

实际上，不会有电商做出这么弱智的推荐，因为他们都会进行特征缩放。在上面的例子中，由于体重数据比身高数据高出了一个数量级，因此在计算欧式距离时，身高的影响相比于体重是可以忽略不计的，起作用的相当于只有体重一个特征，这样的算法自然就会把体重相近的划分到同一个类别。

特征缩放的作用就是消除特征的不同尺度所造成的偏差，具体的变换方法有以下这两种：

标准化（standardization）：xst=x−mean(x)stdev(x)xst=x−mean(x)stdev(x)

归一化（normalization）：xnorm=x−min(x)max(x)−min(x)xnorm=x−min(x)max(x)−min(x)

不难看出，标准化的方法用原始数据减去均值再除以标准差，不管原始特征的取值范围有多大，得到的每组新数据都是均值为 0，方差为 1，这意味着所有数据被强行拉到同一个尺度之上；归一化的方法则是用每个特征的取值区间作为一把尺子，再利用这把尺将不同的数据按比例进行转换，让所有数据都落在 [0, 1] 这个范围之内。虽然实现方式不同，但两者都能够对数据做出重新标定，以避免不同尺度的特征产生不一致的影响，可谓殊途同归。

除了尺度之外，数据的偏度也是值得关注的一个问题。偏度（skewness）是用于描述概率分布非对称性的一个指标。下图给出了两个分别具有负偏度和正偏度的概率分布示意图，从中可以看出具有偏度的分布的形状都是类似的：一侧是瘦高的形状，占据了概率分布的大部分，另一侧则是比较长的拖尾。

想要理解这个图形所表示的概率分布，只要把正偏度的图形想象成你所在单位的工资分布就可以了：左侧的瘦高形状表示了拿着低工资的绝大部分普通员工，右侧的拖尾则表示了工资更高、但人数更少的中层领导和高级主管。无论机关、事业单位还是企业，工资的分布大抵都是这样。

不同偏度的概率分布（图片来自维基百科）

数据服从有偏分布意味着什么呢？意味着数据当中可能存在着异常点（outlier）。30 个维秘模特的体重应该近似地服从正态分布，而正态分布是无偏的对称分布。可是如果把其中一个模特的体重换成相扑运动员的体重，这个数据集的均值就会产生明显的上升，数据的直方图也会朝新均值的反方向产生明显的偏移。这时，偏度就体现为少量异常点对样本整体的拉拽作用，类似于用一个董事长和 99 个普通工人计算平均工资产生的喜剧效果。

面对偏度较大的数据，第一反应就应该是检查是否有异常点存在。一般来说，如果少量数据点和其他数据点有明显区别，就可以认为是异常点。在处理异常点时，首先要检测这些数据的可靠性，判断异常取值是不是由错误或者失误导致，比如那个混进维秘模特里的相扑选手。

如果异常点本身并没有问题，需要考虑的下一个问题就是异常点和正常点是否来源于不同的生成机制，从而具有不同的概率分布。如果对异常点所在的分布的采样数据较少，就不足以体现出分布的特性，导致单个数据点看起来显得突兀。

对于像决策树这类对异常点比较敏感的算法来说，不管来源如何，异常点都需要被处理。最直接的处理办法就是将异常点移除，但当数据集容量较小时，这种一刀切的方式会进一步减少可用的数据，造成信息的丢失，这时就需要采用名为“空间标识”（spatial sign）的数值处理方法。

空间标识方法先对所有的数据点进行前面提到的标准化处理，再用样本向量的 2 范数对样本中的所有特征进行归一化，其数学表达式可以写成

x∗ij=xij∑Nj=1x2ijxij∗=xij∑j=1Nxij2

式中的 NN 是数据的维度。显然，空间标识算法将所有的数据点都映射到高维空间的球面上，这个映射和标准化或者归一化的不同之处在于它处理的对象并不是所有样本的同一个特征，而是同一个样本的所有特征，让所有样本呈现一致的尺度。

当然，即使在没有异常点的情况下，数据依然可能呈现出有偏的分布，这在数字图像处理中并不罕见。有偏分布的一个明显特点是最大值和最小值之间相差较大，通常可以达到20 倍或者更高。

这种数据尺度的不一致即使出现在单个特征上也不是一件好事情，对它进行修正，也就是对数据进行去偏度处理的常用方法就是取对数变换（log transformation），也就是对特征取值取对数。最大值和最小值之间的 20 倍差距经过对数变换后变为 log220=4.3log2⁡20=4.3，这就在一个可以接受的范围内了。除了对数之外，求平方根和求倒数也是移除偏度的常见处理方式。

异常点也好，尺度不一致的数据也好，它们至少还都是完整的数据。可有些时候，一个样本里的某些特征会压根儿没有取值，而是一片空白，这种情况被称为缺失值（missing values）。

数据缺失的可能原因多种多样，在这里就不做展开了，关键还是在于如何处理这些缺失值。最简单粗暴的办法依然是将不完整的数据全部删除，对小数据集来说这依然不是好办法。更主动的处理方式是给这些缺失值进行人为的赋值（imputation），就像数值计算或者信号处理中的插值方法一样。

人为赋值相当于在机器学习中又嵌套了一层机器学习，里层的机器学习被用于估计未知的属性值，也要使用训练数据。最常用的赋值算法是K 近邻算法：选取离具有缺失值的样本最近的 K 个样本，并以它们对应特征的平均值为缺失值赋值。此外，线性回归也可以用来对缺失值进行拟合。但可以确定的是，不管采用什么方法，人为赋值都会引入额外的不确定性，给模型带来的性能造成影响。

会做加法也要会做减法，缺失的数据需要添加，多余的数据也要删除。在模型训练之前移除一些特征有助于增强模型的可解释性，也可以降低计算中的开销。如果两个特征之间的相关性较强，或者说具有共线性（collinearity），这时就可以删除掉其中的一个，这正是主成分分析的作用。

除此之外，如果某个特征在绝大多数数据中的取值都是相同的，那这个特征就没有存在的意义，因为它体现不出对于不同分类结果的区分度。这就像在学校里，老师给所有同学的出勤都打满分，这部分平时分是拉不开成绩差距的。

什么样的特征不具备区分度呢？这里有两个经验性的标准：一是特征取值的总数与样本数目的比例在 10% 以下，这样的特征在 100 个样本里的取值数目不超过 10 个；二是出现频率最高的特征取值的出现频率应该在出现频率次高的特征取值频率的 20 倍以上，如果有 90 个样本的特征取值为 1，4 个样本的特征取值为 2，其余取值的样本数目都在 4 个以下，这样的特征就可以被删除了。

今天我和你分享了在模型训练之前对数据特征进行预处理的一些指导性原则，其要点如下：

特征缩放可以让不同特征的取值具有相同的尺度，方法包括标准化和归一化；

异常点会导致数据的有偏分布，对数变换和空间标识都可以去除数据的偏度；

kk 近邻方法和线性回归可以用来对特征的缺失值进行人为赋值；

删除不具备区分度的特征能够降低计算开销，增强可解释性。

这里介绍的特征预处理技巧可以说是挂一漏万。那么在实际的任务当中，你遇到过哪些不理想的特征数据，又是如何处理的呢？

欢迎分享你的经历。

11 | 基础线性回归：一元与多元

从今天开始，专栏将进入统计机器学习模块。虽然统计机器学习中千姿百态的模型让人眼花缭乱，但究其本原，它们都来源于最原始的线性回归（linear regression）。

在我看来，线性模型最大的优点不是便于计算，而是便于解释。它能以简洁明了的方式清晰体现出输入的变化如何导致输出的变化。正所谓“一生二，二生三，三生万物”，将不同的改进方式融入线性模型的基本思想中，就可以得到各种巧夺天工的复杂方法。

在第一季“人工智能基础课”专栏中，我介绍了线性回归的原理，证明了当噪声满足正态分布时，基于最小二乘法（least squares）的线性回归和最大似然估计是等价的。

《机器学习 | 简约而不简单：线性回归》

这次我们换个角度，来看看最小二乘法的几何意义。之前，线性回归的数学表达式被写成 f(x)=wTx=∑ni=0wi⋅xif(x)=wTx=∑i=0nwi⋅xi。但在讨论几何意义时，这个表达式要被改写成

f(x)=1⋅β0+∑j=1nxj⋅βj=xTβf(x)=1⋅β0+∑j=1nxj⋅βj=xTβ

可别小看这个简单的写法变化，从列向量 xx 到行向量 xTxT 的改变就像矩阵的左乘和右乘一样具有不同的意义。

当输出被写成 wTxwTx 时，其背后的寓意是每个包含若干输入属性和一个输出结果的样本都被视为一个整体，误差分散在不同的样本点上；而当输出被写成 xTβxTβ 时，其背后的寓意是每个单独属性在所有样本点上的取值被视为一个整体，误差分散在每个不同的属性上。但横看成岭侧成峰，观察角度的变化不会给观察对象本身造成改变，数据本身是没有变化的。

假设数据集中共有 NN 个样本，那么 xTxT 就变成了 N×(n+1)N×(n+1) 维的数据矩阵 XX，它的每一行表示的都是同一个样本的不同属性，每一列则表示不同样本中的相同属性。如果待拟合数据的特性完美到任意两个属性都线性无关的话，XX 就可以看成一个由它的所有列向量所张成的空间。

一般来说，属性的数目 nn 会远远小于数据的数目 NN，因此 XX 张成的是 NN 维空间之内的n 维生成子空间，或者叫n 维超平面。这个超平面的每一个维度都对应着数据集的一个列向量。理想条件下，输出 yy 作为属性的线性组合，也应该出现在由数据属性构成的超平面上。但受噪声的影响，真正的 yy 是超平面之外的一个点，这时就要退而求其次，在超平面上找到离 yy 最近的点作为最佳的近似。

﻿最小二乘的几何意义（图片来自 Elements of Statistical Learning，图 3.2）

在上图中，黄色区域表示由所有属性张成的超平面；黑色向量 x1x1 和天蓝色向量 x2x2 表示输入属性；红色实线 yy 表示真实输出，水平的红色虚线 y^y^ 表示数据的最优估计值（属性的线性组合）；垂直的红色虚线表示 yy 与 y^y^ 的残差，它与超平面正交。

根据几何知识不难得出，要找的最佳近似 y^y^ 就是 yy 在超平面上的投影，而最佳近似所对应的系数 β^β^ 就是线性回归的解，点 y^=Xβy^=Xβ 和 yy 之间的距离就是估计误差，也叫残差（residual），它就是最小二乘法最小化的对象，其表达式是 ||y−Xβ||2||y−Xβ||2。对参数 ββ 求导不难得到，能够使均方误差最小化的参数 β^β^ 应该满足

(y−Xβ^)TX=0(y−Xβ^)TX=0

这个式子说明了最小二乘法的几何意义：计算高维空间上的输出结果在由所有属性共同定义的低维空间上的正交投影（orthogonal projection）。投影操作意味着残差不会在数据维度上遗留任何分量，这种基于误差和数据正交性的最优解也经常出现在信号处理当中。

在实际应用中，如何解释线性回归的结果呢？下面这个例子可以说明。

眼下世界杯正进行得如火如荼。如果爱好足球，你一定不会对数据网站 WhoScored 感到陌生，它的一大特色是会在每场比赛结束后根据球员表现给出评分，0 分最低，10 分最高。虽然这个评分系统能够直观体现谁踢得好谁踢得差，但关于其专业性的质疑却从未停止。那么 WhoScored 的评分到底准不准呢？我们不妨用线性回归做个测试。

如果 WhoScored 的评分足够合理，那球员的评分就应该和球队的成绩呈现出正相关，而线性又是正相关最直接的描述。为了验证球队赛季积分 yy 和所有球员的赛季平均评分 xx 之间是否存在线性关系，我从网站上复制了 2017~18 赛季英超联赛的相关数据，这个包含 20 个样本的小数据集就是训练集。在拟合数据时，我使用的第三方库是 StatsModels，之所以选择这个库是因为它能够给出更多统计意义上的结论，这些结论对于理解线性回归模型大有裨益。

2017~18 赛季英超联赛积分榜与评分榜（图片来自 whoscored.com）

在模型拟合之前有必要对输入数据做一点处理，那就是将因变量从球队的赛季总积分转换成场均积分。在足球联赛中，一场比赛的胜 / 平 / 负分别对应 3/1/0 分，因此计算场均积分可以看成是某种意义上的归一化，使数据在 [0, 3] 这个一致的较小尺度上得到更加直观的比较。

在使用 StatsModels 拟合模型时，首先要用 add_constant 函数在每个输入数据的后面添加一个 1，借此把常数项纳入模型之中；接下来就可以调用 OLS，也就是普通最小二乘法（ordinary least squares）作为拟合对象，计算线性模型的参数；最后使用 fit 函数获取拟合结果。要查看拟合模型的统计特性，只需打印出模型的 summary。下图就是对英超数据集的拟合结果。

英超数据集上的简单线性回归拟合结果

可以看到，模型拟合最核心的结果显示在第二排：coef 表示的是参数的估计值，也就是通过最小二乘计算出的权重系数。拟合结果告诉我们，球队场均积分 yy 和球员平均评分 xx 之间的关系可以近似表示为回归式 y=3.0685x−19.4345y=3.0685x−19.4345，这说明如果所有球员共同努力将平均评分拉高 0.1 的话，球队在每场比赛中就能平均多得 0.306 分。

右侧 std err 表示的是参数估计的标准误（standard error），虽然最小二乘得到的是无偏估计量，意味着估计结果中不存在系统误差，但每一个特定的估计值结果依然会在真实值的附近波动，标准误度量的就是估计值偏离真实值的平均程度。

最后两列 [0.025 0.975] 给出了 95% 置信区间：每个参数真实值落在这个区间内的可能性是 95%。对于线性回归而言，置信下界和上界分别是估计值减去和加上二倍的标准误，也就是 coef±2×±2×std err。

置信区间告诉我们，平均评分拉高 0.1 并不意味着球队每场一定能多得 0.306 分，但多得的分数基本在 0.258 到 0.356 之间。如果用 2016-17 赛季的数据作为训练数据的话，这个数据的计算结果就变成了 0.33——也落在置信区间之内，这也验证的估计结果的波动性。

中间两列中的 t 和 P>|t|都是统计学中的关键指标，它们评估的是拟合结果的统计学意义。t 代表 tt 统计量（tt-statistic），表示了参数的估计值和原始假设值之间的偏离程度。在线性回归中通常会假设待拟合的参数值为 0，此时的 tt 统计量就等于估计值除以标准误。当数据中的噪声满足正态分布时，tt 统计量就满足 tt 分布，其绝对值越大意味着参数等于 0 的可能性越小，拟合的结果也就越可信。

P>|t|表示的则是统计学中争议最大的指标——pp 值。pp 值（pp-value）是在当原假设为真时，数据等于观测值或比观测值更为极端的概率。简单地说，pp 值表示的是数据与一个给定模型不匹配的程度，pp 值越小，说明数据和原假设的模型越不匹配，也就和计算出的模型越匹配。在这个例子里，原假设认为待估计的参数等于 0，而接近于 0 的 pp 值就意味着计算出的参数值得信任。

看完第二排再来看第一排，也就是对模型拟合数据的程度的评价，重要的指标在右侧一列。R-squared 表示的是 R2R2 统计量，也叫作决定系数（coefficient of determination），这个取值在 [0, 1] 之间的数量表示的是输出的变化中能被输入的变化所解释的部分所占的比例。在这个例子里，R2=0.905R2=0.905 意味着回归模型能够通过 xx 的变化解释大约 91% 的 yy 的变化，这表明回归模型具有良好的准确性，回归后依然不能解释的 9% 就来源于噪声。

R2R2 统计量具有单调递增的特性，即使在模型中再添加一些和输出无关的属性，计算出来的 R2R2 也不会下降。Adj. R-squared 就是校正版的 R2R2 统计量。当模型中增加的变量没有统计学意义时，多余的不相关属性会使校正决定系数下降。校正决定系数体现出的是正则化的思想，它在数值上小于未校正的 R2R2 统计量。

﻿

英超数据集上简单线性回归（左）和多元线性回归（右）的拟合结果

上图给出了英超数据集上简单线性回归和多元线性回归的拟合结果，其中蓝点为数据点，红点为预测点。在简单回归中，大部分数据点集中在拟合直线附近，一个明显的异常点是中游球队水晶宫（Crystal Palace）。

回到英超数据集的例子，图形结果和数值指标都表明线性回归能够较好地拟合两者之间的关系，这说明 WhoScored 的评分系统是值得信任的。但这个例子只是线性回归的一个特例，它特殊在输出的因变量只与单个的输入自变量存在线性关系，这种模型被称为简单线性回归（simple linear regression）。更一般的情况是因变量由多个自变量共同决定，对这些自变量同时建模就是多元线性回归（multivariate linear regression）。

与简单线性回归一样，多元线性回归中的参数也要用最小二乘法来估计。还是以积分和评分的关系为例，在简单线性回归中，自变量是所有球员在所有比赛中评分的均值，但是球场上不同位置的球员发挥的作用也不一样。为了进一步分析不同位置球员对球队表现的影响，就要将单个自变量替换成不同位置球员（门将 / 后卫 / 中场 / 前锋）在整个赛季中的平均评分，再使用多元回归进行拟合。

在这个实例中，多元回归的属性，也就是自变量被设置为每队每个位置上出场时间较多的球员的赛季平均评分的均值，所有选中球员的出场时间都在 1000 分钟以上。

利用 OLS 模型可以得到多元回归的结果，可如果对结果加以分析，就会发现一个有趣的现象：一方面，多元模型的校正决定系数是 0.876，意味着所有位置评分共同解释了输出结果的大部分变化，这也可以从预测值与真实值的散点图上观察出来；可另一方面，只有后卫评分和前锋评分的 pp 值低于 0.05，似乎球队的战绩只取决于这两个位置的表现。

﻿

英超数据集上的多元线性回归拟合结果

看起来校正决定系数和 pp 值给出了自相矛盾的解释，这时就需要观察另外一个重要的指标：FF 统计量。

FF 统计量（FF-statistic）主要应用在多元回归中，它检验的原假设是所有待估计的参数都等于 0，这意味着只要有一个参数不等于 0，原假设就被推翻。FF 统计量越大意味着原假设成立的概率越低，理想的 FF 值应该在百千量级。可在上面的多元回归中，FF 统计量仅为 34.57，这就支持了 pp 值的结论：估计出的参数的统计学意义并不明显。

英超数据集在统计上的非显著性可能源自过小的样本数导致的过拟合，也可能源自不同属性之间的共线性（collinearity）。可在更广泛的意义上，它揭示的却是多元线性回归无法回避的一个本质问题：模型虽然具有足够的精确性，却缺乏关于精确性的合理解释。

假定数据共有 10 个属性，如果只保留 10 个属性中的 5 个用于拟合的话，肯定会有不止一个 5 元属性组能够得到彼此接近的优良性能，可对不同 5 元组的解读方式却会大相径庭。这种现象，就是统计学家莱奥·布雷曼口中的“罗生门”（Rashomon）。

《罗生门》是日本导演黑泽明的作品，取材于日本作家芥川龙之介的小说《草莽中》。一名武士在竹林中被杀，不同当事人的供词既是不同程度上的事实，也是不同角度下的谎言。布雷曼用这个词来描述最优模型的多重性，以及由此造成的统计建模的艰难处境：当不同的多元线性模型性能相近，却公说公有理婆说婆有理时，到底应该如何选择？

将“罗生门”深挖一步，就是机器学习和统计学在认识论上的差异：统计学讲究的是“知其然，知其所以然”，它不仅要找出数据之间的关联性，还要挖出背后的因果性，给计算出的结果赋予令人信服的解释才是统计的核心。

相比之下，机器学习只看重结果，只要模型能够对未知数据做出精确的预测，那这个模型能不能讲得清楚根本不是事儿。四十年前那句名言说得好：不管白猫黑猫，抓住耗子就是好猫。这句话用在机器学习上再合适不过了。

今天我向你介绍了基于最小二乘法的线性回归模型的理解以及从统计学角度的阐释，其要点如下：

线性回归拟合的是高维空间上的输出结果在由所有属性共同定义的低维空间上的正交投影；

简单线性回归的统计意义可以用 tt 统计量和 pp 值等指标描述；

多元线性回归的统计意义可以用 FF 统计量描述，但回归结果可能缺乏对模型的解释能力；

机器学习与统计学的区别在于机器学习重于预测，统计学则重于解释。

本篇中的例子只以 2017~18 赛季英超联赛的数据作为训练数据集。如果使用不同赛季的数据训练的话，你就会发现每次拟合出来的系数都不一样。这样的事实会让你如何看待估计出的系数的准确性呢？

欢迎发表你的观点。

注：本文中的数据及代码可在下面地址查看。 https://github.com/tywang89/mlin40

12 | 正则化处理：收缩方法与边际化

今天的内容是线性回归的正则化扩展。正则化称得上是机器学习里的刮骨疗毒，刮的是过拟合（overfitting）这个任何机器学习方法都无法摆脱的附骨之疽。

本质上讲，过拟合就是模型过于复杂，复杂到削弱了它的泛化性能。由于训练数据的数目是有限的，因此我们总是可以通过增加参数的数量来提升模型的复杂度，进而降低训练误差。可人尽皆知的是，学习的本领越专精，应用的口径就越狭窄，过于复杂的模型就像那个御膳房里专门切黄瓜丝的御厨，让他改切萝卜就下不去刀了。

正则化（regularization）是用于抑制过拟合的方法的统称，它通过动态调整估计参数的取值来降低模型的复杂度，以偏差的增加为代价来换取方差的下降。这是因为当一些参数足够小时，它们对应的属性对输出结果的贡献就会微乎其微，这在实质上去除了非相关属性的影响。

在线性回归里，最常见的正则化方式就是在损失函数（loss function）中添加正则化项（regularizer），而添加的正则化项 R(λ)R(λ) 往往是待估计参数的 pp- 范数。将均方误差和参数的范数之和作为一个整体来进行约束优化，相当于额外添加了一重关于参数的限制条件，避免大量参数同时出现较大的取值。由于正则化的作用通常是让参数估计值的幅度下降，因此在统计学中它也被称为系数收缩方法（shrinkage method）。

将正则化项应用在基于最小二乘法的线性回归中，就可以得到线性回归的不同修正（penalized linear regression）。添加正则化项之后的损失函数可以写成拉格朗日乘子的形式

E~(w)=12∑n=1N[f(xn,w)−yn]2+λg(||w||p),g(||w||p)<tE~(w)=12∑n=1N[f(xn,w)−yn]2+λg(||w||p),g(||w||p)<t

其中的 λλ 是用来平衡均方误差和参数约束的超参数。当正则化项为 1- 范数时，修正结果就是LASSO；当正则化项为 2- 范数的平方时，修正结果就是岭回归；当正则化项是 1- 范数和 2- 范数平方的线性组合 α||w||22+(1−α)||w||1α||w||22+(1−α)||w||1 时，修正结果就是弹性网络（elastic net）。

﻿正则化对线性回归的改进（图片来自 Pattern Recognition and Machine Learning，图 3.4）

岭回归和 LASSO 具有不同的几何意义。上图给出的是岭回归（左）和 LASSO（右）的可视化表示。图中的蓝色点表示普通最小二乘法计算出的最优参数，外面的每个蓝色圆圈都是损失函数的等值线，每个圆圈上的误差都是相等的，从里到外误差则越来越大。

红色边界表示的则是正则化项对参数可能取值的约束，这里假定了未知参数的数目是两个。岭回归中要求两个参数的平方和小于某个固定的取值，即 w21+w22<tw12+w22<t，因此解空间就是浅色区域代表的圆形；而 LASSO 要求两个参数的绝对值之和小于某个固定的取值，即 |w1|+|w2|<t|w1|+|w2|<t，因此解空间就是浅色区域代表的方形。

不管采用哪种正则化方式，最优解都只能出现在浅色区域所代表的约束条件下，因而误差等值线和红色边界的第一个交点就是正则化处理后的最优参数。交点出现的位置取决于边界的形状，圆形的岭回归边界是平滑的曲线，误差等值线可能在任何位置和边界相切。

相形之下，方形的 LASSO 边界是有棱有角的直线，因此切点最可能出现在方形的顶点上，这就意味着某个参数的取值被衰减为 0。

这张图形象地说明了岭回归和 LASSO 的区别。岭回归的作用是衰减不同属性的权重，让所有属性一起向圆心收拢；LASSO 则直接将某些属性的权重降低为 0，完成的是属性过滤的任务。

而弹性网络作为两者的折中，结合了不同的优点：它不会轻易地将某些属性抛弃，从而使全部信息得以保留，但对不重要的特征也会毫不手软地大幅削减其权重系数。

对正则化以上的认识都来自于频率主义的视角。在上一季的专栏中我曾介绍过，从概率的角度看，岭回归是当参数 ww 满足正态分布时，用最大后验概率进行估计得到的结果；LASSO 是当参数 ww 满足拉普拉斯分布时，用最大后验概率进行估计得到的结果。

这样的结论体现出贝叶斯主义对正则化的理解：正则化就是引入关于参数的先验信息。

但是翻开贝叶斯主义的机器学习词典，你不会找到“正则化”这个词，因为这个概念并没有显式地存在，而是隐式地融于贝叶斯定理之中。贝叶斯方法假设待估计的未知参数满足一定的概率分布，因此未知参数对预测结果的影响并不体现为满足某种最优性的“估计值”，而是通过积分消除掉未知参数引入的不确定性。这个过程在之前探讨贝叶斯视角下的概率时，已经通过 Alice 和 Bob 投球的例子加以解释，你可以回忆一下。

在贝叶斯的术语里，将未知随机变量按照其概率分布积分成常量的过程叫边际化（marginalization）。边际化是贝叶斯估计中非常重要的核心概念，它起到的正是正则化的作用。

还是以线性回归为例，假定每个输出 yy 都是其属性 xx 的线性组合与服从正态分布 N(0,σ2)N(0,σ2) 的噪声的叠加，属性的权重系数 ww 则服从 N(0,α)N(0,α) 的先验分布。

那么利用训练数据 yy 估计测试数据 y∗y∗ 时，输出的预计分布（predictive distribution）就可以写成以下的条件概率

p(y∗|y,α,σ2)p(y∗|y,α,σ2)

=∫p(y∗|w,σ2)p(w|y,α,σ2)dw=∫p(y∗|w,σ2)p(w|y,α,σ2)dw

在这个式子中，αα 和 σ2σ2 都是独立于训练数据的超参数。在频率主义的最大似然估计中，预测结果并不会将参数 ww 的估计准确性表示到结果中。

而贝叶斯主义则根据 ww 每一个可能的取值计算出对应结果 y∗y∗，再对连续分布的 ww 取平均。

就可以得到 y∗y∗ 的概率分布，这就是上面这个表达式的含义。

对于预测结果 y∗y∗ 来说，它的不确定性既来自于训练数据 yy，也来自于未知的超参数 αα 和 σ2σ2。

但事实上超参数只是人为设定的数值，在真实的估计任务中，我们需要得到与任何多余参量都没有关系的 p(y∗|y)p(y∗|y)。

在全贝叶斯的框架下，要积分掉超参数的影响，就必须一视同仁地对超参数进行概率分布 p(α)p(α) 和 p(σ2)p(σ2) 的建模，这些超参数的先验信息就被叫作超先验（hyperprior）。

引入超先验后，目标概率就可以写成

p(y∗|y)p(y∗|y)

=∫p(y∗|w,σ2)p(w,α,σ2|y)dwdαdσ2=∫p(y∗|w,σ2)p(w,α,σ2|y)dwdαdσ2

看到这里，你肯定被这么多乱七八糟的符号搞的晕头转向了！因为正常人都会有这种感觉。这正是贝叶斯概率为人诟病的一个缺点：难以求出解析解！

要计算这个复杂的积分必须使用一些近似的技巧。首先，利用条件概率的性质，上式中的第二个积分项，也就是已知训练数据时参数和超参数的条件概率可以改写成

p(w,α,σ2|y)=p(w|y,α,σ2)p(α,σ2|y)p(w,α,σ2|y)=p(w|y,α,σ2)p(α,σ2|y)

等式右侧的第一项其实就是岭回归的最优参数，可以证明这个概率服从参数已知的正态分布，因而可以看成一个确定项。可在计算第二项，也就是根据训练数据确定超参数时，就只能将实数域上的概率密度近似为最可能（most probable）的取值 αMPαMP 和 σ2MPσMP2，用点估计结果代替原始的概率分布。

利用贝叶斯定理可以得出，最可能的超参数取值应该让下面的后验概率最大化

p(α,σ2|y)=p(y|α,σ2)p(α)p(σ2)p(y)p(α,σ2|y)=p(y|α,σ2)p(α)p(σ2)p(y)

在计算中，分母上的 p(y)p(y) 与超参数无关，因此可以忽略不计；由于超参数的取值是任意的，将它们的超先验分布设定为无信息的先验（uninformative prior）就是合理的选择，p(α)p(α) 和 p(σ2)p(σ2) 也就会以常数形式的均匀分布出现。

所以，寻找最可能的 αMPαMP 和 σ2MPσMP2 就变成了计算边际似然概率（marginal probability）p(y|α,σ2)p(y|α,σ2) 的最大值。把边际似然概率对待估计的参数进行展开，就可以将后验概率最大化等效成似然概率最大化

p(y|α,σ2)=∫p(y|w,σ2)p(w|α)dwp(y|α,σ2)=∫p(y|w,σ2)p(w|α)dw

积分的第一项是最大似然估计的解，第二项则是参数满足的先验分布，经过复杂的计算可以得出，积分结果仍然具有正态分布的形式，下面的任务就是找到使训练数据 yy 出现概率最大的一组超参数 αα 和 σ2σ2。表示噪声的强度的超参数 σ2σ2 其实是个固定的取值，通常可以通过多次试验直接测出。在确定 σ2σ2 之后，就可以用梯度下降法来找到最优的 αα 了。

总结起来，利用贝叶斯概率来确定最优参数的步骤可以归纳如下：求解的对象是已知训练数据时，测试数据的条件概率 p(y∗|y)p(y∗|y)，要计算这个条件概率就要对所有未知的参数和超参数进行积分，以消除这些变量。

而在已知的数据和未知的超参数之间搭起一座桥梁的，正是待估计的参数 ww，它将 p(y∗|y)p(y∗|y) 的求解分解成两部分，一部分是根据已知数据推断参数，另一部分是根据参数推断未知数据。

而在根据已知数据推断参数时，又要先推断超参数，再利用超参数和数据一块儿推断参数。对超参数的推断则可以通过边际似然概率简化。

﻿贝叶斯推断过程示意图

和具有直观几何意义的岭回归相比，贝叶斯边际化处理中一个接一个的条件概率没法不让人头疼。这么复杂的方法到底意义何在呢？它的价值就在于计算出的结果就是最优的结果。

频率主义的正则化只是引入了一个正则化系数 λλ，但 λλ 的最优值到底是多少呢？只能靠重复试验确定，这就需要用验证数据集（validation set）来评估每个备选 λλ 的最优性。

相比之下，贝叶斯主义的边际化就简化了最优化的过程，让边际似然概率最大的超参数就是最优的超参数。

这样做的好处就是所有数据都可以用于训练，不需要额外使用验证集，这在数据较少时是非常有用的。

在编程中，很多第三方的 Python 库都可以直接实现不同的正则化处理。在 Scikit-learn 库中，线性模型模块 linear_model 中的 Lasso 类和 Ridge 类就可以实现 l1l1 正则化和 l2l2 正则化。使用这两个类对上一篇文章中拟合出来的多元线性回归模型进行正则化处理，将两种算法中的正则化项参数均设置为 λ=0.05λ=0.05，就可以得到修正后的结果：

不同线性回归方法的结果比较

线性系数的变化直观地体现出两种正则化的不同效果。在未经正则化的多元线性回归中，用红框圈出来的系数比较反直觉，因为它意味着门将的表现对球队积分起到的是负作用，这种结论明显不合常理。

这个问题在两种正则化操作中都得以解决。

LASSO 将 4 个特征中 2 个的系数缩减为 0，这意味着一半的特征被淘汰掉了，其中就包括倒霉的守门员。在 LASSO 看来，对比赛做出贡献的只有中场和前锋球员，而中场的作用又远远不及前锋——这样的结果是否是对英超注重进攻的直观印象的佐证呢？

和 LASSO 相比，岭回归保留了所有的特征，并给门将的表现赋予了接近于 0 的权重系数，以削弱它对结果的影响，其它的权重系数也和原始多元回归的结果更加接近。但 LASSO 和岭回归的均方误差都高于普通线性回归的均方误差，LASSO 的性能还要劣于岭回归的性能，这是抑制过拟合和降低误差必然的结果。

不同回归算法的拟合结果示意图（蓝点为多元线性回归，绿点为 LASSO，红点为岭回归）

今天我和你分享了频率观点下的正则化和贝叶斯观点下的边际化，以及它们在线性回归中的应用，其要点如下：

正则化的作用是抑制过拟合，通过增加偏差来降低方差，提升模型的泛化性能；

正则化项的作用是对解空间添加约束，在约束范围内寻找产生最小误差的系数；

频率视角下的正则化与贝叶斯视角下的边际化作用相同；

边际化对未知的参数和超参数进行积分以消除它们的影响，天然具有模型选择的功能。

最后需要说明的是，正则化的最优参数通常会通过交叉验证进行模型选择来产生，也就是在从不同数据子集上计算出的不同 λλ 中择优取之。由于英超数据集的样本数目较少，所以没有添加交叉验证的过程。

岭回归和 LASSO 虽然都能降低模型的方差，但它们处理参数的方式不同，得到的结果也不一样。那么在你看来，这两种正则化手段分别适用于什么样的场景呢？

欢迎发表你的观点。

13 | 线性降维：主成分的使用

在前一篇文章中，我以岭回归和 LASSO 为例介绍了线性回归的正则化处理。这两种方法都属于收缩方法（shrinkage method），它们能够使线性回归的系数连续变化。但和岭回归不同的是，LASSO 可以将一部分属性的系数收缩为 0，事实上起到了筛选属性的作用。

和 LASSO 这种间接去除属性的收缩方法相对应的是维度规约。维度规约这个听起来个高大上的名称是数据挖掘中常用的术语，它有一个更接地气的同义词，就是降维（dimensionality reduction），也就是直接降低输入属性的数目来削减数据的维度。

对数据维度的探讨来源于“维数灾难”（curse of dimensionality），这个概念是数学家理查德·贝尔曼（Richard Bellman）在动态优化问题的研究中提出的。

发表于《IEEE 模式分析与机器智能汇刊》（IEEE Transactions on Pattern Analysis and Machine Intelligence）第 1 卷第 3 期的论文《维数问题：一个简单实例（A Problem of Dimensionality: A Simple Example）》在数学上证明了当所有参数都已知时，属性维数的增加可以让分类问题的错误率渐进为 0；可当未知的参数只能根据数量有限的样本来估计时，属性维数的增加会使错误率先降低再升高，最终收敛到 0.5。

这就像一群谋士七嘴八舌在支招，当领导的要是对每个人的意见都深入考虑再来拍板的话，这样的决策也没什么准确性可言了。

维数灾难深层次的原因在于数据样本的有限。当属性的维数增加时，每个属性每个可能取值的组合就会以指数形式增长。对于二值属性来说，2 个属性所有可能的取值组合共有 4 种，可每增加一个属性，可能的组合数目就会翻番。

一般的经验法则是每个属性维度需要对应至少 5 个数据样本，可当属性维数增加而样本数目不变时，过少的数据就不足以体现出属性背后的趋势，从而导致过拟合的发生。当然，这只是维数灾难的一种解释方式，另一种解释方式来源于几何角度的数据稀疏性，这里暂且按下不表。

在数据有限的前提下解决维数灾难问题，化繁为简的降维是必经之路。降维的对象通常是那些“食之无味，弃之可惜”的鸡肋属性。食之无味是因为它们或者和结果的相关性不强，或者和其他属性之间有较强的关联，使用这样的属性没有多大必要；弃之可惜则是因为它们终究还包含一些独有的信息，就这么断舍离又会心有不甘。

如果像亚历山大剑斩戈尔迪之结一般直接砍掉鸡肋属性，这种“简单粗暴”的做法就是特征选择（feature selection）。另一种更加稳妥的办法是破旧立新，将所有原始属性的信息一点儿不浪费地整合到脱胎换骨的新属性中，这就是特征提取（feature extraction）的方法。

无论是特征选择还是特征提取，在“人工智能基础课”中都有相应的介绍。

今天我要换个角度，先从刚刚介绍过的岭回归说起。假设数据集中有 NN 个样本，每个样本都有 pp 个属性，则数据矩阵 XX 的维度就是 N×pN×p。将中心化处理后，也就是减去每个属性平均值的 XX 进行奇异值分解（singular value decomposition）可以得到

X=UDVTX=UDVT

其中的 UU 和 VV 分别是 N×pN×p 维和 p×pp×p 维的正交矩阵，其各自的所有列向量可以张成一个子空间；DD 则是对角矩阵，对角线上的各个元素是数据矩阵 XX 按从大到小顺序排列的奇异值（singular value）djdj。可以证明，岭回归求出的最优系数可以写成 β^=(XTX+λI)−1XTyβ^=(XTX+λI)−1XTy。将 XX 的奇异值分解代入岭回归的预测输出中，就可以得到：

Xβ^=∑j=1pujd2jd2j+λuTjyXβ^=∑j=1pujdj2dj2+λujTy

其中的 ujuj 是矩阵 UU 的列向量，也是 XX 的列空间的一组正交基，而岭回归计算出的结果正是将训练数据的输出 yy 投影到以 ujuj 为正交基的子空间上所得到的坐标。除了空间变换之外，岭回归的收缩特性也有体现，那就是上式中的系数。当正则化参数 λλ 一定时，奇异值 djdj 越小，它对应的坐标被衰减地就越厉害。

除了经历不同的收缩外，奇异值 djdj 还有什么意义呢？djdj 的平方可以写成对角矩阵 DD 的平方，利用奇异值分解又可以推导出 D2D2 和数据矩阵 XX 如下的关系

XTX=VD2VTXTX=VD2VT

这个表达式实际上就是矩阵的特征分解（eigen decomposition）：等式左侧的表达式实际上就是数据的协方差矩阵（covariance matrix）乘以维度 NN，VV 中的每一列 vjvj 都是协方差矩阵的特征向量，D2D2 中的每个对角元素 d2jdj2 则是对应的特征值。如果你对主成分分析还有印象，就不难发现每一个 XvjXvj 都是一个主成分（principal component），第 jj 个主成分上数据的方差就是 d2j/Ndj2/N。

解释到这儿，就能够看出岭回归的作用了：岭回归收缩系数的对象并非每个单独的属性，而是由属性的线性组合计算出来的互不相关的主成分，主成分上数据的方差越小，其系数收缩地就越明显。

数据在一个主成分上波动较大意味着主成分的取值对数据有较高的区分度，也就是上一季中提到的“最大方差原理”。反之，数据在另一个主成分上方差较小就说明不同数据的取值较为集中，而聚成一团的数据显然是不容易区分的。岭回归正是通过削弱方差较小的主成分、保留方差较大的主成分来简化模型，实现正则化的。

﻿﻿不同方差的主成分示意图，2 点钟方向的主成分方差较大，11 点钟方向的主成分方差较小（图片来自维基百科）

看到这里你可能就想到了：既然主成分都已经算出来了，与其用岭回归兜一个圈子，莫不如直接使用它们作为自变量来计算线性回归的系数，这种思路得到的就是主成分回归（principal component regression）。

主成分回归以每个主成分 zj=Xvjzj=Xvj 作为输入计算回归参数。由于不同的主成分是两两正交的，因此这个看似多元线性回归的问题实质上是多个独立的简单线性回归的组合，每个主成分的权重系数可以表示为

θ^m=<zm,y><zm,zm>θ^m=<zm,y><zm,zm>

其中 <><> 表示内积运算。需要注意的是这里的 yy 和数据矩阵的每一列 xjxj 都要做去均值的处理，主成分回归的常数项就是 yy，也就是所有数据输出结果的均值 y¯y¯。

当主成分回归中使用的主成分数目等于数据的属性数目 pp 时，主成分回归和岭回归的结果是一致的。可如果放弃方差最小的若干个主成分，得到的就是约化的回归结果，从而更加清晰地体现出主成分分析的思想。

主成分分析是典型的特征提取方法，它和收缩方法的本质区别在于将原始的共线性特征转化为人为生成的正交特征，从而带来了数据维度的约简和数据压缩的可能性。数字图像处理中的特征脸方法是主成分回归最典型的应用之一。

所谓“特征脸”（eigenface）实际上就是用于人脸识别的主成分。用特征脸方法处理的人脸图像都具有相同的空间维度，假定图像的像素数目都是 100×100100×100，那么每一个像素点都是一个属性，数字图像就变成了 10000 维空间中的一个点。可一般数字图像慢变特性决定了这 10000 个特征之间具有很强的关联，直接处理的话运算量较大不说，还未必有好的效果，可谓事倍功半。

﻿﻿根据 AT&T Laboratories Cambridge Facedatabase 人脸数据库生成的特征脸

图片来自 https://www.bytefish.de/blog/eigenfaces/

引入主成分分析后，情况就不一样了。主成分分析可以将 10000 个相互关联的像素维度精炼成 100～150 个特征脸，再用这些特征脸来重构相同形状的人脸图像。

上图是真实计算出的一组特征脸图像，如果是晚上一个人在家玩手机的话，那这组惊悚的特征脸很可能让你吓得不轻。可如果你能想明白一个问题：这只是一组被打成正方形的 10000 多维的相互正交的主成分，而原始图像让它们碰巧具有了人脸的轮廓，这些人不人鬼不鬼的东西就没有那么恐怖了。

这些主成分可以用来分解任意一张面孔，说不定我的一寸照片就可以表示成 2727 的组合呢。

前面对主成分分析的解释都是从降维的角度出发的。换个角度，主成分分析可以看成对高斯隐变量的概率描述。隐变量（latent variable）是不能直接观测但可以间接推断的变量，虽然数据本身处在高维空间之中，但决定其变化特点的可能只是有限个参数，这些幕后的操纵者就是隐变量，寻找隐变量的过程就是对数据进行降维的过程。

概率主成分分析（probabilistic principal component analysis）体现的就是高斯型观测结果和高斯隐变量之间线性的相关关系，它是因子分析（factor analysis）的一个特例。概率主成分分析的数学推导比较复杂，在这里不妨直接给出结论：

假定一组数据观测值构成了 DD 维向量 XX，另外一组隐变量构成了 QQ 维向量 ZZ，两者之间的线性关系就可以表示为

X=WZ+μ+ϵX=WZ+μ+ϵ

其中关联矩阵 WW 是由标准正交基构成的矩阵，非零向量 μμ 表示观测值的均值，ϵϵ 则是服从标准多维正态分布 N(0,σ2I)N(0,σ2I) 的各向同性的噪声。如果假设隐变量 ZZ 具有多元标准正态形式的先验分布 p(Z)p(Z)，去均值观测数据 XX 的对数似然概率可以写成

logp(X|W,σ2)=−N2ln|C|−12∑i=1NxTiC−1xilog⁡p(X|W,σ2)=−N2ln⁡|C|−12∑i=1NxiTC−1xi

其中 C=WWT+σ2IC=WWT+σ2I。计算可得，让似然概率取得最大值的参数值为 W^=V(D2−σ2I)1/2W^=V(D2−σ2I)1/2。根据这个 W^W^ 又可以计算出超参数 σ2σ2 得最大似然估计值 σ^2=1D−Q∑j=Q+1Dd2jσ^2=1D−Q∑j=Q+1Ddj2，这说明噪声方差就是所有被丢弃的主成分方差的均值。而当 ϵ→0ϵ→0 时，概率主成分分析的线性系数 W^W^ 就会退化为经典的主成分分析中的 VV。

除了似然概率外，根据正态分布的性质也可以计算出隐变量的后验概率 p(Z|X)p(Z|X)。令 F^=W^TW^+σ^2IF^=W^TW^+σ^2I，后验概率满足的就是以 F^−1W^XF^−1W^X 为均值，σ2F^−1σ2F^−1 为方差的正态分布。当 ϵ→0ϵ→0 时，隐变量的最优值就会收敛为经典主成分 XVXV。

在实际问题中，使用的主成分数目是个超参数，需要通过模型选择确定，而概率主成分分析对测试数据的处理就可以完成模型选择的任务。从重构误差的角度出发，经典主成分分析一般会让被选中的主成分的特征值之和占所有特征值之和的 95% 以上。在贝叶斯框架下，计算最优的主成分数目需要对所有未知的参数超参数进行积分，其过程非常复杂，在这里就不讨论了。

同其他隐变量模型一样，概率主成分分析也是个生成模型，其生成机制如下图所示。首先从服从一维正态分布的隐变量 zz 中得到采样值 z^z^，以 wz+μwz+μ 为均值的单位方差二维正态分布就是数据 xx 的似然分布，将先验分布与似然分布相乘，得到的就是最右侧的二维分布 p(x)p(x) 了。

﻿﻿概率主成分分析表示的数据生成机制

图片来自 Machine Learning: A Probabilistic Perspective, 图 12.1

在 Scikit-learn 中，主成分分析对应的类是 PCA，它在 decomposition 的模块种。还是以英超数据集为例，对多元线性回归的数据进行主成分分析，可以得到 10 个主成分的方差，以及它们占总方差的比例：

英超数据集上所有主成分的方差及其比例

从结果中可以看出，方差最大的主成分占据了近 4/5 的总方差，前两个主成分的方差之和的比例则超过了 90%。在对数据进行降维时，如果将方差的比例阈值设定为 95%，保留的主成分数目就是 2 个，这说明 2 个主成分已经足以解释输出结果中 90% 的变化。

使用前两个主成分对英超数据集进行变换的结果

为了对主成分分析后的数据分布产生直观的认识，可以将变换后的数据点显示在低维空间中，以观察它们的集中程度。出于观察方便的考虑，在可视化时只选择了方差最大的前两个主成分，虽然这样做会造成较大的误差，但变换后的数据就可以在平面直角坐标系上显示出来，如上图所示。

可以看出，经过变换后的数据点依然分散在整个二维平面上，但根据它们在横轴上的取值已经可以近似地将数据划分为两个类别，其原因很可能是蓝线两侧的数据代表了两种类型的球队风格，就像来自两个高斯分布的随机数。

今天我和你分享了从岭回归到主成分回归的推导过程，以及作为降维方法和特征提取技术的主成分分析，其要点如下：

在有限的数据集下，数据维度过高会导致维数灾难；

降维的方法包括特征选择和特征提取；

主成分分析将原始的共线性特征转化为新的正交特征，从而实现特征提取；

概率主成分分析是因子分析的一种，是数据的生成模型。

在机器学习中，还有一种和主成分分析名字相似的方法，叫作独立成分分析（independent component analysis）。那么这两者之间到底有什么区别和联系呢？

你可以查阅资料加以了解，并在这里分享你的理解。

14 | 非线性降维：流形学习

“云行雨施，品物流形”，这是儒家经典《易经》对万物流变的描述。两千多年之后，“流形”一词被数学家借鉴，用于命名与欧几里得空间局部同胚的拓扑空间。

虽然流形这个词本身有着浓厚的学院派味道，但它的思想你却一点儿不会陌生。最著名的流形模型恐怕非瑞士卷（Swiss roll）莫属。如图所示的瑞士卷是常见的糕点，只是它的名字未必像它的形状一样广为人知。瑞士卷实际上是一张卷起来的薄蛋糕片，虽然卷曲的操作将它从二维形状升级成了三维形状，但这个多出来的空间维度并没有产生关于原始结构的新信息，所以瑞士卷实际上就是嵌入三维空间的二维流形。

瑞士卷（左）与瑞士卷流形（右）示意图

图片来自维基百科与 http://yinsenm.github.io/figure/STAT545/Swiss.png

在机器学习中，流形（manifold）指的是嵌入在高维数据空间中的低维子空间，它的维数是低维数据变化的自由度（degree of freedom of variability），也叫作固有维度（intrinsic dimensionality）。流形学习（manifold learning）正是通过挖掘数据的内在结构实现向固有维度的降维，从而找到与高维原数据对应的低维嵌入流形。

和主成分分析相比，流形可以是线性的，但更多是非线性的。正因如此，流形学习通常被视为非线性降维方法的代表。它不仅能够缓解维数灾难的影响，还具有比线性降维方法更强的特征表达能力。除了非线性外，流形学习的方法一般还是非参数的，这使流形能够更加自由地表示数据的固有维度和聚类特性，但也让它对噪声更加敏感。

要将数据从高维空间映射到低维流形上，首先要确定低维流形的结构，其次要确定高维空间到低维流形的映射关系。可在实际问题中，不管是流形结构还是流形维数都不是已知的，因此有必要做出一些先验假设以缩小问题的解空间。当关于流形的假设聚焦在数据的几何性质上时，就可以得到多维缩放（multiple dimensional scaling）算法。

在确定流形结构时，多维缩放让高维空间上的样本之间的距离在低维空间上尽可能得以保持，以距离重建误差的最小化为原则计算所有数据点两两之间的距离矩阵。根据降维前后距离保持不变的特点，距离矩阵又可以转化为内积矩阵。利用和主成分分析类似的方法可以从高维空间上的内积矩阵构造出从低维空间到高维空间的嵌入，其数学细节在此就不赘述了。

可是，原始高维空间与约化低维空间距离的等效性是不是一个合理的假设呢？想象一下你手边有个地球仪，这个三维的球体实际上也是由二维的世界地图卷成，因而可以约化成一个二维的流形。如果要在流形上计算北京和纽约两个城市的距离，就要在地球仪上勾出两点之间的“直线”，也就是沿着地球表面计算出的两个城市之间的直线距离。但需要注意的是，这条地图上的直线在二维流形上是体现为曲线的。

这样计算出的流形上的距离是否等于三维空间中的距离呢？答案是否定的。北京和纽约两点在三维空间中的欧氏距离对应的是三维空间中的直线，而这条直线位于地球仪的内部——按照这种理解距离的方式，从北京去纽约应该坐一趟穿越地心的直达地铁。这说明多维缩放方法虽然考虑了距离的等效性，却没能将这种等效性放在数据特殊结构的背景下去考虑。它忽略了高维空间中的直线距离在低维空间上不可到达的问题，得到的结果也就难以真实反映数据的特征。

吸取了多维缩放的经验教训，美国斯坦福大学的约书亚·泰宁鲍姆（Joshua Tenenbaum）等人提出了等度量映射的非线性降维方法。等度量映射（isometric mapping）以数据所在的低维流形与欧氏空间子集的等距性为基础。在流形上，描述距离的指标是测地距离（geodesic distance），它就是在地图上连接北京和纽约那条直线的距离，也就是流形上两点之间的固有距离。

在流形结构和维度未知的前提下，测地距离是没法直接计算的。等度量映射对这个问题的解决方法是利用流形与欧氏空间局部同胚的性质，根据欧氏距离为每个点找到近邻点（neighbors），直接用欧氏距离来近似近邻点之间的测地距离。

在这种方法中，测地距离的计算就像是奥运火炬，在每一个火炬手，也就是每一个近邻点之间传递。将每个火炬手所走过的路程，也就是每两个近邻点之间的欧氏距离求和，得到的就是测地距离的近似。

在每一组近邻点之间建立连接就可以让所有数据点共同构成一张带权重的近邻连接图。在这张图上，相距较远的两点的测地距离就被等效为连接这两点的最短路径，这个问题可以使用图论和网络科学中发展非常成熟的Dijkstra 算法来求解。计算出距离矩阵后，等度量映射的运算和多维缩放就完全一致了。

﻿等距离映射原理示意图

图 A 表示测地距离与欧氏距离的区别，图 B 表示利用近邻点近似计算测地距离，图 C 表示真实测地距离与近似测地距离的比较，图片来自 A global geometric framework for nonlinear dimensionality reduction, Science, vol. 290, 2319-2323

等度量映射关注的是全局意义上数据的几何结构，如果只关注数据在某些局部上的结构，其对应的方法就是局部线性嵌入。

局部线性嵌入（locally linear embedding）由伦敦大学学院的萨姆·洛维思（Sam Roweis）等人提出，其核心思想是待求解的低维流形在局部上是线性的，每个数据点都可以表示成近邻点的线性组合。求解流形的降维过程就是在保持每个邻域中的线性系数不变的基础上重构原数据点，使重构误差最小。

局部线性嵌入的实现包括两个步骤：在确定一个数据点的近邻点后，首先根据最小均方误差来计算用近邻点表示数据点的最优权值，需要注意的是所有权值之和是等于 1 的；接下来就要根据计算出的权值来重构原数据点在低维空间上的表示，其准则是重构的近邻点在已知权值下的线性组合与重构数据点具有最小均方误差。对重构映射的求解最终也可以转化为矩阵的特征值求解。

局部线性嵌入原理示意图

图 A 表示为数据点 XiXi 选择近邻点，图 B 表示将 XiXi 表示为近邻点的线性组合并计算系数 Wi⋅Wi⋅，图 C 表示保持 Wi⋅Wi⋅ 不变重构数据点 YiYi，图片来自 Nonlinear dimensionality reduction by locally linear embedding, Science, vol. 290, 2323-2326

将两种典型的流形学习算法加以比较，不难发现它们的区别在于对流形与欧氏空间关系的理解上。流形与欧氏空间就像两个平行世界，将它们联系起来的羁绊是拓扑性质的保持。

等度量映射理如其名，它将距离视为空间变换过程中的不变量，强调的是不同数据点关系的不变性，以及数据全局结构的完整保持。打个比方，如果把全局结构看作一个拼图玩具，等度量映射的任务就是将每一块拼图所代表的邻域正确组合，从而构成完美的完整图案。

相比之下，局部线性嵌入在乎的只有数据关系在某个邻域上的不变性。数据点可以用它的邻近点在最小二乘意义下最优的线性组合表示，这个局部几何性质是不会改变的。可是在邻域之外，局部线性嵌入并不考虑相距较远的数据点之间关系的保持，颇有些“各人自扫门前雪，莫管他人瓦上霜”的意味。显然，局部线性嵌入在拼图时更加随意，只要把所有的拼图块按嵌入关系连成一片就可以了，至于拼出什么奇形怪状都不在话下。

基于全局信息的等度量映射（左）和基于局部信息的局部线性嵌入（右）

不管是等度量映射还是局部线性嵌入，都以几何性质作为同构的基础。如果要从概率角度理解流形学习，最具代表性的例子非随机近邻嵌入莫属。随机近邻嵌入（stochastic neighbor embedding）的核心特点是保持降维前后数据的概率分布不变，它将高维空间上数据点之间的欧氏距离转化为服从正态分布的条件概率

pj|i=exp(−||xi−xj||2/2σ2i)∑k≠iexp(−||xi−xj||2/2σ2ipj|i=exp⁡(−||xi−xj||2/2σi2)∑k≠iexp⁡(−||xi−xj||2/2σi2

上式中的 σiσi 是困惑度参数（perplexity），可以近似地看成近邻点的数目。这个概率表达式来描述不同数据点之间的相似性。简单地说，相距越近的点形成近邻的概率越大，相似的概率也就越大。这就像我们在上学时按照身高排队一样，站在一起的人身高会更加接近，位于队首和队尾两个极端的人则会有较大的身高差。

映射到低维空间后，随机近邻嵌入按照和高维空间相同的方式计算低维空间上的条件概率，并要求两者尽可能地相似，也就是尽可能地保持数据间的相似性。重构的依据是让交叉熵（cross entropy），也就是 KL 散度（Kullback-Leibler divergence）最小化。

但 KL 散度不对称的特性会导致相聚较远的点体现为较大的散度差，为了使 KL 散度最小化，数据点映射到低维空间之后就会被压缩到极小的范围中。这就像一群学生突然被紧急集合到操场上，挤在一起之后根本分不清哪些人来自于哪个班，这就是所谓的拥挤问题（crowding problem）。

为了解决拥挤问题，深度学习的泰斗乔弗雷·辛顿和他的学生提出了 tt 分布随机近邻嵌入（tt-distributed stochastic neighbor embedding）。

新算法主要做出了两点改进：首先是将由欧氏距离推导出的条件概率改写成对称的形式，也就是 pij=pji=(pi|j+pj|i)/2pij=pji=(pi|j+pj|i)/2，其次是令低维空间中的条件概率服从 tt 分布（高维空间中的正态分布保持不变）。这两种改进的目的是一样的，那就是让相同结构的数据点在低维空间上更加致密，不同结构的数据点则更加疏远。事实证明，这一目的达到了。

线性可以看成是非线性的特例，从这个角度出发，概率主成分分析其实也可以归结到广义的流形学习范畴中。还记得前一篇文章的图片吗？两个满足正态分布的隐变量使数据分布呈现出类似煎饼的椭圆形状，这张煎饼实际上就是流形。煎饼所在的超平面显示的只是数据的投影，之所以选择这个平面来投影是因为数据的变化集中在这里。相比之下，数据在垂直于超平面的方向上方差较小，因而这些变化在降维时可以忽略不计。

既然都能实现数据的降维，那么以主成分分析为代表的线性方法和以流形学习为代表的非线性方法各自的优缺点在哪里呢？一言以蔽之，线性方法揭示数据的规律，非线性方法则揭示数据的结构。

主成分分析可以去除属性之间的共线性，通过特征提取揭示数据差异的本质来源，这为数据的分类提供了翔实的依据；而流形学习虽然不能解释非线性变化的意义，却可以挖掘出高维数据的隐藏结构并在二维或三维空间中直观显示，是数据可视化的利器，而不同的隐藏结构又可以作为特征识别的参考。

Scikit-learn 中包括了执行流形学习的 manifold 模块，将常用的流形学习方法打包成内置类，调用 Isomap、LocallyLinearEmbedding 和 TSNE 等类就可以计算对应的流形，算法的细节都被隐藏在函数内部，只需要输入对应的参数即可。

用以上算法将多元线性回归的英超数据集投影到二维流形上，由于数据集中的数据点较少，各种算法中近邻点的数目都被设置为 2 个，得到的结果如下。可以看出，三种方式计算出的流形中似乎都存在这一些模式，但说明这些模式的意义可就不像将它们计算出来那么简单了。

对英超数据集进行非线性降维的结果，使用的算法从左到右分别为等距离映射、局部线性嵌入和 tt 分布随机近邻嵌入

今天我和你分享了几种典型的流形学习方法，但没有过多涉及这些方法的数学细节，感兴趣的话，你可以参考不同算法的原始论文。今天的内容要点如下：

流形学习是非线性的降维方法，目的在于找到与高维数据对应的低维嵌入流形；

等度量映射是基于全局信息的流形学习方法，通过测地距离和欧氏距离的等效性计算流形；

局部线性嵌入是基于局部信息的流形学习方法，通过局部线性系数的不变性计算流形；

tt 分布随机近邻嵌入将欧氏距离映射为相似性，利用相似性的保持计算流形。

从前文中英超数据集的流形可以看出，当现实中复杂的高维数据被映射到二维或三维流形上时，大呼神奇之后如何对得到的结果加以解释又是个棘手的问题。那么你觉得流形学习到底具有哪些实在的作用呢？

欢迎分享你的观点。

15 | 从回归到分类：联系函数与降维

线性模型最初被用来解决回归问题（regression），可在实际应用中，更加普遍的是分类问题（classification）。要用线性模型解决分类问题的话，就需要将线性模型原始的连续输出转换成不同的类别。

在分类问题中，一种特殊的情况是类别非黑即白，只有两种，这样的问题就是二分类问题，它可以看成是多分类问题的一个特例，也是今天讨论的对象。

将回归结果转化为分类结果，其实就是将属性的线性组合转化成分类的标准，具体的操作方式有两种：一种是直接用阈值区分回归结果，根据回归值与阈值的关系直接输出样本类别的标签；另一种是用似然度区分回归结果，根据回归值和似然性的关系输出样本属于某个类别的概率。

这两类输出可以分别被视为硬输出和软输出，它们代表了解决分类问题不同的思路。

硬输出是对数据的分类边界进行建模。实现硬输出的函数，也就是将输入数据映射为输出类别的函数叫作判别函数（discriminant）。判别函数可以将数据空间划分成若干个决策区域，每个区域对应一个输出的类别。不同判别区域之间的分界叫作决策边界（decision boundary），对应着判别函数取得某个常数时所对应的图形。用线性模型解决分类问题，就意味着得到的决策边界具有线性的形状。

最简单的判别函数就是未经任何变换的线性回归模型 y(x)=wTx+by(x)=wTx+b，它将回归值大于某个阈值（可以通过调整截距 bb 设置为 0）的样本判定为正例，小于阈值的样本则判定为负例。

在处理多分类任务时，判别函数对每个类别都计算出一组系数 wkwk 和 bkbk，并选择使 yk(x)yk(x) 最大的 kk 作为输出类别。如果分类的边界较为复杂，还可以通过基函数的扩展或者核技巧来突破线性的限制，相关的内容会在后面的文章中涉及。

今天我们先来看看基于软输出的分类方法。软输出利用的是似然度，需要建立关于数据的概率密度的模型，常见的具体做法是对线性回归的结果施加某种变换，其数学表达式可以写成

y(x)=g−1(wTx+b)y(x)=g−1(wTx+b)

这里的 g(⋅)g(⋅) 被称为联系函数（link function），其反函数 f(⋅)=g−1f(⋅)=g−1 则被称为激活函数（activation function）。正是联系函数架起了线性模型从回归到分类的桥梁。

最典型的软输出分类模型就是逻辑回归。在“人工智能基础课”中我曾介绍过，逻辑回归（logistic regression）是基于概率的分类算法，估计的是样本归属于某个类别的后验概率，那么根据贝叶斯定理，二分类问题中的后验概率就可以写成

p(C1|x)=p(x|C1)p(C1)p(x|C1)p(C1)+p(x|C2)p(C2)p(C1|x)=p(x|C1)p(C1)p(x|C1)p(C1)+p(x|C2)p(C2)

对这个表达式做个简单的变量代换，就可以得到

p(C1|x)=11+exp(−a)=σ(a)p(C1|x)=11+exp⁡(−a)=σ(a)

这里的 σ(⋅)σ(⋅) 表示对数几率函数（logistic function），也就是逻辑回归的联系函数，这个非线性的联系函数可以将任意输入映射到 [0, 1] 之间。对数几率函数的自变量 aa 可以改写成

a=lnp(x|C1)p(C1)p(x|C2)p(C2)=lnp(x|C1)p(x|C2)+lnp(C1)p(C2)=wTx+ba=ln⁡p(x|C1)p(C1)p(x|C2)p(C2)=ln⁡p(x|C1)p(x|C2)+ln⁡p(C1)p(C2)=wTx+b

逻辑回归并不能直接给出参数 ww 的解析解，因此需要结合最优化的方法使用。确定参数最常用的方式是使用最大似然估计（maximum likelihood estimation），找到如训练数据匹配度最高的一组参数。

在二分类问题中，若假设当 xx 属于类 C1C1 时，输出的分类结果 rr 为 1，属于类 C2C2 时，输出的分类结果 rr 为 0，那么每个单独的分类结果都满足参数为 σ(x)σ(x) 的两点分布，所有结果构成的向量 rr 就会满足二项分布，这时的似然概率就可以写成分类结果的连乘

p(w,b|x)=∏iσ(xi)ri[1−σ(xi)](1−ri)p(w,b|x)=∏iσ(xi)ri[1−σ(xi)](1−ri)

对似然概率求对数并求解最大值，就可以得到最优的参数了。

和逻辑回归相似的另一种分类模型是线性判别分析，它不仅要估计数据的概率密度，还应用了降维的思想。在前面的两篇文章中，我和你分享了对数据进行线性降维和非线性降维的方法。

其实降维不光是数据预处理的一种手段，它还可以用来执行分类任务——本质上讲，分类问题就是将高维的数据投影到一维的类别标签上。

维度的下降会导致信息的损失，从而使数据在标签维度上产生重叠。属于相同类别的数据重叠在一起并不是严重的问题，但类别不同的数据的重叠就会增加分类问题的错误率，因此好的分类算法既要让相同类别的数据足够接近，又要让不同类别的数据足够远离。基于这一原则进行分类的方法就是线性判别分析。

用于二分类的线性判别分析由著名的统计学家罗纳德·费舍尔于 1936 年提出，按人类的年龄计算已是耄耋之年。归根结底，线性判别分析也是从概率出发，假设不同类别的数据来源于均值不同而方差相同的正态分布，通过判定数据归属于不同正态的可能性来确定类别。

但在设计线性判别分析时，费舍尔利用了一种不同的思路。在计算二分类问题的决策边界时，线性判别分析首先要计算两个类别中数据的均值，以此作为特征来区分不同的类别，让不同类别的数据足够远离就是让两个均值在决策边界上的投影之间的距离足够大。

但仅是均值远离还不够。数据在不同维度上的分布不同会导致有些方向的方差较大，而有些方向的方差较小。如果仅仅考虑均值而忽略了方差，就可能导致判决边界落在波动较大的方向上，由此产生的长尾效应容易使不同类别的数据互相重叠，从而影响分类的精度。因此在投影时，还要让相同类别的数据尽可能集中分布，以避免混叠的出现。

假定训练数据分属两个类别 C1C1 和 C2C2，每个类别中数据的均值用向量 m1m1 和 m2m2 表示，那么这两个均值在超平面 y=wTx+by=wTx+b 上的投影就等于

mk=wTmk(k=1,2)mk=wTmk(k=1,2)

降维后两个类各自的方差可以表示为

sk=∑n∈Ck(yn−mk)2(k=1,2)sk=∑n∈Ck(yn−mk)2(k=1,2)

要同时保证类间距最大和类内方差最小，可以通过最大化下面的目标函数来实现

J(w)=(m2−m1)2s21+s22J(w)=(m2−m1)2s12+s22

其中待求解的参数 ww 需要满足归一化条件 ||w||22=1||w||22=1，而这并不会对 ww 的方向造成影响。将线性回归模型代入 J(w)J(w) 的表达式，可以将它改写成

J(w)=wTSBwwTSWwJ(w)=wTSBwwTSWw

这里有这么几个概念。

类间协方差矩阵（between-class covariance matrix）

SB=(m2−m1)(m2−m1)TSB=(m2−m1)(m2−m1)T

类内协方差矩阵（within-class covariance matrix）

SW=∑n∈C1(xn−m1)(xn−m1)T+∑n∈C2(xn−m2)(xn−m2)TSW=∑n∈C1(xn−m1)(xn−m1)T+∑n∈C2(xn−m2)(xn−m2)T

两者之商的学名叫作广义瑞利商（generalized Rayleigh quotient）。可以求出，使广义瑞利商最大化的解析解为 w=S−1w(m2−m1)w=Sw−1(m2−m1)。

单从形式上看，线性判别分析和主成分分析同属于降维技术，有不少相似的地方，但两者却有本质上的区别。主成分分析的目的是保留不确定性，是通过选择方差最大的主成分来实现信息损失最小的数据低维度重构，整个过程是无监督的。

相比之下， 线性判别分析在降维时要利用数据的类别，因而属于监督学习的范畴，学习的目的则是消除不确定性。消除的不确定性就是类间方差，这部分信息被提取到了类别标签中。分类之后数据的方差越小，意味着降维后剩余的类内不确定性就越小。

在实际应用中，通常可以先使用主成分分析进行特征提取，再利用线性判别分析做训练。这就相当于先把数据的信息集中在某些特征上，再利用不同的类别把这些信息提取出来。

主成分分析（左）与线性判别分析（右）的对比

图片来自 https://zybuluo.com/anboqing/note/117518

将线性模型扩展到分类问题中时，线性判别分析和逻辑回归作为两种具有代表性的模型，都是基于概率生成线性的分类边界，因此有必要做一比较。

线性判别分析就像个傲娇的老师，只愿意指导天赋异禀的学生，这体现在它对数据的要求上：第一，每个类别的数据必须服从潜在的多元正态分布；第二，每个类别的数据必须具有相同或者相近的协方差矩阵；第三，数据的属性之间不能存在较强的共线性，计算出的协方差矩阵应为满秩矩阵；第四，数据中尽可能不存在异常点。

虽然在实际问题中，一定程度上放宽这些条件并不会对线性判别分析的性能产生太大的影响，但这些条件还是严重地限制了方法的应用，使找到一个能解决的问题比解决这个问题更加困难。

相比之下，逻辑回归就没有那么多讲究了，这个老师不管学生好坏都能因材施教。它无需对数据分布做出任何先验假设（两点分布是二分类问题必然的结果），对数据的协方差矩阵和共线性也没有特殊的要求。即使当数据集中存在一些异常点，逻辑回归也能完成精确地分类。整体来说，线性判别分析只能在所有条件都满足时发挥出最佳的性能，在任何其他的场景下都要略逊逻辑回归一筹。

虽然实现的方式有所不同，但本篇所介绍的两种解决分类问题的方法在思想上是一致的，那就是根据数据的概率密度来实现分类。这两种基于似然度（likelihood-based）的模型在执行分类任务时不是以每个输入样本为单位，而是以每个输出类别为单位，将每个类别的数据看作不同的整体，并寻找它们之间的分野。这样看来，数据和人一样，也要面临站队的问题啊！

在 Scikit-learn 中，线性判别分析在模块 discriminant_analysis 中实现，逻辑回归则在模块 linear_model 中实现。由于逻辑回归需要使用有标签的数据，因而原来的回归数据就不能使用了。

这次使用的数据依然来自于 WhoScored 的英超技术统计：我选取了 17/18 赛季平均评分最高的 20 名中卫和 20 名中锋，他们的首发次数均在 15 次以上。数据的属性包括每个人的场均射门数和场均铲球数两个维度，位置则作为分类标签出现。熟悉足球的朋友肯定明白，中卫的铲球数较多，而中锋的射门数较多，因此这两个指标可以用来作为判断位置的根据。

﻿线性判别分析和逻辑回归在中卫 - 中锋数据集上的决策边界，红色圆点代表中卫，蓝色三角代表中锋

用上面的数据集训练使用不同的线性分类模型，得到的效果也不相同。这个数据集本身是线性可分的，也就是存在将两个类别完全区分开来的线性边界，这条边界也被逻辑回归正确地计算出来。可遗憾的是，线性判别分析并没有找到准确的边界，而是将一个热爱防守的前锋（斯旺西城 18 号乔丹·阿尤，每场的铲球多过射门，这不禁让人想起著名的防守型前锋德克·库伊特）误认成后卫。

直观地从数据分布的图示看，这个被线性判别分析误分类的蓝点和其他蓝点相距较远，反倒是和红点更加接近，怎么看怎么像是个异常点。在计算数据的统计特性时，这个离群索居的样本远离了归属类的均值，也就难怪会被同伴所抛弃。这也印证了前面的说法：线性判别分析需要较强的假设来支持。

今天我和你分享了使用线性模型解决分类问题的方法，其要点如下：

在解决分类问题时，线性模型的回归值可以通过联系函数转化为分类结果；

线性判别分析假定数据来自均值不同但方差相同的正态分布，通过最大化类间方差与类内方差的比值计算线性边界；

逻辑回归计算的是不同类别的概率决策边界，输出的是给定数据属于不同类别的后验概率；

基于线性模型的分类方法计算出的决策边界是输入属性的线性函数。

当线性边界不足以完成分类任务时，线性判别分析可以推广为二次判别分析（Quadratic Discriminant Analysis），那么两者之间存在这哪些区别和联系呢？

你可以查阅资料加以了解，并在这里分享你的理解。

16 | 建模非正态分布：广义线性模型

直观来看，上一篇文章介绍的逻辑回归只是对普通线性回归的输出加以变换，以满足问题的需要。但在这简单的现象背后，以逻辑回归为代表的这类线性模型的推广具有更加深刻的数学内涵，因而被称为广义线性模型（generalized linear model）。

线性模型的意义是建立了自变量和因变量的关联，当自变量变化时，因变量也会出现依照比例同等程度的变化。可是现实世界不是数学模型，如果硬要将线性模型套用在实际问题中，很可能会闹出笑话。

如果线性回归告诉你气温每下降 1 度，海滩上的游客就会减少 100 人，那么这条规律适用于科帕卡巴纳或者芭堤雅的问题不大，因为这些著名的度假胜地的游客基数数以万计。可是对于一个最多只能接待 80 名游客的不知名小海滩来说，气温下降 1 度意味着游客数目变成了 -20，难不成工作人员也被冻跑了吗？这和不能听相声是一个道理：“笑一笑十年少”也是个线性模型，要是这个模型属实的话，哪怕只听一分钟相声我都要回到娘胎里去了。

物理学中有个概念叫半衰期，不严格地说，它指的是放射性元素的原子核半数发生衰变所需要的时间。元素的半衰期和原子的总量无关，100 个原子中衰变 50 个的时间和剩下的 50 个原子中衰变 25 个的时间是一致的。和线性模型相比，以半衰期为代表的建模方式似乎更加符合真实世界的规律：因变量变化的绝对尺度通常是非线性的，但其变化比率却会和自变量呈现线性关系。

半衰期的思路也可以自然地延伸到离散输出的问题当中。如果说气温每上升 1 度，某人去海滩的概率就会翻一番，这是否意味着在原本有 75% 的概率去海滩时，温度的上升会将这个概率提高到 150% 呢？肯定不是。气温升高会让去海滩的概率增大，不去海滩的概率减小。如果将去与不去的概率之比定义为几率（odd），那么气温升高会导致相对的几率，而非绝对的概率翻一番显然是更合理的解释。按这种方式计算，气温上升 1 度会让 75% 的概率变成 85.7%，这样就说得通了。

除了能否真实表示自变量和因变量的关联之外，线性回归将因变量的误差定义为正态分布其实也是过于理想的假设。比如当因变量是离散输出时，使用正态分布假设的建模效果自然会大打折扣。在一场足球比赛中，某只球队进球数目超过 8 个的概率微乎其微。因而在预测某队的进球数时，用正态分布对分布在 01234567 这些离散数值上的因变量进行建模就缺乏合理性，泊松分布才是更好的选择。

可不巧的是，正态分布恰恰是狭义线性模型的核心成分，它是联结最小均方误差和最大似然估计的纽带。在求解时，狭义的线性模型建立在最小均方误差的意义上，其解析解可由普通最小二乘法求得，求解时的一个基本前提是因变量，也就是回归结果的误差服从正态分布，这个推导过程我在“人工智能基础课”中有详细介绍。

误差的正态分布意味着因变量既可以增加也减少，其增加或者减少的范围虽然不存在上限，却以较大的概率出现在一个较小的区间内。如果按照前文的方式改造狭义线性模型的话，噪声的正态性质就不能得以保持，简洁明晰的解析解也会不再适用。因此，要拓展线性模型的应用范围，新的数学工具不可或缺。

广义线性模型（generalized linear model）就是这样的数学工具。在广义线性模型中，因变量可以满足任意形式的概率分布，它与自变量的线性组合之间的关系由联系函数定义。逻辑回归就是广义线性模型的一个实例，它的因变量是二进制的输出，联系函数则是对数几率函数。这个实例体现出了在一般意义上，广义线性模型要满足一些共性的条件。

首先，广义线性模型的基础是指数分布族（exponential family）。模型的因变量 yy 由自然参数（natural parameter）ηη 决定，yy 的概率密度函数可以写成

p(y;η)=b(y)exp[ηTT(y)−a(η)]p(y;η)=b(y)exp⁡[ηTT(y)−a(η)]

其中的 T(y)T(y) 是个充分统计量（sufficient statistic），通常令它等于 yy 本身；b(⋅)b(⋅) 和 a(⋅)a(⋅) 都是已知的函数。虽然这个模型看起来比较复杂，但只要选择合适的 b(⋅)b(⋅) 和 a(⋅)a(⋅)，常见的正态分布和指数分布等连续型分布，以及二项分布和泊松分布等离散性分布都能够满足这个条件，也就都属于指数分布族。

在因变量属于指数分布族的前提下，广义线性模型需要求解给定数据 XX 时，充分统计量 T(y)T(y) 的条件期望。当 T(y)=yT(y)=y 时，模型的任务就退化为求解 E(y|X)=μE(y|X)=μ，求解的方法就是利用联系函数定义代表自变量的数据和因变量的条件期望值之间的关系。

“线性”的含义正体现在联系函数的反函数 g(⋅)−1g(⋅)−1 的输入，也就是自然参数 ηη 是数据的线性组合，写成数学表达式就是

μ=g−1(η)=g−1(Xβ)μ=g−1(η)=g−1(Xβ)

这说明数据的线性组合 XβXβ 就是联系函数在输入为条件期望 μμ 时的输出。

总结下来，指数分布族、联系函数和线性关系共同构成了广义线性模型的三大要素。自变量的线性组合就是指数分布族的自然参数，它被送入到激活函数中，计算得出给定数据时因变量的条件期望。在这个更加通用的概念层面上，我们就可以重新审视逻辑回归。

逻辑回归的输出 yy 服从两点分布，如果两点分布的参数是 ψψ，它的概率质量函数就可以写成 p(y;ψ)=ψy(1−ψ)1−yp(y;ψ)=ψy(1−ψ)1−y，这个表达式稍做数学整理就是

p(y,ψ)=exp[ylogψ1−ψ+log(1−ψ)]p(y,ψ)=exp⁡[ylog⁡ψ1−ψ+log⁡(1−ψ)]

令自然参数 ηη 等于标量 log[ψ/(1−ψ)]log⁡[ψ/(1−ψ)]，充分统计量 T(y)T(y) 等于 yy，两个函数 b(y)=1,a(η)=−log(1−ψ)b(y)=1,a(η)=−log⁡(1−ψ)，逻辑回归中的因变量分布就变化为指数分布族的表示形式，因而属于指数分布族。这时，因变量 yy 在数据 XX 和参数 ψψ 下的条件期望就等于 E(y|X,ψ)=ψ=[1+exp(−η)]−1E(y|X,ψ)=ψ=[1+exp⁡(−η)]−1，这就是逻辑回归使用对数几率函数的原因所在。再将自然参数写成数据的线性组合，就是逻辑回归的方法了。

回头来看，广义线性模型解决了前文中提到的狭义线性模型的两个问题，这两个问题体现在广义线性模型的两种成分之上。自变量和因变量之间的系统性关联在广义线性模型中体现为系统成分（systematic component）。和狭义线性模型一样，系统成分仍然保留着对自变量的线性性质，只不过自变量线性组合的结果不再直接和因变量对应，而是要先做出非线性的变换。

因变量的误差在广义线性模型中以随机成分（random component）的角色出现。随机成分不受正态分布的限制，可以被建模成任何属于指数分布族的概率分布。使用指数分布族后，因变量的均值就能够决定误差的性质，从而包含了更多的信息。这不仅大大拓展了广义线性模型的应用范围，还保留了利用最大似然估计计算最优参数的可行性。

说到现在，系统成分和随机成分还是井水不犯河水的独立数量，将它们联系起来的任务就落在了联系函数身上。联系函数将因变量的数学期望表示成自变量线性组合的函数。

在普通线性模型中，联系函数就是因变量本身；而在逻辑回归等比较简单的广义线性模型里，联系函数将指数分布中的自然参数表示成自变量的线性组合，这样的联系函数就是正则联系函数（canonical link）。

正则联系函数的好处是保证待估计参数 ββ 的最小完全统计量存在，所有关于 ββ 的信息都可以由一个和 ββ 维度相同的函数获得。

和普通线性模型一样，广义线性模型也可以从贝叶斯的角度去认识。

贝叶斯学派将待估计的参数同样视为随机变量，因此可以假设参数 ββ 满足多维正态分布，并将它结合到原始的最大似然估计中。之所以不使用均匀分布作为先验分布的原因是当训练数据线性可分时，这种无信息的先验会让似然估计无法计算出结果，相当于将简单的问题复杂化。引入先验分布可以简化模型选择的过程，自动起到正则化的作用，但其计算也会更加复杂，需要通过数值方法来求解。

Scikit-learn 库只能够实现逻辑回归，要构造通用意义上的广义线性模型的话，就要借助侧重统计分析的 statsmodels。在这里我以泊松回归（Poisson regression）为例。

泊松分布适用于描述单位时间或空间内随机事件发生的次数，比如电话交换机接到呼叫的次数，汽车站台的候客人数，机器出现的故障数，自然灾害发生的次数等。在足球比赛中，由于某支球队在每场比赛的进球数是典型的计数型变量，故而通常使用泊松分布来建模。

如果以新科英超冠军曼城队作为数据采集对象，统计曼城队在 2017-18 英超赛季所有主场比赛中的进球数，得到的就是包含 19 个样本的数据集。这个数据集的因变量是符合泊松分布的进球数目，自变量则考虑了一系列和进攻有关的数据，包括射门次数（shots）、射正次数（shots on target）、传球成功率（pass accuracy）、争顶成功率（aerial dual success）、过人次数（dribbles won）和控球比率（possession）这么几个属性。用这些属性对进球数进行泊松回归的拟合，可以得到如下的结果

基于所有属性的泊松回归结果

从结果中可以看出，泊松回归使用的联系函数是自然对数函数。在统计学的显著性上，射正次数、传球成功率和控球比率三个属性对进球数有明显的影响，另外三个属性对进球数基本没有贡献。利用这三个强相关的属性来拟合泊松回归，又可以得到下面的结果

基于强相关属性的泊松回归结果

可以看到，基于强相关属性计算出的线性系数基本没有变化。由于泊松回归使用的联系函数是对数函数，所以线性回归分析出来的结果是因变量期望值的对数，要解释计算出的参数就得对它们做个指数运算。exp(x1)=1.18exp(x1)=1.18 可以粗略地解释为当其他条件不变时，每多一脚命中门框的射门都能让进球数变成原来的 1.18 倍。但整体来看，广义线性模型在增强表达能力时，付出的是可解释性的代价。

今天我和你分享了广义线性模型的概念与原理，它克服了狭义线性模型的一些限制，拓展了线性模型的应用范围。其要点如下：

广义线性模型从模型解释性和变量分布特性上对普通线性模型做了推广；

广义线性模型假定因变量服从指数分布族中的概率分布，这代表了模型中的随机成分；

广义线性模型中的自变量和因变量依然由线性系数决定，这代表了模型中的系统成分；

联系函数建立系统成分和随机成分的关系，将指数分布的自然参数表示为自变量的线性组合。

最后要说明的是，广义线性模型和一般线性模型（general linear model）虽然名字相似，却是两个不同的概念，你可以了解下他们之间的区别，并在这里分享你的理解。

17 | 几何角度看分类：支持向量机

前文中介绍过的逻辑回归是基于似然度的分类方法，通过对数据概率建模来得到软输出。而在另一类基于判别式的硬输出分类方法中，代表性较强的就得数今天要介绍的支持向量机了。

支持向量机并不关心数据的概率，而是要基于判别式找到最优的超平面作为二分类问题的决策边界。其发明者弗拉基米尔·瓦普尼克（Vladimir Vapnik）用一句名言清晰地解释了他的思想：能走直线就别兜圈子。

当然啦，这是“信达雅”的译法，老瓦的原话是“不要引入更加复杂的问题作为解决当前问题的中间步骤（When trying to solve some problem, one should not solve a more difficult problem as an intermediate step. ）”。

在他看来，估算数据的概率分布就是那个作为中间步骤的复杂问题。这就像当一个人学习英语时，他只要直接报个班或者自己看书就行了，而不需要先学习诘屈聱牙的拉丁语作为基础。既然解决分类问题只需要一个简单的判别式，那就没有必要费尽心机地去计算似然概率或是后验概率。正是这化繁为简的原则给支持向量机带来了超乎寻常的优良效果。

一提到支持向量机，大部分人的第一反应都是核技巧。可核技巧诞生于 1995 年，而支持向量机早在 30 年前就已经面世。支持向量机（support vector machine）是基于几何意义的非概率线性二分类器，所谓的核技巧（kernel trick）只是支持向量机的一个拓展，通过维度的升高将决策边界从线性推广为非线性。所以对于支持向量机的基本原则的理解与核技巧无关，而是关乎决策边界的生成方式。

线性可分数据集的决策边界（图片来自维基百科）

想象一下，如果一个数据集是二维平面上的线性可分数据集，那它的决策边界就是一条简单的直线。可这条能将所有训练数据正确区分的直线是不是唯一的呢？显然，答案是否定的，因为两个最近的异类点之间存在一段距离，这从上图中就能看出。事实上，像这样的能正确区分数据的直线有无数条。

那么问题来了：在这些直线里，哪一条是最好的呢？这里我们抛开复杂的数学证明，而是通过直观的几何视角来解释：回头看看上面的示意图，蓝色直线 H2H2 和红色直线 H3H3 都能不出任何错误地完成分类。那么在不存在关于数据的其他信息的情况下，你是会选择 H2H2 还是 H3H3 作为最优决策边界呢？

这里我们先抛除数据的抽象意义，而是把不同颜色的原点想象成是正在打仗的两支军队，现在双方要停火休战，自然要划出一条停火线，以及由停火线延伸出来的非交战区。如果你是黑军的司令官，那就断然不会选择 H1H1 作为停火线，因为它直接把你的一部分麾下赶到对方的阵地当中，把自己人拱手相让可不是优秀的指挥官该做的事情。

既然 H1H1 不行，那 H2H2 行不行呢？这样一条停火线能保证双方各自坚守阵地，看起来是个不错的选择。可问题在于它离双方的阵地太近了，如果有些人存心越雷池搞事，他完全可以偷偷地穿越非交战区并越过停火线，打一梭子黑枪就跑。由于停火线和阵地的距离太近，白军的骚扰部队完全可以在你发现之前就神不知鬼不觉地完成任务并且安全返回了。虽然你的黑军也可以同样地操作以眼还眼以牙还牙，但归根结底还是不利于和平的嘛！

如此看来，能够入你法眼的停火线就只有 H3H3 了，它既保证了所有士兵都驻扎在自己的阵地当中（数据中没有分类错误），又划定出足够宽阔的非交战区，杜绝了偷袭的可能性（数据与决策边界的距离足够大）。有了这样一条理想的停火线，谈判时心里是不是也会多几分踏实呢？

说完这个类比，还是要书归正传，回到数据本身。机器学习的算法关注的不仅是训练误差，更是泛化误差。

在上面的二分类问题中，边界 H2H2 过于靠近一些训练数据，那么这些靠近边界的数据受噪声或干扰影响时，得到的真实数据就更容易从一个类别跳到另外一个类别，导致分类的错误和泛化性能的下降。相比之下，边界 H3H3 距离两侧的数据都比较远，如果这些数据点要从 H3H3 的一侧跳到另一侧的话，它们要跨越的距离就会更大，跳过去的难度也就大多了。

直观的几何意义告诉我们，位于不同类别数据正中间的决策边界对样本扰动的容忍度最高，在未知数据上的泛化性能也就最好。那么问题来了：什么样的超平面才算“正中间”呢？这就得通过构造最优化问题来解决啦！相关内容在“人工智能基础课”中已有介绍，在这里就不重复了。

换个角度看，正中间的超平面实际上就是几何意义上最优的决策边界。还是以二维平面为例，不妨假设存在能够将数据完全区分开来的两条平行线，所有正类数据点都在这两条平行线的一侧，所有负类数据点则在平行线的另一侧。更重要的是，我们要让这两条平行线中的一条经过一个正类点，另一条则经过一个负类点。不难发现，这两个点就是欧氏距离最近的两个异类点了。

接下来，让这两条平行线以它们各自经过的异类点为不动点进行旋转，同时保证平行关系和分类特性不变。在旋转的过程中，两个不动点之间的欧氏距离是不变的，但两条线的斜率一直在改变，因此它们之间的距离也会不断变化。当其中一条直线经过第二个数据点时，两条直线之间的距离就会达到最大值。这时，这两条平行线中间的直线就是最优决策边界。

如果你对上一季的内容还有印象就会想到，落在两条平行线上的几个异类点就是支持向量（support vector）。如果将最优决策边界看成一扇双向的推拉门，把这扇门向两个方向推开就相当于两条平行线的距离逐渐增加。当这两扇门各自接触到支持向量时停止移动，留下来的门缝就是两个类别之间的间隔。

最优分隔超平面与支持向量（图片来自维基百科）

间隔（margin）是支持向量机的核心概念之一，它是对支持向量到分离超平面的距离度量，可以进一步表示分类的正确性和可信程度。根据归一化与否的区别，间隔还可以分成几何间隔（geometric margin）和函数间隔（functional margin），这两者的定义也在“人工智能基础课”中已经做过介绍，你可以回忆一下。

当数据线性可分时，分离超平面有千千万，但几何间隔最大的只有一个。支持向量机的基本思想就是找出能够正确划分数据集并且具有最大几何间隔的分离超平面（maximum-margin hyperplane）。

可是，只是将线性可分的数据分开不算本事，应用在线性不可分的数据上时，支持向量机会不会像单层感知器一样崩溃呢？肯定会啦！但支持向量机明白不能不撞南墙不回头，既然将全部数据点正确分类是不可能完成的任务，那就不如退而求其次，以放过几个漏网之鱼为代价来保证大多数数据的正常分类。

这些漏网之鱼就是通常所说的异常点，它们将线性可分条件下的硬间隔（hard margin）变成了线性不可分条件下的软间隔（soft margin），这就让支持向量机的优化对象从原始的间隔距离变成了间隔距离和分类错误率的折中。

在计算软间隔时，支持向量机利用合页损失函数（hinge loss）来表示分类错误率。合页损失可以看成是对计数表示的分类错误率的近似。从它的图像可以看出，作为一个连续函数，合页损失只计算了错误分类结果的相关指标，分类正确的数据对它是没有贡献的。

因此在软间隔的优化中，也只需要考虑几个异常点对决策边界的影响。这恰恰体现出了支持向量机的思想方法：最终的决策边界仅与少数的支持向量有关，并不会受到大量普通数据的影响。

合页损失的引入可以看成是对线性可分支持向量机的正则化处理，在优化问题中它们会以松弛变量（slack variable）的形式出现。在瓦普尼克的词典里，这个思想叫作结构风险最小化（structrual risk minimization）。和结构风险最小化相对应的是经验风险最小化（empirical risk minimization），表示的就是训练误差最小。

在之前的文章中我们多次提到，训练误差太小并不是好事，这很有可能导致模型过于复杂而出现过拟合。结构风险最小化就是带着抑制过拟合的任务出现的。

瓦普尼克将支持向量机的泛化误差 R(w,b)R(w,b) 分成了两部分，即 R(w,b)=Remp(w,b)+ϕR(w,b)=Remp(w,b)+ϕ。其中 Remp(w,b)Remp(w,b) 是模型在训练集上的经验风险，也就是训练误差，ϕϕ 则表示了训练误差在泛化时的置信区间，也可以叫作置信风险，这是个和假设空间的 VC 维有关的量。

假设空间的 VC 维越小，意味着模型的复杂度越低，对应的置信误差就越小，模型的泛化性能也就越强。

除了间隔之外，支持向量机的另一个核心概念是对偶性（duality）。间隔的作用体现在原理上，而对偶性的作用体现在实现上。虽然通过前面那些形象的例子我解释了为什么最优的决策边界会存在，它们却解决不了如何求解最优边界的问题。无论是硬间隔的计算还是软间隔的计算，都可以通过拉格朗日乘子的引入将原始问题转化成对偶问题来找到最优解。这部分内容在下一篇中会出现，这里先做个铺垫。

用于试验支持向量机的数据也来自英超，关注的焦点在于不同的比赛风格。传统的英式足球强调身体对抗、长传冲吊与高举高打，来自大陆和南美的拉丁派打法则偏重于对球的控制和精准传切，这两种不同的风格可以通过比赛数据直观体现出来。

我将以 2017-18 赛季英超联赛冠军曼城（Manchester City）和副班长西布罗姆维奇（West Bromwich Albion）38 场联赛的数据作为样本，每个样本都包含每场比赛的长传数目、短传数目、头球射门数和脚下射门数 4 个属性，实际使用的则是前两者和后两者各自的比值。

在 Python 中实现支持向量机，需要调用 Scikit-learn 库中的 svm 模块，通过其中的 SVC 类来实现分类。要生成线性边界，需要将 SVC 中的 kernel 参数设置为 linear，同时还要将常数项 CC 设置为一个接近正无穷的值，以避免正则化的使用。

此外，在 svm 模块中还有另外一个名为 LinearSVC 的类，其功能与 linear kernel 的 SVC 近似，但在同一个数据集上得到的结果是不同的。两者的区别你可以参考这个网页 https://stackoverflow.com/questions/45384185/what-is-the-difference-between-linearsvc-and-svckernel-linear，在此感谢原作者。

﻿﻿用支持向量机对比赛风格数据集的分类结果

将数据点以传球比和射门比为横纵坐标画在同一个坐标平面内，得到的就是上图的结果，图中的横坐标是长传数与短传数之比，纵坐标为头球射门与脚下射门之比。可以看出，曼城的球风是长传少头球少，而西布朗恰恰相反。

但具体到不同的比赛中，偶尔也会出现与常规球风相左的情形，这就是数据集中的异常点。由于这个数据集并不是线性可分的，因而只能用软间隔来刻画。从图上看，支持向量机的分类结果差强人意：除了 3 个明显的异常点外，其他数据的划分都是正确的。有些数据点虽然距离最优分离超平面较近，但并没有出现错误。

今天我和你分享了支持向量机的概念与原理，着重从几何意义上解释了算法的来龙去脉，其要点如下：

支持向量机是基于线性判别式几何意义的分类算法；

支持向量机通过间隔最大化来定义最优的决策边界；

支持向量机通过对偶问题来求解最优的决策边界；

支持向量机的目标是让结构风险最小化。

支持向量机固然好用，却由于原理的限制而不能直接地推广到多分类问题上，其几何意义在多分类任务中并不能直观地体现。那么支持向量机如何解决多分类问题呢？

你可以查阅相关资料，并在这里分享你的见解。

18 | 从全局到局部：核技巧

俗话说得好：“支持向量机有三宝，间隔对偶核技巧”。在上一篇文章中我和你分享了间隔这个核心概念，今天就来看看对偶和核技巧的使用。对偶性主要应用在最优决策边界的求解中，其逻辑比较简单。

但在介绍核技巧时，会先后涉及核函数、核方法、核技巧这些近似的概念。虽然从名字上看，它们都是“核”字辈的兄弟，但是在含义和用途上却不能一概而论，因此有必要对它们做一些系统的梳理。

当支持向量机用于线性可分的数据时，不同类别的支持向量到最优决策边界的距离之和为 2/||w||2/||w||，其中的 ww 是超平面的线性系数，也就是法向量。不难看出，让间隔 ||w||−1||w||−1 最大化就是让 ||w||2||w||2 最小化，所以线性可分的支持向量机对应的最优化问题就是

minw,b12||w||2minw,b⁡12||w||2

s.t.yi(w⋅xi+b)≥1s.t.yi(w⋅xi+b)≥1

其中 yiyi 为数据点 xixi 对应的类别，其取值为 ±1±1。

这个问题本身是个凸二次规划（convex quadratic programming）问题，求解起来轻松加随意。但借助拉格朗日乘子，这个原问题（primal problem）就可以改写成所谓的广义拉格朗日函数（generalized Lagrange function）

L(w,b,α)=12||w||2+∑i=1mαi[1−yi(w⋅xi+b)]L(w,b,α)=12||w||2+∑i=1mαi[1−yi(w⋅xi+b)]

其中每个 αiαi 都是 αα 的分量。和原来的优化问题相比，除了和决策边界有关的变量 ww 和 bb 之外，广义拉格朗日函数还引入了一组不小于 0 的参数 αiαi。

这个式子其实从另一个角度说明了为什么最优决策边界只取决于几个支持向量。对于不是支持向量的数据点来说，等式右侧第二项中的 1−yi(w⋅xi+b)1−yi(w⋅xi+b) 是大于 0 的，因此在让 L(w,b,α)L(w,b,α) 最小化时，必须把这些点的贡献去除，去除的方式就是让系数 αi=0αi=0。这样一来，它们就成来支持向量机里的路人甲乙丙丁了。

广义拉格朗日函数的最优化可以分成两步：先把 L(w,b,α)L(w,b,α) 看成 αα 的函数，在将 ww 和 bb 视为常量的前提下求出其最大值。由于 αα 在求最值时被消去，这时求解出的

θp(w,b)=maxαL(w,b,α)θp(w,b)=maxα⁡L(w,b,α)

就是只和 ww 和 bb 有关的函数了。

接下来如何确定最优的决策边界参数呢？这里要分两种情况来考虑。当参数 ww 和 bb 不满足原问题的约束时，总会找到能让目标函数取值为正无穷的 αα，这意味着最大值其实就是不存在。只有符合原问题的要求时，θP(w,b)θP(w,b) 的最大值才有意义。

那么这个最大值等于多少呢？由于 αiαi 和 1−yi(w⋅xi+b)1−yi(w⋅xi+b) 的符号相反，因此两者之积必然是小于 0 的，由此不难得出 θP(w,b)=||w||2/2θP(w,b)=||w||2/2。这里需要注意的是，在确定最优的 αα 时，原始的优化对象 ||w||2/2||w||2/2 是作为常数项出现的。

经过一番折腾之后，原始的最小化问题就被等效为 minw,bθp(w,b)minw,b⁡θp(w,b)，也就是广义拉格朗日函数的极小极大问题。这个极小极大问题是先对 αα 求极大，再对 ww 和 bb 求极小。如果对上一季的内容还有印象的话，你是不是会一拍大腿：一边最大，一边最小，这不就是传说中的鞍点（saddle point）嘛！

计算多重积分时，调换积分顺序是简化计算的常用技巧，这种思路在对偶问题中同样大有用武之地。“极小极大”调个个儿就变成了“极大极小”，确定参数的顺序也要相应地反转。对于支持向量机来说，其广义拉格朗日函数的极大极小问题具有如下的形式

maxαθD(α)=maxαminw,bL(w,b,α)maxα⁡θD(α)=maxα⁡minw,b⁡L(w,b,α)

让广义拉格朗日函数对决策边界的两个参数 ww 和 bb 的偏导数为 0，就可以得到

w=∑i=1mαiyixi,∑i=1mαiyi=0w=∑i=1mαiyixi,∑i=1mαiyi=0

将解出的约束关系先代入到 L(w,b,α)L(w,b,α) 中，再作为拉格朗日乘子项引入 L(w,b,α)L(w,b,α) 的优化，就可以得到原优化问题的对偶问题（dual problem）

maxα∑i=1mαi−12∑i=1m∑j=1mαiαjyiyjxTixjmaxα⁡∑i=1mαi−12∑i=1m∑j=1mαiαjyiyjxiTxj

s.t.∑i=1mαiyi=0,αi≥0s.t.∑i=1mαiyi=0,αi≥0

虽然一顿操作猛如虎将原问题变成了对偶问题，但这两者之间到底能不能完全划等号还是个未知数呢。直观地看，原函数求出来的是 L(w,b,α)L(w,b,α) 最大值的下界，对偶函数求出来的是 L(w,b,α)L(w,b,α) 最小值的上界，后者肯定不会大于前者，但也不是无条件地相等。

好在在数学上可以证明，当上面的过程满足Karush-Kuhn-Tucker 条件（简称 KKT 条件，是一组关于 αα、ww 和 bb 的不等式）时，原问题和对偶问题才能殊途同归。支持向量机对原问题和对偶问题之间等价关系的利用就是它的对偶性（duality）。

说完了对偶性，下面就轮到核技巧了。在核技巧这台大戏里，第一个出场的是核函数，这才是“核”字辈这些兄弟里的开山鼻祖。

要理解核函数，还是要从史上最著名的线性不可分问题——异或问题出发。假设待分类的四个点 (x1,x2)(x1,x2) 分别为 (±0,±1)(±0,±1)，那么只需要添加一个多项式形式的新属性 ϕ(x)=(x1−x2)2ϕ(x)=(x1−x2)2，就可以将原来的四个点分别映射为三维空间上的 (0, 0, 0), (0, 1, 1), (1, 0, 1) 和 (1, 1, 0)。这时，在三维空间中只需要将原来的数据平面稍微向上抬一点，就能完美地区分两个类别了。

既然 ϕ(x)ϕ(x) 能生成新的属性，它就是传说中的核函数吧？非也！ϕ(x)ϕ(x) 只是特征映射（feature map），它的作用是从原始属性生成新的特征。对高维空间上新生成的特征向量进行内积运算，得到的才是真正的核函数（kernel function）。核函数的数学表达式具有如下的形式

k(x,x′)=ϕ(x)Tϕ(x′)k(x,x′)=ϕ(x)Tϕ(x′)

核函数的这个公式给出了生成条件而非判定条件。当给定特征的映射方式后，可以用它来计算核函数；但是当给出一个确定的函数时，如何判定它能不能作为核函数呢？梅塞尔定理（Mercer’s theorem）解决了这个判定问题。

这个定理于 1909 年由英国数学家詹姆斯·梅塞尔（James Mercer）提出，其内容是任何满足对称性和半正定性的函数都是某个高维希尔伯特空间的内积。只要一个函数满足这两个条件，它就可以用做核函数。但梅塞尔定理只是判定核函数的充分而非必要条件，不满足梅塞尔定理的函数也可能是核函数。

之所以要将特征映射表示成核函数，是因为内积的引入简化了高维空间中的复杂运算。映射到高维空间后，待优化的对偶问题就变成了

maxα∑i=1mαi−12∑i=1m∑j=1mαiαjyiyjϕ(xi)Tϕ(xj)maxα⁡∑i=1mαi−12∑i=1m∑j=1mαiαjyiyjϕ(xi)Tϕ(xj)

按照一般的思路，要直接计算上面的表达式就先得写出 ϕ(⋅)ϕ(⋅) 的形式，再在新的高维特征空间上计算内积，但这在实际运算中存在很大困难。尤其是当 ϕ(⋅)ϕ(⋅) 的表达式未知时，那这内积就没法计算了。可即使 ϕ(⋅)ϕ(⋅) 的形式已知，如果特征空间的维数较高，甚至达到无穷维的话，内积的运算也会非常困难。

这时就需要核函数来发挥威力了。核函数说到底是瓦普尼克“能走直线就别兜圈子”思想的产物。既然优化的对象是内积的结果，那么直接定义内积的表达式就可以了，何苦还要引入特征映射和特征空间这些个中间步骤呢？更重要的是，梅塞尔定理为这种捷径提供了理论依据，只要核函数满足对称性和半正定的条件，对应的映射空间就铁定存在。

所以核函数的引入相当于隐式定义了特征映射和特征空间，无需关心这些中间结果的形式就能直接计算待优化的内积，从而大大简化计算。

从核函数出发，可以衍生出其他和“核”相关的概念。从思想上讲，核方法（kernel method）表示的是将低维空间中的线性不可分问题通常可以转化为高维空间中的线性可分问题的思路；从运算上讲，核技巧（kernel trick）表示的是通过间接定义特征映射来直接计算内积的运算方法。两者就像同一枚硬币的两面，虽然浑然一体但还是有所区别，因而有必要加以说明。

在实际应用中，有一类特殊的平稳核函数（stationary kernel），它的参数是两个原始参数之差，也就是 k(x,x′)=k(x−x′)k(x,x′)=k(x−x′)。平稳核函数满足平移不变性（translation invariance），只要输入 xx 和 x′x′ 的相对位置不变，核函数的取值就不会发生变化。如果在平移不变性的基础上再定义各向同性（homogeneity），那核函数的取值就会进一步与方向无关，这样的核函数就可以表示为 k(x,x′)=k(||x−x′||)k(x,x′)=k(||x−x′||)。

一种满足平移不变性和各向同性的核函数是径向基核（radial basis function kernel），其表达式为

k(x,x′)=exp(−||x−x′||22σ2)k(x,x′)=exp⁡(−||x−x′||22σ2)

在数学上可以推导出，径向基核所对应的特征映射是无穷维的，也就是隐式的特征空间是无穷维的空间。计算无穷维的特征映射是个复杂的任务，但径向基核的出现聪明地绕开了这个障碍。应用在支持向量机中，径向基核可以将线性边界变换成非线性边界。

在 Scikit-learn 中设置核函数的方法并不难，只需要将 SVC 类中的参数 kernel 设置为’rbf’即可（也可以使用其他类型的核函数）。径向基核的参数 σσ 决定了高斯函数的宽度，但在 SVC 类中，这个参数是以 γ=1/2σ2γ=1/2σ2 的形式出现的，这意味着调用 SVC 类时 γγ 设置得越大，核的宽度实际上就越窄。

除了核宽度之外，另一个需要需要设置的是正则化参数 CC，这个参数越大，正则化的效果就越弱，当 CC 接近正无穷时，计算出来的就是未经正则化处理的结果。将径向基核应用到线性不可分的数据集中，就可以将两类数据完全分开，如下图所示。在结果中，较大的 CC 让最优决策边界有过拟合的趋势。

使用径向基核的支持向量机对曼城 - 西布朗数据集的分类结果

除了简化内积运算之外，核函数更本质的意义在于对相似性度量（similarity measure）的表示。回忆一下线性代数的内容，内积表示的是两个向量之间的关系。如果将两个向量归一化后再来计算内积，那么求出来的就是两者之间的夹角。而作为原始内积的非线性拓展，核函数重新定义了数据的表征框架：将每个维度上的绝对坐标替换成两两之间的相似度。

这样一来，分类问题就变成了从几何意义出发，基于相似性度量在高维的特征空间上找到线性决策边界，再将它映射成低维空间上非线性的决策边界。

在直观的认识中，两个数据点相距越近，它们归属于同一类别的可能性就越高。如果将径向基的结果看成数据点相似度的话，那么 xx 和 x′x′ 离得越近，两者之间的相似度就越高（接近于 1）；反过来离得越远，相似度就越低（接近于 0）。

接下来，计算出的相似度就成为分类的依据：和哪个类别的相似度高，未知的数据点就归属于哪个类别。和线性判别分析和逻辑回归这些参数化的分类模型相比，核函数更多地借鉴了物以类聚的简单逻辑。

将这种逻辑引申一步就可以得到，核函数是实现局部化（localization）的工具。在解决回归问题时，核函数本质上也是一组权重系数，但它和线性模型中权重系数的区别在于它是取决于距离的，由距离表征的相似度决定了系数的取值。在整体上，数据空间的全局参数并不能通过最小二乘等全局性方法计算出来，而是要将每个核函数所表示的局部尺度特征叠加在一起。

这样看来，每个核函数都像是战国中雄踞一方的诸侯，其势力在远离权力中心的过程中不断减弱。和这些叱咤一方的诸侯相比，作为全局参数模型的周天子就完全是个摆设了。

今天我和你分享了支持向量机中对偶和核技巧的概念与原理，其要点如下：

支持向量机在求解最优边界时需要利用对偶性，将原问题转化为对偶问题求解；

在思想上，核方法将高维空间上的线性边界转化成低维空间上的非线性边界；

在运算上，核技巧能在低维空间中直接计算高维空间中的内积；

核函数具有局部化的特点，是从全局模型到局部模型的过渡手段。

其实在“人工智能基础课中”，高斯形式的径向基函数就有过亮相，它出现在径向基神经网络的介绍中。你可以复习一下这一部分的内容，借此加深对核函数与局部特性关系的理解。

拓展阅读

《人工神经网络 | 各人自扫门前雪：径向基函数神经网络》

说明：知识具有内在联系性，有些内容在“人工智能基础课”里有不同角度的介绍。拓展阅读是为了让你更方便地回顾内容，如已订阅可以直接点击进入文章复习。不阅读，也不影响当前的学习。

19 | 非参数化的局部模型：K近邻

到目前为止，专栏中介绍的机器学习模型都属于参数模型，它们利用训练数据求解出关于问题的一般性知识，再将这些知识通过全局性模型的结构和参数加以外化。

一旦模型的结构和参数被确定，它们就不再依赖训练数据，可以直接用于未知数据的预测。而径向基核的出现一定程度上打破了这种规律，它将普适的全局特性打散成若干局部特性的组合，每个局部特性只能在它所覆盖的近邻区域内得以保持，由此产生的非结构化模型会具有更加灵活的表示能力。

在我看来，局部化的核心作用是模型复杂度和拟合精确性的折中。如果将整个输入空间看作一个大的整体区间，对它进行全局式的建模，那么单个模型就足以描述输入输出之间的规律，但这不可避免地会对表达能力造成较大的限制。

一个极端的情形是让所有输入的输出都等于同一个常数，这样的模型显然毫无信息量可言。可是在另一个极端，如果将局部特性继续加以细化，细化到让每个数据点都定义出不同局部特性的子区间，其结果就是基于实例的学习。

基于实例的学习（instance-based learning）也叫基于记忆的学习（memory-based learning），它学习的不是明确的泛化模型，而是样本之间的关系。

当新的样本到来时，这种学习方式不会用拟合好的算式去计算输出结果或是输出结果的概率，而是根据这个新样本和训练样本之间的关系来确定它的输出。在本地化的语境里，这就叫“近朱者赤，近墨者黑”。

在基于实例的学习方法中，最典型的代表就是 kk 近邻。kk 近邻算法（kk-nearest neighbors algorithm）可能是最简单的机器学习算法，它将每个训练实例都表示成高维特征空间中的一个点。

在解决分类问题时，kk 近邻算法先找到高维空间中与未知实例最接近的 kk 个训练实例，再根据少数服从多数的原则，将这 kk 个实例中出现最多的类别标签分配给未知的实例。从贝叶斯定理的角度看，按照少数服从多数分配标签与后验概率最大化是等效的。

下图是 kk 近邻算法的一个简单的例子。训练数据属于两个不同的类别，分别用蓝色方框和红色三角表示，绿色圆圈则代表待分类的数据点，其类别由 kk 近邻算法决定。可以看到，当 kk 等于 3 时，离未知数据最近的三个点是两红一蓝，因此数据会被归类为红色三角。可是当 kk 从 3 增加到 5 时，多出来的两个实例都是蓝色的，这无疑会导致分类结果发生逆转。

k 近邻算法示意图（图片来自维基百科）

这个例子说明了 kk 近邻算法的一个特点，就是超参数 kk 对性能的影响。作为一种局部加权模型，kk 近邻并不形成关于数据生成机制的全局性假设，而是刻画了数据在不同局部结构上的规律，局部结构的范围就是由 kk 来定义的。

在本质上，超参数 kk 和径向基核（以及其他的核函数）是一样的，只不过径向基核在定义局部结构时使用了连续分布的权值，所有数据对局部特征都有或大或小的贡献；而 kk 近邻使用了离散分布的权值，只有部分足够接近的数据才有资格定义局部特征，它可以视为是可变带宽的径向基核。

从另一个角度看，超参数 kk 表示了模型的复杂度，准确地说是和模型的复杂度成反比关系。如果训练集的容量为 NN，算法的有效参数数目就可以近似表示为 N/kN/k。

kk 均值的分类结果实质上是近邻区域内（就是上图中的圆圈）多个训练实例的平均，越大的 kk 值意味着近邻区域包含的点数越多，平均化的程度就越高，对训练实例中噪声的平滑效果也就越好，相应的模型复杂度就越低。kk 的一个极端取值是直接等于训练集的容量，这相当于所有数据共同定义了同一个局部结构，这时的 kk 近邻就退化成稳定的全局模型了。

反过来，越小的 kk 值意味着近邻区域越狭窄，平均化的程度也就越低。这时的分类结果只由离未知数据点最近的少量训练实例决定，因而更容易受到这些实例中噪声的影响，也会表现出更强的过拟合倾向。当 kk 等于 1 时，未知数据的类别只取决于离它最近的训练实例。

这时画出每个训练实例的近邻边界，所有的近邻边界共同构成了对特征空间的Voronoi 划分（Voronoi tessellation）。当训练实例较多时，这种 1 近邻算法计算出的分类边界会非常复杂，其泛化性能较差。

除了超参数 kk 之外，kk 近邻算法的另一个变量是对距离的定义方式，也就是如何衡量哪些点才是“近邻”的标准。最常用的距离度量无疑是欧氏距离，可除此之外，闵可夫斯基距离（Minkowski distance）、曼哈顿距离（Manhattan distance）和马氏距离（Mahalanobis distance）也可以应用在 kk 近邻算法中，不同的距离代表的是对相似性的不同理解，在不同意义的相似性下，分类结果往往也会有所区别。这些距离是如何来定义的，你可以自己查阅。

对距离的依赖性给 kk 近邻算法带来了一个新问题，那就是维数灾难。在之前介绍维数灾难时我曾经留了一个扣，现在就该解开它了。简而言之，维数灾难对 kk 近邻算法的影响在于在高维空间中，曾经的近邻没有那么“近”了。不管特征空间的维度是多少，近邻区域的维度和特征空间的维度都是一致的。在这个前提下，要在特征维度增加时维持对特征空间的覆盖率不变，近邻区域在每个维度上的尺度就会越来越大。

维数灾难的几何意义其实可以直观地想象出来。如果特征空间是一条长度为 1 的一维直线，那任意一个长度为 0.1 的线段都能覆盖特征空间上 10% 的区域。可一旦特征空间变成二维，要在边长为 1 的正方形里圈出一个面积为 0.1 的小正方形，小正方形的边长就增加到 0.1−−−√=0.3160.1=0.316。这样一来，当数据点的数目不变时，维度的升高会导致原始的低维近邻点变得越来越稀疏，由近邻点所定义的局部结构也会越来越大。这样的局部结构失去了局部的意义，想让算法保证精确的分类性能就越困难了。

维度的升高会导致原始的低维近邻点变得越来越稀疏

（图片来自 http://cleverowl.uk/2016/02/06/curse-of-dimensionality-explained/）

解决维数灾难最直接有效的方式就是增加数据点的数量，当数据点的数量没法增加时就得退而求其次，想办法降低特征空间的维度。还记得降维的主要方法吗？特征选择和特征提取都可以用于 kk 近邻算法对数据的预处理。

作为典型的非参数方法，kk 近邻算法的运行方式和以线性回归为代表的参数方法截然相反。线性回归的运算量主要花在参数拟合上，利用大量的训练数据来拟合出使均方误差最小的一组参数。

一旦这组参数被计算出来，训练数据的历史使命就完成了，新来的数据都会用这组参数来处理。可 kk 近邻算法的训练过程没那么复杂，只需要将数据存储下来就行了。可是对新实例进行分类时，kk 近邻算法需要找到离它最近的 kk 个训练实例，这才是算法主要的运算负荷。

虽然是频率主义的方法，但以核函数和 kk 近邻为代表的非参数方法也可以用来完成贝叶斯统计中概率密度估计（density estimation）的任务。如果用参数方法来进行密度估计，就需要先确定待估计概率密度的形式，再根据训练数据计算表示数字特征的参数。

比如假定概率密度具有正态分布的形式，那就需要估计它的均值和方差；具有指数分布的形式就要估计指数分布的参数。显然，参数化密度估计对概率密度形式的假设具有很强的依赖性，如果对概率分布的形式判断错误，那系数计算得再精确也是南辕北辙。

相比之下，非参数的密度估计就不会对待估计的分布做出什么先验假设，只是假定所有数据满足独立同分布的条件，因而具有更高的灵活性。但要讨论非参数密度估计方法，还是得从一种参数方法——直方图法（histogram）说起。

在统计学生成绩时，通常会计算 <60、60~70、70~80、80~90 和 >90 这些分数段内各有多少人，来大致绘出成绩的分布情况，这就是典型的直方图。直方图法将样本的取值范围划分成若干个等间隔子区间，再统计出现在每个子区间上的样本数目。在直方图上，第 ii 个子区间上的概率可以表示成

pi=niNΔpi=niNΔ

其中 nini 是落在这个子区间内的样本数，NN 是样本容量，ΔΔ 是每个子区间的宽度，它决定了直方图的分辨率。ΔΔ 的取值过小会让直方图过于细密，让过多的局部细节掩盖了分布的整体结构；取值过大又会让直方图过于平滑，体现不出潜在的多模式趋势。要对概率密度做出精确的估计，必须要选择合适的区间宽度。

直方图方法的一个问题在于计算出的概率密度不是连续函数。要解决这个问题，可以将原始的子区间替换成平滑的连续函数，这就让整体概率密度等于所有局部概率密度的叠加，避免了不连续点的出现。

那么用来插值的连续函数应该满足什么样的条件呢？平滑特性决定了它不能只管自己，也要刻画数据的局部特性。那么刻画局部特性的工具是什么呢？核函数嘛！把核函数用于密度估计，就是非参数的核密度估计方法（kernel density estimation）。

直方图（左）与核密度估计（右）（图片来自维基百科）

可有了核函数还不够，还需要确定它的带宽。在密度估计中，核函数带宽决定了局部结构的范围，其作用和直方图的子区间宽度类似。核函数的带宽过大会导致过度平滑，带宽过小则会导致欠平滑，在实际应用中可以通过最优化类似均方误差的指标来确定。

核密度估计虽然能够给出连续的概率密度，但它所有的局部结构都由相同的带宽决定。可是在特征空间上，不同区域数据的密度不同，其局部结构也应该有所区别，这时就需要引入 kk 近邻算法的思想。在基于近邻的密度估计中，近邻点的数目 kk 是唯一的参数，每个数据点的带宽就是第 kk 个最近点和它的距离。和核密度估计的带宽一样，kk 值同样定义了局部结构的性质，因此在选择时也要慎之又慎。

核密度估计和近邻密度估计可以从一个统一的宏观视角加以审视。在高维空间中，如果将数据 xx 的局部结构定义为 RR，那么其概率密度就可以表示为

p(x)=KNVp(x)=KNV

其中 KK 表示 RR 中的数据点数目，VV 表示 RR 的体积，它们都是不确定的量。如果设置 VV 固定、KK 可变来估计概率密度，得到的就是核密度估计；如果设置 KK 固定、VV 可变来估计概率密度，得到的就是近邻密度估计。

当样本容量 N→+∞N→+∞ 时，VV 会随着 NN 的增加而缩小，以保证 RR 上的概率密度为常数；KK 则会随着 NN 的增加而增加，以保证 RR 上的概率密度存在明显的峰值。这时，两种非参数的估计结果都会收敛到真实的概率密度。

和支持向量机一样，kk 近邻算法也可以用来解决分类问题。利用 Scikit-learn 中的 KNeighborsClassifier 类，可以计算出曼城 - 西布朗数据集中的分类边界，其中 kk 的取值分别被设置为 1，7 和 15。可以看到，k=1k=1 时所有训练数据都能正确分类，而 k=15k=15 时误分类率超过了 10%。

这说明当超参数 kk 的取值逐渐变大时，训练数据的误分类率在不断提升，但计算出的分类边界也变得越来越平滑。这是偏差 - 方差折中的典型体现。

今天我和你分享了基于实例的学习方法，以及它的典型代表 kk 近邻算法，其要点如下：

基于实例的学习方法学的不是明确的泛化模型，而是样本之间的关系；

kk 近邻算法是非参数的局部化模型，具有无需训练的优点，但分类新实例的计算复杂度较高；

kk 近邻算法的性能取决于超参数 kk 的取值和距离的定义方式；

核方法和近邻算法都可以用于数据的概率密度估计。

kk 近邻方法是一种消极学习（lazy learning）方法，它并不会从训练数据中直接获取泛化决策，而是将它延迟到新样本出现的时候。相比之下，前面介绍的其他方法都属于积极学习（active learning）方法，在新样本出现前就做好了泛化工作。

那么，你觉得消极方法和积极方法有什么原理和性能上的优缺点呢？

欢迎分享你的观点。

20 | 基于距离的学习：聚类与度量学习

截至目前，我所介绍的模型都属于监督学习范畴，它们处理具有标签的输入数据，给出意义明确的输出，回归模型输出的是连续的回归值，分类模型输出的是离散的类别标签，这些模型都属于预测模型（predictive model）。

另一类模型则隶属于无监督学习，这类模型学习没有标签的数据，其作用也不是计算类别或回归值，而是要揭示关于数据隐藏结构的一些规律，因此也被称为描述模型（descriptive model）。聚类算法就是最具代表性的描述模型。

聚类分析（cluster analysis）实际上是一种分组方式，它使每一组中的组内对象的相似度都高于组间对象的相似度，分出来的每个组都是一个簇（cluster）。由于相似度是聚类的依据，作为相似度主要度量方式之一的距离就在聚类中发挥着重要作用。

在“人工智能基础课”中，我曾介绍过四种主要的聚类算法，你可以结合下面的要点图回忆一下。除了以概率分布为基础的分布聚类以外，其他三类聚类算法都涉及对距离的使用，而其中最典型的就是 kk 均值所代表的原型聚类算法。

《机器学习 | 物以类聚，人以群分：聚类分析》

理解 kk 均值算法的基础是理解它对距离的使用方式。前面介绍的 kk 近邻算法其实也用到了距离，近邻的选择就是以距离为依据的。但近邻点是以内收的形式影响未知的数据，所有近邻点按照一定的规则共同决定处于中心的未知数据的类别。如果将这种影响的方式调转方向，让处于中心的样本作为原型（prototype），像一个小太阳一样用万有引力牵引着周围的其他样本，那么其他样本就会像卫星一样被吸附在原型周围，共同构成一个星系，也就是簇。

和万有引力类似，kk 均值算法中定义的相似度也与距离成负相关关系，样本离原型的距离越小，两者之间的引力越大，相似度也会越高。但和天文学中的星系不同的是，kk 均值算法中簇的中心不会固定不变，而是要动态变化。

如果一个样本离原型太远的话，那引力就可能会减弱到让这个样本被另一个原型吸走，转移到另一个簇当中。簇内样本的流入流出会让簇的中心发生改变，进而影响不同簇之间的动态结构。好在动态结构最终会达到平衡，当所有样本到其所属簇中心的平方误差最小时，模型就会达到稳定下来。

如果聚类的任务是将 NN 个数据点聚类成为 KK 个簇，那它的目标函数就可以写成

J=∑n=1N∑k=1Krnk||xn−μk||2J=∑n=1N∑k=1Krnk||xn−μk||2

其中 xnxn 是数据点，μkμk 是第 k 个簇的中心，也就是簇中所有数据点的均值，rnkrnk 是数据点和簇之间的关系：当 xnxn 被归类到第 kk 个簇时为 1，否则为 0。

在 μkμk 确定的前提下，将数据点 xnxn 归类到离它最近的那个中心 μkμk 就能让 JJ 取到最小值，这时的 rnkrnk 就是最优的。

确定所有的 rnkrnk 后，利用求导可以进一步确定 μkμk 的最优值，其表达式为

μk=∑nrnkxn∑nrnkμk=∑nrnkxn∑nrnk

也就是当前簇中所有数据点的均值。由于 kk 均值本身是个 NP 难问题，所以上面的算法并不能够保证找到全局最小值，很有可能会收敛到局部的极小值上。

根据上面的流程可以总结出 kk 均值算法的步骤。

首先从数据集中随机选取 kk 个样本作为 kk 个簇各自的中心，接下来对其余样本分别计算它们到这 kk 个中心的距离，并将样本划分到离它最近的中心所对应的簇中。当所有样本的聚类归属都确定后，再计算每个簇中所有样本的算术平均数，将结果作为更新的聚类中心，并将所有样本按照 kk 个新的中心重新聚类。这样，“取平均 - 重新计算中心 - 重新聚类”的过程将不断迭代，直到聚类结果不再变化为止。

kk 均值算法的运行流程（图片来自维基百科）

下面的例子是利用 kk 均值算法对英超球队的比赛风格进行分类。这里使用的数据集是 20 支英超球队在 2017-18 赛季的场均数据，用来聚类的两个指标分别是长传数目与短传数目的比值，以及不成功突破数目和成功突破数目的比值。

根据以往对英超球队的理解，我将聚类的数目设为 3 类，初始聚类中心设定为阿森纳（Arsenal）、埃弗顿（Everton）和斯托克城（Stoke）三支球队的指标。

阿尔塞纳·温格治下的阿森纳一直以来都是英超中一股细腻的技术清流，相比之下，号称“天空之城”的斯托克城崇尚高举高打，称得上是泥石流了。而埃弗顿作为中游球队的代表，可以看成是弱化版技术流和加强版身体流的组合。应该说，以这三只球队作为聚类参考是有足够的代表性的。

利用 Scikit-learn 库中的 cluster 模块的 Kmeans 类可以方便地计算出聚类的结果，如下面左图所示。如果你经常看球，就会发现聚类的结果差强人意：近年崛起的托特纳姆热刺（Tottenham Hotspurs）走的也是传控路线，却被划到了硬桥硬马的斯托克城一类；类似的情形也发生在自作孽不可活的典型中游队斯旺西城（Swansea City）身上。

图中右侧显示的是让算法随机选择 3 个中心的聚类结果，它和左侧的结果几乎完全一致，只是在水晶宫（Crystal Palace）一队上存在不同，这说明 3 个初始种子的选择比较准确。

英超球队比赛风格的聚类结果，左图为预设初始中心的结果，右侧为随机选择初始中心的结果

从贝叶斯的角度看，kk 均值算法是高斯混合模型（Gaussian mixture model）的一个特例。

顾名思义，混合模型将数据总体看作来自若干个高斯分布，也就是若干个成分（component）的数据的集合，kk 均值算法聚出来的每一个簇都对应着一个未知参数的高斯分布。所有单个高斯分布的概率密度线性组合在一起，就是整体分布的概率密度，可以表示为

p(x)=∑k=1KπkN(x|μk,Σk)p(x)=∑k=1KπkN(x|μk,Σk)

这个式子里的 πkπk 是混合系数（mixing coefficient），表示的是每个单独的高斯分布在总体中的权重，后面的 N(x|μk,Σk)N(x|μk,Σk) 则是在被选中的高斯分布中，数据 xx 取值的概率。

判断数据 xx 属于哪个簇实际上就是要找到它来自哪个高斯分布，而归属于第 kk 个簇，也就是来自于第 kk 个高斯分布的概率可以用贝叶斯定理表示为

γ(zk)=πkN(x|μk,Σk)∑j=1KπjN(x|μj,Σj)γ(zk)=πkN(x|μk,Σk)∑j=1KπjN(x|μj,Σj)

这里的 γ(zk)γ(zk) 可以形象地解释成第 kk 个高斯分布在解释观测值 xx 时需要承担的“责任”，其中的 zkzk 是个隐变量（latent variable）。

不难发现，根据这个式子计算出的每个 γkγk 都不等于 0，这体现出高斯混合模型和 kk 均值算法的一个区别：kk 均值输出的是非此即彼的聚类结果，属于“硬”聚类（hard assignment）的方法；高斯混合模型则会输出数据归属到每个聚类的概率，得到的是“软”聚类（soft assignment）的结果。

如果假定高斯混合模型中，所有单个分布的协方差矩阵都等于 ϵIϵI，那么每个分布对数据 xx 的“责任”就可以改写为

γ(znk)=πkexp−||xn−μk||2/2ϵ∑Kj=1πjexp−||xn−μj||2/2ϵγ(znk)=πkexp⁡−||xn−μk||2/2ϵ∑j=1Kπjexp⁡−||xn−μj||2/2ϵ

当描述方差的参数 ϵ→0ϵ→0 时，高斯分布就会越来越窄，最终收缩成一个固定的数值。在 ϵϵ 不断变小的过程中，上面这个式子里分子分母中所有 exp(−k/ϵ)exp⁡(−k/ϵ) 形式的项都会同样趋近于 0，但趋近的速度是不一样的。

既然如此，那衰减最慢的是哪一项呢？是 exp(−k/ϵ)exp⁡(−k/ϵ) 中系数 kk 最小的那一项，也就是 ||xn−μj||2||xn−μj||2 最小的这一项。它就像我去参加奥运会百米赛跑，在冲向终点 0 的跑道上被博尔特们远远地甩在后面，当其它的求和项都等于无穷小时，这一项仍然有非 0 的取值。

根据上面的分析，||xn−μj||2||xn−μj||2 最小同样意味着 γnj→1γnj→1。

这说明对观测值 xx 的解释全部被归因于第 jj 个高斯分布。

这时软输出 γnjγnj 就会退化为前文中 kk 均值算法中的硬输出 rnkrnk，数据 xx 也就被分配到离它最近的那个簇中心所对应的簇中。

在 kk 均值算法中，扮演核心角色的是距离的概念。可是距离的求解只是手段，它的目的是衡量局部范围内的相似程度。将 kk 近邻算法和 kk 均值算法这些基于距离的方法推广一步，得到的就是相似性学习（similarity learning）和它的变种度量学习（metric learning），它们在信息检索、推荐系统、计算机视觉等领域发挥着重要作用。

度量学习的出现源于“数据”概念的扩展。倒推 10 年，人们观念中的数据还只是狭义上的数字，只有像年龄、身高、血压这样的数字指标才能被称为数据。可如今呢？任何结构化的文本、图像、DNA 序列，甚至一些非结构化的对象都被纳入数据的范畴，它们都需要利用学习算法进行有效的分析和处理。

这时，如何描述这些抽象数据的关系就成了一个大问题：作为普通读者，我可以不费吹灰之力地区分开金庸和古龙的小说，但这种区别如何在计算机中用数字指标来直观呈现呢？

度量学习就是通过定义合适的距离度量或相似性度量来完成特定的分类或者回归任务。

好的距离度量固然取决于具体问题，但它也要满足非负性（nonnegativity）、对称性（symmetry）和三角不等式（triangle inequality）等一些最基本的要求。马氏距离（Mahalanobis distance）就是这样的一种广义的距离，它的表达式是

distmah(xi,xj)=(xi−xj)TΣ−1(xi−xj)−−−−−−−−−−−−−−−−−−−√distmah(xi,xj)=(xi−xj)TΣ−1(xi−xj)

其中 ΣΣ 是 xixi 和 xixi 所属概率分布的协方差矩阵。马氏距离的好处在于引入了可调节的参数，从而使距离可以通过对数据的学习来加以改善。

因为矩阵 Σ−1Σ−1 是个半正定的矩阵，所以它可以写成 GTGGTG 的形式，利用这一变换可以将马氏距离改写成

distmah(xi,xj)=||Gxi−Gxj||2distmah(xi,xj)=||Gxi−Gxj||2

对马氏距离的学习实际上就是对变换 GG 的学习。一般来说，经过变换后的 GxiGxi 的维度会比 xixi 的原始维度有所降低，因此马氏距离的学习可以看成是一类降维操作，将高维空间中的马氏距离转换为低维空间中的欧氏距离。

马氏距离学习是一类线性的度量学习方法。要实现非线性的度量学习，有两种主要的途径：一种是通过核函数引入非线性的作用，将学习的对象变成 ||Gϕ(xi)−Gϕ(xj)||2||Gϕ(xi)−Gϕ(xj)||2，另一种则是直接定义出非线性的距离度量 dist(xi,xj)=||ϕ(xi)−ϕ(xj)||2dist(xi,xj)=||ϕ(xi)−ϕ(xj)||2，其作用范围既可以是全局也可以是局部。非线性度量学习的方法有很多，你可以根据自己的需要进一步深入了解。

今天我以 kk 均值算法为例，和你分享了基于距离的学习方法，还简单地介绍了对基于距离的学习的扩展，也就是度量学习，包含以下四个要点：

聚类分析是一类描述模型，它将数据按照相似度分成不同的簇；

kk 均值算法根据距离来判定数据的聚类；

从概率角度看，kk 均值算法是高斯混合模型的一种特例；

度量学习的任务是构造出适合于给定问题的距离度量或相似度的度量。

度量学习一般求解的是全局性度量，但必要的时候也可以将局部特性引入到度量学习中，这种方法通常被应用在异质的数据集上。在特定的任务中，局部度量学习（local metric learning）的效果会优于全局度量学习，但相应的计算开销也会较大。

你可以查阅资料了解局部度量学习的特点，并在此分享你的看法。

21 | 基函数扩展：属性的非线性化

虽然线性回归是机器学习中最基础的模型，但它的表达能力会天然地受到线性函数的限制，用它来模拟多项式函数或者指数函数等非线性的关系时，不可避免地会出现误差。要获得更强的表达能力，必须要把非线性的元素纳入到学习模型之中。

以核技巧为代表的局部化模型就是一种有效的非线性的尝试。但它的非线性来源于非参数的处理方式，也就是将很多个规则的局部组合成一个不规则的整体。那么有没有可能在全局层面上添加非线性元素呢？

还记得线性回归的表达式吗？在这里我把它重写一遍

y=β0+β1x1+β2x2+⋯+βnxny=β0+β1x1+β2x2+⋯+βnxn

其中的 xixi 可以看成是和属性相关的基函数（basis function）。在最原始的线性回归中，基函数的形式是恒等函数，因此这样的模型无论对属性 xixi 还是对系数 βiβi 都是线性的。

但在统计学中，线性模型名称中的“线性”描述的对象是未知的回归系数 βiβi，也就是回归结果和回归系数之间存在着线性关系。这说明回归式中的和属性相关的每一项对输出的贡献程度都是固定的，但这些贡献到底以什么样的形式来输出，是属性取值本身还是它的平方抑或开根号，线性模型并没有做出指定。

充分利用关于基函数的灵活性，就可以将线性回归的表达式推广成

y=β0+β1ϕ(x1)+β2ϕ(x2)+⋯+βnϕ(xn)y=β0+β1ϕ(x1)+β2ϕ(x2)+⋯+βnϕ(xn)

显然，当 ϕ(⋅)ϕ(⋅) 是个非线性的函数时，回归结果实际上就是经过非线性变换的输入属性的线性组合，因变量和自变量之间也就建立起了非线性的关系。这种生成非线性的参数模型的方法就是基函数扩展（basis expansion）。

如果你对高等数学还有印象的话，就会发现基函数扩展并不是一个陌生的概念，只不过没有以这样的名字出现。在信号分析中，傅里叶变换（Fourier transform）是最基本最核心的工具，它可以实现时域和频域的转换，将时域信号表示成无数个频率成分的组合。这个表达的过程就是傅里叶逆变换（inverse Fourier transform）

f(t)=12π∫+∞−∞F(ω)ejωtdωf(t)=12π∫−∞+∞F(ω)ejωtdω

其中的 ejωtejωt 代表频率成分 ωω，这个虚指数函数作为傅里叶变换中的基函数，显然是时间 tt 的非线性函数。而 F(ω)F(ω) 表示这个频率成分的权重系数，需要通过傅里叶变换（Fourier transform）来计算

F(ω)=∫+∞−∞f(t)e−jωtdtF(ω)=∫−∞+∞f(t)e−jωtdt

由于时间变量 tt 在 F(ω)F(ω) 的积分中被消除，因此每个频率成分在信号中的比例，也就是每个权重系数都不会因时间的变化而变化，只和频率本身有关，这也是傅里叶变换属于线性变换的原因。

基扩展方法最简单的应用是多项式回归。多项式回归（polynomial regression）将自变量 xx 和因变量 yy 之间的关系定义为 xx 的 nn 阶多项式，从而使 xx 和 yy 之间呈现出非线性的关系。在只有一个自变量的情况下，多项式回归的表达式可以写成

y=β0+β1x+β2x2+⋯+βnxny=β0+β1x+β2x2+⋯+βnxn

多项式回归可以看成是多元线性回归的一个特例，但它的可解释性却并不清晰。在傅里叶变换中，不同的虚指数函数 ejωtejωt 之间是相互正交的，因而它们可以看成是互不相关的一组自变量，共同定义出一个特征空间。

但是当自变量 xx 在 [0, 1] 上均匀分布时，xx 和 x2x2 之间的相关系数可以达到 0.97！在如此强的相关系数之下，很难将两者对回归结果的各自贡献准确地区分开来。

英超数据集的线性回归结果和 10 次多项式回归结果

除了难以解释之外，多项式回归还有较高的过拟合风险。还是以前文中的英超数据集为例，线性回归假设场均积分和平均评分之间存在 y=ax+by=ax+b 的关系。从拟合结果来看，虽然存在异常点和误差，这种关系却把握住了自变量和因变量之间的主要趋势。

如果想要继续降低误差，就可以应用更加复杂的多项式模型。显然，用 10 次多项式来拟合英超数据集，相当于用 5 倍于线性模型的参数换来均方误差近一半的下降。但训练集上的误差较小并不意味着测试集上的误差较小，根据偏差方差分解的理论，这么复杂的模型方差通常会比较大，其泛化性能将不容乐观。

既然全局概念在基扩展中的表现差强人意，局部化处理就又成了自然而然的选择。其实，多项式回归和局部化的非参数方法可以说是殊途同归，两者的目的都是模拟自变量和因变量之间的非线性关系，因此用非参数模型来实现非线性化是水到渠成的方式。多元自适应回归样条就是一种典型的非参数回归方法。

多元自适应回归样条（multivariate adaptive regression splines, MARS）是线性回归的推广，用于对自变量的非线性和不同自变量之间的相互作用进行建模。它和多项式回归的区别在于后者将非线性的来源看作全局模型的固有属性，而前者则视非线性为不同参数的线性模型的组合。

如果将一个非线性函数的定义域划分成很多足够小的区域的组合，那在每个小区域上函数都会近似地满足线性性质。将这个过程调转方向，用很多条直线组合成一条曲线，就是 MARS 方法的思路。

简单线性回归与多元自适应回归样条的比较（图片来自维基百科）

上面这张图可以直观地体现出 MARS 的原理。图中左侧是原始的线性回归，虽然它和大部分数据点有较高的符合度，但右上角的离群点却与模型有明显的偏离。而 MARS 做出的改进就是在回归结果中建立一个分界点，将原来的模型一分为二，不同的区域用不同的参数来描述。这相当于通过增加参数的数目引入非线性的元素，起到降低均方误差、提高拟合精度的作用。

看到这里，你可能就一拍大腿：虽然起了火星哥这么高大上的名字，但 MARS 背后的原理不就是分段函数嘛！没错，这种由不同的多项式函数在多个临界点上拼接而成的函数就叫回归样条（regression spline）。

在自变量的不同取值范围内，样条的系数会有所不同，系数发生变化的临界点就是分段的结点（knot）。在估计不同区间段内的系数时，MARS 采用的也是最小二乘法。

一般来说，拼接起来的样条在结点上需要满足连续性的条件：最简单的是函数本身的连续性，也就是临界点的左极限与右极限相等，都等于函数值。如果在此基础上进一步满足一阶导数连续和二阶导数连续，这样的样条就是三次样条（cubic spline）。

三次样条由不同的三阶多项式拼接而成，它在结点处的不连续性已经不能被人眼所察觉。让三次样条进一步在边界区域满足附加的线性约束条件的话，得到的就是自然三次样条（natural cubic spline）。

和预先确定分段结点、再产生基函数并拼接的回归样条相比，另一类名为平滑样条的方法可以动态地确定结点的位置和数目。平滑样条（smoothing spline）要在拟合数据的同时尽可能保证拟合结果具有平滑的特性，这也是它名称的来源。平滑样条的任务是计算出让下面的误差函数最小化的拟合结果 g(⋅)g(⋅)

E=∑i=1N[yi−g(xi)]2+λ∫g′′(t)2dtE=∑i=1N[yi−g(xi)]2+λ∫g″(t)2dt

可以看出，平滑样条的最小化对象具有“误差函数 + 正则化项”的形式，这与岭回归和 LASSO 的思想不谋而合。

上面式子中的 λ≥0λ≥0 是平滑系数（smoothing parameter），体现了算法对函数 g(⋅)g(⋅) 的波动性的控制。二阶导数反映的是函数在某个点上变化的剧烈程度：直线 y=ax+by=ax+b 的二阶导数为 0，说明其图形在整个定义域上都有平滑的形状；而自由落体的表达式 y=gt2/2y=gt2/2 的二阶导数约等于 5，说明其图形在每个点上都有剧烈的变化。

平滑系数的作用就是通过控制模型的平滑度来实现偏差和方差的折中。λ=0λ=0 意味着算法对模型的平滑度不做控制，将每个数据点都作为自然三次样条的结点，得到的拟合结果就会发生剧烈的抖动；λ=+∞λ=+∞ 则意味着对抖动做出最大程度的抑制，其结果就是将平滑样条退化为普通线性回归。在实际应用中，平滑系数这个超参数的取值一般要通过交叉验证来确定。

前面讨论的几种非线性的处理方式针对的都是单变量的情形，可以看成是对简单线性回归的推广。如果将推广的对象扩展到多元线性回归，得到的就是广义可加模型。

广义可加模型（generalized additive model）将标准线性回归中的每个自变量以及可能存在的自变量之间的交互项都替换成一个非线性的平滑函数，各个非线性函数之间则保持相加的关系，其数学表达式可以写成

yi=β0+f1(xi1)+f2(xi2)+⋯+fp(xip)yi=β0+f1(xi1)+f2(xi2)+⋯+fp(xip)

广义可加模型可以和之前介绍过的广义线性模型相融合，通过链接函数将可加模型的结果转换为线性模型的输出，这使得广义可加模型也可以用于分类算法中。

要使用 Python 语言实现回归样条模型，可以利用 patsy 库。patsy 库脱胎于统计中的 R 语言，可以看成是 R 语言的部分功能在 Python 中的实现。它使用简短的字符串“公式语法”描述统计模型，因而适合和 statsmodels 配套使用。想要了解关于 patsy 工作方式的更多信息，你可以查阅其官方文档。

利用 patsy 实现回归样条时，主要应用它的 cr 函数来生成自然三次样条作为基函数。将回归样条应用到线性回归的英超数据集中，当结点的数目为设定为场均评分的 3 个四等分点时，样条回归的结果如下图所示。

可以看出，回归结果是一条平滑的曲线，但计算均方误差的话你会发现，样条回归的均方误差比线性回归的均方误差还要大。其原因可能在于数据本身已经具有良好的线性特性，因此强行使用非线性模型进行拟合不会带来良好的效果。

三次样条回归与普通线性回归的结果比较

今天我和你分享了通过基函数扩展实现非线性模型的方法，包含以下四个要点：

基扩展将线性回归中的自变量替换为非线性的函数，使模型能够描述非线性关系；

多项式回归将回归结果表示为属性的多项式之和；

样条方法将回归结果表示为若干非线性函数的组合，可以分为回归样条和平滑样条；

广义可加模型是对多元线性回归的基扩展。

基函数的扩展主要出现在统计学的文献中，被看成是曲线拟合的有力工具，在机器学习中反而并不多见。那么你认为在以预测建模为主要目标的机器学习中，它能够发挥什么样的作用呢？

欢迎分享你的观点。

22 | 自适应的基函数：神经网络

回眸人工神经网络的前半生，不由得让人唏嘘造化弄人。出道即巅峰的它经历了短暂的辉煌之后便以惊人的速度陨落，几乎沦落到人人喊打的境地。可谁曾想三十年河东三十年河西，一位天才的出现让神经网络起死回生，众人的态度也迅速从避之不及变成趋之若鹜。如果人工神经网络果真有一天如人所愿实现了智能，不知它会对自己的命运作何评价。

人工神经网络（artificial neural network）是对生物神经网络的模拟，意在通过结构的复制实现功能的复制。但人类神经系统在百万年进化中留下的智能密码并没有那么容易破解，因而神经网络最终也难以跳出统计模型的窠臼，成为线性模型大家族的又一位成员。

感知器示意图（图片来自 Machine Learning: an Algorithmic Perspective, 图 3.1）

人工神经网络的祖师爷是感知器（perceptron），其作用是根据输入数据的属性对它进行二分类。当偏置 b=0b=0 时，感知器计算输入属性的线性组合 w1x1+⋯+wnxnw1x1+⋯+wnxn，所有参数 wiwi 共通构成分类边界的法向量 ww。求出的线性组合接下来被送入激活函数（activation function）中计算结果。感知器的激活函数是符号函数，其输出的二元结果就表示了两种不同的类别。

感知器的学习过程示意图

（图片来自 https://www.willamette.edu/~gorr/classes/
cs449/Classification/perceptron.html）

上图给出了感知器的学习过程。训练数据集是个线性可分的数据集，数据点的星号和圆圈代表不同的类别。感知器的初始参数是随机生成的，用这组随机参数生成的分类边界是图中的红色虚线。显然，在分类边界两侧的两个类别中都有误分类的点。

直观来看，要让走错片场的星号和圆圈找到组织，唯一的办法就是调整分类边界，让新边界把原始边界上方不同颜色的点区分开来。

调整的方法一目了然：既然星号集中在左侧而圆圈集中在右侧，那就要让分类边界向右侧旋转，把右侧的星号包进来，把左侧的圆圈踢出去。右侧子图表示的就是将原始边界试探性地旋转一个角度所得的结果。虽然这个小角度的旋转还是没能完全正确分类，却对分类的准确率有所改善。只要在此基础上进一步旋转，新的分类边界就可以将两个类别的点完全分开了。

由于分类时无需使用数据的概率分布，因此感知器是一种基于判别式的分类模型。但它和前面提到的线性判别分析又有所不同，其算法不是利用所有数据的统计特性一鼓作气计算出最优的参数，而是通过不断试错为参数优化过程提供反馈，从而实现动态的参数调整。具备自适应的学习能力是感知器和前面所有模型相比独有的优势。

在感知器的动态学习过程中，作为优化目标出现的是感知准则（perceptron criterion）。之所以没有选择常见的误分类率作为指标是因为它并不适用于参数的动态学习过程。

在分类时，产生每一种分类结果的分类边界都不是唯一的，这就让误分类率变成了关于参数 ww 的分段常数函数。这不仅会使关于 ww 的误分类率存在间断点，在求解梯度时也无法给出关于参数移动方向的信息。

感知准则虽然也是建立在误分类率的基础上，但它完全回避了上面的那些缺点，其表达式可以写成

EP(w)=−∑x∈XMwTxntnEP(w)=−∑x∈XMwTxntn

其中 XMXM 是由所有误分类点组成的集合，这说明分类正确的点都具有零误差。感知准则的基本思路是让每个误分类点的贡献 −wTxntn−wTxntn 都大于 0，这就保证了感知准则整体上的非负性。

二元变量 tntn 可以看成是数据点的真实类别和预测类别的差值，其作用在于控制每个误分类点的贡献。如果一个正类被判定为负类，那 tntn 就是个大于 0 的值，可以取成 +1；反过来负类被判定成正类时，tntn 则取 -1。当感知准则取得最小值 0 时，所有的数据点都被正确分类，感知器算法也就完全收敛。

对上面定义的感知准则求解梯度，可以得到每个轮次中参数的更新方式，也就是

w(τ+1)=w(τ)−η∇EP(w)=w(τ)+ηxntnw(τ+1)=w(τ)−η∇EP(w)=w(τ)+ηxntn

其中的超参数 ηη 是学习率（learning rate），ττ 表示的是算法的轮次。这个表达式是感知器算法的批处理更新原则（batch update principle）。

根据这个算法的角度回头看上面的示意图，可以获得更清晰的解释。左侧子图中的 p1 点是个被误判为负类的正类点，其系数 tn=+1tn=+1。

要让这个点被正确分类，原始的系数向量 ww 就要和向量 p1 与学习率的乘积相加，其几何意义就是向 p1 接近，移动的结果就是图中的 wnewwnew。

位于第三象限的 p2 同样是误分类点，但是是被误判为正类。当负类被误判为正类时，tntn 的取值为 -1，此时原始的系数向量 ww 要和向量 p2 与学习率的乘积相减，这里的减法体现为右侧子图中两个天蓝色箭头的方向区别。相减的几何意义是让新系数 wnewwnew 远离误分类点 p2，不难看出，它和上面对 p1 的操作具有相同的效果。

感知器模型可以进一步推广为多层感知器（multilayer perceptron），也就是神经网络。最简单的神经网络是多个感知器的线性集成，神经网络的总输出是对每个感知器单独输出的线性组合进行非线性变换。

放在线性模型的大框架下，具有单个隐藏层的神经网络的数学表达式可以写成

f(x)=σ[∑j=1Mβjh(∑i=1Nαixi+α0)+β0]f(x)=σ[∑j=1Mβjh(∑i=1Nαixi+α0)+β0]

其中 σ(⋅)σ(⋅) 是输出层的激活函数，其最常见的选择是对数几率函数，这时输出层实质上就是个逻辑回归分类器。

除了对数几率函数之外，双曲正切函数tanhtanh（hyperbolic tangent）也是不错的选择，tanhtanh 的值域是 [-1, +1]，这让它的特性和对数几率函数略有差别。

h(⋅)h(⋅) 表示的是隐藏层的激活函数，它既可以与 σ(⋅)σ(⋅) 相同，也可以选取其他的非线性函数。αiαi 和 βjβj 分别表示了隐藏层和输出层的权重系数与偏置。

从上面的公式中不难看出，神经网络的每个神经元都可以看成是做了基函数扩展的线性模型：非线性的激活函数不仅将输出变成了输入属性的非线性函数，也变成了权重系数的非线性函数，体现的是整体的非线性处理。

当所有的激活函数都取恒等函数时，神经网络就将退化成最基础的线性回归。但神经网络的动态学习能力可以自适应地调整模型的参数，也就是线性组合中的权重系数。

神经网络的一个创新之处在于隐藏层的引入。除了输入层和输出层之外，所有无法直接观察的层都属于隐藏层（hidden layer）。隐藏层的输出可以看成是某种导出特征（derived feature），它并不直接存在于输入之中，却可以根据对输入特征的挖掘推导出来。神经网络的强大之处就是能够自适应地提取并修正人造特征，从而适配到数据中潜在存在的模式，深度学习优异的性能便由此而来。

在解决分类问题时，对神经网络的参数优化依赖于对交叉熵（cross-entropy）的最小化。网络输出的分类结果 tt 满足两点分布，它关于数据 xx 和参数 ww 的似然概率可以写成

p(t|x,w)=y(x,w)t[1−y(x,w)]1−tp(t|x,w)=y(x,w)t[1−y(x,w)]1−t

其中 y(x,w)y(x,w) 是输出层激活函数为对数几率函数时的输出，可以视为 xx 归属于正类的条件概率。求解上面式子的负对数似然，得到的就是交叉熵误差函数

E(w)=−∑n=1N[tnlnyn+(1−tn)ln(1−yn)]E(w)=−∑n=1N[tnln⁡yn+(1−tn)ln⁡(1−yn)]

交叉熵的最小化与似然概率的最大化是等效的。误差函数的最小值可以通过反向传播（backpropagation）方法来求解，这在上一季的专栏中已经有过介绍，这里就不重复了。

神经网络中隐藏神经元的数目决定着网络的泛化性能，足够多的神经元可以实现任意复杂的函数，却也会带来严重的过拟合倾向，因而通过正则化的手段来控制网络的复杂度和性能是非常必要的。

一种简单的策略是权重衰减（weight decay），它与前面介绍过的岭回归类似，也是通过添加二次的正则化项来避免过拟合。权重衰减的误差函数可以写成

E~(w)=E(w)+λ2wTwE~(w)=E(w)+λ2wTw

这里的 λλ 是个超参数，控制着权重衰减的幅度。

另一种经常应用于神经网络中的正则化是早停（early stopping）。早停是建立在验证数据集上的正则化策略，简单地说就是对每一轮次训练出的模型计算出其在验证集上的性能，并将当前模型的参数和超参数存储下来。

在之后的每一轮训练中，训练结果在验证集上的性能都被拿来和先前存储的模型性能进行比较，之后保留两者中表现较好的模型的配置。这种策略和感知器训练中的口袋算法（pocket algorithm）类似。

如果从贝叶斯的角度去分析神经网络，模型训练的任务就变成了根据先验假设和训练数据来计算未知参数的后验分布，再对参数的分布积分来计算预测结果，写成数学表达式就是

p(ynew|xnew,D)=∫p(ynew|xnew,w)p(w|D)dwp(ynew|xnew,D)=∫p(ynew|xnew,w)p(w|D)dw

其中的 DD 表示数据集。积分式中的第一项在分类中就对应着对数几率函数的输出，第二项则是参数的后验概率。对神经网络的贝叶斯分析涉及大量的复杂运算，所以我在这里就只介绍一些基本的思路。

在用于分类的神经网络中，先验假设就是参数 ww 的概率分布，这个分布通常被处理成零均值的高斯分布。这个高斯分布的参数 αα 又可以用超先验来表示。由于分类结果是离散的随机变量，它不像连续变量一样存在估计值和真实值的偏差，也就不用对这部分误差定义先验了。

虽然参数本身的先验分布是高斯形式，但激活函数的非线性特性会导致给定数据时参数对于数据的后验概率不满足高斯分布，这时就需要使用拉普拉斯近似（Laplace approximation）生成一个高斯分布，作为对未知后验的模拟。拉普拉斯近似的具体细节在这里暂且略过，你只需要知道它的用处就可以了。

在生成高斯分布时，拉普拉斯近似需要找到后验概率的一个最大值，这等效于对添加正则化项的误差函数 E~(w)E~(w) 进行最小化，其中的正则化项就是参数 ww 先验分布的体现。利用复杂的数值计算方法可以求出后验概率的最大值，进而确定后验概率的高斯近似。

处理完了参数 ww，还要处理超参数 αα。在后验概率的计算中，和参数 ww 相关的超参数被看成是已知的固定值。但在计算预测结果时，还需要考虑超参数 αα 的分布。

对参数 ww 进行积分可以得到数据关于超参数的似然分布，也就是边际似然函数（marginal likelihood）。对边际似然函数进行最优化可以得到关于超参数 αα 的点估计。由于非线性的激活函数让积分难以计算，通常会假设参数的后验概率非常窄，再利用使后验概率最大的参数来计算未知数据的输出。

神经网络是非参数模型的一种，它利用激活函数对线性模型做出了非线性的扩展，让每个输出变成了权重系数的非线性函数，从而在整体上拟合出非线性的效果。更重要的是，它引入了隐藏神经元与隐藏层，这种特殊的结构能够对原始的特征实现重构，从而给数据分析带来了更多的可能。

在 Scikit-learn 中，实现感知器的类 Perceptron 属于线性模型模块 linear_model，这样设置的原因无疑在于感知器本身属于线性判别模型。由于前面使用的中锋 - 中卫数据集是个线性可分的数据集，因此可以用感知器来进行分类。

下图给出了感知器对数据集的分类结果，从左到右的迭代次数分别为 1，3 和 5。可以看出，当初始分类结果有误时，感知器的算法会不断将分类边界向误分类点的方向调整，直到分类正确为止。

感知器对中锋 - 中卫数据集的分类结果

之前使用过的另一个分类数据集——曼城 - 西布朗数据集是个线性不可分的数据集，可以用它来验证多层感知器的性能。实现多层感知器的类叫做 MLPClassifier，在神经网络模块 neural_network 之中。但由于这个数据集是近似线性可分的，即使使用多层感知器也不会生成明显的非线性判决边界，你可以自己运行一下代码并观察结果。

今天我和你分享了感知器和神经网络的基本原理，包含以下四个要点：

神经网络是一类非线性模型，利用非线性的激活函数对输入的线性组合进行分类；

神经网络可以通过误差反向传播自适应地调整网络结构中的参数；

神经网络中隐藏层的作用是构造出新的导出特征；

用贝叶斯方法分析神经网络时，需要使用近似方法来应对非线性导致的计算问题。

2017 年时，神经网络的元老宿耆乔弗雷·辛顿（Geoffrey Hinton）提出了“胶囊网络”（capsule）的概念。胶囊由神经网络单个层中的若干神经元组合而成，可以看成是层中的一个子层。胶囊可以执行大量的内部计算，并输出一个矢量形式的结果，获得更多的输出信息。

你可以查阅关于胶囊网络的资料，思考它对神经网络的发展有何意义，并在这里分享你的见解。

23 | 层次化的神经网络：深度学习

虽然只是对生物神经网络的低水平模仿，人工神经网络却给机器学习打开了一扇全新的大门。自适应的特性让它能够灵活地更新参数，非线性则赋予它具有更加强大的表达能力。曾经的阿喀琉斯之踵——异或问题也随着隐藏层的引入迎刃而解，由原始特征重构而成的导出特征使多层感知器摆脱了对数据集线性可分的限制，呈现在神经网络前方的是大有可为的广阔天地。

神经网络最重要的正名出现在 1989 年，美国学者乔治·塞本科（George Cybenko）证明了神经网络以对数几率作为激活函数时的通用逼近定理。

简而言之，通用逼近定理（universal approximation theorem）说的是如果一个前馈神经网络（feed-forwad neural network）具有单个隐藏层，隐藏层就可以利用有限个神经元来逼近定义在实数集上的任意连续函数。

1991 年，奥地利学者库尔特·霍尔尼克（Kurt Hornik）又证明了通用逼近特性并不取决于激活函数的选择，而是由多层前馈网络自身的架构决定，这就为神经网络的性能提供了坚实的理论依据。

每一个隐藏神经元都能够生成线性的分类边界，在不同的局部选取不同的线性边界，拼接起来的就是全局层面非规则的形状，这就是通用逼近定理说明的主要问题。

虽然给出了理论的良好性质，但通用逼近定理只是一个存在性定理，它没有说明拟合复杂形状的边界到底需要多少个隐藏神经元，也没有解释要如何才能学习出这样复杂的边界。

当单个隐藏层在广度上难以实现时，一个自然的思路就是以网络结构的深度来换取广度，也就是通过增加隐藏层的数目来降低每个隐藏层中神经元的数目，这就是深度学习的起源。

准确地说，深度学习（deep learning）是一类学习方法，它应用的模型架构是深度神经网络（deep neural network）。

深度神经网络是具有多个隐藏层的神经网络，也可以说是浅层神经网络的层次化（hierarchical）组合，其背后是多级的思想。如果把层次化的深度网络压扁成一个平面，得到的就是全连接的单隐藏层神经网络；反过来，深度网络也可以看成是对满足通用逼近定理的单层网络的正则化，通过削减多余的连接来提升网络的泛化性能。

层次化（hierarchicalization）其实是解决问题的一种固有思路，大到政府架构小到快递配送都能看到层次化的身影。层次化的机器学习是将一个复杂的问题分解成若干个简单的问题，再在不同的层面上对这些简单问题进行表示和学习。

从功能上看，深度神经网络通过多个隐藏层的级联实现对输入特征连续不断的非线性处理，提取和变换出了新的特征，每个层次都能够将它的输入数据转换成更加抽象一些的复合表示，这就相当于通过结构的层次化实现抽象特征的层次化。

在图像识别中，特征层次化的作用体现得最为明显。下面的这个例子来自于约书亚·本吉奥（Yoshua Bengio）等人的大作《深度学习》（Deep Learning），在识别这张图片时，理想的算法应该能够将由像素的灰度值所组成的数组输出“女人”这样的标签，识别的过程就是逐层提取模式的过程。

算法的第一层可以根据灰度的空间分布提取出诸如边缘这类在较小的几何尺度上保持不变性的低层次特征，第二层进一步从边缘的组合中抽象出角度和弧度等高级的形状特征，第三层再根据形状的组合抽象出面部和身体等器官的轮廓，最后将这些器官的轮廓组合成关于“女人”的潜在模式。

深度学习示意图（图片来自 Deep Learning，图 1.2）

除了层次化之外，深度学习的另一个主要特点是分布式，由本吉奥在深度学习的开山文献《人工智能中的深度结构学习》（Learning Deep Architectures for AI）中提出。

在前面的文章中我介绍过维度灾难：在构造局部模型时，数据维度的增加会让低维空间中数据点的近邻不再保持，新来的数据就可能找不到任何作为参考的近邻点；而在构造全局模型时，数据维度的增加又会增加模型中参数的数量，使不同自变量对因变量的贡献程度变得难以衡量，导致多元线性回归中的“罗生门”现象。

同是处理高维数据，深度学习采用了分布式表示（distributed representation），将作为整体的高维特征打散成若干个低维特征的组合。

比方说，在传统的学习框架下学习“高富帅”这个概念时，不管是全局模型还是局部模型都会把它看作一个整体，要么寻找它的近邻“白富美”，要么用一组诸如身高和财产之类的属性去拟合它。可是在分布式表示的框架下，“高富帅”这个概念被拆分成“高”、“富”、“帅”三个单独属性的组合，三个属性同时满足才能形成整体意义上的概念。

分布式表示体现了化整为零的思想，其优势是多重的。一方面，它增强了神经网络的表达能力。

在分布式表示下，如果“高”、“富”、“帅”这 3 个属性各有两种取值，那么“高”与“不高”就可以用两个神经元来表示，另外两个属性也是如此，所以要描述这 3 个属性形成的所有可能的组合需要 6 个神经元，而在非分布式的局部表示（localized representation）下，3 个属性的组合需要用 23=823=8 个神经元来刻画。显然，属性的数目越多，每个属性可能的取值越多，分布式表示的优势就越明显。下图是关于分布式表示的直观图示，可以用来帮助理解。

非分布式表示（左）与分布式表示（右）的区别

（图片来自 https://www.oreilly.com/ideas/how-neural-networks-learn-distributed-representations）

另一方面，分布式表示在表达上的优势也会反作用于学习。

局部表示秉持的是非此即彼的二元论，它对一个概念的学习结果只有“高富帅”和非“高富帅”这两种可能，并不存在类似于“矮富帅”或者“高穷帅”这样的推广。

在分布式表示中就不存在这样的限制，它既然能把不同的属性表达出来，也就能够通过基于近似的表达学习出单个的属性。给出“高富帅”和“矮富帅”的样本组合，深度学习能学到后面两个特征；给出“高富帅”和“白富美”的组合，深度学习也能够学到“富”的属性，这是局部表示框架下的传统学习难以做到的。

层次化和分布式相辅相成，让深度学习如虎添翼。层次化为分布式提供了更丰富的特征选择，分布式又可以利用层次化构造出更加复杂的模式。

通俗地说，层次化能够识别出眉毛、眼睛、嘴这些不同的器官，而分布式的表示能够确定只要这些器官组合在一块儿，十有八九是张人脸。柳叶眉加杏核眼加樱桃口是，八字眉加三角眼加香肠嘴也是，两者的区别只是视觉效果上的差距。

感知器的自适应性（adaptivity）在深度神经网络上也得以保持，虽然其中的过程颇费周折。受梯度消失的限制，传统的反向传播算法不能直接用来训练深度网络，这使得训练的难度一度成为限制深度网络应用的掣肘。现在，深度神经网络的训练采用的是逐层预训练结合整体微调的方法，每一层的预训练通过自编码器实现，整体的微调则使用反向传播，其具体的细节在“人工智能基础课”中已经做过介绍，你可以回忆一下。

和之前介绍的其他所有浅层模型（shallow learner）相比，深度学习可说是上得厅堂下得厨房：它既能够像主成分分析或者流形学习那样，找到数据当中的隐含模式；又能够像逻辑回归或者朴素贝叶斯那样，对数据进行分类。这相当于把无监督学习和监督学习两手抓两手硬，也开辟了理解深度学习的两个角度。

从预测的角度看，深度神经网络可以看成是一组堆叠起来的广义线性模型。

在广义线性模型中，自变量的线性组合作为链接函数反函数的自变量出现，其结果等于因变量的数学期望。

在深度学习中，每个神经元其实都表示了一个广义线性模型，增加神经元的数目就是增加线性变换的复杂度。由于前一层中模型的输出会作为后一层模型的输入，不同层次之间的交互相当于对广义线性模型进行了参数的扩展，增加层数就是增加非线性变换的次数。线性变换和非线性变换一轮又一轮的组合让深度网络具备了更强的拟合能力。

而从解释的角度看，深度学习起到的是降维的作用，从高维数据中提取出隐藏的低维几何结构——没错，就是流形。

深度学习既要从高维空间中构造出低维流形，也要找到高维数据在低维流形中的表示，前者是对高维数据的参数化过程（parameterization），后者则是在流形上对数据的参数表示（parametric representation）。

将高维数据映射到低维流形上能够简化进一步的回归或分类任务，使用浅层的支持向量机或者 kk 近邻算法就能搞定。这种思路将深度生成模型解释为流形的展开，深度判别模型解释为流形的分离，数据变换则解释为计算样本在流形上的投影。

最后来看看贝叶斯视角下的深度学习。和前面提到的其他模型一样，贝叶斯主义将深度神经网络的优化也看作后验概率最大化的问题，参数的先验分布在这个过程中会以正则化项的形式出现。贝叶斯主义关于深度学习的一个有趣结论是将预训练（pre-training）过程看成正则化项，这显然在暗示预训练的作用在于确定参数的先验分布。

在介绍神经网络时我曾提到，权重衰减器就对应着参数的高斯先验。而在深度学习中，用来抑制过拟合的 dropout 方法和具有伽马先验的贝叶斯岭回归（Bayesian ridge regression）是等效的。

今天我和你分享了深度神经网络一些主要的设计思想，以及看待深度神经网络的不同角度。但深度学习的原理至今尚未得到清晰的解释，阐释它的思路也是众说纷纭、莫衷一是。本文中的观点虽然都来自于这个领域的研究权威，但也仅仅作为一家之言供你参考。总结起来，今天的内容包含以下四个要点：

深度神经网络是具有层次化结构的多层神经网络；

深度神经网络采用分布式表示，提升了网络结构的表达能力和学习能力；

深度神经网络是一组堆叠起来的广义线性模型；

深度学习能够找到高维数据所对应的低维流形。

深度学习作为眼下关注度最高的机器学习概念，看好者公说公有理，看衰者婆说婆有理，那么你是如何看待深度学习的前景的呢？

欢迎发表你的观点。

24 | 深度编解码：表示学习

在上一讲中我提到，深度学习既可以用于解释也可以用于预测。在实际中，这两个功能通常被组合使用，解释功能可以看作编码器，对高维信息进行低维重构；预测功能则可以看作解码器，将低维重构恢复成高维信息。

这样的两个深度网络级连起来，就形成了编码 - 解码结构（encoder-decoder model）。这种结构在诸如语音、文本、图像等高维数据的处理中应用广泛，取得了良好的效果。

编解码的思想来源于信息论，是信息传输与处理的基础理论之一。但在通信中，编解码的对象是底层的语法结构，也就是对携带信息的符号进行编码，通过数据压缩实现信息的高效传输，但输出的符号本身与其所表达的含义并无关联。

在深度学习中，编解码的操作更多在语义层面完成，无论是文本还是图像，编解码的目的都是重新构造数据的表示方式，简化学习任务的难度。

在最初的尝试中，编码器和解码器并不是分开的，而是存在于单个的深度网络中，这种深度结构就是自编码器。

自编码器（autoencoder）属于生成模型，它的作用是以无监督的学习方式学到数据集的稀疏表示，从而给数据降维。显然，它和前面介绍过的主成分分析殊途同归。可以证明，如果自编码器只有一个线性隐藏层，同时使用均方误差作为损失函数，那么 kk 个隐藏神经元的权重系数就代表了输入数据的 kk 个主成分。

从编解码的全过程来看，如果要构造出有效的表示，自编码器的输入和输出就应该是近似相等的，那它学习的对象是个恒等函数。看到这儿你可能就不理解了：恒等函数有什么好学的呢，原样输入原样输出不就完了吗？这话一点儿毛病没有，但成立的前提是原样输入原样输出的功能可以实现。

这就像学美术的学生需要临摹画作，再高的临摹技术也比不过手机拍照来得像，但你拿一张照片去跟老师交差肯定是要挨骂的。自编码器要研究的不光是如何近似恒等函数，而是如何用 50 个中间变量构造出包含 100 个自变量的恒等函数，这样的问题就没那么简单了。

需要说明的是，在结构上，自编码器隐藏神经元的数目未必会少于输入 / 输出神经元。但即使有 200 个隐藏的神经元，自编码器通常也只会激活这些潜在中间变量里的一小部分，达到的效果仍然是用 50 个中间变量拟合 100 维的恒等函数，这种即使在过完备时依然得以保持的稀疏特性（sparsity）是自编码器实现降维的核心特性。

自编码器的稀疏特性可以从能量的角度来解释。在自编码器最初的设计中，编码器的任务是生成参数矩阵 WCWC，用来计算输入数据 XX 的码字向量，解码器的任务是生成参数矩阵 WDWD，用来重构的码字向量所对应的初始数据 X~X~。

如果编码器和解码器直接级连的话，这就是个主成分分析的系统。但自编码器和主成分分析的区别在于引入了稀疏逻辑模块（sparsifying logistic），将编码器输出的码字 ZZ 非线性地映射成特征码字 Z¯Z¯。特征码字大部分元素的取值为 0，非零元素值则落在 [0, 1] 这个区间内。

定义损失函数时，自编码器将非线性的编解码过程综合考虑，提出了能量（energy）的概念，其数学表达式为

E(X,Z,WC,WD)=EC(X,Z,WC)+ED(X,Z,WD)=12||Z−WCX||2+12||X−WDZ¯||2E(X,Z,WC,WD)=EC(X,Z,WC)+ED(X,Z,WD)=12||Z−WCX||2+12||X−WDZ¯||2

其中的第一项表示编码器的预测能量（prediction energy），第二项表示译码器的重构能量（reconstruction energy），作为两者之间接口的稀疏逻辑则具有以下的非线性映射关系

z¯i(k)=ηeβzi(k)ξi(k),ξi(k)=ηeβzi(k)+(1−η)ξi(k−1)z¯i(k)=ηeβzi(k)ξi(k),ξi(k)=ηeβzi(k)+(1−η)ξi(k−1)

其中 kk 表示第 kk 个训练样本，ii 表示特征码字中的第 ii 个元素。通过 ξi(k)ξi(k) 的递归表达式可以看出，稀疏逻辑的本质就是计算所有训练样本中相同码字单元的加权 softmax 分类结果，其中的参数 ηη 控制特征码字的稀疏程度，ηη 越小非零元素越少；参数 ββ 则控制特征码字的平滑程度，ββ 越大码字的输出就越接近两点分布。通过合理地增大 ββ 并减小 ηη，自编码器就可以实现稀疏的表示。

将编码器和解码器整合到同一个结构之中的自编码器可以说是个特例，它的编码器和解码器都可以堆叠成层次化的结构，来实现更加复杂的非线性映射。在自编码器的基础上推广一步，将编码器和解码器各自作为一个独立的深度网络区分开来，可以实现更加强大的功能。

《红黄蓝之构成》（Composition II in Red, Blue and Yellow）（1930）（图片来自维基百科）

上面这张图片是荷兰大师皮埃·蒙德里安（Piet Mondrian）的名作《红蓝黄之构成》（Composition II in Red, Blue and Yellow），可不要小看这幅画，这个看似简单的色块组合摆到拍卖行就是千万美元起步的价格。当然，我的目的不是讨论几何抽象画派的艺术造诣，而是要从稀疏表示的角度来看待这幅画。

显然，这张图像中的像素只有少数几种取值，而相同取值的像素又基本上集中在一起。如果将每一组聚合在一起的颜色相同的像素用一串编码来表示，就可以大大地压缩这幅《构成》的体积，这就是所谓的游程编码（run length coding）。

同样的思路也可以应用到图像的语义处理之中。从语义上看，《构成》其实就是不同颜色的几何形状的组合，而每个形状的特征无外乎长度、宽度和颜色这样三个维度，对图像的学习实际上就是对这三个维度的学习。

在“人工智能基础课”中我介绍过卷积神经网络，这是基于神经网络的图像处理使用的最主要的工具。卷积神经网络本身就可以看成是个庞大的编码器，其中的卷积层用于提取特征，不同的卷积核（convolutional kernel）代表不同的特征类型。

在图像的每个局部上，和卷积核相似度最高的区域都被下采样操作（subsampling）筛选出来，用于下一阶段的特征提取。在卷积层和下采样层的迭代过程中，低层次的特征不断组合成高层次的特征，数字图像的表示方式也从原始的像素集合变成卷积得到的特征组合，这两个层也就构成了卷积神经网络的编码器。

对卷积出来的表示进行解码相当于反转编码的过程，编码的输出经过上采样的处理之后再和卷积核进行卷积。上采样（upsampling）不仅可以补充缺失分辨率，还能确定编码器学到的码字中每个元素的覆盖范围，卷积操作则在覆盖范围上计算上采样结果和特征本身的匹配程度。

随着上采样和卷积的不断进行，高层次的特征如庖丁解牛般一点点被拆解成低层次的特征，这些特征在重构出的图像中又体现为像素的分类结果。如此这般，一个完整的卷积网络编解码可以将原始图像重构成不同语义的组合，来自斯坦福大学 CS231n 课程的下图就是个典型的例子。

卷积网络编解码

（图片来自 http://cs231n.stanford.edu/slides/2017/
cs231n_2017_lecture11.pdf）

和卷积网络相比，编解码结构更直观的应用是在循环神经网络中。循环神经网络是增加了时间维度的神经网络，是自然语言处理、尤其是机器翻译的利器。机器翻译需要将一种语言的句子映射成另一种语言的句子，这类序列到序列的模型（sequence-to-sequence model）正是编解码结构的用武之地。

不管使用循环神经网络还是长短期记忆网络，编解码结构在处理翻译问题时都是整体读取输入的语句，将输入语句编码成定长的向量码字表示。在带有时序的神经网络中，编码的码字会以隐藏状态的形式出现，并被编码器分字翻译成输出。在译码时，译码器会根据隐藏状态和之前时刻的输出来确定当前时刻输出的似然概率，并选择最优的结果。

在谷歌的招牌神经机器翻译系统（Google neural machine translation）中，编码器和译码器中不同的长短期记忆层以残差连接，以提升反向传播中的梯度流，加快深层网络训练的速度。编码器网络的最底层和解码器网络的最顶层通过注意力模块进行连接，其作用在于使译码器网络在译码过程中分别关注输入语句的不同部分。其中具体的细节在这里就不做介绍了。

编码器和译码器并不一定非要具有相同的类型，异构的神经网络一样可以用来构成编解码结构。在微软公司于 2017 年自然语言处理实证方法会议（Conference on Empirical Methods in Natural Language Processing）发表的论文《利用卷积神经网络学习语句的通用表示》（Learning generic sentence representations using convolutional neural networks）中，研究者就提出了一种学习文本分布式表示的架构。

这种架构以卷积神经网络作为编码器，将输入语句转化为连续取值的码字，译码器则采用长短期记忆网络。之所以选择卷积网络作为编码器，作者的解释是一是卷积网络可以达到稀疏的效果，降低参数的数目；二是卷积网络的层次化结构有助于识别语句中的语言模式，这是循环网络无法做到的。

除了文本处理外，图像处理也可以应用到异构的编解码结构。在韩国研究者的论文《用于图像捕捉的文本导向注意力模型》（Text-guided attention model for image caption）中，作者使用一个卷积网络对待捕捉的图像编码，用一个循环网络对包含捕捉对象的文本编码，两者的输出用注意力机制处理后再对卷积网络的输出进行加权。译码器则利用长短期记忆网络将码字转换成语句。感兴趣的话，你可以自己阅读文章，了解细节。

编解码结构的核心是生成数据的表示，因而属于表示学习的范畴。表示学习（representation learning）也叫特征学习（feature learning），其目标是让机器自动发现原始数据中与输出相关度较高的隐含特征，因而能够自动生成新特征的技术都可以归纳到表示学习中。

今天介绍的编解码结构则可以看成是表示学习的一类应用。《表示学习：综论与新视角》（Representation Learning-A Review and New Perspectives）是关于表示学习的一篇综述，如果想深入了解表示学习，可以阅读这篇文献。

今天我和你分享了由深度网络衍生出来的编解码结构，以及相关的表示学习概念，包含以下四个要点：

编解码结构可以重构数据的表示方式，提取出高层次的特征；

自编码器将编码器和解码器集成到同一个深度网络中，是一种无监督的生成模型；

卷积神经网络和循环神经网络都可以用来构造编解码结构；

表示学习也叫特征学习，是让机器自动提取数据特征的技术。

和特征学习相对应的概念是特征工程（feature engineering），也就是人工提取数据特征。这样做虽然能够充分利用垂直领域的先验知识，却在效率上远远逊色。那么你是如何看待特征学习与特征工程的利弊与结合的呢？

欢迎发表你的观点。

25 | 基于特征的区域划分：树模型

不知道你是否留意过非洲的地图？和其他大洲按照地理边界划分国界的方式不同，很多非洲国家的国境线都是规则的直线条组合。这种非自然的划分背后隐藏着一段屈辱的历史：19 世纪起，欧洲的资本主义新贵们开始了对非洲的掠夺。而在巧取豪夺资源之外，他们也没有忘记抢占地盘，这些横平竖直的国境线就是对当年殖民主义者瓜分非洲无声的控诉。

下图是主要殖民国家在非洲的势力范围划分图，图片里的非洲如俎上的鱼肉般被肆意切割，切下的每一块都像黑奴一样，被烫上宗主国的烙印。

瓜分非洲（Scramble for Africa）（图片来自维基百科）

当然，我的目的不是探讨历史，举这个例子的原因是从非洲地图容易直观地联想到机器学习中基于树方法的分类结果。树模型（tree-based model）遵循“分而治之”的思路，以递推方式将特征空间划分为若干个矩形的区间，再在每个区间上拟合出一个简单的模型。在分类问题中，这个简单模型就是类别的标签选择。在“人工智能基础课”中，我曾以用于分类的决策树为例，对树模型做了介绍，你可以回忆一下。下图就是分类决策树对特征空间进行划分的一个实例。

决策树的生成与对特征空间的划分（图片来自 Pattern Recognition and Machine Learning, 图 14.5 & 14.6）

这一次，我将换个角度，从线性回归模型出发来理解树模型，这种理解思路将从回归树开始。

顾名思义，回归树（regression tree）是用来完成回归任务的树模型。和全局的线性回归相比，树模型是局部化的模型，可以实现非线性的拟合。在从整体到局部的过渡中，回归树的操作和之前介绍过的回归样条方法一脉相承，采用的都是“分段函数”的思路，但两者的区别在于回归树对特征空间执行的是递归式划分（recursive partitioning）。递归的划分不要求一步到位，而是步步为营地对前一次划分的子区域继续做出细化，直到满足预先设定的要求为止。这一点在上面的图示中也有所体现。

这样看来，回归树和原始线性回归的区别仅仅在于全局和局部的差异吗？非也！回归树的表达能力强在对于特征之间相互作用（interaction）的刻画。当用来预测输出的特征有多个时，不同的特征之间很可能存在着交互作用，共同对输出产生影响，而这种影响的作用就超出了线性的范畴。假设输入的特征有 x1x1 和 x2x2 两个，如果要考虑它们之间的相互作用，线性回归的模型就需要改写成

y=a0+a1x1+a2x2+bx1x2+ϵy=a0+a1x1+a2x2+bx1x2+ϵ

当 x1x1 和 x2x2 各自产生一点微小的变化时，这种变化在交互项中的累积就是

(x1+δ1)(x2+δ2)=x1x2+δ2x1+δ1x2+δ1δ2(x1+δ1)(x2+δ2)=x1x2+δ2x1+δ1x2+δ1δ2

可以看出，原始的单个交互项在扰动之后变成了四项，其中的最后一项无疑会给线性模型的解释造成困扰。而当特征的数目增加时，特征之间交互项的数目会以指数速度增加，从而给这些非线性的描述带来严重的困难。

和线性回归“由因及果”的推理方式相比，回归树采用了更有弹性的“由果推因”的方式。它并不直接构造从自变量到因变量明确的数量关系，而是通过对因变量进行分组来确定自变量的影响方式。

分组的依据有两个：一个是作为输出的因变量的相似性，另一个是作为输入的单个自变量的相异性。因变量的相似性决定了被划分到同一组的数据在输出上的差别较小，自变量的相异性则决定了被划分到不同组的数据在某一个输入属性上的差别较大。对划分好的数据集继续迭代执行这个过程，就可以完成对特征空间的递归式划分。

由于回归树采用树状结构来建模，因此从树结构的角度看，对数据集的递归式划分就是对树模型的不断分枝，每个分枝点都是让因变量产生最大差异的那个自变量。在这个过程中，每个节点内样本的同质性会不断增强，当样本完全同质化或者数目过少时，回归树的构造就完成了。分枝点具体的选择原则在上一季的专栏中我已经做过介绍，你可以回忆一下。

回归树和分类树的区别在于将信息增益的指标替换成了方差，算法会选择分类后两个类别方差之和最小，也就是和原始方差相比下降最大的那个属性进行划分，这种划分方式被称为方差下降（variance reduction）。

下面这个对回归树划分方式的说明来自中文文献《CART 分类与回归树介绍》，这篇文章发表在 1997 年《火山地质与矿产》的第 18 卷第 1 期上，这从侧面反映出统计学习的应用范围有多么广泛。文章说明划分的优劣取决于生成的结点中因变量的离散程度，划分之后因变量的取值越集中，划分的效果就越好。树生成的算法就是一步一步找到每一个最优的划分。

假设训练集中总共有 300 个数据，方差为 51.5。有一种划分方式将数据集分为 142 和 158 两组，两组的方差分别是 46.7 和 49.3。这表明左右两个结点中因变量的离散程度和总体的离散程度相近，显然，这一划分的效果不佳。相比之下，另一个划分可以让左结点中的方差为 20.3，右结点中的方差为 26.0。这种划分减少了一半的方差，在每个结点里，因变量都更加接近它们的平均值，因而是个更好的划分。

这样的过程体现出局部化模型典型的处理方式，也就是先将整体划分成局部，使每个局部都体现出一定的规律性，再对每个局部的规律做出拟合。划分可以通过逐步选择具有最大信息增益或者最大方差下降的特征来完成，那么在划分出的局部上如何来拟合呢？回归树给出了一个非常简单的答案，那就是每个局部上所有数据的取值都是常数，其数值等于这个局部内样本点输出的均值。这样的决策树输出的就是像楼梯一样高低错落的超平面的组合。

为了测试回归树的效果，我用它对一直应用于回归任务的英超数据集进行了拟合，结果如下。实现回归树需要调用 Scikit-learn 库中 tree 模块的 DecisionTreeRegressor 类。在拟合时，回归树的最大深度被设置为 3，这意味着对特征空间的划分次数为 3 次，最多可以分成 23=823=8 个区域。可以看到，在一维的情形下，回归树其实是分段的常数函数，只不过不同分段之间的分界点并不是人为指定，而是通过方差下降的方法计算出来的。

回归树在英超数据集上的拟合结果

为了进一步考察回归树在多元回归问题中的表现，并观察回归树对特征之间的交互的处理方式，我们再来看看用回归树去拟合位置评分数据和场均积分的关系。出于便于可视化的考虑，在位置评分中我只选择了后卫评分和前锋评分两者作为输入的特征。选择这两者的考虑是在前面的多元回归分析中已经证明，这两个属性和积分之间存在较强的相关性，而两个属性所映射的二维平面也更容易观察。

从回归树的结果可以看出，在不同的数据点上，两个特征的交互方式是不同的。树算法首先根据防守球员的得分将数据集一分为二。在防守水平前三分之一的队伍中，进攻水平并没有产生太大的影响，一上一下两个傲然不群的数据点更像是数据集中的异常点。而在防守较差的三分之二里，进攻和防守之间的互动就复杂了许多，形成的区域划分也复杂了许多。

回归树在英超数据集上的多元拟合结果

无论是回归树还是分类树，在生成时都遵循相同的流程，就是先划分特征空间，再对每个特征空间去拟合。两者的区别主要在于选择划分特征时采用的指标不同。和线性回归相比，决策树更加符合人类做出决策、尤其是像医学诊断这类决策的思维流程，它的描述性还要更好一些。但是决策树对加性关系的表达能力不强，如果因变量真的是自变量的线性组合的话，使用决策树恐怕就要弄巧成拙了。

在可用于划分的自变量较多时，即使树结构的结点树已经预先设定，要穷举搜索到方差和最小的最优树依然是个费时费力的过程。贪心策略是确定决策树的结构时通常采用的方法。

贪心策略（greedy strategy）是活在当下的方法，在生成树时每次只增加一个结点，确定结点时采取在当前状态下最优的选择，让每个子集都在当前条件下具有最正确的分类。但这种方式并不能确保找到全局的最优解，因而容易造成过拟合。

贪心策略的另一个问题是终止条件，当树结构达到一定深度后，进一步的划分很可能不会让子集方差产生明显的下降，继续划分下去就会造成过拟合。应对这一现象的手段是先让贪心策略生成一棵比较复杂的树，当每个子集中样本的数目都达到下限时终止算法，再来对这棵树进行剪枝操作。

剪枝（pruning）是对决策树残余方差和复杂度之间的折中，对回归树来说，剪枝的目标函数可以写成

C(T)=∑τ=1|T|∑xn∈Rτ(tn−1Nτ∑xn∈Rτtn)2+λ|T|C(T)=∑τ=1|T|∑xn∈Rτ(tn−1Nτ∑xn∈Rτtn)2+λ|T|

其中 xnxn 表示样本的自变量，tntn 表示样本的因变量，RτRτ 表示决策树划分出的区域，其中包含 NτNτ 个样本，TT 表示划分区域的数目。显然，TT 的作用是对目标函数的正则化。

决策树一个主要的缺点是对数据点异常敏感，训练数据集一点不起眼的变动就足以生成一棵完全不同的决策树，而数据集中的异常点也会对决策树结果造成未知的影响。此外，在处理回归任务时，决策树得到的是不连续的结果。这样看来，回归样条就可以视为决策树的一个优化。

广义来看，决策树可以视为对基本线性模型的层次化集成，这里的基本模型就是数据在每个划分区域上的回归或分类规则，这些规则一般是线性的。决策树的作用是将这些固定的局部线性规则进行拼接式的组合，从而生成整体意义上的非线性模型。后面我们将发现，看似简单的集成策略却能在机器学习中发挥出出人意料的优异性能。

今天我以回归树为例，和你分享了决策树的基本原理，包含以下四个要点：

决策树是局部化的非参数模型；

决策树生成算法先将特征空间划分成若干区域，再在每个区域上拟合输出；

决策树能够更加灵活地刻画不同属性之间的相互作用；

决策树可以看成最简单的集成模型。

作为规则集合的决策树不仅仅是一类机器学习的模型，更是决策分析中常用的结构化方法。那么你能想到哪些决策树在机器学习之外的应用呢？

欢迎发表你的观点。

26 | 集成化处理：Boosting与Bagging

伊壁鸠鲁（Epicurus）是古希腊一位伟大的哲学家，其哲学思想自成一派。在认识论上，伊壁鸠鲁最核心的观点就是“多重解释原则”（Prinicple of Multiple Explanantions），其内容是当多种理论都能符合观察到的现象时，就要将它们全部保留。这在某种程度上可以看成是机器学习中集成方法的哲学基础。

集成学习架构图（图片来自 Ensemble Methods: Foundations and Algorithms，图 1.9）

集成学习的常用架构如上图所示。在统计学习中，集成学习（ensemble learning）是将多个基学习器（base learners）进行集成，以得到比每个单独基学习器更优预测性能的方法。每个用于集成的基学习器都是弱学习器（weak learner），其性能可以只比随机猜测稍微好一点点。

集成学习的作用就是将这多个弱学习器提升成一个强学习器（strong learner），达到任意小的错误率。

在设计算法之前，集成学习先要解决的一个理论问题是集成方法到底有没有提升的效果。虽说三个臭皮匠赛过诸葛亮，但如果皮匠之间没法产生化学反应，别说诸葛亮了，连个蒋琬、费祎恐怕都凑不出来。

在计算学习的理论中，这个问题可以解释成弱可学习问题（weakly learnable）和强可学习问题（strongly learnable）的复杂性是否等价。幸运的是，这个问题的答案是“是”，而实现从弱到强的手段就是提升方法。

通俗来说，提升方法就是诸葛丞相手下这样的三个臭皮匠，啊不，裨将的组合：其中的第一位擅用步兵和骑兵，奈何对水战一窍不通，这样的将领用来对付曹操可以，对付孙权就有点儿吃亏了。为了补上第一位将军的短板，第二位裨将在选择时专门挑选了水战功力雄厚的。可惜人无完人，这位水军高手也有严重的偏科，骑在马上还可以，指挥步兵就是去送人头。这两位参谋放在一起，指挥骑兵一点儿问题都没有，但另外两个军种就差点儿意思。

为了查缺补漏，诸葛丞相在第三位裨将的选择上颇费了一番心思，找到了一位步战和水战兼通的将军。这样一来，这三位裨将组成的联席会议就能游刃有余地指挥各种战斗：无论在哪种战法上，专业的将领都能够占到了总体中的多数。虽然每一位将领单独拎出来都有严重的缺陷，可三个组合在一起就能让战斗力大大地提升。

提升方法示意图（图片来自 Elements of Statistical Learning，图 10.1）

上面的解释意在说明，提升方法（boosting）通过改变训练数据的分布来训练不同的弱学习器，再将它们组合成强学习器。虽然不受具体训练方法的限制，但大多数提升算法都会迭代生成与数据分布相关的弱分类器，并将它们以加权组合的方式添加到最终的强分类器中。每当一个新的弱学习器加入后，数据的权重都会被重新分配（reweighting），被错误分类的样本占据更大的权重，被正确分类样本的权重则被相应地削减，这保证了未来的弱学习器会更多地以前车之覆作为后车之鉴。

既然训练数据都是一样的，那么如何在每个轮次中选择不同的权重分配呢？

在自适应提升（adaptive boosting, AdaBoost）这个最成功的提升算法中，权重分配的策略是这样的：以二分类任务为例，首先给每个样本赋予相同的权重 wi=1/Nwi=1/N，再用它们来训练弱分类器 fm(x)fm(x) 并计算训练误差 ϵmϵm，根据训练误差可以计算出权重调整的系数 αm=0.5log[(1−ϵm)/ϵm]αm=0.5log⁡[(1−ϵm)/ϵm]，并对每个样本的权重 wiwi 做出调整

wi←wi⋅exp[αmI(xi)]wi←wi⋅exp⁡[αmI(xi)]

对分类错误的样本 I(xi)=1I(xi)=1，分类正确的样本 I(xi)=−1I(xi)=−1，这样做的作用就是放大误分类样本的权重。新计算出的权重经过归一化处理后，就可以用来继续训练下一个弱分类器，直到集成出强分类器为止。强分类器的数学表达式为

F(x)=sign[∑m=1Mαmfm(x)]F(x)=sign[∑m=1Mαmfm(x)]

如果将二分类任务进行推广，那么上面表达式中的符号函数 sign(⋅)(⋅) 就可以去掉，得到的就是一个进行了基函数扩展的线性回归模型。

和决策树类似，提升方法本质上是个广义可加模型，它的每个组成部分都是一个单独的弱学习器。随着弱学习器不断被添加到强学习器中，新的扩展基函数也被不断添加到广义可加模型中，但每一个添加的扩展基函数都预先经过优化，优化的过程是逐步来完成的。

在此基础上可以进一步推导得出，当使用指数函数 exp[yi⋅f(xi)]exp⁡[yi⋅f(xi)] 作为损失函数时，作为基扩展的 AdaBoost 模型计算的就是样本属于某个类别的对数几率。换言之，AdaBoost 就是加强版的逻辑回归。

提升方法的重点在于取新模型之长补旧模型之短来降低偏差，尽可能获得无偏的估计，模型之间是相互依赖的。如果去除对依赖性的限制，使用相互独立的模型来实现集成，典型的方法就是装袋法。

装袋法（bagging）是自主聚合（bootstrap aggregating）的简称，是模型均衡的一种手段。我们都知道，如果对 NN 个相互独立且方差相同的高斯分布取均值，新分布的方差就会变成原始方差的 1/N1/N。

将同样的道理推广到统计学习上，从训练数据集中利用重采样（resampling）抽取出若干个子集，利用每个子集分别建立预测模型，再对这多个预测值求平均，就能够降低统计学习方法的方差。需要注意的是，装袋法并没有降低偏差的效果，也就没法提升预测的准确性，因此在选择基学习器时，应当以偏差较小的优先。

秉承平均主义观点的装袋法有个特点，就是在不稳定的弱学习器上效果尤为明显。假设用于平均的学习器是 h(⋅)h(⋅)，那么装袋法的结果就是 h(⋅)h(⋅) 在自助采样法采出来的数据分布上的期望值。

利用方差不等式 (E[X])2≤E[X2](E[X])2≤E[X2] 可以计算出，经过装袋后模型的方差不会大于每个单独训练出来模型的方差在自助采样分布上的数学期望，也就是先求期望再求方差优于先求方差再求期望。

这样的性质说明装袋法对方差的降低实际上是一种平滑效应：模型在不同的数据子集上波动越大，装袋法的效果就越好。如果模型本身受数据的影响不大的话，那装袋也不会起到太好的提升效果。

这样的道理在生活中也有所体现：一个团队里总会有一些哪里需要哪里搬的“万金油”型成员，在必要的时候顶到缺人的岗位上，可一旦全是万金油成员的话，这对团队的帮助就非常有限了，甚至还会起到反作用。

装袋法之所以能够降低方差，最主要的原因在于它可以平滑高次项的方差。对于具有 xn,n≥3xn,n≥3 形式的高阶指数项来说，输入和输出之间存在着雪崩的效应，输入端一点微小的扰动都可能导致输出的大幅波动。如果输入输出关系的拟合结果中存在这样的高阶项，它就必然是不稳定的。

装袋法的好处在于能够降低高阶项的方差，同时又不会影响到线性项的输出。所以如果弱学习器是多项式这类高阶模型，或是决策树这类容易受样本扰动影响的模型，用装袋法来集成都是不错的选择。

从贝叶斯的角度看，装袋法的输出是近似于后验最优的预测，但这需要弱学习器满足次序正确的条件。还是以分类问题为例，如果给定的样本 xx 属于类别 yy 的概率最大，那么次序正确（order-correct）的分类器 h(⋅)h(⋅) 就应该以最大的概率把 xx 划分到 yy 中。

可以证明，这种情况下装袋法能够达到的最高精度就是按照后验概率对样本进行划分，此时模型的错误率就是贝叶斯错误率（Bayes error rate）。

决策树是集成学习最青睐的基学习器，无论是提升法还是装袋法，其代表性的算法都是在决策树的基础上发展出来的。

接下来，我将原始决策树算法和集成化的决策树算法应用在线性不可分的曼城 - 西布朗数据集上，观察其分类的结果。

可以看到，在使用单棵决策树的 DecisionTreeClassifier 类时，深度为 4 时还会存在误分类点，可再增加一层结点就可以实现完全正确的分类。但需要说明的是，由于决策树的初始生成方式是随机的，即使深度相同的树也不能保证每次都产生相同的边界。

单棵决策树对曼城 - 西布朗数据集的分类结果

采用决策树的集成可以得到不同的分类边界。在 Scikit-learn 中，两种继承方法都在 ensemble 模块中，类的名称分别是 AdaBoostClassifier 和 BaggingClassifier。

在 AdaBoost 和装袋法中，每个基学习器都被设置为深度为 3 的决策树。从结果中可以看出，提升方法可以得到完全正确的结果，但装袋方法的分类还会存在误差。其原因在于深度为 3 的决策树属于弱学习器，本身存在着不小的偏差。提升方法可以同时控制偏差和方差，将每个数据点都正确分类；但装袋方法只能降低方差而没法改善偏差，出现误分类点也就不奇怪了。

集成化决策树对曼城 - 西布朗数据集的分类结果

除了提升法和装袋法之外，另一种知名度较低的集成方法是堆叠法。堆叠法（stacking）也叫堆叠泛化（stacked generalization），是层次化的集成方法，其思想和神经网络类似，只不过神经网络堆叠的对象是神经元和隐藏层，而集成方法堆叠的是同构或者异构的基学习器。

堆叠法先要用自助采样生成不同的数据子集，用数据子集训练第一层中不同的基学习器。第一层基学习器的输出再被送到第二层的元分类器（meta classifier）中作为输入，用来训练元分类器的参数。

堆叠法的思想和前两种方法有所不同。无论是提升法还是装袋法，其重点都落在单个模型的生成方式上，也就是如何训练出合适的基学习器，基学习器的形式一般是统一的。

而堆叠法的重点在于如何将不同的基学习器的结果组合起来，研究的对象是让所有基学习器共同发挥出最大效果的组合策略。某种意义上说，堆叠法的训练数据不是原始的训练数据集，而是不同基学习器在训练数据集上的结果，起到的是模型平均（model averaging）的作用，提升法和装袋法都可以看成它的特例。正因如此，堆叠法除了被视为集成方法外，还可以看成是模型选择的一个手段。

集成方法超出了简单的模型范畴，是元学习（meta learning）的方法。元学习还没有业界公认的标准解释，但通常被理解为“关于学习的学习”。在集成方法这个实例中，元学习体现在通过改变数据特征、数据集和算法构造方式，通过多算法的融合来实现更加灵活的学习。

今天我和你分享了集成学习的基本原理，以及典型的集成学习方法，包含以下四个要点：

集成学习可以将多个弱学习器组合成强学习器，是模型的融合方法；

提升方法通过重新分配数据的权重来改善弱学习器，可以提升模型的偏差性能；

装袋方法通过重新采样数据来改善弱学习器，可以提升模型的方差性能；

堆叠方法通过重新构造输出来改善弱学习器，可以看成广义的模型选择。

不同的集成方法也可以集成起来。如果将提升方法的输出作为装袋方法的基学习器，得到的是 MultiBoosting 方法；而如果将装袋方法的输出作为提升方法的基学习器，得到的就是 Iterativ Bagging 方法。

对这两种关于集成的集成，你可以查阅资料，深入了解它们的原理与优缺点，并在这里留下你的见解。

27 | 万能模型：梯度提升与随机森林

上一篇文章中我和你分享了提升法和装袋法这两种典型的集成方法，它们都可以用在决策树模型上，对多棵不同的树进行组合。然而直接使用这两种集成方法只是初级的策略，将它们的强化版用在决策树上可以得到更加强大的万能模型，也就是梯度提升决策树和随机森林。

梯度提升（gradient boosting）的思想来源于对提升方法的推广。显式的提升方法本身可以解释为对一个合适的损失函数的优化，如果将损失函数的选择扩展为任意的可微函数，并将提升方法和最优化中的梯度下降（gradient descent）结合起来，得到的就是梯度提升。

梯度提升将提升方法视为函数式的迭代梯度下降算法，通过迭代地选择指向负梯度方向的函数，也就是弱学习器来优化整个函数空间上的代价函数。在 AdaBoost 中，每个弱学习器的短板通过权重的加强得以凸显；而在梯度提升中，凸显的方式被替换成了梯度。

要理解梯度提升方法的妙处，还是要先从回归问题说起。在解决回归问题时，模型的输出 f(x)f(x) 和真实值 yy 之间的差值 h(x)=y−f(x)h(x)=y−f(x) 被称为残差（residual），它表示了数据中模型所不能刻画的那些部分。

传统的单一模型对残差无能为力，可集成方法的引入给处理残差提供了新的思路，那就是用新的基学习器去拟合残差，作为对上一个模型的修正。将拟合真实值 yy 和拟合残差 hh 的模型集成起来，可以获得更加精确的拟合结果。

上面的过程类似于日常生活中的猜数字游戏。要猜测未知的数字，我先要随机地选择一个初始值进行猜测，再根据猜测值和真实值之间的大小关系来调整。随着一轮轮猜测的不断进行，猜测的结果就会越来越接近真实的未知数字，这个逼近真实值的过程就是不断拟合残差的过程。

思考一下回归问题中的梯度下降，你就会发现它和残差拟合实际上是等效的。如果以均方误差 [y−f(x)]2/2[y−f(x)]2/2 作为损失函数，那么对 f(x)f(x) 计算出的梯度就等于 f(x)−yf(x)−y。这意味着残差和负梯度是完全一致的，对残差的拟合就是对模型负梯度的拟合，而根据残差来更新集成后的模型实际上就是根据负梯度来进行更新。这样一来，梯度提升方法就变成了广义上的梯度下降。

这里我们不妨对原始梯度下降和梯度提升加以比较：梯度下降算法中的负梯度和梯度提升方法中的残差在数学上是等价的，但意义却有所不同。负梯度指向的是单个模型参数更新的方向，残差则表示了集成模型下一个模型的拟合目标。梯度的不断下降可以让模型的参数逐渐收敛到最优参数上，而残差的不断拟合则让集成之后的模型越来越接近真实的数据生成机制。

从这种等价关系出发，以梯度的角度构造提升方法会带来更多的便利，其中最重要的一点就是损失函数的重新定义。梯度提升方法本身是建立在负梯度和残差之间等价关系的基础上的，可是一旦有了这种等价关系，我们反过来又可以放弃狭义的残差，从广义的损失函数的负梯度角度去构造提升方法。这样的过程其实就是从特殊到一般，再从一般到特殊的认识思路。

以决策树作为基学习器，使用梯度提升方法进行集成，得到的就是梯度提升决策树（gradient boosting decision tree, GBDT）。在每一轮的提升过程中，GBDT 都会使用决策树来拟合计算出负梯度，因此整个模型就是一大堆决策树的组合。

在解决分类问题时，GBDT 中的负梯度可以表示成样本归属于每个类别的真实概率和上一轮预测概率的差值，这个差值会被回归树拟合，拟合值与上一轮预测概率求和就是这一轮的输出。

GBDT 是利用提升方法生成的全能模型，它在装袋方法上的对应是随机森林。

随机森林（ramdom forest）由若干个随机树（random tree）模型组成，每一棵单独的随机树都采用自助采样作为数据重采样的手段，但只会随机选择少量的特征用于生成树结构，这样生成的随机树也无需进行剪枝的处理。

这个算法其实是两种随机化方法——属性随机化和数据随机化的组合，两种随机化方法就像是倚天剑和屠龙刀，刀剑互斫才生出随机森林这本旷世秘籍。

属性随机化的思想也叫随机子空间方法（random subspace method），由香港学者 Ho Tin-Kam 首先提出。

属性随机化的好处在于让每个单独的基学习器不会过分关注在训练集中具有高度预测性或者描述性的特征，这样的特征虽然在训练数据中举足轻重，却将对数据的解释限制在狭窄的范围之内，未必能对测试数据进行精确预测。而随机抽取出的不同属性构成了不同的随机子空间，应用不同的随机子空间去训练不同的单个决策树。其实就是集成学习中非常重要的多样性思想（diversity）的体现。

归根结底，属性随机化的作用还是在于机器学习中老生常谈的问题，那就是提升泛化性能，抑制过拟合。

对于每棵单独的决策树来说，如果在训练集上能达到 100% 的正确率，那么它所生成的分类边界就适用于所有在所选择属性上和训练数据具有相同取值的新数据，即使这些新数据在没有用于这棵特定决策树分类的属性上有不同的取值也没关系。

这样一来，森林里的每棵树就在不同的随机子空间，也就是在不同的角度上进行泛化，从而给模型整体的泛化带来更多的可能性。相比之下，无论是预剪枝还是后剪枝，都是针对将所有属性视为整体的决策树的正则化，其效果就来得不如随机子空间好。

虽然 Ho Tin-Kam 在随机子空间的基础上进一步提出了随机森林的方法以及名称，但她的工作侧重于生成随机化的分类判别式，从头到尾都没有涉及对数据的自助重采样，而这恰恰被视为随机森林的核心。

数据随机化是由从统计学半路出家的莱奥·布雷曼（之前的文章中也提到过这位老先生）提出，他在此基础上进一步发展出了我们今天所熟知的随机森林模型。

数据随机化最主要的作用在于去除各独立模型之间的相关性，这个装袋方法的思想一脉相承。单棵决策树会对它自己的训练集中潜在的噪声高度敏感，但只要不同的树之间有较好的独立性，这种敏感特性就不会扩散到整个森林里。

此外，数据随机化的作用还体现在包外样本上。对于装袋法这种有放回的采样来说，大概会有三分之一的数据在训练过程中不会被用到，这部分未利用的数据就是包外样本（out-of-bag sample）。包外样本实际上起到了验证集的作用，可以证明，在包外样本计算出来的错误率是真实错误率的无偏估计，这就给算法的评估提供了一个比较靠谱的参考。

随机森林是一种比较复杂的模型，从不同的角度去观察它，就可以和不同的其他模型建立联系。由于一个样本可以出现在森林里的不同决策树上，在不同的决策树上又会归属于不同的叶子结点，所有和这个样本归属于同一个叶子结点的其他样本都会对它产生影响。

这样看来，随机森林就是局部化的近邻模型的拓展，和传统的 kk 近邻算法不同的是，不同近邻点的权重并不相等，而是取决于树的结构和训练数据的结构。将这一思路再延伸一步，还可以建立起随机森林和核方法之间的联系。

除了局部化之外，随机森林又可以看成是对数据进行分布式建模的产物。每一个样本本身是定义在高维空间之上的，但属性随机化起到了降维的作用，将样本映射到随机子空间中，再在不同的低维空间上从不同属性出发来定义同一个样本，这和深度学习的想法不谋而合。只不过随机森林并不具备深度学习的层次化结构，而是直接将分布式的表征赋予同等地位，进行扁平化的组合，这固然可以简化运算，却也限制了表达能力的提升。

在 Scikit-learn 中，这两种万能模型都定义在 ensemble 模块中，分别是 GradientBoostingClassifier 和 RandomForestClassifier 类。将这两种方法应用在前面使用的线性不可分的数据集上，可以得到不同的正确分类边界。但这个轻量级的实例只是用来对模型产生直观的认识，将这两种模型用在这样简单的数据集上有些杀鸡用牛刀的意味。

GBDT 和随机森林对曼城 - 西布朗数据集的分类结果

最后让我们来看一看集成学习中的一个理论问题，就是误差 - 分歧分解（error-ambiguity decomposition）。在集成方法中，假定最终的输出结果 f(x)f(x) 是每个基学习器单独输出的线性组合 ∑Ni=1wifi(x)∑i=1Nwifi(x)，其中线性系数全部为正且和为 1，那么每个基学习器的分歧就可以表示为

ai(x)=[f(x)−fi(x)]2ai(x)=[f(x)−fi(x)]2

集成模型的分歧是所有基学习器的分歧的线性组合

a(x)=∑i=1Nwiai(x)a(x)=∑i=1Nwiai(x)

这个表达式可以看成是所有独立输出对加权平均求出的加权方差。如果直接拿每个基学习器的结果和真实的输出 y(x)y(x) 做比较的话，每个基学习器和集成模型各自的均方误差就可以写成

ei(x)=[y(x)−fi(x)]2,e(x)=[y(x)−f(x)]2ei(x)=[y(x)−fi(x)]2,e(x)=[y(x)−f(x)]2

对上面的表达式做一些数学处理，就可以得到集成模型分歧和均方误差之间的关系

e(x)=e¯(x)−a(x)=∑i=1Nwiei(x)−a(x)e(x)=e¯(x)−a(x)=∑i=1Nwiei(x)−a(x)

将每个基学习器的分歧 ai(x)ai(x) 和误差 ei(x)ei(x)，以及集成模型的误差 e(x)e(x) 在数据的概率分布上积分，就可以得到它们在数据集上的数学期望 AiAi、EiEi 和 EE。再以加权系数 wiwi 对 AiAi 和 EiEi 进行线性组合，又可以得到模型分歧的集成 A¯A¯ 和误差的集成 E¯E¯。这时，集成模型的泛化误差就可以表达为

E=E¯−A¯E=E¯−A¯

这个表达式就是泛化误差的误差 - 分歧分解，它解释了集成学习中强调多样性的原因。表达式的第一项是基学习器关于真实结果的加权平方误差，第二项则是基学习器关于集成结果的加权平方误差。各基学习器之间的相关性越小，它们和集成结果之间的差别就越大，计算出的分歧也就越大。通过增加个体的方差来减小集体的方差，这就是集成学习的奇妙之处。

误差 - 分歧分解表明，集成学习成功的关键在于每个基学习器的和而不同。“和”指的是每个基学习器都要有良好的性能，“不同”指的是基学习器的原理之间存在差别。但在实际当中要想找到理想配置的话，除了大量尝试似乎别无他法。

今天我和你分享了梯度提升决策树和随机森林这两种万能模型，包含以下四个要点：

梯度提升决策树和随机森林都是在各类问题上表现优异的通用模型；

梯度提升决策树是提升方法的推广，利用上一轮次的梯度信息构造决策树；

随机森林是装袋方法的推广，利用属性随机化和数据随机化构造决策树；

误差 - 分歧分解解释了集成学习强调基学习器多样性的原因。

在介绍线性回归时我曾提到，随机森林虽然可以取得较高的精度，但在可解释性上却不能让人满意。这意味着模型不能给出关于数据的一般性规律，模型的价值也就会大打折扣。

那么你是如何看待模型性能与可解释性之间的矛盾的呢？

欢迎分享你的观点。

总结课 | 机器学习的模型体系

用 17 讲的篇幅，我和你分享了目前机器学习中的大多数主流模型。可是除开了解了各自的原理，这些模型背后的共性规律在哪里，这些规律又将如何指导对于新模型的理解呢？这就是今天这篇总结的主题。

要想在纷繁复杂的模型万花筒中梳理出一条清晰的脉络，还是要回到最原始的出发点——线性回归。线性回归是所有机器学习模型的鼻祖，其原因不仅源于它悠久的历史，还在于它三个最基本的特点。

线性（这不是废话么）：除了常数之外最简单的函数关系。

全局性：一组线性系数适用于整个输入空间。

数据不变性：不对输入数据进行任何预处理。

这三个特点决定了线性回归简洁的数学形式、清晰的可解释性和受限的表达能力。要想从线性回归出发，得到更加复杂的模型，就要摆脱这三个基本假设的限制，从内部对模型加以改造。

线性是首当其冲的改造对象。要对复杂的客观世界进行建模，非线性是不可或缺的要素。但从线性到非线性的过渡并非一蹴而就，而是循序渐进地实现，其演进的过程大致遵循“属性非线性——参数非线性——全局非线性”的路线图。

首先是属性的非线性化，典型的处理手段就是基函数的扩展。基函数的引入本质上是对特征空间的重构。一般来说，所有基函数构成一组正交基，自变量和因变量之间的非线性关系就被限制在这组正交基展成的线性空间里。基函数的形式越复杂，模型刻画复杂关系的能力就会越强。从这个角度看，多项式模型和分段的样条模型都可以归入属性非线性化的范畴。

除了对作为自变量的属性进行非线性化处理之外，待估计的模型参数也可以非线性化。这里我用参数的非线性化来指代属性不变但参数改变的模型，但由于参数本身是常量而非变量，因此参数的非线性化是以自适应调整的方式体现的。这种演化的代表模型就是以感知器为代表的神经网络。而在神经网络中，激活函数的使用又可以看成是基函数扩展的一个实例。

如果在前两者的基础上，进一步对属性和参数实现全局的非线性化，得到的就是广义线性模型。广义线性模型的非线性化是通过非线性的链接函数实现的，将线性组合的整体作为非线性化的对象。这种处理方法从根本上改变了线性模型的结构，将线性模型的应用范围从回归推广到了分类。

处理完线性特性，接下来就轮到全局性了。一手遮天的全局特性限制了模型的灵活性，改进的方法在于将它改造成若干个局部模型的组合，其演进的过程可以描述为“结构化局部——非结构化局部——分布式表示”。

结构化局部模型的代表是核函数，虽然它原本的目的不在于此，却在事实上起到了局部化的作用。具有固定形式的核函数给每个样本都定义了归它管辖的一亩三分地，非样本点的取值则等于所有样本在这个点贡献的求和。如果说非线性化是重新定义了属性空间的话，那么局部化就是对属性空间进行了手术刀般精细的切割，它将线性回归拓展为核回归，还衍生出了基于距离的学习。

核函数是具有明确解析式的数学函数，这说明它还具备一定的结构特性。如果将局部的结构特性都不加保留地完全拆解，那就是以 kk 近邻为代表的基于实例的学习。kk 近邻算法秉持少数服从多数的朴素观念，将学习的方法简化到了极致，它甚至不能被称为一个模型，因为支配它的不是参数，而是规则。在线性回归中应用 kk 近邻方法的话，它就变成了局部加权回归。

将局部化的思想再推进一步，就是分布式表示。局部化是对数据样本所在的特征空间的切割，可分布式表示却是对特征空间的重组，将原来单个的数据点变出了多个分身，分别作为对数据不同角度的观察结果。分布式表示虽然没有对特征空间显式的局部化处理，但它却将数据点分散成局部的组合，这在朴素贝叶斯和深度学习中都有体现。

改造了线性回归本身之后，还要改造线性回归对数据的处理方式。过多的特征数会导致维数灾难的发生，因此稀疏化就成为改进线性回归的另一个角度。降维其实也是对特征空间的重建，但无监督的特性使它通常出现在数据预处理的步骤之中。根据手段的不同，数据的降维技术可以近似地划分成“直接降维——线性降维——非线性降维”这样几个类别。

直接降维的处理对象是未经处理原始的输入维度，典型的方法是特征选择。特征选择会把对结果贡献不大的特征直接剔除，这无疑会造成信息量的损失。此外，利用统计特性降维的线性判别分析也可以归入这一范畴。相比之下，以主成分分析为代表的特征提取方法就克服了这个缺点，通过特征的线性重组来实现数据的降维。对主成分进行筛选时虽然也会产生信息的损失，但会具有更好的可控性。

如果抛开线性的限制，从样本的结构属性而非信息属性出发实现降维，这样的方法就是非线性降维，它的另一个名字就是流形学习。所谓流形的含义是嵌入到高维空间内的低维结构，流形学习的任务就是在高维空间上把这个隐藏的低维结构提取出来，从而更好地观察和分析数据。

上面这三种途径都是作用在模型内部，通过修正模型自身的特性来达到演化。如果换个角度，从外部对模型进行拓展的话，常用的方法就包括正则化、层次化和集成化。

正则化意在通过添加对待求解参数额外的约束条件来提升模型的泛化性能，避免过拟合，通常体现为模型中的正则化项。贝叶斯主义对正则化的理解来得更加直截了当：所谓正则化其实就是给模型套上先验分布的紧箍咒。定义了先验分布就可以应用最大后验概率估计，让后验概率最大化的过程就是正则化的过程。

层次化和集成化都是对模型结构的外部改进。层次化是将模型串联起来，通过逐级地学习来追求由浅入深的效果；集成化则是将模型并联起来，让多个模型群策群力，充分发挥集体智慧。深度学习和随机森林的成功已经向世人证明，这两种手段都能让模型之间产生充分的互动，从而得到良好的学习效果。

说到这里，我们就从线性回归出发，构建起了如下图所示的（我个人理解的）机器学习模型鸟瞰图。无论是作用于模型内部的非线性化、局部化和稀疏化，还是作用于模型外部的正则化、层次化和集成化，这些技巧实际上都属于方法（method）的范畴。实际问题的解决方案往往来源于一种或者多种方法和基本模型的组合。

所以在我看来，在读完这个专栏之后，你可以把所有具体的模型全部忘掉，只要领会这些方法，任何见过没见过的模型你都不会觉得陌生。

机器学习模型鸟瞰图

从机器学习模型的体系架构出发，按照由浅入深的顺序，我向你推荐以下的机器学习参考书。

《机器学习》（Machine Learning），汤姆·米切尔（Tom Mitchell）

《机器学习》（Machine Learning），彼得·弗拉克（Peter Flach）

《机器学习导论》（Introduction to Machine Learning），埃塞姆·阿培丁（Ethem Alpaydin）

这三本书是入门读物，共同的特点是结构清晰，难度适中。第一本是历久弥新的经典教材，虽然内容较为久远，却仍不失为理想的入门读物；第二本遵循从任务到模型的顺序，将模型分为树模型、规则模型、线性模型、距离模型和概率模型几类；第三本则先后介绍了参数方法、非参数方法和局部模型，并将频率主义和贝叶斯主义的内容融合在一起。读这些书时可以思考作者们对内容的编排，将重点放在建立关于机器学习的知识框架与体系上面。

《统计学习基础》（Elements of Statistical Learning），特雷沃·哈斯蒂等（Trevor Hastie, et. al.）

《模式识别与机器学习》（Pattern Recognition and Machine Learning），克里斯托弗·毕晓普（Christopher Bishop）

《深度学习》（Deep Learning），伊恩·古德菲洛等（Ian Goodfellow, et. al.）

这三本书是进阶读物，对方法的原理分析具有一定的深度，也会涉及大量的数学运算。前两本书是机器学习领域的经典，分别从频率主义和贝叶斯主义的角度对机器学习做出了详尽的阐释。第三本书则是目前关于深度学习唯一的专著，覆盖范围较广，适合针对某个主题做选择性的阅读。

《机器学习：概率视角》（Machine Learning: A Probabilistic Perspective），凯文·墨菲（Kevin Murphy）

《深入理解机器学习》（Understanding Machine Learning），沙伊·沙莱夫 - 施瓦茨等（Shai Shalev-Shwartz, et. al.）

《统计学习理论的本质》（The Nature of Statistical Learning Theory），弗拉基米尔·瓦普尼克（Vladimir Vapnik）

这三本书是专业读物。第一本堪称机器学习的百科全书，从贝叶斯角度对机器学习的几乎所有问题展开论述。这本书不太适合阅读，更适用于作为词典随时查阅。第二本则聚焦于机器学习的理论领域，虽然页数不多却充斥着各种定理与证明过程，和前面的所有书目都不是一个路数。如果想要深入理解机器学习的理论进展，这本书绝对不容错过。

最后一本是理论大师瓦普尼克毕生绝学的简化版。他的《统计学习理论》（Statistical Learning Theory）书如其名，对通过样本推断总体规律的数学问题做了详尽的论证，是统计学习思想的集大成者，读起来自然艰深晦涩。《统计学习理论的本质》是《统计学习理论》的简化版，在大幅度削减篇幅和数学细节的同时保留了核心结论。这本书的作用是“欲穷千里目，更上一层楼”，读通之后，你将建立起看待机器学习高屋建瓴的视角。

常言道“授人以鱼不如授人以渔”，我希望今天的这篇总结中的思路能成为那个三点水的“渔”，帮你厘清每个孤立模型背后的联系和逻辑。

在这段时间的学习过程中，你遇到了哪些问题？又有哪些想法呢？欢迎你留言和我讨论。

28 | 最简单的概率图：朴素贝叶斯

从今天起，我们将进入概率图模型的模块，以贝叶斯的角度重新审视机器学习。

在机器学习任务中，输入和输出之间并不是简单的一对一的决定关系，两者之间通常存在着一些可见或不可见的中间变量。要计算输出变量的概率分布，就得把这些中间变量纳入到建模的框架之中。要简洁明快地表达多个变量之间的复杂的相关关系，图模型无疑是理想的选择。将图模型和概率模型结合起来，就是这个模块的主题——概率图模型（probabilistic graphical model）。

在“人工智能基础课”中，我曾用简短的篇幅粗略地介绍过概率图模型的概念和分类。这次我们从实例出发，看一看最简单的概率图模型——朴素贝叶斯分类器（naive Bayes classifier），并以它作为从统计机器学习到概率图模型的过渡。

还记得朴素贝叶斯的原理吗？回忆一下，朴素贝叶斯利用后验概率最大化来判定数据所属的类别，其“朴素”之处在于条件独立性的引入。条件独立性假设保证了所有属性相互独立，互不影响，每个属性独立地对分类结果发生作用，这样类条件概率就变成了属性条件概率的乘积。这在概率图中体现为条件独立关系（conditioanl independence）：如果将朴素贝叶斯模型画成有向图的话，它就是下图中的贝叶斯网络，类别信息指向所有的属性，任何两个属性之间都没有箭头的指向。

朴素贝叶斯的概率图模型（图片来自 Probabilistic Graphical Models: Principles and Techniques，图 3.2）

朴素贝叶斯的好处在于可以将属性和类别的联合分布表示成一个关于类的先验分布（prior distribution）和一组与属性相关的条件概率分布（conditional probability distribution）的乘积，这个过程被称为因子分解（factorization）。如果数据共有 NN 个属性变量 XiXi，其分类结果为另一个变量 YY，那么朴素贝叶斯的因子分解就可以表示为

p(Y,X)=p(Y)⋅∏i=1Np(Xi|Y)p(Y,X)=p(Y)⋅∏i=1Np(Xi|Y)

这种条件独立关系用概率图模型的术语来描述的话就是

∀i,(Xi⊥X−i|Y)∀i,(Xi⊥X−i|Y)

它的含义是属性 XiXi 和其他所有属性关于类别 YY 条件独立。将这个式子和前面的示意图结合起来，可以发现因子分解的模块化特性（modularity）。当一个新的属性出现时，整体上的联合分布肯定会发生变化。但利用因子分解，生成新的联合分布只需要添加新属性关于输出的条件分布，而无需对原始分布的其他参数做出调整。在概率图模型中，这种操作就是添加一条有向边及其对应的结点这么简单。

朴素贝叶斯通过因子分解来计算样本属于每个类别的后验概率。反过来，它也可以依赖因子分解来生成新的数据，因而属于生成模型的范畴。在生成样本时，朴素贝叶斯首先按照先验分布抽取出一个类别，再按照类别下的条件概率分布生成不同属性的取值。

在解决分类问题时，朴素贝叶斯在判别模型上的对应是逻辑回归，它体现出的是和朴素贝叶斯截然相反的思路。

逻辑回归的计算目标是分类边界，边界又是各个属性的线性组合，样本中每个属性的取值共同决定了样本。从图模型的角度观察，逻辑回归就是朴素贝叶斯的反转：朴素贝叶斯是类别变量 YY 中伸出若干个箭头指向每一个属性变量 XiXi；逻辑回归则是每个属性变量 XiXi 都伸出一个箭头，共同指向类别变量 YY。这意味着分类的输出依赖于属性的取值，根据这种依赖关系计算出来的是在不同的属性取值下，分类结果的可能性，也就是条件概率 p(Y|X)p(Y|X)。

朴素贝叶斯的运算流程在上一季中已经有过介绍，在这里简单地总结一下：先验分布就是训练数据集上不同类别的数据所占的比例；每一个条件概率分布可以利用最大似然估计来计算，其计算方式就是在同一个类别的所有数据中，统计属性为特定值的数据所占的比例。但这种方式有一个潜在的问题，当样本容量较小时，某些属性的取值可能压根儿没有出现过，导致计算出来的似然概率为 0，从而与真实情况产生偏差。

要解决这个问题，传统的方法是在条件概率分布的计算中引入拉普拉斯平滑（Laplacian smoothing），而从纯贝叶斯方法的角度看，拉普拉斯平滑就是对隐含的参数引入先验分布。在贝叶斯方法中，参数的先验分布通常被设置为共轭先验。共轭先验（conjugate prior）是贝叶斯主义里的重要概念，指的是先验概率和后验概率具有相同的形式。

贝叶斯定理相当于用似然概率对先验概率进行加权得到后验概率，当先验概率和给定的似然概率共轭时，计算出的后验概率和先验概率将会服从同一分布，只是两者的参数有所不同。这就是引入共轭先验的好处：它将新概率分布的计算简化为新参数的计算，而无需重新确定分布的种类，从而降低了贝叶斯方法的运算复杂度。

看到这里，你是否想到了另一个相似的概念呢？共轭先验类似于线性代数中的特征向量，进一步推广就是信号理论中的特征函数。共轭先验相当于定义了一个函数空间，在这个空间上，作为泛函算子的似然概率作用在共轭先验上，定义了从先验到后验的演化过程，使输入和输出具有相同的形式。但这更大程度上是一种用于简化后验概率运算数学技巧，共轭先验本身并不能揭示关于数据机制任何潜在的规律。

既然共轭先验有这么容易计算，如何找到合适的共轭先验就成了下一个问题。可以证明，任何服从指数族分布的似然函数都存在共轭先验。在多分类问题中，每个样本都归属于多个类别中的一个，而属于每个类别的概率之和等于 1，因此类的先验分布可以看成是二项分布的推广，叫作多项分布（multinomial distribution）或者类别分布（categorical distribution），其最典型的代表就是掷骰子得到的分布。狄利克雷分布（Dirichlet distribution）就是类别分布的的共轭先验，其表达式可以写成

Dir(α)=Γ(∑ki=1αi)∏Ki=1Γ(αi)∏i=1Kxαi−1i,∑i=1Kxi=1Dir(α)=Γ(∑i=1kαi)∏i=1KΓ(αi)∏i=1Kxiαi−1,∑i=1Kxi=1

其中 αα 是狄利克雷分布的参数，Γ(⋅)Γ(⋅) 表示伽马函数（gamma function）。利用因子分解后的似然概率对因子分解后的先验概率进行加权，其作用就是对先验分布的参数加以修正。狄利克雷分布的参数被修正为 Ni+αiNi+αi，其中 NiNi 是每个类别中的样本数目。当 α=1α=1 时，这些先验就等效为拉普拉斯平滑。

下面这个例子给出了关于贝叶斯朴素贝叶斯很好的说明，它来自大卫·巴伯（David Barber）的著作《贝叶斯推理与机器学习》（Bayesian Reasoning and Machine Learning）中的例 10.3。这个例子是这样的：

“问题的任务是判断一个人到底是英格兰人还是苏格兰人，判断的依据是五个二元属性，从上到下分别是爱吃奶油酥饼、不喜欢拉格啤酒、喝威士忌、吃粥和不看英格兰的足球比赛。在训练数据中包括左侧 6 个英格兰人和右侧 7 个苏格兰人的属性列表。现在来了一个新的五元组 x=(1,0,1,1,0)Tx=(1,0,1,1,0)T，那这个人是苏格兰人的可能性有多大呢？”

上例中的训练数据集（图片来自 Bayesian Reasoning and Machine Learning）

直接用朴素贝叶斯方法来求解这个问题的方法比较简单，容易计算出类先验概率 p(scottish)=7/13,p(english)=6/13p(scottish)=7/13,p(english)=6/13。在每个类别上又可以计算出相互独立的属性条件概率，将所有这些概率代入贝叶斯定理中就可以得到，这个人是苏格兰人的概率是 0.8076，你可以自己验算一下。

可是用纯贝叶斯方法来解决这个问题，那就没那么简单了。出于简化运算的目的，这个例子没有给类分布设定先验，而是令属性关于类别的所有条件概率都服从相互独立的狄利克雷先验分布。由于狄利克雷分布是多项分布的共轭先验，而属性关于类别的二项分布又可以看成是多项分布的特例，因此根据先验计算出来的后验概率也服从狄利克雷分布，只是参数会有所变化。

假定属性的条件概率 θis©=p(xi=s|c)θsi©=p(xi=s|c) 表示当数据的类别为 cc 时，第 ii 个属性的取值为 ss 的条件概率。由于数据类别为 2，属性数目为 5，属性取值为 2，条件概率的总数就是 2×5×2=202×5×2=20，每个条件概率都对应一个无信息的均匀狄利克雷分布的超参数 uis©=1usi©=1。根据狄利克雷分布的性质，计算出的后验概率的超参数可以写成

u^is©=uis©+∑n:cn=cI[xni=s]u^si©=usi©+∑n:cn=cI[xin=s]

这么一大堆让人眼花缭乱的符号表达的就是一个意思：在每个类别 cc 中计算每个属性 ii 等于每个值 ss 出现的次数，再将计算结果加在三元组 c,i,sc,i,s 所对应的原始参数 uis©usi© 上。比方说，在 c=0c=0 的英格兰人中，所有样里本 i=1i=1 的第一个属性中，s=0s=0 的样本有 3 个，相应的 u10(0)u01(0) 就被更新为 3+1=43+1=4 了。

更新之后的参数就可以用来计算后验概率，计算出的后验概率将进一步被用于新样本的分类，其数学推导比较复杂，感兴趣的话你可以参考原书。利用狄利克雷分布的数学性质可以求出，新样本 x=(1,0,1,1,0)Tx=(1,0,1,1,0)T 是苏格兰人的概率是 0.764，这略低于非贝叶斯方法求出的结果。

在 Scikit-learn 中，实现朴素贝叶斯分类器的是 naive_Bayes 模块。由于前面例子中的属性都是二值属性，因此需要调用模块中的 BernoulliNB 类。在使用这个类时需要注意的是其中的参数 αα，这个参数的默认取值为 1.0，表示对数据进行拉普拉斯平滑，将它设定为 0 则是直接利用数据进行计算。

利用这个类去处理上面的例子你会发现，α=0α=0 得到的是一般朴素贝叶斯的结果，α=1α=1 得到的则是贝叶斯朴素贝叶斯的结果。这也验证了拉普拉斯平滑的作用实际上就是给类别设定均匀分布的共轭的先验。

使用 BernoulliNB 类对文中例子的计算结果

今天我和你分享了朴素贝叶斯方法的概率图表示，以及贝叶斯方法中共轭先验的概念，包含以下四个要点：

朴素贝叶斯是最简单的概率图模型，具有发散的星型结构；

朴素贝叶斯能够计算属性和类别的联合分布，因而属于生成模型；

共轭先验可以保证先验分布和后验分布具有相同的形式和不同的参数；

拉普拉斯平滑的作用是给类别设定均匀分布的共轭先验。

朴素贝叶斯是最简单的贝叶斯分类器，如果将属性之间相互独立的强限制放宽，得到的就是树增强朴素贝叶斯（tree augmented naive Bayes），它可以看成是朴素贝叶斯到通用的贝叶斯网络的过渡。

你可以查阅资料，了解树增强朴素贝叶斯的原理，并在这里发表你的见解。

29 | 有向图模型：贝叶斯网络

在上一篇文章中，我和你分享了最简单的概率图模型——朴素贝叶斯分类器。由于朴素贝叶斯假定不同的属性相互独立，因而它的概率图具有发散的星型结构。但在实际当中，这样的条件独立性几乎是不可能满足的，属性之间总会有些概率性的关联，如果将属性之间的关联体现在概率图模型中，就相当于把朴素贝叶斯中互相独立的结点联结起来，得到的正是贝叶斯网络。

贝叶斯网络（Bayesian network）也叫信念网络（belief network），由一些顶点和连接某些顶点的边构成，每个顶点代表一个随机变量，带箭头的有向边则表示随机变量之间的因果关系。

从拓扑结构看，贝叶斯网络是有向无环图，“有向”指的是连接不同顶点的边是有方向的，起点和终点不能调换，这说明由因到果的逻辑关系不能颠倒；“无环”指的是从任意顶点出发都无法经过若干条边回到该点，在图中找不到任何环路，这说明任何变量都不能自己决定自己。

贝叶斯网络是对随机变量以及存在于它们之间的不确定性的一种表示（representation），它以因子分解的方式定义了联合概率分布的数据结构，还给出了这个分布中的一系列条件独立性假设。

下面这个例子出自发表于《AI 季刊》（AI Magazine）第 12 卷第 4 期的论文《傻瓜贝叶斯网络》（Bayesian networks without tears），它说明当事件之间的因果关系不能完全确定时，基于概率的贝叶斯网络是如何发挥作用的。

“假设有一天我回家晚了，还碰巧没带钥匙，所以在敲门之前我想先看看家里有没有人。我太太的习惯是不在家时把廊外灯打开，但如果有客人约定来访的话，即使她在家时也会开灯。另外，我还养了一条狗，家里没人的时候会把狗锁在院子里。但狗在院子里也不能确定地说明家里没人，因为如果狗狗犯错的话也会被不让进屋。反正不管怎样，只有狗狗在外面，听到门口有人它就会叫，但我又分辨不出到底是不是我家的狗在叫。那么问题来了，如何判断我家里到底有没有人呢？”

在这个例子中，所有的因果联系都不是绝对的，灯开不意味着家里肯定没人，狗在院子里也一样。如果灯是开着的但没有听到狗叫，或者听到狗叫但是灯没开，这些情况下就只能对家里有没有人做出概率性的推断。贝叶斯网络就是概率推断的有力工具，它的条件独立性可以在已知的概率值较少时依然做出准确的推断。下图就是利用已知的因果联系构造出的贝叶斯网络。

“家里有没有人”的贝叶斯网络

从结构上看，条件独立性在一定程度上简化了随机变量的关系，在给定父结点的条件下，每个结点都和它的所有非后代结点条件独立。这意味着每个结点的概率既取决于它的父结点，也取决于它的子结点。从结构上看，父结点、子结点以及子结点的后代结点共同形成一条逻辑关系上的通路，概率的变化就是在这条通路上传导。如果其他结点不在这条通路上，就大概率不会受到处在通路上的结点的影响。

在上面的例子中，“听到狗叫”是“狗在外面”的子结点，而它本身又没有后代结点。所以只要“狗在外面”这个事件确定了，那么能不能听到狗叫就不会被任何其他变量提供的信息所影响。但对于狗是不是在外面这个问题，事情就没有那么简单了，它既会受到“家人外出”和“狗犯错”这两个父结点的影响，也会受“听到狗叫”这个子结点的影响，其中每一个的变化都会改变对于“狗在外面”这个论述的判断。

给定条件概率的贝叶斯网络

要对贝叶斯网络进行定量计算，就需要给每个根结点所表示的随机变量赋予概率值，同时给表示不同结点之间依赖关系的每条有向边所代表的所有条件概率赋值。上图给出了确定条件概率取值之后的贝叶斯网络。根据这些概率就可以计算一种情况——当灯是开着的但没有听到狗叫时，家里有人的概率。具体的求解方法今天先不讨论，留到后面再做解释，本篇先把重点放在贝叶斯网络的结构特性上。

结构上的条件独立性降低了贝叶斯网络所需要求解的概率的数目，从而在根本上降低推断的计算成本。在上面的例子中，随机变量的数目，也就是结点的数目是 5 个，每个随机变量又都只有 2 种可能的取值。在不考虑条件独立性时，要定义这 5 个随机变量的联合分布的话，就得计算 25−1=3125−1=31 个联合概率的值。从数学上看，所有变量的联合分布可以写成

p(fo,bp,lo,do,hb)=p(fo)p(bp|fo)p(lo|bp,fo)p(do|lo,bp,fo)p(hb|do,lo,bp,fo)p(fo,bp,lo,do,hb)=p(fo)p(bp|fo)p(lo|bp,fo)p(do|lo,bp,fo)p(hb|do,lo,bp,fo)

但是在条件独立性下，每个结点上只需要计算 2m2m 个条件概率，其中 mm 是指向这个结点的有向边数目。这样计算下来，在上面的例子中只需要定义 10 个条件概率就可以解出任何一种可能性，这就是条件独立性带来的运算便利。相应地，联合分布的表达式也会简化为

p(fo,bp,lo,do,hb)=p(fo)p(bp)p(lo|fo)p(do|bp,fo)p(hb|do)p(fo,bp,lo,do,hb)=p(fo)p(bp)p(lo|fo)p(do|bp,fo)p(hb|do)

这样的简化在这个特例里看起来并不起眼，可一旦贝叶斯网络的规模增加到具有成百上千个结点，这种简化的重要性就会凸显出来。

贝叶斯网络可以视为一个条件独立性的大集合。在这个集合中，除了显式存在的条件独立关系之外，还能不能根据它的因子分解读出隐藏的条件独立关系呢？答案是肯定的。

在“人工智能基础课”中，我介绍了近邻结点之间顺连（linear）、分连（diverging）、汇连（converging）等基本的连接方式。这三种基本结构都隐含着各自的条件独立性，它们的组合又可以形成更加复杂的连接方式，构成新的条件独立关系。这是贝叶斯网络中的核心概念，值得多花一些笔墨来介绍。

在复杂的网络中，两个结点就像公交线路的起点和终点，中间还间隔着若干个站点，这些站点之间的线路都是单行线，但方向又可能有所不同。这时要判断起点和终点之间的线路到底能不能承载信息的传输，就需要使用特定的准则。不严谨地说，在给定一些证据（evidence），也就是某些结点的取值固定时，如果一个结点的变化会影响到另一个结点的变化，那它们就是 dd 连通的（dd-connected），它们之间存在着 dd 连接路径（dd-connecting path）。反过来，不存在 dd 连接路径的两个结点就是 dd 分离的（dd-separation）。

和全称命题 dd 分离相比，存在性的 dd 连通概念更容易理解。那么如何判定在给定证据集时，两个结点是否是 dd 连通的呢？这需要让两结点之间的所有结点都满足以下两个条件中的任意一个：

以顺连或者分连的形式连接，且不属于证据集

以汇连形式连接，且结点本身或者其子结点属于证据集

第一个条件容易理解：它相当于在两个结点之间直接构造出一条有向的通道，通道中每个结点的取值都不是固定的，这保证了信息流动的畅通无阻。第二个条件则相当于用证据生成两个结点的关联。就像在上面的例子中，在不知道狗是否在外面时，“家人外出”和“狗犯错”两者是相互独立、互不影响的。可一旦狗在外面作为证据出现，同时又知道家人没有外出，就立刻可以确定是狗犯错了。这就是通过汇连结构间接实现信息通路的实例。

dd 分离性是条件独立性的充分必要条件，它既具备可靠性（soundness）也具备完备性（completeness）。如果两个结点是 dd 分离的，那它们就肯定满足条件独立；反过来如果两个结点条件独立，两者之间也必定不会存在 dd 连接路径。所以用 dd 分离的概念可以通过简单地检测网络的连通性来推断因子分解分布的独立性，这是验证条件独立性的具体方法，对于简化大规模的复杂网络非常重要。

由 dd 分离性可以引出马尔可夫毯（Markov blanket）的概念。将所有结点分成互斥的若干个子集，如果在给定集合 XX 的条件下，集合 AA 中的任何变量都和集合 BB 条件独立，那么满足这一条件的最小集合 XX 就是集合 AA 的马尔可夫毯。这里的 AA 和 BB 就像两个不同的交际圈，两者你走你的阳关道，我过我的独木桥，只有在 XX 的牵线搭桥之下才会有所来往。

马尔可夫毯的意义在于划定了描述集合 AA 所需要的数据范围，一个结点的马尔可夫毯包括它的父结点、子结点和共父结点，也就是子结点的其他父结点。马尔可夫毯包含了所有关于集合中变量的信息，非马尔可夫毯中的变量在描述 AA 时都是冗余的。如果要计算 AA 中变量的概率，就不需要惊动所有变量，只需要对马尔可夫毯进行处理就可以了。

从图结构的角度分析贝叶斯网络的话，还可以定义出独立图的概念。独立图（Independency map, I-map）是对概率分布进行拆解的产物。如果概率分布 PP 中所有的条件独立性都能够在有向无环的图结构 GG 中表示出来，那么 GG 就是 PP 的独立图。

有了独立图的概念之后，就可以从概率模型和图结构两个角度来定义贝叶斯网络。所谓贝叶斯网络其实就是由 (G,P)(G,P) 构成的偶对，其中概率分布 PP 可以根据图 GG 进行因子分解，图 GG 是分布 PP 分解得到的独立图。这两种解释共同构成了对贝叶斯网络，以及所有概率图模型的综合阐释。

要在 Python 语言中实现概率图模型的话，可以使用第三方库 pgmpy，这是由《利用 Python 掌握概率图模型》（Mastering Probabilistic Graphical Models using Python）的作者安库尔·安坎（Ankur Ankan）所开发并维护的。

利用这个库可以实现前文的例子中给出的模型。在使用中，建模贝叶斯网络需要用到 models 模块的 BayesianModel 类，定义离散的条件概率需要用到 factors.discrete 模块的 TabularCPD 类，具体的构造方式你可以查看代码。

在构造完成之后，不妨做个小实验，测试一下当门外灯亮却没有听到狗叫时，家中有人的概率。这里将所有的二元随机变量为真的情况设为取 0 值，为假的情况设为取 1 值，因此“门外灯亮却没有听到狗叫”就可以记作“light_on = 0, hear_bark = 1”。将这两个变量的取值代入到网络中进行推断，可以计算出家里有人和没人的可能性几乎是一半一半。

文中贝叶斯网络实例的推理结果

今天我和你分享了贝叶斯网络的基本原理，包含以下四个要点：

贝叶斯网络是有向无环图，可以用于因果推断；

贝叶斯网络既是具有条件独立性的随机变量的联合分布，也是联合概率分布的因子分解结果；

贝叶斯网络中的条件独立性可以通过 dd 连通路径和 dd 隔离性描述；

贝叶斯网络的概率分布描述和独立图描述可以相互转换。

目前，贝叶斯网络及其推断在医疗诊断中已经得到了广泛的应用。那么你是如何看待概率推断在医疗领域中的使用，自动化推断和人类医生相比又有哪些优势劣势呢？

欢迎分享你的观点。

30 | 无向图模型：马尔可夫随机场

作为有向图模型的代表，贝叶斯网络将随机变量之间的条件独立性与依赖关系嵌入到图结构之中，既有助于直观表示，又能简化计算。但这是不是意味着贝叶斯网络可以通吃所有概率关系呢？并非如此。

下面这个例子就说明了贝叶斯网络的局限之处，它取自达芙妮·科勒（Daphne Koller）的经典教材《概率图模型》（Probabilistic Graphical Models）的例 3.8。

“四个学生 Alice、Bob、Charles 和 Debbie 在一个学习小组中，但由于 A 和 C、B 和 D 两两之间因为感情的纠葛导致没有交流，因此每个人可以交流的对象都只有 2 个。这样的关系应该如何表示呢？”

这四个学生可以建模成概率图中的四个结点，也就是四个随机变量。用贝叶斯网络构造这组关系时，由于 A 和 C 之间不存在交流，两者之间也就没有信息的流动，所以在给定 B 和 D 的前提下，A 和 C 是条件独立的；同样的道理，在给定 A 和 C 的前提下，B 和 D 也是条件独立的。这就要求构造出来的贝叶斯网络能够同时表示这两组条件独立性。

贝叶斯网络的局限性（图片来自 Probabilistic Graphical Models，图 3.10）

上图表示的是两种可能的贝叶斯网络结构，但两者都没法同时表示两个条件独立性。在左侧的子图中，从 A 到 C 的两条通路都是顺连结构，中间的结点分别是 B 和 D。固定的 B 和 D 堵塞了信息流动的通道，从而保证了 A 和 C 的条件独立性。

但反过来，B 和 D 是不是独立的呢？这两个结点与 A 共同构成了分连结构，因此它们关于 A 是条件独立的。可同时它们又和 C 构成了汇连结构，这意味着 C 的确定会同时导致 B 和 D 的变化，条件独立性也就无从谈起了。

右侧的子图同样存在缺陷。从上向下看，这是两个分连结构的拼凑，保证了 A 和 C 的条件独立；可如果换个角度，从下往上看的话，这又是两个汇连结构的拼凑，无论是 A 还是 C 都搭建了从 B 到 D 的通路，这样的结构也不能同时形成两组条件独立性。

说到底，这个例子中的结构就像咬住自己尾巴的贪食蛇，是一个典型的环状结构：每一个结点只与和它相邻的两个结点相关，和其他结点全部条件独立。这其实是将顺连结构的首尾扣在了一起，可就是这么简单的操作就足以让作为无环图的贝叶斯网络无计可施了。环状结构中其实不存在方向的概念，不管是顺时针还是逆时针的流动都能够回到原点，就像环路公交车不管是正向出发还是反向出发最终都要回到始发站。如果在这样的循环依赖结构上强加方向的限制，反而会起到适得其反的效果。

将贝叶斯网络中边的方向去掉，得到的就是马尔可夫随机场。马尔可夫随机场（Markov random field）又叫马尔可夫网络（Markov network），也是一种用来表示随机变量之间关系的概率图模型，但它的特点和贝叶斯网络恰恰相反：连接顶点的边没有方向，图中也可以存在环路结构。

和贝叶斯网络相比，马尔可夫随机场侧重于表示随机变量之间的相互作用：虽然它不能进行因果的推理，却可以对循环依赖关系建模。如果用马尔可夫随机场来表示前文中的例子，得到的就是下图的结果。

马尔可夫随机场（图片来自 Probabilistic Graphical Models，图 3.10）

马尔可夫随机场的结构确定之后，接下来就要对它进行参数化（parameterization），以完成定量的计算。由于马尔可夫随机场中的变量之间的相互作用不再是明确的条件依赖关系，贝叶斯网络中的条件概率分布也就不再适用了。在参数化的过程中，马尔可夫随机场着重刻画变量之间的连接关系，并由此引入了因子（factor）的概念。

因子也叫势函数（potential function），是定义在结点所表示的变量子集上的非负函数，随机变量每一组可能的取值都对应着一个因子值。如果两个随机变量在某个特定取值上的因子越大，说明这两个随机变量在这一组取值上的兼容性越好，也就意味着这一组取值同时出现的可能性比较大。

利用因子概念就可以对前文的马尔可夫随机场加以参数化。假定 ABCD 四个随机变量都是二元变量，取值非 0 即 1，下图给出了对每两个相互关联的变量之间的因子定义。在第一个因子 ϕ1(A,B)ϕ1(A,B) 中，(a0,b0)(a0,b0) 的因子值最大，意味着两个变量最可能同时取 0；ϕ1(a0,b1)>ϕ1(a1,b0)ϕ1(a0,b1)>ϕ1(a1,b0) 则说明当 Alice 和 Bob 意见相左时，Bob 更加容易占据上风。同理可以得到，Bob 和 Charles、Alice 和 Debbie 都容易达成共识，而 Charles 和 Debbie 在一起就吵架。

上例的因子图（图片来自 Probabilistic Graphical Models，图 4.2）

定义的所有因子都有相同的作用，那就是定量描述直接关联的随机变量的关联性。将所有局部上的因子组合起来，得到的就是马尔可夫随机场整体的分布。和贝叶斯网络一样，局部因子也是通过相乘的方式加以结合，形成所有随机变量的联合概率分布。但由于对因子直接计算的结果不等于 1，所以还需要额外的归一化过程。从因子函数到概率分布的数学表达式可以写成

p(a,b,c,d)=ϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a)∑a,b,c,dϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a)p(a,b,c,d)=ϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a)∑a,b,c,dϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a)

上式中分母上的归一化常数被称为划分函数（partition function），它的取值等于所有因子的和。可以看出，无向的马尔可夫随机场实际上建模了所有变量的联合分布，这就和贝叶斯网络对条件分布的建模形成了对比。在上面的例子中，如果要计算四个随机变量分别等于 a0,b0,c1,d1a0,b0,c1,d1 的概率，就需要先将反映它们之间的依赖关系的因子相乘

ϕ1(a0,b0)⋅ϕ2(b0,c1)⋅ϕ3(c1,d1)⋅ϕ4(d1,a0)=30×1×1×1=30ϕ1(a0,b0)⋅ϕ2(b0,c1)⋅ϕ3(c1,d1)⋅ϕ4(d1,a0)=30×1×1×1=30

在计算中需要注意的是，在两个因子相乘时，将这两个因子联系起来的中间变量的取值必须是匹配的。

上面求出的只是一种可能出现的取值。对于 4 个二值变量来说，所有取值的组合共有 16 种。计算出所有 16 个值后再进行归一化，就可以得出 a0,b0,c1,d1a0,b0,c1,d1 的概率 p(a0,b0,c1,d1)=4.1⋅10−6p(a0,b0,c1,d1)=4.1⋅10−6。

上面的这个表达式其实还蕴含着另外一层含义，那就是因子的概念不仅适用于单个随机变量，也适用于随机变量的集合。如果不做归一化的话，按照上面的方法所计算出的 ϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a)ϕ1(a,b)⋅ϕ2(b,c)⋅ϕ3(c,d)⋅ϕ4(d,a) 实际上就是 ABCD 这四个变量整体的因子。

需要说明的是，虽然因子在形式上看起来和条件概率很像，但两者的意义是不同的，这种不同也会体现在数值上。每个因子都是联合分布的一部分，因子之间也会产生相互作用，只有对因子之间的相互作用进行边际化处理之后，得到的才是真正的条件概率。

如果把单个因子视为概率，那么前文中因子的归一化所形成的概率分布就是吉布斯分布（Gibbs distribution）；如果把吉布斯分布中的所有因子都改写成指数函数的形式，它就又变成了玻尔兹曼分布（Boltzmann distribution）。在统计力学中，玻尔兹曼分布可以用于描述系统的能量分布，相关的内容属于物理学的范畴，在这儿就不多说了。

马尔可夫随机场和吉布斯分布是等价的，其等价性由哈默斯利 - 克利福德定理（Hammersley-Clifford theorem）所保证。这个定理的内容比较复杂，其中最主要的一点是只有当非负的概率分布可以进行因子分解时，它才能和无向的图结构等价。可以进行因子分解的概率分布是吉布斯分布，其等价的图结构就是马尔可夫随机场。

对马尔可夫随机场进行因子分解，其目标是将原始的图结构整合成若干个团。团（clique）是由结点的组合形成的全连接结构，团中的任意两个结点之间都存在互相连接的边。如果在已有的团中加入任何一个多余的结点都不能成团的话，这样的团就是极大团（maximal clique），极大团和吉布斯分布的关系可以类比为贝叶斯网络中的独立图和概率分布的关系。下图给出了划分极大团的一个实例。

马尔可夫随机场中的极大团

和贝叶斯网络一样，马尔可夫随机场也需要体现条件独立关系。如果两组结点 XX 和 YY 通过第三组结点 ZZ 相连接，XX 中的任意一个结点到 YY 中的任意一个结点的路径都要经过 ZZ 中的结点，而不存在绕过点集 ZZ 的通路的话，那就可以说 XX 和 YY 被 ZZ 所分离，ZZ 是 XX 和 YY 的分离集（separation set）。如果把概率的变化想象成水的流动，那么 ZZ 就是上游 XX 和下游 YY 之间的一道大闸。一旦 ZZ 中的随机变量不再变化，这道大闸就会堵住信息流动的通道，从而让 XX 和 YY 条件独立。

马尔可夫随机场中的条件独立性就是马尔可夫性。根据分离集在图结构上的不同特点，马尔可夫性也被分为以下三种形式。

全局马尔可夫性（global Markovianity）：给定两个变量子集的分离集，则这两个变量子集条件独立。

局部马尔可夫性（local Markovianity）：给定一个变量子集的邻接变量，则这个变量和其他所有变量条件独立，也就是邻接变量构成了此变量和其他变量的分离集。

成对马尔可夫性（pairwise Markovianity）：给定其他所有变量，则剩下的两个非邻接变量条件独立，也就是其他所有变量共同构成非邻接变量的分离集。

要用 Python 建模马尔可夫随机场可以使用 pgmpy，这里以前文中四人小组的例子为例。马尔可夫随机场的核心是因子，建模马尔可夫随机场需要用到 models 模块的 MarkovModel 类，因子的定义则需要通过调用 factors.discrete 模块的 DiscreteFactor 类来实现。构造出模型后可以计算划分函数，进而计算所有随机变量的联合分布。

作为两种最主要的概率图模型，贝叶斯网络和马尔可夫随机场虽然结构不同，但都是对概率分布的参数化和对条件独立性的表示，因而可以相互转化。将贝叶斯网络变成马尔可夫随机场较为简单，只需要将所有边的方向全部去掉，同时在汇连结构的两个共父结点结点之间添加无向边，这个过程被称为端正化（moralization），得到的结果就是端正图（moral graph）。

贝叶斯网络的端正化（图片来自维基百科）

相比之下，将马尔可夫随机场转化成贝叶斯网络就没那么容易了。这其中最关键的问题在于因果关系的确定，也就是有向边到底由谁指向谁，不同的指向会导致不同的条件独立性。这时就不光要给已有的边添加方向，还要给原始马尔可夫随机场中的环结构添加额外的边来形成弦图（chordal graph），这个过程被称为三角化（triangulation）。构造出的弦图可以进一步表示为贝叶斯网络，其具体细节在这里就不介绍了。

今天我和你分享了马尔可夫随机场的基本原理，包含以下四个要点：

马尔可夫随机场是无向图，可以用于建模变量之间的相互作用；

马尔可夫随机场与可以进行因子分解的吉布斯分布等价；

马尔可夫随机场中的条件独立性可以分为全局性、局部性和成对性；

马尔可夫随机场和贝叶斯网络可以相互转化。

虽然不能用于因果推断，但马尔可夫随机场在图像处理中有着非常广泛的应用，图像分割、去噪、目标识别等计算机视觉任务中都能见到马尔可夫随机场的身影。

你可以查阅资料，了解马尔可夫随机场在不同图像处理任务中的应用方式，并在这里分享你的见解。

31 | 建模连续分布：高斯网络

无论是贝叶斯网络还是马尔可夫随机场，定义的变量都服从取值有限的离散分布，变量之间的关联则可以用有限维度的矩阵来表示。如果将随机变量的范围从离散型扩展到连续型，变量的可能取值就有无穷多个，这时变量之间的依赖关系就不能再用表格的形式来表示了，需要重新定义概率图模型中的相互作用与条件独立性。

考虑最简单的情形，也就是结点所表示的随机变量都服从高斯分布，由高斯型连续随机变量构成的概率图模型统称为高斯网络（Gaussian network）。

如果多个服从一维高斯分布的随机变量构成一个整体，那它们的联合分布就是多元高斯分布（multivariate Gaussian distribution），其数学表达式可以写成

p(x)=1(2π)n/2|Σ|1/2exp[−12(x−μ)TΣ−1(x−μ)]p(x)=1(2π)n/2|Σ|1/2exp⁡[−12(x−μ)TΣ−1(x−μ)]

其中 μμ 是这组随机变量的均值向量（mean vector），ΣΣ 是这组随机变量的协方差矩阵（covariance matrix），|Σ||Σ| 是它的行列式值。

协方差矩阵是对称的正定（positive definite）矩阵，表示了不同变量之间的关联：如果两个变量线性无关，那么其协方差矩阵中对应的元素就等于 0，这意味着两个变量满足边际独立性（marginal independency）；如果所有变量都线性无关的话，协方差矩阵就退化为对角矩阵。

协方差矩阵的逆矩阵 J=Σ−1J=Σ−1 被称为信息矩阵（information matrix），信息矩阵和均值向量的乘积则被称为势向量（potential vector）。

引入信息矩阵意在定义条件独立性（conditional independency）：和边际独立性不同，条件独立性不能直接在协方差矩阵中体现出来，必须通过信息矩阵加以观察。信息矩阵的元素等于 0 说明对应的两个变量在给定其他变量的前提下条件独立，比如 J1,3=0J1,3=0 就意味着着在其他变量固定时，x1x1 和 x3x3 条件独立。

在高斯分布的基础上可以进一步定义高斯线性模型。高斯线性模型（linear Gaussian model）指的是一个随机变量可以表示为一组随机变量的线性组合，这个随机变量本身的不确定性则可以用高斯分布来建模，这种关系写成数学表达式就是

y=β0+β1x1+⋯+βkxk+ϵ,ϵ N(0,σ2)y=β0+β1x1+⋯+βkxk+ϵ,ϵ N(0,σ2)

这其实和原始线性回归的假设是完全一致的。把这种关系放到概率图模型中，那么所有的 xixi 都可以看成结点 yy 的父结点，它们一起构成了汇连结构。从概率角度看，给定这些父结点后，子结点 yy 的条件概率就服从高斯分布，其均值是 xixi 的线性组合，方差则是噪声 ϵϵ 的方差。

上面的表达式中假设所有自变量 xixi 都有固定的取值，如果这些自变量都是随机变量，共同服从均值为 μμ，协方差矩阵为 ΣΣ 的多维高斯分布的话，那么可以证明随机变量 yy 也是高斯随机变量，它的均值等于 β0+βTμβ0+βTμ，方差等于 σ2+βTΣβσ2+βTΣβ，和变量 XiXi 的协方差则等于 ∑kj=1βjΣi,j∑j=1kβjΣi,j。

这样的结论告诉我们，高斯线性模型实际上定义了一个高斯贝叶斯网络（Gaussian Bayesian network），整个概率图所表示的联合分布就是一个大的多维高斯分布。

高斯贝叶斯网络的表示可以用下面这个例子来直观地解释，这个例子来自《概率图模型》（Probabilistic Graphical Models）的例 7.3。

“如果一个线性高斯网络具有顺连结构 X1→X2→X3X1→X2→X3，其中 X1X1 的概率密度 N(1,4)N(1,4)，已知 X1X1 时 X2X2 的条件概率密度为 N(0.5X1−3.5,4)N(0.5X1−3.5,4)，已知 X2X2 时 X3X3 的条件概率密度为 N(−X2+1,3)N(−X2+1,3)，试求解整个网络所表示的联合分布。“

在高斯形式已经确定的前提下，求解联合分布实际上就是求解所有变量的均值向量和协方差矩阵。由于 X2X2 等于 0.5X1−3.50.5X1−3.5，将 X1X1 的均值为 1 代入这个线性关系，就可以求出 X2X2 的均值等于 0.5×1−3.5=−30.5×1−3.5=−3，同理可以求出 X2X2 的均值等于 −(−3)+1=4−(−3)+1=4。

求完了均值再来看协方差，协方差矩阵的对称性决定了对于 3 维变量来说，计算协方差矩阵需要确定 6 个元素。X1X1 的方差 Σ11=4Σ11=4 是已知的，这部分方差将会以线性系数为比例体现在 X2X2 中，和 X2X2 自身的不确定度共同构成随机变量完整的方差，也就是 Σ22=0.52×4+4=5Σ22=0.52×4+4=5。将 X2X2 的方差代入 X3X3 的线性关系，又可以计算出 Σ33=(−1)2×5+3=8Σ33=(−1)2×5+3=8。这三个方差定义了变量自身的不确定性，是协方差矩阵中的对角线元素。

确定了对角线元素后，下一步就是确定非对角线上的元素，也就是不同变量之间的相关性。由于 X2X2 这个变量只取决于 X1X1，其关联的强度由线性系数确定，因而两者之间的协方差就等于线性系数和 X1X1 方差的乘积 Σ12=0.5×Σ11=2Σ12=0.5×Σ11=2。这个数字的含义在于用 X1X1 的变化对 X2X2 的变化的影响。同理可以求出，X2X2 和 X3X3 之间的协方差为 Σ23=−1×Σ22=−5Σ23=−1×Σ22=−5。

在这个顺连结构中，X1X1 和 X3X3 之间并不存在直接的作用，而是以 X2X2 作为媒介和中转。X1X1 对 X3X3 的作用实际上可以分成两个阶段，第一个阶段是 X1X1 的变化首先影响 X2X2，第二个阶段是 X2X2 的变化继续影响 X3X3。在协方差的计算中，第一个阶段体现为 X1X1 和 X2X2 之间的协方差，第二个阶段则体现为 X2X2 和 X3X3 之间的线性系数的加权作用。两者相乘形成了一个整体，也就是 Σ13=Σ12⋅(−1)=−2Σ13=Σ12⋅(−1)=−2。由此，就可以写出联合分布的均值向量和协方差矩阵

关于这个例子需要说明的一点是，由于协方差矩阵中所有的元素都不为 0，说明这些变量两两之间都不是边际独立的。但顺连结构告诉我们，当 X2X2 确定时，X1X1 和 X3X3 条件独立，所以它的信息矩阵中会有两个零元素。这说明在图结构中，表示同一个联合分布只需要更少的参数。

但淮南为橘淮北为枳，图结构的优势也可能变成劣势。想象一下汇连结构 X1→X2←X3X1→X2←X3，由于汇连结构中不存在条件独立的结点，因此联合分布的信息矩阵中所有元素都是非零的。但由于 X1X1 和 X3X3 互不影响，因此协方差矩阵中反倒存在着零元素。

在此基础上，如果再给结点 X1X1 和 X3X3 赋予一个共同的父结点 X4X4，让这三者形成分连结构的话，那整个网络中就既没有条件独立性，也没有边际独立性，无论是协方差矩阵还是信息矩阵中就都不会出现非零元素了。

将多元高斯分布嵌入到无向的马尔可夫随机场中，得到的就是高斯马尔可夫随机场（Gaussian Markov random field）。在处理高斯随机场时，先要对多元高斯分布的概率密度做些处理，将指数项中的协方差逆矩阵 Σ−1Σ−1 替换为信息矩阵 JJ 并展开。由于均值向量和信息矩阵都是常量，将它们去掉就可以得到概率密度的正比关系

p(s)∝exp[−12xTJx+(Jμ)Tx]p(s)∝exp⁡[−12xTJx+(Jμ)Tx]

这个式子被称为高斯分布的信息形式（information form）。由于式子中的 xx 是向量，因此展开后的结果中会包含两种多项式成分：一种成分是单个变量 XiXi 的函数，其表达式可以写成 −Ji,ix2i/2+hixi−Ji,ixi2/2+hixi，其中 hihi 是势向量的第 ii 个分量；另一种成分是两个变量 XiXi 和 XjXj 乘积的函数，其表达式可以写成 −Ji,jxixj−Ji,jxixj。

在高斯随机场中，这两个不同的成分具有不同的意义。只与单个变量相关的成分可以看成每个结点的势函数（node potential），同时涉及两个变量的成分则可以看成连接这两个结点的边的势函数（edge potential）。如果信息矩阵的元素 Ji,j=0Ji,j=0，其对应的边势也等于 0，就说明这两个结点之间并没有连接的边。

需要说明的是，在前一篇对马尔可夫随机场的介绍中我提到了边势，但并没有涉及结点势的概念。其原因在于结点势并不是通用的概念，它只存在于具有成对马尔可夫性的网络之中。下图是一个典型的成对马尔可夫随机场，每个结点都和它所有的非邻接结点条件独立，在信息矩阵 JJ 中，这些条件独立的结点组合所对应的元素就等于 0。

成对马尔可夫随机场（图片来自 Probabilistic Graphical Models，图 4.A.1）

多元高斯分布定义的是成对的马尔可夫随机场，其中的每个势函数都具有二次型的形式。反过来，由于任何合法的高斯分布都具有正定的信息矩阵，所以如果一个成对随机场能够改写成多元高斯分布，那它的势函数的系数所形成的矩阵也必须得满足正定的条件。

对连续分布的建模能够大大拓展概率图模型的应用范围，毕竟现实中大量的观测结果都是连续变化的。虽然高斯分布并不适用于所有的连续变量，但良好的数学性质和便于计算的特点让它成为了理想条件下近似建模的首选。

如果一个概率图模型中的随机变量既有离散型也有连续型，这样的网络就是混合网络（hybrid network）。混合网络让人头疼的一个问题是同一个结点的父结点可能存在不同的类型，其中既有连续分布的结点，也有离散分布的结点。而在处理这些父结点不同的子结点时，需要根据情况分类讨论。

如果子结点是连续分布的结点，那么问题就简单了。由于离散分布的父结点取值的组合是有限的，就可以对每一种可能的取值都为子结点定义一组线性系数，将离散结点的信息编码到这组线性系数当中。

这样一来，子结点就可以表示成连续父结点的线性组合，其中的线性系数则由离散父结点来决定。这种模型被称为条件线性模型（conditional linear model），它本质上是一组不同参数的高斯分布所形成的混合模型（mixture model），每个分布的权重取决于这一组参数出现的概率。

当一个离散的子结点具有连续的父结点时，解决的方法也不复杂。最简单的办法是采用阈值模型（threshold model），当连续变量的取值大于阈值时输出 1，小于阈值时输出 0。更加精细的一种方式是用借鉴逻辑回归或者 softmax 回归的思想，计算离散的子结点关于连续的父结点的条件概率，并输出条件概率最大的结果。

今天我和你分享了概率图模型中对连续型随机变量的建模与表示，其要点如下：

高斯网络采用高斯线性模型建模连续变量，其数字特征为均值向量和协方差矩阵；

高斯贝叶斯网络利用多元高斯分布生成独立图，利用信息矩阵计算网络中的条件概率；

高斯马尔可夫随机场具有成对马尔可夫性，通过高斯分布可以确定结点势和边势；

混合网络是同时具有离散型结点和连续型结点的概率图模型。

在现实生活中，自然界客观存在的属性通常是连续分布的，而人为定义出来的属性则通常是离散的，那么你能想象出有哪些离散变量和连续变量共存的应用场景呢？

欢迎分享你的观点。

32 | 从有限到无限：高斯过程

上一讲中我基于高斯分布介绍了建模连续型分布的高斯网络，其中所用到的多元高斯分布是一元高斯分布的扩展与推广。但在多元高斯分布中，变量的数目依然是有限的。如果像傅里叶变换（Fourier transform）那样，将无数个服从高斯概率的随机变量叠加到一起，这个在向量空间上形成的高斯分布就变成了函数空间上的高斯过程。

在概率论和统计学中，高斯过程（Gaussian process）是由出现在连续域上的无穷多个随机变量所组成的随机过程，不管连续域是时间还是空间，在上面定义的无穷维向量都可以看成是个函数（function）。高斯过程的高斯性（Gaussianity）指的是这无穷多个随机变量联合起来共同服从无穷维高斯分布，如果从中取出一部分变量，这些变量的边际分布也是高斯形式的。

不妨假设 y(x)y(x) 是个高斯过程。从空间尺度上看，如果在定义域中任取出一些点 x1,x2,⋯,xNx1,x2,⋯,xN，那么这些点的联合分布就是多元的高斯分布。更重要的是，这样的性质对于定义域上的任何子集都成立，也就是不管如何取点、取多少点，这些随机变量的高斯性都能够一致地保持。从时间尺度上看，即使每次都抽取相同的点，随机过程的特性依然决定了样本每次独立的实现都会有所差异，但是在统计意义上，同一个自变量在多次抽取中得到的结果也是满足高斯分布的。

从数据生成的角度看，高斯过程还可以通过线性回归更加直观地理解。给定线性关系 y=wTxy=wTx 之后，对于每一个可能出现的权值向量 ww，都会有一条直线和它对应。所有 ww 所对应的直线就会布满整个二维空间，而线性回归的任务就是找到那条和训练数据匹配度最高的那条直线。找到最优的直线意味着确定后验意义下最优的线性系数 ww，因此这个过程归根结底还是个参数化的过程。

如果要将上面的参数化过程过渡为完全的非参数化过程，就要摆脱对于参数 ww 的依赖，最直接的方法是不定义 ww 的先验，而是直接定义在函数空间上的输出 y(x)y(x) 的先验，也就是给出 y(x)y(x) 取不同形式的概率。这样一来，直接对函数建模的非参数模型就摆脱了参数模型的局限性，从而具备了更强大的拟合能力。而函数建模最简单的模型就是给连续的 y(x)y(x) 赋予高斯型的先验分布，得到的就是高斯过程。

在高斯过程中，每个可能的 y(x)y(x) 都是从高斯过程中抽取的一个样本。有限维度的高斯分布可以用均值向量和协方差矩阵这两个数字特征完全地刻画。而在无穷维的高斯过程中，这两者都变成了函数的形式。均值函数取决于训练数据 XX，它体现了样本出现的整体位置，而这个整体位置通常被设置为 0。这样处理的原因在于和均值代表的绝对位置相比，表示不同数据点之间关系的协方差矩阵才是高斯过程的关键所在。

要理解协方差函数在高斯过程中的作用，首先要明确高斯过程的一个主要特点，那就是它建模的对象不是自变量 xx 和因变量 yy 之间的关系，而是不同的因变量 yy 和 y′y′ 之间的关系，正是这种思想决定了高斯过程的非参数特性。因变量之间的关系正是通过协方差函数体现，假定训练数据集是 (X,y)(X,y)，线性关系中的权重系数为 ww，那么输出的协方差函数就可以表示成

Cov(y)=E[yyT]=XE[wwT]XT=KαCov(y)=E[yyT]=XE[wwT]XT=Kα

其中 KK 被称为格拉姆矩阵（Gram matrix），其元素为 Kij=K(xi,xj)=(xi)TxjKij=K(xi,xj)=(xi)Txj，这里的 αα 是参数 ww 所服从的高斯分布方差的倒数。这表示未知函数 f(⋅)f(⋅) 在 xixi 和 xjxj 两点上的函数值服从二元高斯分布，其均值可以不失通用性地视为 0，协方差矩阵则是上面求出的 Cov(y)Cov(y) 中对应行列所形成的 2×22×2 方阵。

在这个表达式中，如果引入基函数的扩展来定义函数的先验，用函数 ϕ(⋅)ϕ(⋅) 对输入的自变量做一个特征映射，那协方差函数的元素就变成了

Kij=ϕ(xi)Tϕ(xj)Kij=ϕ(xi)Tϕ(xj)

显然，这时的协方差函数已经具有了核函数的形式。如果你一时没有想起核函数为何物，那就复习一下前面支持向量机的内容。当 KijKij 取作径向基函数的形式 exp(−|xi−xj|2/2)exp⁡(−|xi−xj|2/2) 时，它就有了一个新的名字——平方指数（squared exponential）。

高斯过程其实就是核技巧在概率模型中的扩展，它将输出的协方差表示成输入的函数，再通过协方差来描述数据点之间的关系。在预测新样本时，高斯过程给出的不是对预测结果的点估计，而是完整的概率分布，这是一般的频率主义方法不能比的。

前面对高斯过程的理解都是从函数空间（function space）的角度出发的，换个方向的话，高斯过程也可以从参数空间（weight space）的角度来认识，这种理解方式是将高斯过程应用到线性回归的拟合之中，也被称为高斯过程回归（Gaussian process regression）。这部分内容实际上就是将上面的分析调转方向，通过定义特征映射将数据在高维空间中表示出来，再在高维空间上应用贝叶斯的回归分析。

高斯过程回归的数学细节较为繁冗，在这里就不做展开了，感兴趣的话你可以参考卡尔·拉斯姆森（Carl Edward Rasmussen）和克里斯托弗·威廉姆斯（Christopher KI Wiliams）的著作《机器学习中的高斯过程》（Gaussian Process for Machine Learning）。

其结论是用高斯过程计算出的预测分布（predictive distribution）也是一个高斯分布，它的均值是后验意义下的最优估计，方差则表示了估计结果的可信范围。这两个参数都和高斯过程的协方差函数，也就是核函数有关。使用不同的核函数，得到的估计结果也不会相同。

高斯过程之所以选择高斯分布做先验，是因为它符合之前介绍过的最大熵原理。当随机变量的协方差矩阵给定时，高斯分布的不确定性是最大的，这符合机器学习不做出多余假设的思想。另一方面，高斯分布良好的数学特性也让它适用于贝叶斯主义的方法。对高斯分布进行边际化处理，得到的结果依然是高斯分布，这对于涉及大量积分计算的贝叶斯方法无疑是个福音。

作为一类非参数的局部化模型，高斯过程和其他局部化的模型有什么区别和联系呢？不妨在这里对它们做个比较。

核回归（kernel regression）就是一种局部化回归模型，它利用的是核函数的平滑作用，用核函数对未知数据点附近的已知数据点的输出结果进行加权，再将加权的结果作为未知数据点的输出。这相当于将输入空间划分成不同的局部区域，在每个局部上拟合一个常数 θ0θ0 作为输出。

在核回归的基础上深入一步就是局部加权回归。局部加权回归（locally weighted regression）在每个局部上拟合的目标不是常数，而是一阶的线性模型 θ0+θ1xθ0+θ1x。

本质上讲，这些局部化的回归模型就是套上了核函数外衣的 kk 近邻方法，其中的核函数并没有统计特性上的意义，只是作为加权系数出现，所以被称为平滑核（smoothing kernel）。平滑核必须满足的是归一化的条件，也就是所有权重系数的积分等于 1。相比之下，来源于协方差矩阵的核函数完全满足正定的条件，是根红苗正的Mercer 核。当然，根据高斯过程的核函数可以计算出对应的平滑系数，计算出来的结果被称为等价核（equivalent kernel）。

既然说到核函数，就不能不提它最经典的应用——支持向量机。利用数学推导可以得出，在处理二分类问题时，支持向量机和高斯过程的损失函数具有相似的形式，其区别在于前者使用的是合页损失函数，后者使用的是似然概率的负对数。如果能够将合页损失等价为某种形式的似然概率，那么这两种方法就是等效的。可遗憾的是，这样的似然概率并不存在。

需要说明的是，将高斯过程应用于二分类问题时，高斯分布的特性反倒成为了运算中的掣肘。常用的处理方法是对高斯过程进行拉普拉斯近似（Laplace approximation），具体做法是将求解出来的预测分布的对数进行泰勒展开（Taylor expansion），将二阶项以上的高阶项全部去掉。由于后验概率的方差通常较小，其形状是狭窄的尖峰形式，因此这种近似并不会造成太大的误差。

最后一个用来和高斯过程进行比较的模型是大名鼎鼎的神经网络。通用逼近定理证明了具有单个隐藏层的神经网络可以拟合任何非线性的函数，拉德福德·尼尔（Radford Neal）则在他的著作《神经网络的贝叶斯学习》（Bayesian Learning for Neural Networks）中进一步证明了单隐层的神经网络会收敛于所有参数都服从高斯先验的高斯过程，换言之，两者可以相互取代。

但并不是所有人都认同这种观点，《信息论、推理与学习算法》（Information Theory, Inference and Learning Algorithm）的作者大卫·麦凯（David JC MacKay）就表示，神经网络的作用在于发现数据中潜在的特征与模式，而高斯过程只是简单的函数平滑。如果两者真的等效，那岂不是意味着我们都高估了神经网络吗？这种现象被麦凯称为“连孩子带洗澡水一起倒丢了”。

可是在十多年后的今天再回首，麦凯所言似乎一点儿毛病都没有。

在 Scikit-learn 中，高斯过程被定义在 gaussian_process 模块，模块中的类一部分用来实现回归或者分类功能，另一部分则定义了常用的核函数。将高斯过程应用在回归数据集和线性不可分的分类数据集上，结果如下图所示，这里使用的核函数是最常见的高斯核。

在回归问题中，高斯过程回归器 GaussianProcessRegressor 拟合出的结果就是利用高斯函数对原函数进行插值拟合，其中红色曲线是结果分布的均值，灰色阴影表示 95% 置信区间；在分类问题中，高斯过程分类器 GaussianProcessClassifier 计算出的则既可以直接输出类别，体现为图中的决策边界，也可以输出样本归属于类别的概率。当然，如果调整核函数的形式和参数，得到的结果也会不同。

高斯过程的回归和分类结果

今天我和你分享了高斯过程的基本原理，包含以下四个要点：

高斯过程由无穷多个随机变量组成，定义的是函数的先验分布；

函数空间上的高斯过程是核技巧在概率模型中的应用，通过定义因变量之间的相关性计算输出；

参数空间上的高斯过程是在高维空间中进行贝叶斯的回归分析；

高斯过程可以通过等价核、似然概率和高斯先验与其他模型联系起来。

在高斯过程中，一般的惯例是将均值函数设置为 0。那么如果均值函数是非零的函数，它对高斯过程的结果又会产生什么影响呢？

你可以查阅相关资料，并在这里分享你的见解。

33 | 序列化建模：隐马尔可夫模型

前几讲中介绍概率图模型都没有涉及“时间”尺度，模型所表示的都是同一时刻下的状态，因而不能建模随机变量的动态特性。如果要定义系统在时间尺度上的演化，就需要引入系统状态（system state）的概念，每一时刻的系统状态都是表示系统属性的随机变量。

将图模型中的结点用表示时间流动的有向边连接起来，得到的是动态贝叶斯网络（dynamic Bayesian nework），其最简单的实现是隐马尔可夫模型（hidden Markov model）。

隐马尔可夫模型实现的是序列化的建模，它打破了对数据独立同分布的固有假设，侧重于时序上的依赖关系。在自然语言和金融市场数据这类时间序列（time series）中，某个数据往往会受到之前数据的影响，这种情况下还要强行套用独立同分布假设的话，肯定不会符合实际情况。隐马尔可夫模型正是将过去对现在的影响纳入模型中，以此来实现更加准确的预测。

隐马尔可夫模型则是通过隐藏状态生成观测序列的马尔可夫过程。在更简单的马尔可夫链（Markov chain）里，所有状态是都直接可见的，因此状态转移概率是唯一的参数。而在隐马尔可夫模型中，状态本身不是直接可见的，可见的是取决于状态的输出。由于每个状态都有和输出相关的概率分布，因而隐马尔可夫模型的输出就能够提供关于隐藏状态的信息。

隐马尔可夫模型可以通过下面这个例子来直观地描述，这个例子来自维基百科，是匈牙利数学家乔治·波利亚（George Polya）所提出的罐子问题（urn problem）的变种。

罐子问题表示的隐马尔可夫模型（图片来自维基百科）

上图给出了这个例子的图示：一个观察者不能靠近的房间里有 3 个罐子 X1,X2,X3X1,X2,X3，每个罐子里都有同样标签的 4 个球 y1,y2,y3,y4y1,y2,y3,y4。一个具有上帝视角的控制者按一定概率首先选定一个罐子，再从罐子里随机抽取出一个球，放到和房间外面连接的传送带上，同时再补充一个同样的球到罐子里。这样观察者能看到的就是每次抽出的球，而不是每次抽球的罐子。

在隐马尔可夫模型中，罐子表示的是由概率模型生成的不可观测的随机序列，每个罐子都代表了系统的一种状态，所以这个隐藏的序列叫作状态序列（state sequence），也就是上图中圆圈的部分。从罐子中抽出的球表示的是由每个状态所生成的观测所组成的随机序列，这个可见的序列叫作观测序列（observation sequence），也就是上图中方形的部分。序列中的每个位置都代表了一个时刻，从而体现出对时序的建模。

回到前面的例子，在选取罐子时，控制者的策略并不是完全随机的，他在某一时刻的选择只取决于前一时刻的选择，而与之前所有时刻的选择都没有关系，这个状态变化的过程就是齐次马尔可夫过程（homogeneous Markov process）。

有一种“浪漫”的说法说鱼的记忆只有 7 秒，这么看来齐次马尔可夫过程的记忆就只有 1 轮。在前面的例子里，如果某个时刻的状态是 X3X3，那就说明上一时刻的状态一定是 X2X2，因为从状态 X1X1 是没法直接跳转到 X3X3 的。

在观测时，任意时刻的观测只取决于当时的状态，而与其他的状态和观测无关，这样的隐马尔可夫模型就满足观测独立性（observation independence）。

假设所有可能的状态 qiqi 总共有 NN 个，所有可能的观测结果 vjvj 总共有 MM 个，所有抽取出的状态结果 itit 构成长度为 TT 的状态序列，所有状态生成的观测结果 otot 则构成长度为 TT 的观测序列。基于齐次马尔可夫性和观测独立性这两个假设，就可以给出隐马尔可夫过程的定量表示。

在第一个时刻的状态选择中，每个状态会被赋予一个初始概率（initial probability）πi=P(i1=qi)πi=P(i1=qi)，这些初始概率共同组成了初始状态概率向量（initial state distribution）ππ。

随着时序的推移，系统的状态也会不断变化，从上一个状态 qiqi 跳转到下一个状态 qjqj 的概率 aij=P(it+1=qj|it=qi)aij=P(it+1=qj|it=qi) 叫做转移概率（transition probability），所有状态转移概率组成一个维度和状态数目相同的 NN 维对称方阵 AA，这个矩阵就是状态转移概率矩阵（transition probability matrix）。

对于观察者来说，状态是不可见的，可见的是由状态生成的观测。但状态和观测不是一一对应的关系，一个状态会按照概率分布产生不同的观测。在某一时刻，状态 qjqj 生成观测 vkvk 的概率 bj(k)=P(ot=vk|it=qj)bj(k)=P(ot=vk|it=qj) 叫作发射概率，或者观测概率（emission probability）。

由于可能的状态数目是 NN 个，每个状态又有 MM 种可能的观测，这么多观测的概率共同形成了 N×MN×M 维的观测概率矩阵 BB（emission probaility matrix）。

初始状态概率向量、状态转移概率矩阵和观测概率矩阵共同构成了隐马尔可夫模型的三要素。初始状态概率向量确定了隐马尔可夫模型的结构，状态转移概率矩阵生成了隐藏的状态序列，观测概率矩阵则确定了如何从状态生成观测。三者一起定义出完整的隐马尔可夫模型。下图就给出隐马尔可夫模型的概率图表示。

隐马尔可夫的概率图表示，其中 xx 表示状态，yy 表示观测（图片来自维基百科）

在隐马尔可夫模型中，表示隐藏的状态的变量也叫隐变量（latent variable）。一般来说，马尔可夫链假设当前的输出只和之前的有限个输出有关，这有限个输出的数目就是阶数。

马尔可夫链的阶数越高，它需要确定的参数也就越多。而隐马尔可夫模型通过引入隐变量将输出，也就是观测之间的马尔可夫性转移成隐变量之间的马尔可夫性，虽然没有明显地增加参数的数目，却能表示输出之间更复杂的依赖关系。这种结构也被称为状态空间模型（state space model），广泛应用在信号分析和控制论等其他领域中。

从时序上看，上面的模型有马尔可夫的特性；从数据生成的角度看，隐马尔可夫模型又可以看成是一种推广的混合模型。从上面的图中可以看出，同样的观测结果可能来自于不同的状态，因此可以看成是不同状态的混合，每一个状态都对应着混合结果中的一个成分。只不过其中不同的成分不是相互独立的，它们由马尔可夫链所定义的依赖关系联系起来。

推而广之，混合模型（mixture model）是由若干个成分构成的概率模型，每个成分都来自一个独立的概率分布。在总体中采出来的每个样本都是多个成分的混合。虽然不能准确地确定单个样本来自于哪个成分，但通过多个样本的统计特性可以推断出每个混合成分的特征。最常见的混合模型是高斯混合模型（Gaussian mixture model），其中的每个成分都是高斯分布。这部分内容暂且按下，稍后再做详解。

隐马尔可夫模型属于生成模型，可以从贝叶斯的角度加以审视。隐马尔可夫的三要素共同定义了状态和观测的联合分布，其中转移概率相当于隐藏状态的先验分布，而观测概率相当于已知状态时观测的似然分布。

但对于隐藏状态本身的变化而言，我们默认了它们的先验分布是不包含信息的均匀分布。但由于转移概率本身是多取值的分类分布，因此自然的思路是将转移概率的先验设置为狄利克雷分布，也就是分类分布的共轭先验。

狄利克雷分布中有一系列的参数 αiαi，如果所有参数的取值都相等，这样的分布就是对称狄利克雷分布（symmetric Dirichlet distribution）。这种分布也可以看成是无先验的分布，并不能反映出哪些状态比其他状态更可能出现。

这唯一的参数被称为浓度参数（concentration parameter），能够决定转移矩阵的稀疏程度。小于 1 的浓度参数对应的转移矩阵是稀疏矩阵，其中对于每个给定的源状态，只有少数目标状态具有不可忽略的转移概率。

如果一个狄利克雷分布还不够，那还可以使用层次化的狄利克雷分布。在两级先验中，上层分布（the upper distribution）控制着下层分布（the lower distribution）的参数，下层分布再来继续控制转移概率。这里的上层分布起到的就是前面无信息先验的作用，可以决定哪些状态更容易出现，它的浓度参数决定了状态的密度。

虽然标准的隐马尔可夫模型是生成模型，其在判别模型中的对应是条件随机场（conditional random field）。条件随机场融合了马尔可夫随机场的无向图特性和隐马尔可夫模型的条件特性，如果将上图中隐马尔可夫模型中的有向边都改成无向边，就形成了线性链（linear chain）条件随机场。

线性链条件场将状态定义为可见的输入，发射概率和转移概率也被重新定义为特征函数（feature function）。特征函数可以用来计算输出关于输入的条件概率，进而实现判别，其数学细节在这里就不赘述了。

在 Python 中有一个专门实现隐马尔可夫模型的库 hmmlearn，这个库原本是 Scikit-learn 中的一个模块，但在新的版本中自立门户。这里使用的例子是根据英超近 15 个赛季曼市德比的结果构造出的隐马尔可夫模型，其中状态变量被设定为主客场，有 2 个取值；观测变量则被设定为曼城方的比赛结果，有胜平负 3 个取值；模型的三要素可以根据 30 场比赛的结果统计出来。

在未知 2018-19 赛季英超日程安排，也就是不知道主客场这个隐变量的条件下，利用隐马尔可夫模型也能估计两场曼市德比的胜负。估计结果表明：两队每场都要拼个你死我活，单场比赛平分秋色不太可能出现。

今天我和你分享了隐马尔可夫模型的基本原理，包含以下四个要点：

隐马尔可夫模型由隐藏的状态序列和可见的观测序列构成，能够对时序依赖关系建模；

隐马尔可夫模型的定量描述包括初始状态向量、状态转移矩阵和观测矩阵三部分；

作为生成模型，隐马尔可夫可以视为混合模型的推广；

隐马尔可夫模型的判别方法对应是条件随机场。

隐马尔可夫模型最主要的用武之地非自然语言处理莫属，语音和文字之间天然的时序关联让隐马尔可夫模型如鱼得水。

你可以查阅资料，了解隐马尔可夫模型在自然语言处理中的应用，并在这里分享你的见解。

34 | 连续序列化模型：线性动态系统

在隐马尔可夫模型中，一般的假设是状态和观测都是离散的随机变量。如果假定隐藏的状态变量满足连续分布，那么得到的就是线性动态系统。虽然这个概念更多地出现在信号处理与控制论中，看起来和机器学习风马牛不相及，但是从马尔可夫性和贝叶斯概率的角度观察，线性系统也是一类重要的处理序列化数据的模型。

线性动态系统（linear dynamical system）的作用可以通过下面这个例子来说明。假设一个传感器被用于测量未知的物理量 zz，但测量结果 xx 会受到零均值高斯噪声的影响。在单次测量中，根据最大似然可以得到，对未知的 zz 最优的估计值就是测量结果本身，也就是令 z=xz=x。可是如果可以对 zz 进行多次重复测量的话，就可以通过求解这些结果的平均来平滑掉随机噪声的影响，从而计算出更加精确的估计。

可一旦多次测量结果是在不同的时间点上测出的，也就是时间序列 x1,x2,⋯,xNx1,x2,⋯,xN 时，问题就没有那么简单了，因为这种情况下需要将未知变量 zz 的时变特性考虑进去，前一时刻的 zz 和后一时刻的 zz 就不一样了。如果还是像上面那样直接对不同时刻的测量结果求均值的话，虽然随机噪声的影响可以被平滑掉，但变量本身的时变特性又会作为另一种噪声出现在结果中。

这种按倒葫芦起了瓢的结果显然不是我们想要的。要想获得更精确的估计，可以根据 zz 的具体变化特性采用不同的策略。如果变量 zz 具有慢变的特性，也就是它的波动周期远远大于测量周期，那么不同时刻的测量结果中的差别几乎全部来源于随机噪声，变量本身并不会出现多少波动。这时就可以将平滑窗口的长度，也就是用于求平均的测量结果的数目取得大一些，以取得更好的抑制随机噪声的效果。

反过来，如果变量本身是快速变化的，这时就要适当地调小平滑窗口，同时给相距较近的测量结果赋予更大的平滑权重。如果变量变化的时间尺度比相邻测量之间的时间间隔还要小，两次测量之间都能变量都能经历多次波动，就只能以测量结果作为最优的估计了。

上面的描述只是定性的说明，如果要在此基础上对最优的平滑参数进行定量计算的话，就需要对系统的时间演化和测量过程进行概率式的建模，其模型就是线性动态系统。

线性动态系统也是一种动态贝叶斯网络，其中的显式变量和隐藏变量都是连续变量，它们之间的依赖关系则是线性高斯的条件分布。最典型的线性动态系统是用于描述一个或一组高斯噪声影响下的实值变量随时间变化的过程，可以用以下的条件概率表示：

P(X(n)|X(n−1))=N(AX(n−1),Q),P(O(n)|X(n))=N(HX(n),R)P(X(n)|X(n−1))=N(AX(n−1),Q),P(O(n)|X(n))=N(HX(n),R)

其中 XX 是 nn 维的隐藏状态变量，OO 是 mm 维的观测变量，AA 是定义了模型的线性转化规则的 nn 维方阵，QQ 是定义了状态随时间演化过程中的高斯噪声的 nn 维方阵，HH 是定义了从状态到观测的线性转化规则的 n×mn×m 维矩阵，RR 是定义了观测结果中高斯噪声的 mm 维方阵。隐藏状态变量初始的取值 X(0)X(0) 也满足高斯分布，其概率密度可以写成

P(X(0))=N(X(0)|μ0,V0)P(X(0))=N(X(0)|μ0,V0)

如果将线性动态系统放在状态空间表象（state space representation）下观察，上面的条件概率就可以改写成状态方程的形式

X(n)=AX(n−1)+wX(n)=AX(n−1)+w

O(n)=HX(n)+vO(n)=HX(n)+v

X(0)=t(0)+uX(0)=t(0)+u

其中 w,v,uw,v,u 都是均值为 0 的高斯分布。

对原始的线性动态系统模型的一种扩展方式是将系统中的初始状态 X(0)X(0) 从单个的高斯分布改写为高斯混合模型。如果高斯混合模型中包含 KK 个成分，那么后面所有状态也会是多个高斯分布的混合，通过求解边界概率依然可以对模型进行概率推断。

除了状态本身的概率分布外，从状态到观测的观测概率也可以写成高斯混合模型的形式。如果观测概率是 KK 个高斯分布的混合，那么初始状态 X(0)X(0) 的后验概率同样是 KK 个高斯分布的混合。随着时序的推进，后验概率的表示会变的越来越复杂。在时刻 nn，状态 X(n)X(n) 的后验概率数目可以达到 KnKn 个，这时参数的指数式增长就会削弱模型的实用性。

从隐马尔可夫模型和线性系统出发，可以定义出一些非传统机器学习意义上的概念。如果要根据截至目前的观测结果来估计隐藏变量，这样的问题就是滤波问题（filtering）；如果要根据一串完整的观测序列来估计隐藏变量，这样的问题就是平滑问题（smoothing）。滤波和平滑对隐变量的估计都属于概率图模型推断任务的范畴，在离散的隐马尔可夫模型和连续的线性动态系统中都可以实现。

另一个只适用于离散模型的运算是译码（decoding），其任务是根据观测序列找到后验概率最大的隐变量序列。这些术语被更广泛地应用在通信和信息处理之中，但是站在更宏观的角度看，它们也可以归结到广义的机器学习范畴之中。

如果要在离散的时间序列上分析连续分布的状态和观测结果的话，需要使用线性卡尔曼滤波器这个数学工具。线性卡尔曼滤波器（linear Kalman filter）的作用是根据一串包含统计噪声和干扰的观测结果来计算出单一的、但是更加精确的观测估计。在某个时间点上，给定截止目前所获得的所有证据，可以计算出关于系统的当前状态的置信状态（belief state），其中包含了最大的信息量。在离散的时序上，时刻 nn 的置信状态可以定义为

σ(n)(X(n))=P(X(n)|o(0:n))σ(n)(X(n))=P(X(n)|o(0:n))

其中 X(n)X(n) 表示当前的状态，o(0:n−1)o(0:n−1) 表示之前所有的观测。在线性高斯的依赖关系下，置信状态服从高斯分布，因而可以用参数有限的均值向量和协方差矩阵来表示，具有紧凑的形式。卡尔曼滤波器的作用就是对置信状态的均值和协方差进行更新，更新的过程可以分成两个步骤：首先根据目前所有可用的观测计算出隐藏状态变量的置信，这个置信叫作先验置信状态（prior belief state），其表达式可以写成

σ(⋅n+1)(X(n+1))=P(X(n+1)|o(0:n))=∑X(n)P(X(n+1)|X(n))σ(n)(X(n))σ(⋅n+1)(X(n+1))=P(X(n+1)|o(0:n))=∑X(n)P(X(n+1)|X(n))σ(n)(X(n))

式子中上标的 ⋅⋅ 是先验置信状态的标志。接下来，在这个先验置信状态的条件下要考虑最近的观测结果，根据推测出的先验置信状态和当前的观测结果共同确定当前的置信状态，其表达式可以写成

σ(n+1)(X(n+1))=P(X(n+1)|o(0:n),o(n+1))=P(o(n+1)|X(n+1))σ(⋅n+1)(X(n+1))P(o(n+1)|o(0:n))σ(n+1)(X(n+1))=P(X(n+1)|o(0:n),o(n+1))=P(o(n+1)|X(n+1))σ(⋅n+1)(X(n+1))P(o(n+1)|o(0:n))

这个递归过滤的过程对随时间变化的置信状态进行动态更新，可以看成是递归贝叶斯估计在多元高斯分布中的应用。递归贝叶斯估计（recursive Bayesian estimation）通过对不同时间观测值的递归使用来估计未知的概率分布，是隐马尔可夫模型中常用的推理方法。线性卡尔曼滤波器就是递归贝叶斯估计在连续分布的状态变量上的推广。

在卡尔曼滤波过程中，先验置信状态的更新由状态转移更新（state transition update）来表示。以上面的线性系统为例，直观上看，先验置信状态的新均值 μ⋅t+1μ⋅t+1 是将状态转移的线性变换 AA 应用在上个时间点的均值 μ⋅tμ⋅t 上，新的协方差矩阵 Σ⋅t+1Σ⋅t+1 也是将状态转移的线性变换 AA 应用在上个时间点的协方差 Σ⋅tΣ⋅t 上，再加上噪声的协方差 QQ。总而言之，一个变换就可以将状态更新全部概括。

和状态转移更新相比，确定当前置信状态的观测更新（observation update）要复杂一些。置信状态的均值可以表示为先验置信的均值加上来源于观测结果的修正项，这个修正项是观测残差（observation residual），也就是期望观测值和实际观测值之间区别的加权，加权系数是被称为卡尔曼增益（Kalman gain）的系数矩阵 KK。

置信状态的协方差也是对先验置信的协方差进行修正，修正的方式是减去卡尔曼增益加权后的期望协方差。在数学推导中，置信状态的参数表达式可以写成

K(n+1)=Σ(⋅n+1)HT(HΣ(⋅n+1)HT+R)−1K(n+1)=Σ(⋅n+1)HT(HΣ(⋅n+1)HT+R)−1

μ(n+1)=μ(⋅n+1)+K(n+1)(o(n+1)−HΣ(⋅n+1))μ(n+1)=μ(⋅n+1)+K(n+1)(o(n+1)−HΣ(⋅n+1))

Σ(n+1)=(I−K(n+1)H)Σ(⋅n+1)Σ(n+1)=(I−K(n+1)H)Σ(⋅n+1)

卡尔曼增益是卡尔曼滤波器中的核心参数，它体现的是观测的重要性。当表示测量误差的协方差矩阵 RR 趋近于 0 时，卡尔曼增益会收敛到状态 - 观测矩阵的逆 H−1H−1，这意味着真实的观测结果在置信状态的更新中扮演着越发重要的角色，预测的观测结果的地位则会不断下降。在此基础上进一步可以得到，置信状态在更新后，其协方差趋近于 0，表示当前的状态几乎是确定的。

反过来，当先验置信的协方差矩阵 Σ(⋅n+1)Σ(⋅n+1) 趋近于 0 时，计算出的卡尔曼增益也会趋近于 0。这种情况下，在置信更新中占据主导地位的就变成了对分布的预测结果，后验置信和先验置信的统计特性几乎完全一致，观测结果反而变得无足轻重。随着时序的推移，置信状态最终会收敛到某个分布上，系统的不确定性也会呈现出稳定的状态。

上面介绍的是最原始的卡尔曼滤波器，其原理可以推广到更加复杂的情况中。如果将状态转移和状态到观测的关系建模为非线性关系，并用泰勒展开中的一阶导数和二阶导数进行局部的线性化处理，这样的卡尔曼滤波器就是扩展卡尔曼滤波器（extended Kalman filter）。

另一种用于非线性动态的改进是无迹卡尔曼滤波器（unscented Kalman filter），它是通过无迹变换来对非线性动态进行线性化。两者的具体细节在此就不介绍了，感兴趣的话你可以自行查阅资料了解。

无论是扩展卡尔曼还是无迹卡尔曼，都是对非线性特性的确定性近似（deterministic approximation）。它们放弃了精确计算的追求，转而以确定的方式求解近似的结果。这里的确定性指的是只要用相同的方式进行近似，每次得到的结果都是一样的。如果用随机的方式来对非线性特性做出近似，对应的方法就是粒子滤波（particle filter）。

粒子滤波的任务也是根据观测结果估计隐藏的状态。它并不通过复杂的积分计算出准确的结果，而是对总体的分布进行采样，用样本的经验分布来代替总体的真实分布，用样本的均值来代替总体的积分运算。

由于这种方法和蒙特卡洛采样的思路近似，因而也被称为序贯蒙特卡洛（sequential Monte Carlo）。作为一种非参数方法，粒子滤波可以用来建模任意形式的概率分布，虽然效果未必有多好，很多情况下却是唯一可行的方法。

粒子滤波用样本的平均值来代替总体分布的数学期望，但这里的平均值不是一般的平均，每个样本点都被赋予一个权值，样本及其权重共同构成了粒子滤波中的“粒子”。整个粒子滤波的过程就是动态调整样本的权重，使经验分布不断接近真实分布的过程，具体的数学细节在这里就不讨论了。

今天我和你分享了线性动态系统和一些滤波算法的基本原理，包含以下四个要点：

线性动态系统是具有连续状态变量的隐马尔可夫模型，所有条件概率都是线性高斯分布；

线性动态系统的求解是根据先验置信状态和观测结果来更新系统的置信状态；

卡尔曼滤波器可以对线性动态系统进行精确求解；

当系统具有非线性和非高斯特性时，可以通过扩展卡尔曼滤波器、无迹卡尔曼滤波器和粒子滤波等方法求解。

卡尔曼滤波器及其变种在动态的运动目标跟踪中有广泛的应用，是机器人感知、定位与导航的一种重要方法。

你可以查阅资料，了解卡尔曼滤波器具体的应用方式，并在这里分享你的见解。

35 | 精确推断：变量消除及其拓展

在前面的几讲中，我和你分享了概率图模型中的一些代表性模型，它们都属于表示（representation）的范畴，将关系通过结点和有向边精确地表示出来。接下来，我们将对概率图模型的推断任务加以介绍。

推断（inference）是利用图结构表示的联合分布来计算某个变量的概率，得到关于目标问题的数字化结论。在概率图模型中，因子分解与条件独立性这两大法宝可以大量节约概率运算，给推断问题带来简洁高效的解法。

概率图中的推断可以分为两类：精确推断和近似推断。精确推断（exact inference）是精确计算变量的概率分布，可以在结构比较简单的模型中实现；近似推断（approximate inference）则是在不影响推理正确性的前提下，通过适当降低精度来提高计算效率，适用于结点数目多、网络结构复杂的模型。在这一讲中，我们先来分析精确推断。

精确推断最基本的方法是变量消除（variable elimination），这种方法对“与待求解的条件概率无关的变量”进行边际化处理，也就是将中间变量约掉，从而计算出目标概率。变量消除的基本思想可以通过贝叶斯网络中所举的例子来解释，问题对应的贝叶斯网络如下图所示，所有的先验概率与条件概率都在图中给出。

贝叶斯网络实例

如果要用变量消除法计算变量 hbhb 的分布，就得把除 hbhb 之外的所有变量挨个消除。由于变量 bpbp 只和另一个变量 dodo 相关，所以以它作为突破口是个不错的选择。将所有和变量 bpbp 相关的因子相乘，再对变量 bpbp 求和，就可以算出一个新因子

ψ1(fo,do)=∑bpp(bp)p(do|fo,bp)ψ1(fo,do)=∑bpp(bp)p(do|fo,bp)

除了 bpbp 之外，另一个根结点是 fofo。它会同时直接影响 lolo 和 dodo，所以在计算因子时需要将这两个变量都考虑进来。fofo 与 dodo 的关系已经由上面计算出的新因子所定义，与 lolo 的关系则是纯粹的条件概率，两者结合可以表示为另一个新因子

ψ2(do,lo)=∑foψ1(fo,do)p(fo)p(lo|fo)ψ2(do,lo)=∑foψ1(fo,do)p(fo)p(lo|fo)

变量 lolo 只出现在新因子 ψ2ψ2 中，消除这个变量的结果就是只和变量 dodo 有关的因子 ψ3(do)=∑loψ2(do,lo)ψ3(do)=∑loψ2(do,lo) 求和。最后，根据 dodo 与 hbhb 之间的关系可以将变量 dodo 消除掉，获得最终的结果

p(hb)=∑doψ3(do)p(hb|do)=∑dop(hb|do)∑lo∑fop(fo)p(lo|fo)∑bpp(bp)p(do|fo,bp)p(hb)=∑doψ3(do)p(hb|do)=∑dop(hb|do)∑lo∑fop(fo)p(lo|fo)∑bpp(bp)p(do|fo,bp)

从上面的过程可以看出，变量消除的过程就是不断对中间变量穷举并求和（variable summation），整个过程通过对因子的操作实现。因子（factor）的概念在马尔可夫随机场一讲中有过介绍，在这里就不重复了。如果在目标变量 XX 和单个中间变量 YY 上共同定义出因子函数 ϕ(X,Y)ϕ(X,Y)，那么对 YY 的穷举求和就可以表示为 ψ(X)=∑Yϕ(X,Y)ψ(X)=∑Yϕ(X,Y)，也就是对因子函数的边际化（factor marginalization）。

如果随机变量 YY 在多个因子 ϕ1(X,Y),ϕ2(Z,Y),⋯ϕ1(X,Y),ϕ2(Z,Y),⋯ 中都出现的话，就需要综合考虑这个变量的整体作用，也就是将所有包含这个公共变量的不同因子相乘（factor multiplication）。这样做相当于将单个变量“孤立”出来，它产生的所有影响都体现在因子函数的乘积之中，对所有因子函数的乘积统一进行边际化就可以彻底消除变量 YY 的所有影响。

将上面两个步骤结合起来，就可以得到变量消除的完整过程。变量的消除根据变量之间的依赖关系，按照从简单到复杂的顺序完成。

在选定一个待消除的变量后，首先要找到和这个变量有关的所有因子函数，将它们相乘以得到对变量影响方式的完整描述，再对这个变量在不同取值下的联合概率求和，以计算将它消除之后的边缘概率。按照这样的顺序将所有中间变量消除后，就可以计算出想要的边际概率了。

不难看出，这样的的求解方法建立在“因子乘积 - 变量求和”的步骤上，因而被称为和积变量消除（sum-product variable elimination）。

前面介绍的都是利用变量消除来进行因果推断，也就是解决解释问题。那么这套方法能不能用来由果推因呢？当然可以！还是以上面的贝叶斯网络为例，在前面我曾直接给出结论，在灯亮但狗没叫时，家里有人和没人的概率是一半一半。那么这个概率究竟是怎么计算出来的呢？

这个问题实际上求解的是后验概率 p(fo=0|lo=0,hb=1)p(fo=0|lo=0,hb=1)。由于两个观察变量 lo 和 hb 并不存在子结点，它们所定义的因子 ϕ(fo,lo)ϕ(fo,lo) 和 ϕ(do,hb)ϕ(do,hb) 就只包含和自身相关的条件概率。而贝叶斯网络中的其他 3 个变量共同构成了汇连结构，要将它们和观察变量区分开来，不妨用这三者共同定义出另一个因子 ϕ(fo,bp,do)ϕ(fo,bp,do)。由于两个观察变量具有确定的结果，因此在计算因子的关系时，只需要考虑 lo=0,hb=1lo=0,hb=1 的情形。这样就可以将所有因子以列表形式表示出来。

可以看出，上面的因子表格中的左侧 3 列涵盖了 3 个未知变量所有可能的取值，第 4 列则给出了对应的因子函数值。在执行变量消除时，首先要进行因子相乘，也就是计算每一行里所有概率的乘积，这相当于求解在这个贝叶斯网络中出现 lo=0,hb=1lo=0,hb=1 的所有可能性。由于问题问的是查询变量 fofo 的分布，在求和时就需要对中间变量 bpbp 和 dodo 进行求和，也就是边际化处理。

具体做法是将所有 fo=0fo=0 所在行的因子乘积求和，得到联合概率 p(fo=0,lo=0,hb=1)p(fo=0,lo=0,hb=1)；再将所有 fo=1fo=1 所在行的因子乘积求和，得到联合概率 p(fo=1,lo=0,hb=1)p(fo=1,lo=0,hb=1)。利用贝叶斯定理进行归一化后就可以求出，后验概率 p(fo=0|lo=0,hb=1)=0.5006p(fo=0|lo=0,hb=1)=0.5006，这和贝叶斯网络一讲中计算出的结果是完全一致的。

在预测问题中，已知的 lo=0lo=0 和 hb=1hb=1 被称为证据（evidence）。基于证据的推断本质上是计算非归一化的联合分布 p(fo,lo=0,hb=1)p(fo,lo=0,hb=1)，利用贝叶斯网络的性质可以证明，这个分布其实是个吉布斯分布，起到归一化作用的常数 p(lo=0,hb=1)p(lo=0,hb=1) 则可以看成是约化因子（reduced factor）。

基于和积的变量消去算法实际是利用了乘法对加法的分配律，将对多个变量的积的求和分解为对部分变量交替进行的求积与求和。如果图模型的规模较小，结点的数目较少，直接利用全概率公式进行求和或求积分，就可以计算出每个结点的边缘概率。但当结点数目增加时，和积变量消去的计算量会以指数形式增长。从运算效率的角度对变量消去加以改进，得到的就是置信传播算法。

置信传播（belief propagation）也是精确推断的算法，它将图模型中每个节点的概率分布传递给相邻的节点，以此影响相邻节点的概率分布状态，经过一定次数的迭代，每个节点的概率分布将收敛到一个平稳分布。这种算法适用于包括贝叶斯网络和马尔可夫随机场在内的所有概率图模型，但今天我将以一种新的模型——因子图为例来说明它的原理。

因子图（factor graph）是一类二分图，用来表示对函数的因子分解，其中的结点分为变量结点（variable node）和因子结点（factor node）两种，相关的结点之间则由无向边连接。假定一个因子图表示的是函数 g(x1,x2,x3)=f1(x1)f2(x1,x2)f3(x1,x2)f4(x2,x3)g(x1,x2,x3)=f1(x1)f2(x1,x2)f3(x1,x2)f4(x2,x3)，那它的结构就如下图所示。因子图能够更加直观地刻画函数的可分解性，贝叶斯网络和马尔可夫随机场也都可以表示成因子图。

因子图示例（图片来自维基百科）

置信传播算法的核心概念是消息（message），它是结点之间信息流动的载体。在因子图中，从变量 vv 到因子 aa 的消息是来自除 aa 之外所有与 vv 相邻因子的消息乘积，如果 vv 没有除 aa 之外其他的邻接因子，其消息就被设置为均匀分布。

反过来，从因子 aa 到变量 vv 的消息就复杂一些，它先要对除来自 vv 外，进入 aa 的所有变量消息相乘，再对乘积边际化掉所有除 vv 之外和 aa 邻接的所有变量，这在本质上和变量消除的和积算法是一致的。每个变量的置信度就是根据这样的准则在图结构中往返流动，不断更新。

如果经过多轮迭代后，图模型的因子收敛到稳态，这时就可以计算单个结点的边际概率。每个结点的边际概率都正比于和它相邻的所有因子传递给它的消息的乘积，归一化处理后就可以得到真正的概率。一个因子所包含的所有变量的联合边际分布则正比于因子函数本身和来自这些变量的消息的乘积，和单个结点一样，这个值也需要归一化处理。

置信传播算法在理论上并不保证对所有图结构都能收敛，但当图模型具有树结构时，计算出的概率分布一定会收敛到真实值，从而实现精确推断。无环图天然地具有树的特性，可即使原始的图中存在有向或者无向的环路结构，也可以通过让变量聚集成不同的团来生成类似树的结构，这种结构就是团树。

团树（clique tree）也叫联结树（junction tree），是一种通过变量连接的结构。其特点是如果一个变量出现在树结构的两个团中，那它就一定会出现在连接这两个团的路径上的所有团中。

这样看来，每个相连的团都像是古时候的驿站，它们的公共变量则是信使。在传递消息时，首先要在团树中选出一个根结点，从这个根结点出发构造出一棵树。根节点通常是包含待查询的目标变量的团，以此作为消息传递的枢纽，生成的树则是传递消息的道路网。

马尔可夫随机场及其团树示例（图片来自维基百科）

消息的传递需要经过两个步骤：第一个步骤是收集（collection），指的是所有叶结点向根结点传递消息，直到根结点收到所有邻接结点的消息，这是消息汇总的过程；第二个步骤是分发（distribution），指的是根结点向叶结点传递消息，直到所有叶结点均收到消息，这是消息更新的过程。这样的一来一回之后，团树的每条边上都有不同方向的两条消息，基于这些消息就能计算出所有变量的边际概率。

和变量消除相比，置信传播的优势在于提升了计算效率。变量消去算法的缺点在于一次变量消去只能求出本次查询变量的条件分布，不同的查询将带来大量的重复计算。在团树中流动的每个消息都相当于对一组关联因子的封装，查询不同变量时只需调用相关的封装就可以了，从而避免了复杂的重复运算。

在 pgmpy 中，团树被定义为 models 模块中的 JunctionTree。利用 BayesianModel 类中的 to_junction_tree 函数可以将现有的贝叶斯网络转换成团树，转换出的团树就可以使用 inference 模块中的 BeliefPropagation 类来求解。用团树和置信传播求解上面的例子，可以得到与对贝叶斯网络进行变量消除一致的结果。

贝叶斯网络的团划分

今天我和你分享了对概率图模型的精确推断，包含以下四个要点：

推断是利用图结构表示的概率分布计算查询变量的概率，可以分为精确推断和近似推断；

变量消除通过对非查询变量的边际化处理实现精确推断，具体步骤包括因子乘积和变量求和；

置信传播通过消息传递实现精确推断，具有较高的计算效率；

将图模型改造成团树结构可以保证置信传播算法的收敛性。

在变量消除中，选取消除变量的顺序是个重要的问题，顺序选得好可以很大程度上简化运算。在文中的例子里，确定消除顺序的原则是最小邻居，也就是选择依赖变量最少的变量。那么除此之外，还有哪些确定消除顺序的原则呢？

你可以查阅相关资料，并在这里留下你的看法。

36 | 确定近似推断：变分贝叶斯

虽然精确推断能够准确计算结果，但它的应用范围却严重受限。当网络的规模较大、结点较多时，大量复杂的因子会严重削弱精确推断的可操作性，虽然这类方法在原则上依然可行，却难以解决实际问题。

另一方面，如果模型中同时存在隐变量等非观测变量和未知的参数时，复杂的隐藏状态空间也会让精确的数值计算变得难以实现。要在这样的模型上实现推断，就不得不借助近似推断。

近似推断是在精确性和计算资源两者之间的折中。如果具有无限的计算资源，精确推断也不是不能实现，但近似推断可以在有限时间内解决问题，而不是画一张水月镜花的大饼。从实现方式上看，近似推断可以分为确定性近似和随机性近似两类，今天我先和你聊聊确定性近似。

确定性近似（deterministic approximation）属于解析近似（analytical approximation）的范畴。绝大多数贝叶斯推断任务最终都可以归结到后验概率的计算，算出来的后验概率在理想情况下应该以解析式的形式出现。

当这个函数复杂到没法用解析式表达时，一个直观的思路是找到另一个形式更简洁的函数按照一定规则来尽可能地逼近这个复杂函数，这种方法就是确定性近似。我们再熟悉不过的四舍五入其实就是最简单的确定性近似。

确定性近似的典型代表是变分贝叶斯推断（variational Bayesian inference），它解决的问题是对隐变量 yy 关于已知输入 xx 的后验概率 p(y|x)p(y|x) 的近似，近似的方式是利用最优的近似概率分布 q(y)q(y) 来逼近 p(y|x)p(y|x)。

这里的 q(y)q(y) 表示的是 yy 在 xx 这一组特定的输入数据之上的分布，它并不会将 xx 视为可变的参量。

从数学上看，如果假定模型的参数 αα 是固定不变的，那么隐变量 yy 关于输入 xx 的后验概率可以写成

p(y|x,α)=p(y,x|α)∫yp(y,x|α)p(y|x,α)=p(y,x|α)∫yp(y,x|α)

虽然后验概率将数据和模型联系起来，但隐变量的不可观察性使分母上的积分式变得无法计算。期望最大化算法（EM）虽然能够用于求解隐变量，但它是使输出结果最大的那个隐变量取值来代替原本的求和运算，简化求解的同时也失去了贝叶斯推断的边际化这一精髓。要在保留边际化操作的基础上做出近似，就得借助于变分法。

变分法的出发点是观测的概率分布 p(x)p(x)，它的对数可以利用条件概率的性质来加以改写

log[p(x)]=log∫yp(x,y)=log∫yp(x,y)q(y)q(y)=logEqp(x,Y)q(y)log⁡[p(x)]=log⁡∫yp(x,y)=log⁡∫yp(x,y)q(y)q(y)=log⁡Eqp(x,Y)q(y)

上面的表达式中涉及对求和项的对数运算，这时利用简森不等式（Jensen’s inequality）可以将它简化为对对数项的求和，也就是

log[p(x)]≥Eqp(x,Y)q(y)=Eqlogp(x,Y)−Eqlogq(y)log⁡[p(x)]≥Eqp(x,Y)q(y)=Eqlog⁡p(x,Y)−Eqlog⁡q(y)

等式右侧的结果被称为变分下界（variational lower bound），也叫证据下界（evidence lower bound），它小于或者等于等式左侧的 log[p(x)]log⁡[p(x)]，用对数概率减去变分下界就可以得到 q(y)q(y) 和 p(y|x)p(y|x) 的 KL 散度。

这说明变分下界可以用来表示隐变量的预测分布 q(y)q(y) 和根据观测结果推导出的真实分布 p(y|x)p(y|x) 到底相差多少，也就是近似的接近程度。两个分布之间的变分下界越大，它们之间的 KL 散度就会越小，分布特性也就越接近。

提升变分下界要两手抓：一方面要尽可能地增加 p(x)p(x)，因为等式左侧不小于等式右侧，变分下界的增加意味着 log[p(x)]log⁡[p(x)] 得增加得更多，这一过程被称为近似学习（approximate learning）；另一方面，在 p(x)p(x) 确定之后，就需要找到在这个确定的 p(x)p(x) 上，让变分下界最大的隐变量分布，也就是 q(y)q(y)，这一过程被称为近似推断（approximate inference）。

要对变分下界做出优化，需要引入平均场理论的方法。平均场理论（mean field theory）与其说是方法，不如说是思想：它将复杂的整体模型简化为若干个相互独立的局部模型的组合。

在变分贝叶斯中，平均场理论将复杂的多变量 yy 分解成一系列独立的因子 yiyi，多变量的分布 q(y)q(y) 则被因子化成所有因子分布的乘积

q(y)=∏i=1Nqi(yi)q(y)=∏i=1Nqi(yi)

不难看出，这和前面介绍过的朴素贝叶斯的思想不谋而合，只不过朴素贝叶斯拆分的是属性，平均场拆分的是因子。将平均场的因子化结果回过头代入到变分下界的表达式中，可以将高维的 q(y)q(y) 拆解成低维概率分布乘积的形式，并给出每个低维概率分布的最优解表达式

q∗j(yj)=1Zexp[Ei≠j(logp(y,x))]qj∗(yj)=1Zexp⁡[Ei≠j(log⁡p(y,x))]

其中 ZZ 是归一化的常数。当然，实际情况是隐变量之间是存在着依赖关系的，因而平均场理论在简化运算的同时，也会付出精确性的代价。

从宏观层面看，变分法将推断问题改造成了泛函（functional）的优化问题，这也是“变分”一词的来源。优化的目的是用简单的、容易计算的分布 q(y)q(y) 来拟合复杂的、不容易计算的后验分布 p(y|x)p(y|x)，优化的对象是变分下界。

将变分推断应用在贝叶斯网络中可以实现自动化的推理，对应的方法被称为变分消息传播（variational message passing）。

对贝叶斯网络中的结点应用变分贝叶斯推断时，只需要关注这个节点的马尔可夫毯，也就是它的父结点（parent）、子节点（child）以及共父结点（co-parent）。在计算结点 HjHj 对应的低维概率分布 Q∗jQj∗ 时，这些结点和 HjHj 之间的条件概率都会作为变量出现，而不在马尔可夫毯中的其他结点的作用就体现为常数。

马尔可夫毯示意图（图片来自维基百科）

出于简化计算的考虑，变分消息传播算法假设待计算节点 HjHj 关于其父结点的条件概率分布属于指数分布族，并且是父结点分布的共轭先验，这样的模型叫作共轭指数模型（conjugate-exponential model）。

指数分布族具有计算上的便利：它的对数形式是可计算的，状态也完全可以由自然参数表示；先验分布的共轭特性同样有助于简化运算，它保证了后验分布和先验分布具有相同的形式，区别只在于参数的不同。

有马尔可夫毯和共轭指数模型作为基础，就可以对贝叶斯网络进行消息传播了。虽然变分消息传播的具体机制比较复杂，但其基本原则无外乎两条：父结点向子结点传播自身分布的充分统计量的数学期望，而子结点向父结点传播自身分布的自然参数。

在子结点向父结点传播消息之前，首先要接收来自共父结点的消息，这是由汇连结构中变量之间的依赖性所决定的。接收到所有来自父结点和子结点的消息后，目标结点用这些消息来更新自己的自然参数，进而更新后验分布，在一轮一轮的迭代过程中，变分分布就会逐渐接近最优值——这与置信传播的思路不谋而合。

同为处理未知参数和隐变量的方法，变分贝叶斯和后面要介绍的 EM 算法之间有着千丝万缕的联系。下面的表格来自约翰霍普金斯大学的自然语言处理专家杰森·艾斯纳教授（Jason Eisner）的讲义《变分推断的高层次解释》（High-Level Explanation of Variational Inference），它将变分法和 EM 算法纳入到了统一的框架下。

表格的第一行给出了最简单的情形：当问题超参数和参数全部给定时，相当于用确定的模型来估计隐变量，这种对隐变量的预测就是典型的推断问题。具体的实现方式是前向 - 后向算法（forward-backward algorithm），如果对前向 - 后向算法进行近似处理，就可以得到变分推断（variational inference）。

如果放弃对隐变量分布的求解，而是直接给出最可能的状态，推断问题就被简化成为解码问题（decoding），最典型的方法非基于最大后验的维特比译码（Viterbi decoding）莫属。

在此基础上把问题复杂化一些，将参数设定为未知的话，推断问题就变成了估计模型参数的学习问题（learning），这在后面会有详细的阐述。出于运算复杂性的考虑，处理未知参数时可以直接找到让输出后验概率最大化的那一组参数，这就是 EM 算法。

将 EM 算法中参数的最大化替换成标准贝叶斯推断中的边际化操作，其结果就是本讲的主题——变分贝叶斯。这也体现出变分贝叶斯和 EM 的区别：EM 中应用了隐变量的概率分布，但对待估计的参数只是做出点估计；变分贝叶斯则一视同仁，对两类非观测变量都使用分布来描述。

最复杂的情形发生在连超参数都无法确定时，解决这类问题需要借助经验贝叶斯方法（empirical Bayes method）。

经验贝叶斯方法其实就是在统计学习模块中介绍的贝叶斯方法，也就是引入超先验构造层次模型的做法。经验贝叶斯会计算出级别最高的超先验分布的参数最可能的取值，而不是对它的分布进行积分，这让它有别于全贝叶斯的途径。这种方法在计算隐变量的后验分布时使用变分推断来估计，所以被称为变分 EM（variational EM）。

在专门用于贝叶斯机器学习的库 PyMC3 中，变分推断可以通过 ADVI 类实现。ADVI 的全称是自动微分变分推断（Automatic Differentiation Variational Inference），是一种基于平均场理论的高效算法，它将变分后验分布初始化为球面高斯分布，不同参数的后验彼此无关，再通过训练数据拟合到真实的后验上。

将变分推断运用到前面介绍过的简单线性回归中，可以模拟出线性系数和偏置的分布。受计算机性能的限制，代码中的 nn 设定得较小，但实际上 nn 越大，推断结果才会越精确。

今天我和你分享了变分贝叶斯推断的基本原理，以及它和 EM 算法之间的关联，包含以下四个要点：

变分贝叶斯推断是基于确定性近似的推断方法；

变分贝叶斯用简单的近似分布来拟合真实的后验分布，并利用平均场分解简化对变分下界的优化；

变分消息传播可以在贝叶斯网络上实现变分推断；

变分贝叶斯和 EM 算法都是对隐变量的处理，可以从统一的角度分析。

发表于《美国统计联合会会刊》（Journal of American Statistical Association）第 12 卷第 518 期上的《从统计学看变分推断》（Variational Inference: A Review for Statisticians）是一篇很好的综述，文中以贝叶斯高斯混合模型为例介绍了变分推断的具体应用。

你可以研究一下这个实例，来加深对变分推断的理解。

37 | 随机近似推断：MCMC

本质上说，确定性近似是遵循着一定的原则，使用一个分布来近似另一个分布，近似结果取决于确定的规则。可是在很多预测任务中，完整的后验分布并不是必需的，我们关注的对象只是某个因变量在后验分布下的期望，或者具有最大后验概率的那个取值。这时再使用确定性近似来计算预测结果，尤其是连续函数在连续分布下的预测结果又是个在计算上颇为棘手的问题。

有些时候，即使目标分布的形式是已知的，对它的求解也存在着困难。就拿常见的 Beta 分布来说，其概率密度可以表示为 p(x)=Cxα−1(1−x)β−1p(x)=Cxα−1(1−x)β−1，其中常数 α,βα,β 都是分布参数，常数 CC 是归一化因子。可问题在于如果不能计算出这个复杂的参数 CC，即使能够确定分布的形状，也没法对分布进行直接的采样。这种情况下也要借助随机性近似。

既然求解解析解既复杂繁冗又无甚必要，那就不妨用统计学的核心概念——抽样来解决问题。用样本分布来代替难以求解的后验分布，这就是随机性近似的思想。

随机性近似（stochastic approximation）属于数值近似（numerical approximation）的范畴，它对数据的生成机制进行建模，通过模型生成符合真实分布的抽样结果，再利用这些抽样结果表示未知的概率分布。

随机性近似的典型方法是马尔可夫链蒙特卡洛方法（Markov Chain Monte Carlo method），简称 MCMC。其作用是在概率空间中构造合适的马尔科夫链，再应用蒙特卡洛方法进行随机采样来拟合目标的分布。

MCMC 体现的是真正的概率密度的思想，它虽然不能计算分布的表达式，却可以将概率等比例地放大。频率意义下的概率就是数据出现的频度，归一化的作用只是让它变成公理化的概率，而不会对频率解释产生任何影响。

MCMC 的出发点就在于消除掉那个不影响分布趋势却又没它不行的归一化常数 CC 对概率求解的影响，通过对简单分布（比如均匀分布）进行抽样来拟合出更加复杂，甚至于压根儿不存在解析式的分布形式。

虽然都可以缩写成 MC，但马尔可夫链和蒙特卡洛方法却是两个完全不同的概念。

蒙特卡洛方法诞生于曼哈顿计划中，其缔造者是数学家斯坦尼斯拉夫·乌拉姆（Stanislaw Ulam）和不世出的天才约翰·冯诺伊曼（John von Neumann）。蒙特卡洛本身是袖珍王国摩纳哥的一块国土，以其大名鼎鼎的蒙特卡洛赌场闻名于世，这样的名字或多或少地说明了这个方法和作为概率论不竭灵感源泉的赌博娱乐之间的深厚渊源。

这个号称 20 世纪最伟大的算法其实不难理解。通俗地说，它就是通过多次独立重复的随机实验来模拟确定性的概率分布，或者求解难以计算的求和问题，其精确性由大数定律所保证。

蒙特卡洛方法最广为人知的应用可能就是对圆周率 ππ 的估算：在一个单位面积的正方形里随机且均匀地抛洒若干个点，然后统计这些点中和某个选取出的顶点之间距离小于 1 的点的数目。

如果将这个选出来的参考顶点视为圆心，那么和它的距离小于 1 的这些点就都在四分之一圆内，四分之一圆内的点数和所有点数的比例就是 π/4π/4 的估计值。当随机生成的点数达到 30000 时，ππ 的估计误差可以下降到 0.07% 以下。

用蒙特卡洛法估计 ππ 值（图片来自维基百科）

使用蒙特卡洛方法估计未知的目标分布 p(x)p(x) 时，可以先引入另一个概率分布 q(x)q(x) 作为参考分布，这个参考分布被称为建议分布（proposal distribution），具有简单的形式和易于采样的特性。与建议分布配套的还有个常数 MM，两者共同满足 Mq(x)≥p~(x)Mq(x)≥p~(x)，这里的 p~(x)p~(x) 是未归一化的概率，是目标分布 p(x)p(x) 与另一个常数 ZZ 的乘积。

如果将上面的两个准概率分布画在同一个坐标系里，Mq(x)Mq(x) 对应的曲线会将 p~(x)=Zp(x)p~(x)=Zp(x) 对应的曲线完全包住，两者之间会存在一段间隔。在执行采样时，首先按照概率分布 q(x)q(x) 生成一个随机数 x0x0，接着在 [0,Mq(x0)][0,Mq(x0)] 的区间上通过均匀采样采出来一个新数 u0u0。如果得到的 u0u0 大于 p~(x0)p~(x0)，那它就落在两条曲线之间的区域，这样的样本会被直接抛弃；如果 u0u0 小于 p~(x0)p~(x0)，那它就落在 p~(x)p~(x) 曲线的下方，这样的样本才会保留。

拒绝采样示意图

图片来自《机器学习》（Machine Learning）第 50 卷第 1 期 5-43，《用于机器学习的 MCMC 介绍》（An introduction to MCMC for machine learning）。

由于需要根据样本的特性决定接受或是拒绝，因而以上的采样机制被称为拒绝采样（rejection sampling）。可以证明，拒绝采样等效于对目标分布 p(x)p(x) 进行多次独立的采样。一般说来，即使对系数 ZZ 进行优化处理，拒绝采样也会有较高的拒绝率，其运算效率通常较低。

蒙特卡洛方法只是随机采样的过程，而要确保采出来的样本服从我们想要的分布，需要借助第一个 MC：马尔可夫链。马尔可夫链假定每一时刻的状态只依赖于前一时刻的状态，每一个状态又会以一定的概率变化为另一个状态，状态之间所有的转化概率共同构成了这个马尔可夫链的状态转移矩阵（transition matrix）。

转移矩阵可以将任意的初始概率分布变成马尔可夫链的稳态分布（equilibrium distribution）。稳态分布由转移矩阵决定，而与初始的概率分布无关，不管每个状态的初始概率如何，经过若干轮次的转换之后，都可以得到符合稳态分布的样本。这意味着如果能够计算出某个稳态分布所对应的马尔科夫链的状态转移矩阵，服从这个稳态分布的数据样本就唾手可得。

引入了马尔可夫性后，MCMC 最原始的实现——Metropolis 算法便呼之欲出。Metropolis 算法可以看成是结合了马尔可夫链的拒绝采样，它将原始的数据点初始化为 x0x0，将转移概率初始化为 q(x|x0)q(x|x0)。需要注意的是，Metropolis 算法中的转移概率必须具备对称的特性，也就是 q(x|y)=q(y|x)q(x|y)=q(y|x) 对任意的 xx 和 yy 都成立。

在每一轮数据的生成中，Metropolis 算法会根据上一轮的结果 xtxt 和以建议分布形式出现的转移概率 q(x|xt)q(x|xt) 生成 x′x′，这个新生成的样本将以 α=p~(x′)/p~(x(t))α=p~(x′)/p~(x(t)) 的概率被接受。在实现中，接受的策略体现为生成一个在 [0, 1] 上均匀分布的随机数 uu，如果 u<αu<α 就接收新样本，反之则继续使用上一轮次的旧样本。如果新样本的出现引起了 p~(⋅)p~(⋅) 的增加，也就是 α>1α>1 的话，这样的新样本就是必然被保留的。

直观理解，在模拟分布时，Metropolis 就像一只在山头上游弋，标记自己领地的老虎。它会在概率密度大，也就是数据出现频度高的位置多转几圈，多留下自己的气味；而在概率密度小，数据出现频度低的位置，示意性地巡逻一下，留一点味道就可以了。数据的概率密度正是通过气味的浓度，也就是采样的样本出现的次数所定义的。

但这样的行为又带来了一个问题，那就是 Metropolis 在生成新样本时更倾向于接收那些来自分布集中区域的样本。如果新样本导致准概率密度的增加，那它就 100% 会被接受。可如果导致准概率下降，新样本就存在被丢弃的可能，下降的程度越大，被接受的概率就越低，这将会导致生成的样本更容易抱团在一起。如果将 Metropolis 算法中对称的建议分布设定为以上一轮的结果为中心的高斯分布，生成的序列就会变成围着一个小区域转圈圈的随机游动（random walk）。

将原始 Metropolis 算法的中建议分布的对称特性去掉，得到的就是广泛应用的Metropolis-Hastings 算法，简称MH 算法。

马尔可夫链的特性决定了根据给定的状态矩阵确定对应的稳态分布是小菜一碟，可根据给定的稳态分布找到对应状态矩阵的难度却有如大海捞针。为了简化寻找转移矩阵的难度，MH 算法利用了稳态分布的一个充分非必要条件，那就是细致平稳性（detailed balance）。细致平稳性的数学表达式可以写成

π(i)Qij=π(j)Qjiπ(i)Qij=π(j)Qji

其中 ππ 是马尔可夫链的稳态分布，QQ 是马尔可夫链的转移矩阵。这个式子的含义在于从状态 ii 转移到状态 jj 的概率质量恰好等于从 jj 转移回 ii 的概率质量，转入和转出之间存在动态平衡，分布 ππ 就是稳态分布。但在具体问题中，任意选择的目标分布 p(x)p(x) 和起到转移矩阵作用的建议分布 q(x)q(x) 很难满足细致平稳性，这时就需要对它们做一些人为的修正，修正方式是引入参数 αα，令它满足

p(i)Q(i,j)α(i,j)=p(j)Q(j,i)α(j,i)p(i)Q(i,j)α(i,j)=p(j)Q(j,i)α(j,i)

不难看出，参数的引入使转移矩阵被修正为 Q(⋅)α(⋅)Q(⋅)α(⋅)，这可以避免 Metropolis 算法对小概率样本的一刀切。在 MH 算法中，参数 αα 就是接受率，可以理解为执行这次从 ii 到 jj 的转移的概率。要让接受率满足上面的条件，最简单的方式是设定两者之中较大的一个为 1，再利用等式关系计算出另外一个，这样生成的样本分布 p(z)p(z) 就是马尔可夫链的稳态分布。

MH 算法的一个特例是针对高维分布的吉布斯采样（Gibbs sampling）。在一个 NN 元分布中计算每个变量关于其他所有变量的条件分布，可以得到 NN 个一元条件分布。吉布斯采样就是对这些条件分布进行采样：在给定初始值后，吉布斯采样按照每个一元条件分布依次产生新的样本并全部接受，作为下一轮更新的基础。

追根溯源，吉布斯采样来源于对吉布斯随机场（Gibbs random field）的研究，它相当于将一个高维的马尔可夫链庖丁解牛，拆解成多个一维的马尔可夫链，高维马尔可夫链整体的状态转移也相应地被拆解成不同一维链轮流的状态转移。这样的拆解并不会影响到细致平稳条件，因而得到的分布依然是目标的稳态分布。另外，吉布斯采样并不会拒绝产生的样本，这使它和 MH 算法相比具有效率上的优势，从而成为应用最广泛的 MCMC 算法。

利用 PyMC 库可以实现 MCMC 采样。出于便于对比的考虑，本讲以估计硬币正反面的概率为例。硬币出现正面的概率 pp 可以用二项分布建模，其先验和后验则用共轭的贝塔分布建模，因而可以给出后验概率精确的解析结果。利用投掷 50 次硬币出现 20 次正面的数据，就可以用 Metropolis 算法来估计二项分布的参数 pp 了。结果表明，MCMC 的结果和解析结果基本吻合。

今天我和你分享了 MCMC 方法的基本原理，以及 MH 算法和吉布斯采样等具体的实现方式，包含以下四个要点：

MCMC 是基于随机性近似的推断方法；

MCMC 利用基于蒙特卡洛方法的随机采样将任意的初始分布转化为马尔可夫链的稳态分布；

MCMC 的关键问题是找到和目标稳态分布匹配的转移矩阵；

MCMC 的典型方法包括一维的 MH 算法和多维的吉布斯采样。

在 MCMC 中，转移概率或者建议分布 q(x,y)q(x,y) 的选择是关键因素，其设计的优劣会直接影响到算法的性能。

你可以查阅相关文献，了解转移概率常见的设计思想，并在这里留下你的见解。

38 | 完备数据下的参数学习：有向图与无向图

介绍完表示和推断之后，我们将进入概率图模型的最后一个任务，也就是学习问题。

在推断任务中，我们会根据已知的模型来确定实例的特性，模型的结构和参数都作为输入的一部分出现。学习任务（model learning）则是将推断任务的过程颠倒过来，根据数据来构造出能够反映数据潜在规律的模型，也就是对概率图模型的训练。

概率图模型的学习和其他的机器学习一样，都属于自动化的建模方式。构造概率图模型的依据是变量之间的依赖关系，这些依赖关系的建立则需要仰赖垂直领域的先验知识。如果用纯人工的方式来构建概率图模型，那么在网络的节点数目较多、规模较大时，其工作量将是惊人的。将学习任务引入概率图模型之中，就可以基于结构化的数据高效地计算出网络的结构与参数，从而大大简化训练的流程。

根据学习对象的不同，学习任务可以大体分为参数学习和结构学习两类。

参数学习（parameter learning）是在已知图模型结构的前提下估计其参数，也就是节点之间的条件概率，这可以看成是个数值优化问题。

结构学习（structure learning）是在图模型完全未知的情况下先确定其结构，再根据结构来计算参数。结构学习可以看成是针对结构和参数的联合优化，可以存在单一的全局最优解。

今天这一讲中，我们先来看看参数学习，这个任务还可以进一步地分类。根据模型结构的不同，参数学习可以分为对贝叶斯网络的学习和对马尔可夫随机场的学习。

有向和无向的差异给两种结构的学习带来了截然不同的解决方案：在贝叶斯网络中，每一对节点之间都定义了归一化的条件概率分布，因此学习任务针对的是每个单独的局部；而在马尔可夫随机场中，归一化操作是通过全局化的划分函数来完成的，参数的全局耦合性使得这个复杂的任务不能被分解成若干简单任务的组合，造成了更大的学习难度。

最简单的参数学习问题是利用完全观测的数据估计贝叶斯网络的参数，网络结构中并不存在隐变量。从频率主义出发，可以基于似然概率最大化来实现参数的估计。最大似然估计的目标是找到让现有数据出现的概率、也就是似然函数最大化的那一组参数。根据贝叶斯网络的局部特性，全局似然函数可以被拆解成一些独立的局部似然函数的乘积，每个独立项都对应着网络中的一个条件概率分布，这就是似然函数的全局分解（global decomposition）。

似然概率的全局分解有什么作用呢？那就是简化参数估计的运算。基于全局分解可以单独对每个局部似然函数进行最大化，而无需考虑其他局部结构的影响，将每个局部似然函数的最优参数合并在一起，得到的就是全局似然函数的最优解。

这一技巧最简单而又最具代表性的应用就是朴素贝叶斯分类器。将类似然函数改写成属性似然函数的乘积就是基于朴素贝叶斯图结构的全局分解，在此基础上计算属性的似然概率，就是统计当每个属性取得不同的取值时，归属于某个类别的样本在这个类别所有样本中所占的比例。如果你对朴素贝叶斯还有些陌生，可以参考专栏的第 28 讲，以及“人工智能基础课”中的内容。

前面介绍的最大似然估计出自频率主义的视角，如果要从贝叶斯主义出发，就得先给每个参数设定先验分布，以实现最大后验估计。表示先验分布的变量一般来说会与现有贝叶斯网络的数据和结构独立，与原始的贝叶斯网络共同形成新的元网（meta-network）。可以证明，如果不同参数的先验分布是相互独立的，那么它们的后验分布也会继承这种独立性，所以对最大后验估计的求解也可以遵循从局部到整体的方式，这和最大似然估计是一致的。

不难看出，对完整观测的贝叶斯网络进行参数估计，就是将传统的最大似然估计和最大后验估计应用到有向图模型这个特定的场景中。图模型中的条件独立性还可以进一步将全局优化分解为相互独立的局部优化，从而实现一定的简化。

可是在马尔可夫随机场中，问题就没有这么简单了。考虑一个最简单的马尔可夫随机场 A–B–CA–B–C，这个图模型中的势函数有两个，分别是 ϕ1(A,B)ϕ1(A,B) 和 ϕ2(B,C)ϕ2(B,C)，它的划分函数 ZZ 等于所有两个势函数的乘积对变量 A,B,CA,B,C 所有可能的取值进行求和。在给定一组数据 a,b,ca,b,c 时，这个实例的似然概率可以写成

p(a,b,c)=ϕ1(a,b)⋅ϕ2(b,c)Z=ϕ1(a,b)⋅ϕ2(b,c)∑a,b,cϕ1(a,b)⋅ϕ2(b,c)p(a,b,c)=ϕ1(a,b)⋅ϕ2(b,c)Z=ϕ1(a,b)⋅ϕ2(b,c)∑a,b,cϕ1(a,b)⋅ϕ2(b,c)

在对这个式子进行最大化时，就不能对 ϕ1(a,b)ϕ1(a,b) 和 ϕ2(b,c)ϕ2(b,c) 分开处理，各自求解最大值了。因为划分函数 ZZ 是由所有的参数共同决定的，无论是 ϕ1(a,b)ϕ1(a,b) 还是 ϕ2(b,c)ϕ2(b,c) 发生变化，都会导致 ZZ 发生变化。划分函数就像一条履带，将这两个因子像两个齿轮一样扣在一起，并将一个的变化传导给另一个，让两者必须作为一个整体来加以优化。

在马尔可夫随机场的参数学习中，上面乘积式中的每个因子都会被改写为对数线性的形式，也就是变量集特征函数的指数加权求和。这样一来，模型的参数就变成了对数线性模型中的权重，并通过对权重似然函数的最优化来实现参数学习。

利用划分函数是关于待估计参数的凸函数这一条件，可以证明对数似然函数是单峰函数，只有全局最优而没有局部最优。求解这个全局最优值就等价于找到让对数似然函数梯度为 0 的那一组参数，此时得到的最优解将和真实模型完全匹配。但问题是单凭这个准则不能给出问题的解析解，要计算出最优参数必须借助梯度法等最优化的方法。

虽然马尔可夫随机场不能像贝叶斯网络那样将整体化为局部之积，但它在结构上也是可以被分解的。如果马尔可夫随机场的图结构是弦图（chordal graph），那它就是可分解的（decomposable）。

什么是弦图？是指无向图中任意长度大于 3 的环路中都至少存在一条弦，也就是连接环路中不相交的顶点的无向边。下图就是一个弦图的实例，连接结点 X2X2 和 X3X3 的那条边就是弦。

具有弦图结构的马尔可夫随机场

可分解的马尔可夫随机场可以被划分成不同的团，每个团的势函数都可以被初始化为经验边际函数（empirical marginal）。如果这个团和其他团之间存在公共节点，那么它的势函数还要除以公共结点的经验边际函数。利用这种经验方式计算出每个团的势函数后，将得到的结果相乘，其结果就是最大似然估计的结果了。

还是以上面的弦图为例，结点 X1,X2,X3X1,X2,X3 构成了一个团，其势函数可以表示为经验边际

ψML1,2,3=p~(x1,x2,x3)ψ1,2,3ML=p~(x1,x2,x3)

按同样的方式可以写出团 X2,X3,X4X2,X3,X4 的经验势函数，但由于它和上面的团共享了公共结点 X2X2 和 X3X3，就需要用这两个公共节点的经验势加以约化，其结果为

ψML2,3,4=p~(x2,x3,x4)p~(x2,x3)ψ2,3,4ML=p~(x2,x3,x4)p~(x2,x3)

同理可以求出团 X2,X4,X5X2,X4,X5 的势函数

ψML2,4,5=p~(x2,x4,x5)p~(x2,x4)ψ2,4,5ML=p~(x2,x4,x5)p~(x2,x4)

三者相乘就是整个模型的似然函数，基于这一函数可以实现参数的最大似然估计。

可分解马尔可夫随机场的最大似然估计问题可以通过上面的方式简化，可如果图结构本身是不可分解的，模型的学习就要借助于更一般的方法，迭代比例拟合就是这样的一种方法。

迭代比例拟合（iterative proportional fitting）可以在给定经验边际的条件下求解未知的势函数，具体的方法是一个一个地去满足经验边际的约束，但满足下一个约束可能破坏上一个约束，所以需要通过迭代来逼近所有的边际条件。

马尔可夫随机场的运算成本较高，要简化运算的话，既可以使用近似推理过程计算梯度，也可以使用其他目标函数来代替似然函数。

近似推理是将学习问题当成推断问题来解决，包括传播近似推理和抽样近似推理两种技术，传播近似推理是将信念传播算法应用在马尔可夫随机场的学习中，抽样近似推理则通常借助 MCMC，用平稳分布作为参数后验分布的估计。

用来代替似然函数的目标函数则包括伪似然函数、对比散度和最大间隔函数等，其中的对比散度已经被用于受限玻尔兹曼机的训练中。

今天我和你分享了概率图模型中的参数学习任务，包含以下四个要点：

参数学习的任务是在已知模型结构的前提下估计其参数，可以看成是模型的训练；

贝叶斯网络的参数学习可以由整体分解为局部，在局部上应用最大似然估计或者最大后验估计；

马尔可夫随机场的参数学习不能分解，也不存在解析解，可以使用通用的迭代比例拟合方法找到全局最优解；

马尔可夫随机场的参数学习可以通过近似推理和目标函数替换加以简化。

今天介绍的内容关注的是完备数据基础上的参数学习，如果数据集是不完备的，就可能会缺失某些变量的观测样本，或者存在不能被观测的隐变量。后一种情况可以通过 EM 算法来解决，那么前一种情况如何处理呢？

你可以查阅资料了解相关内容，并在这里分享你的见解。

39 | 隐变量下的参数学习：EM方法与混合模型

前面我曾介绍过隐马尔可夫和线性动态系统这类隐变量模型。所谓的隐变量表示的其实是数据的不完整性，也就是训练数据并不能给出关于模型结果的全部信息，因此只能对模型中未知的状态做出概率性的推测。

在今天这一讲中，我将和你分享一种在隐变量模型的参数学习中发挥重要作用的方法：期望最大化算法。

期望最大化算法（expectation-maximization algorithm, EM）是用于计算最大似然估计的迭代方法，其中的期望步骤（expectation step）利用当前的参数来生成关于隐变量概率的期望函数，最大化步骤（maximization step）则寻找让期望函数最大的一组参数，并将这组参数应用到下一轮的期望步骤中。如此循环往复，算法就可以估计出隐变量的概率分布。

EM 算法虽然可以在不能直接求解方程时找到统计模型的最大似然参数，但它并不能保证收敛到全局最优。一般来说，似然函数的最大化会涉及对所有未知参量求导，这在隐变量模型中是无法实现的。

EM 算法的解决方法是将求解过程转化为一组互锁的方程，它们就像联动的齿轮一样，通过待求解参数和未知状态变量的不断迭代、交叉使用来求解最大似然。

具体的做法是给两组未知数中的一组选择任意值，使用它们来估计另一组，然后使用这些更新的取值来找到前一组的更好估计，然后在两者之间交互更新，直到得到的值都收敛到固定点。

EM 算法的实现方法可以通过一个通俗易懂的实例加以阐释，这个例子来源于期刊《自然 ⋅⋅ 生物技术》（Nature Biotechnology）第 26 卷第 8 期上的论文《何为期望最大化算法？》（What is the expectation maximization algorithm?）。考虑到之前关于贝叶斯统计的教程也是来源于这个期刊，概率推断与机器学习在生命科学中的重要性便不言而喻。

隐变量已知时，利用最大似然法求解参数（图片来自 What is the expectation maximization algorithm?）

上图就是用来解释 EM 算法的问题。假定有两枚不同的硬币 AA 和 BB，它们的重量分布 θAθA 和 θBθB 是未知的，其数值可以通过抛掷后计算正反面各自出现的次数来估计。具体的估计方法是在每一轮中随机抽出一枚硬币抛掷 10 次，同样的过程执行 5 轮，根据这 50 次投币的结果来计算 θAθA 和 θBθB 的最大似然估计。

在上图的单次实验中，硬币 AA 被抽到 3 次，30 次投掷中出现了 24 次正面；硬币 BB 被抽到 2 次，20 次投掷中出现了 9 次正面。用最大似然估计可以计算出 θ^A=24/(24+6)=0.8,θ^B=9/(9+11)=0.45θ^A=24/(24+6)=0.8,θ^B=9/(9+11)=0.45。

这样的问题显然没有什么挑战性，可如果作为观测者的我们只能知道每一轮中出现的正反面结果，却不能得知到底选取的硬币到底是 AA 还是 BB，问题可就没那么简单了。

这里的硬币选择就是不能直接观测的隐变量。如果把这个隐变量扔到一边不管，就没有办法估计未知的参数；可要确定这一组隐变量，又得基于未知的硬币重量分布进行最大似然估计。这样一来，问题就进入了“鸡生蛋，蛋生鸡”的死胡同了。

毛主席曾教导我们：“自己动手，丰衣足食”。既然数据中的信息是不完整的，那就人为地给它补充完整。在这个问题中，隐藏的硬币选择和待估计的重量分布，两者确定一个就可以确定另一个。

由于观测结果，也就是正反面出现的次数直接给出了关于重量分布的信息，那就不妨人为设定一组初始化的参数 θ^(t)=(θ^(t)A,θ^(t)B)θ^(t)=(θ^A(t),θ^B(t))，用这组猜测的重量分布去倒推到底每一轮使用的是哪个硬币。

计算出的硬币选择会被用来对原来随机产生的初始化参数进行更新。如果硬币选择的结果是正确的，就可以利用最大似然估计计算出新的参数 hatθ(t+1)hatθ(t+1)。而更新后的参数又可以应用在观测结果上，对硬币选择的结果进行修正，从而形成了“批评 - 自我批评”的循环过程。这个过程会持续到隐藏变量和未知参数的取值都不再发生变化，其结果就是最终的输出。

将上面的思路应用的下图的投掷结果中，就是 EM 算法的雏形。两个初始的参数被随机设定为 θ^(0)A=0.6,θ^(0)B=0.5θ^A(0)=0.6,θ^B(0)=0.5，在这两个参数下出现第一轮结果，也就是 5 正 5 反的概率就可以表示成

P(H5T5|A)=0.65×0.45,P(H5T5|B)=0.510P(H5T5|A)=0.65×0.45,P(H5T5|B)=0.510

对上面的两个似然概率进行归一化可以得出后验概率，两者分别是 0.45 和 0.55，也就是下图中的结果。这说明如果初始的随机参数是准确的，那第一轮结果更可能由硬币 BB 生成。同理也可以计算出其他 4 轮的结果来自不同硬币的后验概率，结果已经在下图中显示。

隐变量未知时，利用 EM 算法求解参数（图片来自 What is the expectation maximization algorithm?）

在已知硬币的选择时，所有正反面的结果都有明确的归属：要么来自 AA 要么来自 BB。利用后验概率可以直接对硬币的选择做出判断：1/4 两轮使用的是硬币 BB，2/3/5 三轮使用的是硬币 AA。

既然硬币的选择已经确定，这时就可以使用最大似然估计，其结果和前文中的最大似然估计结果是相同的，也就是 θ^(1)A=0.8,θ^(1)B=0.45θ^A(1)=0.8,θ^B(1)=0.45。利用这组更新的参数又可以重新计算每一轮次抽取不同硬币的后验概率，你可以自己计算一下。

虽然这种方法能够实现隐变量和参数的动态更新，但它还不是真正的 EM 算法，而是硬输出的 kk 均值聚类。真正的 EM 算法并不会将后验概率最大的值赋给隐变量，而是考虑其所有可能的取值，在概率分布的框架下进行分析。

在前面的例子中，由于第一轮投掷硬币 AA 的可能性是 0.45，那么硬币 AA 对正反面出现次数的贡献就是 45%，在 5 次正面的结果中，来源于硬币 AA 的就是 5×0.45=2.255×0.45=2.25 次，来源于硬币 BB 的则是 2.75 次。同理可以计算出其他轮次中 AA 和 BB 各自的贡献，贡献的比例都和计算出的后验概率相对应。

计算出 AA 和 BB 在不同轮次中的贡献，就可以对未知参数做出更加精确的估计。在 50 次投掷中，硬币 AA 贡献了 21.3 次正面和 8.6 次反面，其参数估计值 θ^(1)A=0.71θ^A(1)=0.71；硬币 BB 贡献了 11.7 次正面和 8.4 次反面，其参数估计值 θ^(1)B=0.58θ^B(1)=0.58。利用这组参数继续迭代更新，就可以计算出最终的估计值。

上面的实例给出了对 EM 算法直观的理解。在数学上，EM 算法通过不断地局部逼近来解决似然概率最大化的问题。

假定模型中未知的参数为 θθ，隐藏的状态变量为 ZZ，输出的因变量为 YY，那么三者就构成了一个马尔可夫链 θ→Z→Yθ→Z→Y。EM 算法相当于是通过 p(z|θ)p(z|θ) 的最大化来简化 p(y|θ)p(y|θ) 的最大化，下面我将以算法在高斯混合模型中的应用来说明这个过程。

顾名思义，高斯混合模型（Gaussian mixture model）是由 KK 个高斯分布混合而成的模型。这个模型在前面的第 20 讲中曾经有所提及，你可以回顾一下。在高斯混合模型中，每个高斯分布的系数 πkπk 可以看成是它出现的概率。模型生成的每个样本都只能来自混合模型中的唯一一个成分，就像每一轮投掷只能使用一枚硬币一样。

作为一个生成模型，高斯混合先按照概率 πkπk 选择第 kk 个高斯分布，再按照这个分布的概率密度采出一个样本，因此高斯分布的选择和样本的取值共同构成了混合模型的完备数据（complete data）。但从观察者的角度看，分布的选择是在生成数据的黑箱里完成的，所以需要用隐变量 zz 来定义，单独的观测数据 xx 就只能构成不完备数据（incomplete data）。

对高斯混合模型的学习就是在给定不完备数据 XX 时，估计模型中所有的 πkπk、μkμk 和 σkσk，这些未知的参数可以统称为 θθ。最优的参数 θθ 应该让对数似然函数 logp(X|θ)log⁡p(X|θ) 最大化，其数学表达式可以写成

L(θ|X)=logp(X|θ)=log∏n=1Np(xn|θ)=∑n=1Nlog(∑k=1KπkN(xn|μk,Σk))L(θ|X)=log⁡p(X|θ)=log⁡∏n=1Np(xn|θ)=∑n=1Nlog⁡(∑k=1KπkN(xn|μk,Σk))

可以看到，上面的表达式涉及对求和项计算对数，这对于求解极值来说颇为棘手。好在我们还有隐变量，虽说混合模型中存在若干个成分，但落实到单个样本上，每个样本只由其中的一个高斯分布产生。

引入隐变量能够确定这个唯一的分布，也就是去掉上面表达式中对成分 kk 的求和，从而避免对求和项的复杂对数运算。如果已知每个样本 xnxn 所对应的隐变量 znk=1znk=1，那就意味着第 nn 个样本由第 kk 个混合成分产生，上面的表达式就可以简化为

L(θ|X,Z)=∑n=1NlogπkN(xn|μk,Σk)L(θ|X,Z)=∑n=1Nlog⁡πkN(xn|μk,Σk)

但隐变量本身也是随机变量，只能用概率描述。如果将参数当前的估计值 θ(t)θ(t) 看作真实值，它就可以和不完备数据结合起来，用于估计隐变量的分布。隐变量的分布可以利用贝叶斯定理计算，将混合参数 πkπk 看作先验概率，单个的高斯分布 N(μk,Σk)N(μk,Σk) 看作似然概率，就不难计算出隐变量 znkznk 关于 kk 的后验概率

p(znk|xn,θ(t))=πkN(xn|θ(t))∑j=1KπjN(xn|θ(t))p(znk|xn,θ(t))=πkN(xn|θ(t))∑j=1KπjN(xn|θ(t))

如果你对第 20 讲的内容还有印象，就会发现这个后验概率就是其中提到的 " 责任 γnkγnk"，其意义是第 kk 个高斯分布对样本的响应度（responsibility）。由于这里计算出的后验是随机变量 znk=1znk=1 的概率，它实际上代表的就是 znkznk 的数学期望。

有了隐变量的后验概率，就可以将它代入到基于完备信息的对数似然概率中，通过求和对隐变量进行边际化的处理。求出的目标对数似然 L(θ|X,Z)L(θ|X,Z) 关于隐变量 ZZ 的数学期望也叫作 QQ 函数，其数学表达式为

Q(θ,θ(t))=∑Zp(Z|X,θ(t))L(θ|X,Z)Q(θ,θ(t))=∑Zp(Z|X,θ(t))L(θ|X,Z)

其中 p(Z|X,θ(t))=∏Nn=1p(znk|xn,θ(t))p(Z|X,θ(t))=∏n=1Np(znk|xn,θ(t))。

将对隐变量求解数学期望和对每个样本对数似然求和的顺序调转，也就是先针对每个样本求出期望，再将所有期望值求和，就可以得到完备数据下对数似然的数学期望

Q(θ,θ(t))=∑n=1N∑k=1Kγnk[logπk+logN(xn|μk,Σk)]Q(θ,θ(t))=∑n=1N∑k=1Kγnk[log⁡πk+log⁡N(xn|μk,Σk)]

这是期望步骤的最终结果。接下来的最大化步骤需要找到让上面的表达式最大化的新参数 θ(t+1)θ(t+1)，这只需要对 πkπk、μkμk 和 ΣkΣk 分别求偏导数就可以了。

在 Scikit-learn 中，EM 算法被内嵌在 mixture 模块中的 GaussianMixture 类中，调用这个类就调用了 EM 算法。用 GaussianMixture 类对 20 支英超球队的聚类数据进行分类，得到的结果如下图所示，其中不同的高斯分布用不同颜色的椭圆表示。可以看出，每个高斯分布都由相距较近的点组成。

你可以将高斯混合模型的结果和 20 讲中 kk 均值的结果作一比较，观察硬聚类和软聚类的区别。

英超球队的高斯混合聚类结果

今天我和你分享了期望最大化算法的基本原理，及其在高斯混合模型中的应用，包含以下四个要点：

期望最大化算法通过迭代来求解令观测结果似然概率最大化的未知参数；

期望步骤计算完备数据的似然概率关于隐变量的数学期望；

最大化步骤通过最大化期望步骤的结果来计算新的参数估计值；

期望最大化算法主要用于高斯混合模型等含有隐变量的概率图模型的学习。

除了高斯混合模型之外，对隐马尔可夫网络的学习也需要使用 EM 算法。在隐马尔可夫的文献中，EM 算法通常被称为 Baum-Welch 算法（Baum-Welch algorithm）。两者虽然名称不同，但原理是一样的。

你可以参考维基百科等资料，了解 Baum-Welch 算法的特点，并在这里分享你的见解。

40 | 结构学习：基于约束与基于评分

看完了参数学习，我们再来看看结构学习。

结构学习（structure learning）的任务是找到与数据匹配度最高的网络结构，需要同时学习未知图模型的结构和参数。这也很容易理解：模型的结构都不知道，参数自然也是不知道的，所以需要一并来学习。结构学习的任务是根据训练数据集找到结构最恰当的模型，这无疑比参数学习要复杂得多，也有更多的不确定性。

对图模型进行结构学习的目的有两个。一方面在于知识发现（knowledge discovery），根据因变量的结果来判定自变量之间的依赖关系；另一方面则在于密度估计（density estimation），估计出数据分布的特性，据此对新样本进行推断。

对图模型进行结构学习有哪些方法呢？主要有三种，分别是基于约束的学习、基于评分的学习和基于回归的学习，这三种方法都可以应用在有向的贝叶斯网络和无向的马尔可夫随机场中，但在下面的介绍中我将以较为简单的贝叶斯网络为例。

基于约束的结构学习（constraint-based structure learning）将贝叶斯网络视为条件独立性的表示，与贝叶斯网络的语义非常贴近。这种方法首先从数据中识别出一组条件独立性作为约束，然后尝试找到最符合这些约束的网络结构。基于约束的学习与贝叶斯网络的结构特征密切相关，但它缺乏类似于似然函数的显式目标函数，因而不能直接找到全局的最优结构，也就不适用于概率框架。

基于约束的典型算法是 SGS 算法，这个名字来源于三位设计者的首字母缩写。SGS 采用遍历式的方法来判定结点之间是否应该有边存在，它首先在结点集合上构造出全连接的无向图，再对图中多余的边做出删减。具体的做法是判断选出的两个节点 i,ji,j 在给定其他所有结点的条件下是否条件独立，如果存在让 ii 和 jj 满足 dd 分离性的结点子集，那就把 ii 和 jj 之间的边去掉。对所有的结点对都进行上述操作，就可以删除冗余边，得到新的简化无向图。

上面的步骤只能确定边的存在性，要形成贝叶斯网络还得给通过审核的每条边确定方向。定向的方法是找到所有具有 i−j−ki−j−k 形式，也就是两端的结点互不相连、但都与中间结点相连接的结点三元组，并判断 ii 和 kk 之间的条件独立性。当且仅当 ii 和 kk 无论如何都不满足 dd 分离性时，将这个三元组定义成汇连结构 i→j←ki→j←k。

对所有的三元组都进行完上面的检测之后，接下来要重复以下步骤：如果三元组具有 i→j−ki→j−k 的形式，同时 jj 又没有指向其他结点的有向边，那就直接添加一条从 jj 到 kk 的有向边 j→kj→k；如果 ii 和 jj 之间存在未确定方向的边，同时还有从 ii 出发经过其他结点到 jj 的有向路径，那么两者之间的无向边就被定向为 i→ji→j。当以上步骤重复到没有新边需要定向时，图模型的结构就确定了。

SGS 算法最大的问题在于运算复杂度，其运算量会随着结点数目的增加以超指数的方式增长，因而不具备可扩展性。除了计算问题之外，SGS 算法在可靠性上也有缺陷，其确定高阶条件独立关系的可靠性远不如低阶独立关系。在 SGS 算法的基础上还衍生出了 PC 算法和针对大规模网络的增长 - 收缩算法（grow-shrinkage algorithm），在此就不赘述了。

与基于约束的学习不同，基于评分的结构学习（score-based structure learning）把结构学习问题处理为模型选择问题。这种学习方法将图模型与数据的匹配程度定义为评分函数（score function），再在所有可能的结构中搜索出评分最高的那个作为结果。

基于评分的学习的首要任务是选择合适的评分函数。评分函数决定了数据和结构之间的拟合程度，必须要满足评分等价性和可分解性两个条件。评分等价性指的是独立性关系相同的等价网络所获得的分数应该相同，可分解性指的则是评分函数能够被分解为多个子函数的累加，每个子函数对应一个局部结构，一个结构的变化不会影响其他结构部分的分数。

定义评分函数的常见出发点是信息论，如果将学习问题看作最优编码问题，就可以定义出最小描述长度作为评分函数。

最小描述长度（minimal description length）借鉴了信息熵的概念，其目标是找到一个能以最短编码长度描述训练数据的模型。

计算出的模型长度包括两部分，一部分用来描述贝叶斯网络本身，其字节数取决于参数个数；另一部分用于描述用这个网络表示的数据，其字节数取决于数据在模型下的似然概率。

网络中的参数越多，似然概率的表示就越精确，但过拟合的风险也会越大。两者的折中就是模型复杂性与模型表示样本的准确性之间的平衡这个老生常谈的问题。

除了最小描述长度之外，赤池信息量准则（Akaike information criterion）和贝叶斯信息量准则（Bayesian information criterion）也是基于信息论的评分函数，它们都将评分表示成“模型 + 数据”的组合，其形式可以看成是给模型下的对数似然概率 lnLln⁡L 添加了和模型参数数目有关的正则化项。

赤池信息量准则的正则化项是参数数目 kk 乘以常数系数，而贝叶斯信息量准则的正则化项则是参数数目 kk 乘以样本容量 nn 的对数，两者的数学表达式为

AIC=2k−2lnL,BIC=klnn−2lnLAIC=2k−2ln⁡L,BIC=kln⁡n−2ln⁡L

和最小描述长度一样，这两个指标也是越小越好。

在设计评分函数时，如果将数据和模型融合在一起，得到的评分函数就是贝叶斯狄利克雷评分（Bayesian Dirichelet），这个函数可以写成对狄利克雷分布的求和。

贝叶斯狄利克雷评分是在已知结构时通过计算样本数据的边际似然函数作为评分的依据，计算时假定贝叶斯网络的参数服从狄利克雷形式的先验分布。利用似然等价性约束，也就是等价结构获得的分数相同可以对贝叶斯狄利克雷评分做出改进，这一改进就相当于计算模型关于样本集的后验概率。

选定了合适的评分函数后，接下来就要在假设空间中搜索这个评分函数上的最优解。由于评估所有备选结构的分数难以实现，因此在搜索时，通常使用启发式算法来查找次优结构。贪婪搜索、遗传算法、进化规划、模拟退火算法和蚁群算法等启发式算法都可以应用在最优结构的搜索中。

将贪婪搜索应用在结构学习中时，需要先初始化一个网络结构，以它为蓝本每次对一条边进行增加、删除或者改变方向，直到新结构的评分函数值不再降低为止。要进一步简化运算量，还可以对图结构施加额外的约束以削减假设空间，这相当于又引入了一重先验。

和前面两位老大哥相比，基于回归的结构学习（regression-based structure learning）至少从资历上说还是个小弟。这类算法的出发点是将目标函数表示为图模型参数的线性组合，再对线性模型进行 L1L1 或 L2L2 正则化处理来控制模型的复杂度。其优势在于可以确保目标函数最优解的存在性，明确了学习问题的意义，同时还具有良好的可扩展性。

基于回归的不同方法之间的区别在于目标函数的不同。最直接的方式是将图结构关于数据的对数似然定义为目标函数，并使用拉普拉斯先验来简化模型。结点之间的独立性也可以用 LASSO 回归来估计，这通常被应用于建模连续变量的高斯图模型（Gaussian graphical model）中，其任务是确定给定结点的马尔可夫毯，线性系数不为 0 的其他结点和目标结点之间都存在依赖关系。

将回归模型与评分函数相结合，还可以把最小描述长度表示为参数的线性组合，对其进行优化以确定模型结构。关于这些方法的具体细节在此就不作介绍了。

上面所介绍的方法都是建立在完全观测数据的基础上的。如果模型中存在隐变量，结构学习的难度也会大大增加。将专门处理隐变量的 EM 算法引入到结构学习之中，得到的就是结构 EM（Structural EM）算法。

结构 EM 算法在具有结构和参数两个维度的假设空间内进行搜索，在每一轮次的搜索中，原始的 EM 算法是为固定的模型更新参数，结构 EM 算法则同时更新参数和模型，更新的方式是让模型的评分函数最大化，评分函数的选择是参数关于模型后验概率的信息熵，当然也可以使用贝叶斯信息量准则或者最小描述长度这类指标。

今天我以贝叶斯网络为例，和你分享了概率图模型中的结构学习任务，包含以下四个要点：

结构学习的任务是找到与数据匹配度最高的网络结构，需要同时确定图模型的结构和参数；

基于约束的结构学习通过条件独立性的约束确定贝叶斯网络的结构，需要先后确定边的存在性和方向；

基于评分的结构学习通过数据和结构的匹配度确定贝叶斯网络的结构，包括选择评分函数和搜索最优结构两个步骤；

对不完备数据实施结构学习可以使用结构 EM 算法。

本讲中介绍的方法都是频率主义下的方法。要使用贝叶斯来进行结构学习，就得先给所有备选模型和所有参数设定先验，再用训练数据去调整先验。显然，这类方法要在所有可能的模型中进行搜索比较，其实用性非常差。

简化贝叶斯结构学习的方式有两种，一种叫贝叶斯模型选择（Bayesian model selection），直接选择最像的模型当作真实模型来使用；另一种叫选择性贝叶斯模型平均（selective Bayesian model averaging），将搜索的范围限制在人为选定的一组模型之中。

关于贝叶斯结构学习更多的细节，你可以查阅资料，了解它的思想与方法，并在这里分享你的见解。

总结课 | 贝叶斯学习的模型体系

在今天这篇总结中，我将对贝叶斯机器学习中涉及的模型做一个系统的梳理。虽然这个模块的主题是概率图模型，内容也围绕着概率图的三大问题——表示、推断和学习展开，但概率图归根结底是手段，其目的是将概率分布用图结构表示出来，进而从贝叶斯定理出发，从概率角度解决机器学习的问题。因此从宏观的角度来对概率模型加以整理是很有必要的。

概率模型基本上都属于生成模型，它们可以建模数据的生成机制，这和统计机器学习以判别模型为主的特色形成鲜明的对比。在统计学习中，几乎所有模型都可以追溯到线性回归的演化，在贝叶斯学习里，起到万物之源作用的是具有最大不确定性的高斯分布，对高斯分布的不同处理方式决定了不同的数据生成方式。

在观察高斯分布的演化时，不妨先从外部入手。最简单的外部拓展方法就是混合，将多个不同数字特征的高斯分布混杂在一起，先按一定概率抽取成分，再根据选定的成分分布生成数据，这种生成模型就是高斯混合模型。在高斯混合模型里，决定每个时刻的观察结果到底来自哪个成分的变量不能被直接观测，因而是隐变量。

除了横向意义上的混合之外，纵向意义上的时序也是外部演化的常见手段，这相当于在数据序列中引入马尔可夫性。如果给高斯混合模型中的隐变量添加时序关系，让下一时刻的状态依赖于这一时刻的状态，就形成了隐马尔可夫模型。如果隐马尔可夫模型的状态数目从有限扩展到无穷多，又形成了线性动态系统。

看完了外部拓展，再来看看内部拓展。贝叶斯模型的内部改进与统计模型类似，无外乎非线性化、局部化和稀疏化三种方式。非线性化改造容易理解，它是将状态转移和状态到观测的关系建模为非线性关系，可以得到非线性动态系统。但这类非线性系统难以求出解析解，也得进行线性的近似。

在概率模型中，稀疏化，也就是降维的最典型方法是因子分析（factor analysis）。因子分析的任务是构造因子模型，将去均值后的观测结果表示成一组公因子（common factor）的线性组合。比如在分析学生的成绩时，物理 / 化学 / 生物这几门课程之间会存在较强的相关性，政治 / 历史 / 地理这几门课程也会存在较强的相关性，物理 / 政治、化学 / 历史之间的相关性就会较弱，这样的相关关系就可以用理科和文科两个互不相关的公因子来刻画。

不难看出，公因子的作用类似高斯混合模型中的隐变量，但它可以起到降维的作用，前面介绍过的主成分分析就可以看成是因子分析的一种实现方式。如果对线性的因子分析做非线性处理，得到的就是独立成分分析。独立成分分析并不强制要求所有源信号以线性方式混合，因而可以作为非线性模型出现。

概率模型的局部化并非将整个定义域上的概率分布打散成若干局部的组合，而是直接一步到位地进化到分布式表示，其直接的结果是矢量量化（vector quantization）。矢量量化和统计学习中的聚类类似，将它添加一个隐藏层就是自编码器。如果将矢量量化的编码结果进行层次化的堆叠，那就形成了玻尔兹曼机——深度学习的早期模型之一。

高斯分布演化出来的模型可以作为基础模型应用到外部的组合中。比如对独立成分分析的结果进行层次化组合，可以得到非线性的高斯网络；对多个隐马尔可夫模型进行混合，可以得到混合隐马尔可夫模型；给矢量量化过程引入时序，实现的又是因子化的隐马尔可夫模型。正所谓一生二、二生三、三生万物，有了基础模型和基本方法，各种复杂的模型就都可以被串联起来。

关于这些具体模型的推断与学习方法推荐阅读发表在《神经计算》（Neural Computation）第 11 卷第 2 期上的文章《线性高斯模型的大一统综述》（A Unifying Review of Linear Gaussian Models），这是一篇非常好的综述文章。

贝叶斯学习模型鸟瞰图

从概率图模型和贝叶斯机器学习的体系出发，我向你推荐以下的参考书。

《贝叶斯方法》（Bayesian Methods for Hackers），卡梅隆·戴维森 - 皮隆（Cameron Davidson-Pilon）

《贝叶斯思维》（Think Bayes），艾伦·唐尼（Allen B. Downey）

这两本书是贝叶斯概率理论的入门读物，它们不像学院派的教材那样用冗长的公式和复杂的符号让人望而却步，而是通过更加贴近生活的实例来传递贝叶斯理论的核心要义，读起来比较轻松。这两本书能带给你关于贝叶斯直观而感性的认识，让艰深的理论看起来没那么晦涩。

《贝叶斯统计方法》（Doing Bayesian Data Analysis），约翰·克鲁斯克（John K. Kruschke）

《贝叶斯数据分析》（Bayesian Data Analysis），安德鲁·格尔曼等（Andrew Gelman, et. al.）

这两本书是将贝叶斯的思想用于统计学和数据分析的进阶读物，其中前者侧重于贝叶斯的统计学，后者侧重于贝叶斯的数据分析，与机器学习结合得更加紧密。和前面两本小书相比，这两本称得上是大部头，两者结合形成了对贝叶斯概率应用的全面图景。

《概率图模型》（Probabilistic Graphical Models），达芙妮·科勒 & 尼尔·弗里德曼（Daphne Koller, Nir Friedman）

《贝叶斯推理与机器学习》（Bayesian Reasoning and Machine Learning），大卫·巴伯（David Barber）

如果说上面两本书是大部头，那《概率图模型》就称得上皇皇巨著了。和《机器学习：概率视角》一样，它也是适用于有问题时查阅的百科全书式教材，当作教材的体验并不理想。后面这一部虽然篇幅小了很多，难度却不遑多让。但这两本大书都是干货满满，如果能花时间深入学习，定能带你从量变走向质变。

行文至此，机器学习这个专栏已经走到尾声。这 40 篇文章是否带给你些许收获，你又对机器学习产生了哪些新的认识呢？欢迎你留言和我讨论。

结课 | 终有一天，你将为今天的付出骄傲

不知不觉间，又一个 40 期的机器学习专栏也走到了尾声。在专栏里，我从理解概率的两大流派入手，以每种流派中的各个模型为主线，对统计机器学习和贝叶斯机器学习做了系统的介绍，并从这些模型中梳理出它们之间关系的脉络，帮助你尽可能地从更加宏观的角度来理解模型内部的关联。

内容：由博返约求精深

和上一季的“人工智能基础课”相比，这一季专栏的内容聚焦于机器学习一点，力求更加深入地挖掘这个主题。增加深度意味着提升难度，无论是写作的我还是阅读的你，都需要投入更多的时间和精力去理解与消化。

理解事物时，我们都习惯从感性认知入手，可要从感性认知进化为理性思辨，你还是不得不和那些恼人的符号和讨厌的公式打交道。然而这是学习的必经之路：直观而具体的认识虽然容易理解，其适用范围却相当有限，要解决现实问题就必须将认识上升到知识的高度，而知识的价值恰恰就蕴含在复杂的公式所体现出的规律之中。

具有普适性的抽象规律，才具有学习的价值。在机器学习中，各种各样的模型某种程度而言其实也是简单具体的实例，诸如局部化和集成化之类的方法才是支配模型演变的规律。正是这些规律与统计学习的理论相结合，才让机器学习变得魅力无穷。

收获：见贤思齐多自省

工作上的职责所在让我接触了很多关于教学的文献与范例，其中一些国内外教学名家的课程堪称醍醐灌顶。虽然学科有所区别，但这些大师总能深入浅出、化繁为简，将深奥的道理以老妪能懂的形式清晰而准确地解释出来。体验这些大师的授课是种享受，在艰辛的求索中感受到一丝如沐春风的惬意。

罗马不是一天建成的，大师们的举重若轻也是来源于多年积累的深厚功底。博学多闻才能融会贯通，只有将广博的专业知识和精湛的教学技艺相结合，方能达到这样的境界。在我自己的角度看，从这个专栏得到的最大收获便是一份鞭策，它在不断提醒我对自己的提升依然任重而道远。

启示：莫道前路多崎岖

最近几年，所谓的“一万小时”理论声名鹊起，甚至被人奉为圭臬。可是在我看来，它无非说明了一个再简单不过的道理：有付出才有收获。究竟练习了一万小时还是两万小时并不是关键，关键在于填满这时间的努力。如果你天赋异禀外加勤于思考，两千个小时可能就足以成为高手；可要是像学弈时净想着射落天鹅的那个小孩一样，怕是十万个小时也是白搭。

之所以要花费这么多的努力和时间，是因为没有任何学问是简单的。如果以玩儿票的态度对待新知，那大可不必为此大费思量；可是要深入学习一门学问的话，这样的痛苦就是必经之路，奢求速成的捷径百分之百徒劳无功。

任何一个成熟的学科都是诸多天才前辈智慧的结晶，如果这些天赋异禀之人尚且需要劈波斩浪，平凡的我辈便只有更加努力，才能在浩瀚的学海中求得生存。只有经过一波又一波惊涛骇浪的洗礼，才有资格去欣赏对岸无双的美景。

不经历风雨，怎能见彩虹，没有人能随随便便成功。终有一天，你将为今天的付出骄傲，加油！