查看全课大纲(第 53 / 82 节)
- 1.函数与数据泛化
- 2.向量:从几何直觉到高维空间
- 3.矩阵与张量
- 4.特征值与特征向量:矩阵变换的不动方向
- 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
- 6.概率与统计:机器学习的数学基础
- 7.独立性与随机变量:贝叶斯公式与二项分布
- 8.期望、方差与协方差:随机变量的数字画像
- 9.联合概率:当一条轴不够用的时候
- 10.概率分布(一):从伯努利到伽马函数
- 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
- 12.机器学习的模型:找输入与输出的关系
- 13.机器学习的应用
- 14.过拟合
- 15.机器学习的分类
- 16.有监督学习:从房价预测说起
- 17.损失函数
- 18.梯度下降(上):更新规则与学习速率
- 19.梯度下降(2)
- 20.牛顿方法
- 21.KNN简介
- 22.距离测算
- 23.朴素贝叶斯
- 24.朴素贝叶斯的实际应用
- 25.信息熵:决策树构建的度量基础
- 26.信息增益与决策树的构建
- 27.ID3算法
- 28.决策树节点的划分
- 29.CART树
- 30.Bagging
- 31.Boosting:自适应提升算法
- 32.Gradient Boosting
- 33.线性模型:回归与分类的同一副骨架
- 34.最小二乘:把最优参数直接解出来
- 35.最小二乘法的几何与概率视角
- 36.极大似然:给最小二乘一个概率出身
- 37.逻辑回归(1):把线性模型接到分类上
- 38.逻辑回归(2):损失函数与多分类
- 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
- 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
- 41.优化方法(1):坐标下降与前向选择
- 42.优化方法(2):前向策略与最小角回归
- 43.拉格朗日乘子法(1):从无约束到等式约束
- 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
- 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
- 46.最大间隔:把分类问题变成优化问题
- 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
- 48.支持向量:边界上的少数派
- 49.SVM 计算过程:一笔到底算完,再走进核方法
- 50.贝叶斯公式:概率即信念
- 51.隐含变量和概率模型:给看不见的原因建模
- 52.EM 算法:期望与最大化的迭代
- 53.琴生不等式:EM 的数学钥匙
- 54.三个硬币问题:EM 的复盘与衔接
- 55.高斯混合模型:用隐变量解释双峰数据
- 56.隐马尔可夫模型
- 57.隐马尔可夫模型(2):前向算法与动态混合模型
- 58.隐马尔可夫模型在 NLP 中的运用
- 59.EM 算法:把「为什么收敛」推到底
- 60.HMM 在 NLP 中的运用:从分词到机器翻译
- 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
- 62.高维下的高斯模型
- 63.主题模型:从词袋到隐含主题
- 64.Dirichlet 分布(1)
- 65.Dirichlet 分布(2)
- 66.统计学习内容回顾
- 67.K-means 算法
- 68.PCA 降维
- 69.SVD 降维
- 70.从聚类到流形
- 71.局部线性嵌入
- 72.随机邻域嵌入:SNE 与 t-SNE
- 73.无参模型:让数据自己说话
- 74.高斯过程:函数空间里的正态分布
- 75.高斯过程(2):噪声、正则化与核的线性组合
- 76.神经网络简介:从感知器到自编码器
- 77.反向传播:把误差一层层传回去
- 78.卷积神经网络(CNN):让特征自己学出来
- 79.循环神经网络(RNN):给网络装上记忆
- 80.深度学习回顾:静态一类,动态一类
- 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
- 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传
琴生不等式:EM 的数学钥匙
约 23 分钟
小象实战讲义 · 机器学习算法精讲
上一节的三硬币例子把 EM 算法「跑」通了:E 步算 、M 步按比例数红绿,转起来就能估参数。但还有一个问题没有回答:凭什么这样转,每一步都「不亏」?这一节回过头来补上性质背后的道理——讲师开场的说法是:大家先知道什么是 EM 算法,我们再说这些性质;有很多人先讲了它的性质,而并不知道为什么。先会用了,再来看为什么——钥匙是一把很老的不等式:琴生不等式(Jensen’s inequality)。它关心的只是极简单的一件事:一个函数的期望,和一个期望的函数,谁大谁小。
💡 核心导读
- 琴生不等式: 与 谁大谁小——凸函数(碗口朝上)前者大,凹函数(包括 )后者大。一张「弦与碗」的图就能记住方向。
- 下界构造:给似然乘上再除以一个隐变量分布 ,「 里的求和」变成「求和里的 」——等式变不等式,得到 EM 要优化的下界。
- E 步的本质: 取后验分布时琴生取等号、下界最紧——上一节算的 正是这个 。
- M 步的本质:固定 、最大化下界——三硬币里「按比例数红绿」的三个分式就是它。
- 单调性:似然永远压着下界;M 步抬下界,似然跟着抬——EM 每次迭代都不亏。
函数的期望 vs 期望的函数
先认识两个词(讲师特意点名):Convex 是凸函数,Concave 是凹函数——别记反了。凸函数的图像像一只碗,碗口朝上;凹函数正相反,碗口朝下。
琴生不等式问的问题:随机变量 经过函数 ,函数的期望 和期望的函数 ,谁大?用讲师的直观图走一遍。
取一个凸函数 ,在横轴上取两个值 和 :
- 先求 和 ——它们是曲线上的两个点。假设 均匀地取 、 两个值,那 就是 、 的均值——落在连接这两点的弦的中点上;
- 再看期望的函数: 是 、 的中点, 是曲线上对应这个中点的值。
凸函数碗口朝上,弦在曲线的上方——弦的中点要比曲线「高出这么一块」。所以对凸函数:
函数的期望,比期望的函数要大。 凹函数正好相反(碗口朝下,弦在曲线下方,「期望的函数在这个包的上面」):
课件给了一个很实用的建议:很多人记不住不等号往哪边开——记住这张「弦与碗」的图,立刻就能想起来。
把讲师的直观图落成代码(两点均匀分布,凸用 ,凹用 ——EM 真正要用到的就是 ):
import math
# 讲师的直观图: X 等概率取 a 和 b 两点(均匀)
a, b = 1, 4
EX = (a + b) / 2 # E[X]: a、b 的中点
# 凸函数 f(x) = x^2 —— 碗口朝上的碗
Efx_convex = (a**2 + b**2) / 2 # E[f(X)]: 弦的中点高度
fEX_convex = EX**2 # f(E[X]): 曲线在中点处的高度
# 凹函数 f(x) = log(x) —— EM 真正要用到的那个
Efx_concave = (math.log(a) + math.log(b)) / 2
fEX_concave = math.log(EX)
print(f"a = {a}, b = {b}, 均匀两点的 E[X] = (a+b)/2 = {EX}")
print()
print("凸函数 f(x) = x^2 (碗口朝上):")
print(f" 函数的期望 E[f(X)] = (a^2 + b^2)/2 = {Efx_convex:.4f} <- 弦的中点")
print(f" 期望的函数 f(E[X]) = ((a+b)/2)^2 = {fEX_convex:.4f} <- 曲线上的点")
print(f" E[f(X)] - f(E[X]) = {Efx_convex - fEX_convex:.4f} (函数的期望更大)")
print()
print("凹函数 f(x) = log(x) (碗口朝下):")
print(f" 函数的期望 E[f(X)] = (ln(a) + ln(b))/2 = {Efx_concave:.4f} <- 弦的中点")
print(f" 期望的函数 f(E[X]) = ln((a+b)/2) = {fEX_concave:.4f} <- 曲线上的点")
print(f" f(E[X]) - E[f(X)] = {fEX_concave - Efx_concave:.4f} (期望的函数更大)")a = 1, b = 4, 均匀两点的 E[X] = (a+b)/2 = 2.5
凸函数 f(x) = x^2 (碗口朝上):
函数的期望 E[f(X)] = (a^2 + b^2)/2 = 8.5000 <- 弦的中点
期望的函数 f(E[X]) = ((a+b)/2)^2 = 6.2500 <- 曲线上的点
E[f(X)] - f(E[X]) = 2.2500 (函数的期望更大)
凹函数 f(x) = log(x) (碗口朝下):
函数的期望 E[f(X)] = (ln(a) + ln(b))/2 = 0.6931 <- 弦的中点
期望的函数 f(E[X]) = ln((a+b)/2) = 0.9163 <- 曲线上的点
f(E[X]) - E[f(X)] = 0.2231 (期望的函数更大)四行数字全部可以手算复核:、,凸函数高出 ;、,凹函数低了 。两个方向都亲眼看到了,琴生不等式就没有神秘感了——差距的全部来源,就是那条弦不贴着曲线。
从极大似然到下界:乘除一个 Q
回到 EM 的舞台。求极大似然时,我们习惯取对数似然:
三笔记号先说清(都是讲师原话的点):
- 上角标 只是样本编号:因为 的 从 1 到大 ,所以加了个上角标——「大家不用关心这上角标是什么」,也别和上一节迭代轮次的裸上角标()混了;
- 课件用 、我们用 :课件原文是 个独立样本,讲师全程用大 ——本讲义统一用 ;
- 分号与竖线是一回事:课件的传统写法是分号 (把 当参数),讲师爱写成条件概率 ——两者一样,不用纠结。
困难在哪?在于我们面对的是有隐含变量的模型。把上一节的边缘化加进来:
于是对数似然变成「 的里面套着一个求和」——正是这个嵌套让直接优化很费劲。EM 的策略(课件原话):反复构造 的一个下界(E 步),然后优化这个下界(M 步)。
第一步:乘上再除以一个 。 给每个样本引入关于隐变量的概率分布 (满足加和为 1),在求和号里同时乘上、除以它:
值没有变——乘除相消。但先在这里停一下,认一认老朋友:上一节三硬币里算的 ,就是这个 。 取 0 或 1,代表这一次结果属于硬币 B 还是硬币 C;「它属于 B 的概率是多大」——那个概率就是我们求过的 。 就是对 的泛化:一个关于隐变量的分布。
第二步:看出期望。 求和号里, 是分布、 是关于 的函数——带权重的求和就是期望。 的外面套着一个期望。
第三步:用琴生。 是什么函数?凹函数——碗口朝下。凹函数下期望的函数要大,所以:
期望可以放到 里面去——代价是从等式变成不等式:
这一步的形态变化看清楚: 从「套着求和」变成了「咬着每一项」。右边这个 ,就是整个 EM 算法的下界。为什么它好优化?因为 直接作用在联合概率 上,不再有求和挡在中间。
而它的用处在于:极大似然 永远压在下界上方——把下界不断增大,极大似然函数也就会不断提高。所以接下来要做的,就是优化这个下界。
选什么样的 Q:越「均匀」越紧
下界是 的函数—— 有无穷多种选法,选哪个?讲师给了一段很直觉的论证。
求很多函数的期望时,什么时候最大?——均匀的时候。 若有三种取值,取 的时候期望最大;四种取值,就是 。这里讲师用了一个老朋友作类比(第 6 章决策树):取 的时候,熵才是最大的;取 或其他分配,熵都更小——均匀的时候熵最大,跟这里是同一个直觉。课件也把这一页标题直接写成 Tight Bound(Maximum Entropy,紧界与最大熵)。
「均匀」翻译成精确条件是什么?就是让圈里那个函数 每个取值都相等——课件写成一串:。这时候这个比值等于一个常数 :期望取在一个「常数取值的随机变量」上,弦贴住曲线,琴生不等式取等号,下界最紧。
比值是常数,意味着分子分母成正比: 正比于 。再补上「 是分布、加和为 1」这个约束——做一次归一化:分子放上联合概率,分母把所有 连加:
(分母那个连加,不就变回 了吗。)最好的 ,就是给定当前观测与当前参数时,隐变量的后验分布。
到这里,EM 的两步就有了正式身份:
- E 步:给定 ,对 做估计——取后验,使下界最紧(「使它均匀的时候才是最好」);
- M 步:给定这个 ,优化 使下界最大。
两者不断叠加:用 求 ,再用 求下一步的 ,再用新的 求 ……不断循环,就得到了 EM 算法。
把公式带回三硬币
讲师在这里特意嘱咐:只讲公式是比较晦涩的——把公式换成刚才举的例子,大家就更能理解了。那就换回去:
- 就是 :上一节对每个观测算的「由 B 掷出来的概率」,就是本节推导里的 ;
- M 步就是数红绿:有了 的估计,直接乘上每一次的概率密度去数数(这里已经不需要 了)——给定 ,求每个参数的最优解。、、 各有一个公式,正是上一节那三个分式;
- 泛化的说法:给定一个关于 的关系,怎么去优化、选择最好的 ——这就是 M 步。
所以 EM 算法分成两个主要的部分,而且它是不断增加的——它所做的事情,就是不断提升那个下界。
绿色曲线:一步一格往上抬
课件里有一张经典的图(Illustration of EM Updating),讲师对着它把整个过程讲了一遍:
我们最期望做的,是求极大似然 这个函数的最大值(板书花絮:讲师特意纠正——「这是 ,不是 LB, 写快了看着像 B 一样」)。直接优化它很难,于是:
- 给定当前的 ,画一条绿色的下界曲线——这条曲线的位置是可以调整的(调整 );
- E 步:把绿色曲线往上提升,直到它在当前 这一点贴住 ——选择什么样的 会使它最大,就把下界移到哪里;
- M 步:沿着这条已经贴好的曲线去优化 ——「把 沿着目前优化好的函数再优化一部分,变成 」;
- 到了新的点,重新构造一条新的下界,再调整、再优化……
一步一步挪过去,最后到达最优的 。图里画的例子是高斯混合模型(GMM)——下一章继续展开。
把这套「接力」写成一个不等式链,就是「每步不亏」的完整证明:
第一个 是琴生不等式(似然压着下界);中间的 是 M 步(新参数让下界不降);最后的等号是 E 步(后验让下界贴住似然)。三个环节各司其职——下界被抬高的每一步,似然都只能跟着往上走。
回到三硬币,把这一格楼梯亲手走一遍(观测取课件第 21 页那串掷硬币记录 HTHHTTHHTHTHTTTHTHTTH,正面 10 次、反面 11 次;初始参数沿用上一节「随便给 0.3、0.4、0.7 都可以」):
import math
# 回到三硬币例子: 观测取课件第 21 页的掷硬币记录 HTHHTTHHTHTHTTTHTHTTH (H=1, T=0)
obs = [1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1]
def ell(pi, p, q):
"""对数似然: log 里面是求和(优化困难的根源)"""
total = 0.0
for x in obs:
joint_b = pi * p**x * (1 - p)**(1 - x) # P(x, z=1)
joint_c = (1 - pi) * q**x * (1 - q)**(1 - x) # P(x, z=0)
total += math.log(joint_b + joint_c)
return total
def lower_bound(pi, p, q, qz1_list):
"""下界: log 直接咬在每个联合概率上(优化变容易的形态)"""
total = 0.0
for x, qz1 in zip(obs, qz1_list):
joint_b = pi * p**x * (1 - p)**(1 - x)
joint_c = (1 - pi) * q**x * (1 - q)**(1 - x)
total += qz1 * math.log(joint_b / qz1)
total += (1 - qz1) * math.log(joint_c / (1 - qz1))
return total
# 随机给定初始参数(上一节: 随便给 0.3、0.4、0.7 都可以)
pi_old, p_old, q_old = 0.3, 0.4, 0.7
# E 步: Q 取后验 —— 就是上一节算的 mu
mu = []
for x in obs:
joint_b = pi_old * p_old**x * (1 - p_old)**(1 - x)
joint_c = (1 - pi_old) * q_old**x * (1 - q_old)**(1 - x)
mu.append(joint_b / (joint_b + joint_c))
ell_old = ell(pi_old, p_old, q_old)
bound_posterior = lower_bound(pi_old, p_old, q_old, mu)
bound_flat = lower_bound(pi_old, p_old, q_old, [0.5] * len(obs))
print(f"观测 {len(obs)} 次, 其中正面 {sum(obs)} 个; theta_old = (pi={pi_old}, p={p_old}, q={q_old})")
print()
print("[E 步] 同一个 theta_old, 两种 Q 得到的下界:")
print(f" 对数似然 ell(theta_old) = {ell_old:.4f}")
print(f" Q = 后验 mu = {bound_posterior:.4f} <- 与似然重合(琴生取等号)")
print(f" Q = 一律取 0.5 = {bound_flat:.4f} <- 低了一截(琴生严格不等)")
# M 步: 固定 mu, 更新参数使下界最大 —— 三硬币里就是按比例数红绿
sum_mu = sum(mu)
pi_new = sum_mu / len(obs)
p_new = sum(m * y for m, y in zip(mu, obs)) / sum_mu
q_new = sum((1 - m) * y for m, y in zip(mu, obs)) / (len(obs) - sum_mu)
ell_new = ell(pi_new, p_new, q_new)
bound_carry = lower_bound(pi_new, p_new, q_new, mu)
print()
print(f"[M 步] 按比例数红绿 -> theta_new = (pi={pi_new:.4f}, p={p_new:.4f}, q={q_new:.4f})")
print()
print("[单步全貌] 下界与似然的接力:")
print(f" ell(theta_old) = {ell_old:.4f} <- E 步后: 下界贴住似然")
print(f" L(mu, theta_new) = {bound_carry:.4f} <- M 步后: 下界抬到新高度")
print(f" ell(theta_new) = {ell_new:.4f} <- 似然跟着到达新高度")
print(f" 单步似然提升 = {ell_new - ell_old:.4f}")观测 21 次, 其中正面 10 个; theta_old = (pi=0.3, p=0.4, q=0.7)
[E 步] 同一个 theta_old, 两种 Q 得到的下界:
对数似然 ell(theta_old) = -15.3007
Q = 后验 mu = -15.3007 <- 与似然重合(琴生取等号)
Q = 一律取 0.5 = -17.6269 <- 低了一截(琴生严格不等)
[M 步] 按比例数红绿 -> theta_new = (pi=0.3354, p=0.2793, q=0.5756)
[单步全貌] 下界与似然的接力:
ell(theta_old) = -15.3007 <- E 步后: 下界贴住似然
L(mu, theta_new) = -14.5323 <- M 步后: 下界抬到新高度
ell(theta_new) = -14.5323 <- 似然跟着到达新高度
单步似然提升 = 0.7684三件事都兑现了:
- 后验取等号: 取后验 时,下界与对数似然精确重合()——琴生不等式的等号条件被亲眼看到;而「一律取 0.5」的 低到了 ——不是后验的 ,弦就贴不住曲线。
- M 步抬下界:按 数完红绿得到新参数,下界从 抬到 ,似然同步提升 。
- 一步到顶的彩蛋:这套数据一轮 E+M 之后,下界又与似然重合了()。这不是巧合:观测只有 0/1,整个三硬币模型能调的只有「出正面的总概率」,而 M 步的恒等式(上一节练一练证过)恰好把它钉在样本频率 上——似然一步就到了这套数据能达到的顶,后验随之不再变化。上一节代码里「第 1 轮迭代就到达不动点」不是小样本运气,是三硬币模型的结构性质。想看「多轮爬楼梯」,要等下一章的连续分布混合(GMM)。
📝 动手练一练
- 双向验证:设 等概率取 和 。对凸函数 和凹函数 ,分别手算 与 ,验证两个方向的不等式,并算出各自的差距。
👉 点击查看参考答案
凸函数 :
,函数的期望更大,差距 。
凹函数 :
,期望的函数更大,差距约 。
两问合起来看:凸、凹两个方向都验过,琴生不等式的「弦与碗」图像就立住了—— 离得越开(把 4 换成 9 试试),弦与曲线的差距越大。
- 回到三硬币:上一节 E 步算出的
mu_i,对应本节推导中的哪个量?M 步更新 的三个分式,对应下界的哪个部分?
👉 点击查看参考答案
- E 步:
mu_i就是 ——第 次结果由硬币 B 掷出的后验概率 。正因为它取的是后验,琴生不等式在当前 处取等号,下界最紧(正文代码第一组对照的 )。 - M 步:三个分式对应固定 后,最大化下界 中分别含 、、 的部分——在三硬币里,它就是「按比例数红绿」。用讲师的泛化说法:给定关于 的关系,怎么去优化、选择最好的 。
本章小结
- 琴生不等式:函数的期望与期望的函数谁大谁小——凸函数前者大、凹函数()后者大;记不住方向,就想「弦与碗」。
- 下界:乘除 、期望视角、 凹性三步走,等式变不等式——「 套求和」变成「 咬每一项」,这就是 EM 优化的对象 。
- E 步: 取后验(比值取常数、琴生取等号、下界最紧)——「均匀/最大熵」直觉的精确落点;上一节的 就是它。
- M 步:固定 最大化下界;似然压着下界,所以 ——EM 每次迭代都不亏。
- 学习路径:讲师的诚实建议——这些公式没有一步步细推(对初学者的意义有限);先把三硬币例子理解得非常清晰,再回过头来对照例子理解抽象公式。
第 12 章到此收口:贝叶斯公式(12.1)→ 隐含变量与概率模型(12.2)→ EM 算法(12.3)→ 琴生不等式(本节)——「先会跑,再懂为什么」。下一章把混合模型从伯努利换成高斯(GMM)与隐马尔可夫(HMM),绿色曲线要开始多轮爬楼梯了。
📋 行动清单
学完本节,你可以立即:
- 画「弦与碗」:凸、凹函数各画一张草图,标出 (弦的中点)与 (曲线上的点)——不等号方向全靠这张图。
- 改跑演示代码:把初始参数换几组(比如 ),验证「后验取等号、平坦 Q 低一截、M 步后似然抬升」这三件事是否组组成立。
- 对照上一节代码:把
mu_i对应 、数红绿对应最大化下界,逐行把两节的公式对上。 - 预习第 13 章《三个硬币问题》:图示里那个高斯混合模型(GMM)的例子,下一章展开。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。