查看全课大纲(第 52 / 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 算法:期望与最大化的迭代
约 38 分钟
小象实战讲义 · 机器学习算法精讲
上一节的三硬币问题停在了最关键的一步:A 决定用 B 还是 C,我们只看得到最终的正反面—— 三个参数怎么估?这一节,讲师「不休息、把问题讲完」:先写出整个系统的似然,看清它是一个混合模型;再用一个「如果知道是哪枚硬币」的思想实验找到估计的钥匙;最后把钥匙变成可迭代的算法——EM(期望最大化)。
💡 核心导读
- 定位:三硬币问题是一个有参数模型—— 三个参数决定整个系统的性能,目标是极大似然。
- 似然:引入隐含变量 ( 掷 B、 掷 C)边缘化后,单次观测的概率是 。
- 混合模型: 与 是两枚硬币的权重——课件笔记称之为伯努利混合模型(Bernoullian Mixture)。
- EM 两步:E 步用当前参数算每个结果由 B 掷出来的概率 (软归属);M 步按 的比例「数红绿」,更新 。
- 迭代:随机给定 , 交替进行; 不再变化时,就得到对整个系统的估计。
先把问题摆正:一个有参数模型
开场两个问答,把问题钉住。
第一,它是一个什么模型?——一个有参数模型(Parametric Model)。这个系统里有 一共三个参数,这三个参数决定了整个系统的性能,所以把它们合起来记作 :。
第二,我们想求什么?——求给定了这些数据之后的 likelihood:说白了,就是想求「给定 时, 的概率是多大」。我们观察到了很多 ,根据这些 来估计 ;最终想要的计算模型,是预测下一个 是正面还是反面的概率——那需要算出最好的参数 (根据以前给定的数据训练出来)。
如果对这件事还有疑惑(讲师照顾基础稍弱的同学),回想正态分布的例子:给定一堆数据,假设它服从一个正态分布 ——训练数据就是想知道 和 是什么;做极大似然,训练出最好的 和 。知道了整个分布长什么样,下次就可以再采样:下一个数据大概就在这个位置,再下一个又能采出来一个。对未来数据的估计,实际上就是算出那个最好的参数。三硬币这里是一模一样的事情——只不过分布更复杂,是 混合构成的一个分布,但最终仍然想求一个最优的参数,来预测下一个 。
写出似然:隐含变量登场
那怎么写这个「复杂分布」?用刚学过的工具——引入隐含变量。
是控制 的变量: 是硬币的正面反面,而「也许有一个变量控制着是 B 还是 C 掷出这个正反面」——很显然, 就是我们看不到的硬币 A 的结果。 也是二值的:
- :这次掷的是硬币 B;
- :这次掷的是硬币 C。
把 的所有可能累加进公式(上一节的边缘化),再给每一项都带上条件 :
(把 都去掉,它就是熟悉的联合概率与条件概率的关系:——只是现在每一项都多了一个条件。)
拆成两半算。
第一半:。由谁决定?由硬币 A。A 是正面时掷 B——所以 ,。「可被计算」。
第二半:。看 的情形:给定掷的是硬币 B,得到正面()的概率多大?这就是关于硬币 B 的伯努利分布——参数是 ,所以是 。同理 时是关于硬币 C 的伯努利分布,参数 :。
合并。把两种情况加在一起,就得到单次观测的分布—— 乘上 B 的伯努利项,加 乘上 C 的伯努利项:
整个系统里那个复杂的关系,就用 三个参数全部解释出来了。
别忘了我们掷了 次:。每一次的分布都由上面这串算出,所以似然是它们的连乘;照例取 log 变成连加:
问题来了:公式(系统)我们已经知道,但 这三个参数是多少?并不知道。我们唯一拥有的数据就是 ——一大堆正面和反面。怎么估计?
这是一个混合模型
先看清 的结构。它的一部分是硬币 B 掷出正面的概率(一个伯努利分布),另一部分是硬币 C 的;而「有多大可能是 B」是 、「有多大可能是 C」是 —— 和 相当于两种情况的权重。这种「权重乘密度再相加」的结构,就叫混合模型(Mixture Model)。
为什么「 乘某物加 乘另一物」就是混合?一个非常直观的想象(讲师原话场景):有两个数,一个 一个 。 是 0 到 1 之间的概率——比如取 (讲师先说 0.5,马上自我纠正:「0.5 不可能,0.3 更好一点」),那么选 的概率是 0.3、选 的概率是 0.7。求它们之间的「均值」时,——相当于选了它们之间的一个中间点,更靠近 B 一点。这就是一种混合。两类可以推广到多类:,只要所有 加起来等于 1,就代表 个事件各按权重 的多模态混合。
所以三硬币的问题,很容易看成「B 和 C 这两种伯努利分布的混合」。课件笔记把它讲得更精确:这是一个 Bernoullian Mixture model(伯努利混合模型), 可以看作 B 和 C 的混合权重;而盒子里的东西可以换成骰子、换成任何服从某种分布的事件——把伯努利换成高斯,就是第 13 章的高斯混合模型。
如果知道是哪枚硬币:红绿标色
估计的钥匙,藏在一个思想实验里。
我们看到这些 ,比如 ——一堆 0、1 的组合,但没法估计 ,关键就在于不知道每个结果是哪枚硬币掷出来的。可是一旦假设我们知道——用课件笔记的画法:把硬币 B 掷出来的结果标成红色、硬币 C 的标成绿色——这件事立刻就可以做了:
- 的估计: 代表 A 掷出正面(从而选 B)的概率,所以就是红色占全部数据的比例——红色个数比上红色加绿色;
- 的估计:红色默认全是 B 掷的, 是 B 掷出正面的概率——所以是红色的一,占所有红色的比例;
- 的估计:同理——绿色的一,占所有绿色的比例。
数数而已。所以讲师在这里点破:隐含变量的关键,就在于我们并不知道它是哪个硬币掷出来的;但一旦知道,这些事都解决了。我们要做的,就是对每一次结果「它由 B 还是 C 掷出来」产生一个估计——只要得到它,剩下的事情都可以做。
用概率标色:μ 与 E 步
可是开头我们并没有红绿——那就近似地估计:给一个新的参数 ,代表「第 次的结果,有多大比例是由 B 掷出来的」。既然 是个混合模型,把 B 的那一半劈出来放在分子、全部可能性放在分母,就是 (贝叶斯公式的又一次现身):
上面的部分是 B 发生的概率,底下是 B 加上 C 发生的概率——所以在给定当前 时,它就是第 次结果由 B 掷出来的概率。
注意它跟红绿标色的关系:我们不可能真的知道每个结果到底是红色还是绿色掷出来的——红色和绿色,是期望得到的结果。我们能做到的,是给每次结果一个「属于红色」的概率:它也许属于红色是 0.7、它是 0.2、它是 0.9、它是 0.4、0.8……「带着比例的红色」——把 0.7 个红色、0.2 个红色这样加在一起,就是所有的红色。用给定的这些 ,对红绿给出一个更好的估计,这个估计就是 。
这一步,就是 EM 里的 E step(Expectation,求期望):根据给定的参数,求每一个掷出来的结果有多大概率是由 B 掷出来的。
M 步:按比例数数
有了 ,就可以按红绿标色的方式「数数」了——只是现在每一个数都带着比例。
的更新: 代表「掷了 次里面,平均有多少次用了 B」。掷 100 次、,就代表约 30 次的结果是 B 掷出来的。所以把每一次「属于 B 的份额」 合在一起求均值:
的更新:红色里有多少红色的一。红色的总数是 (把带着比例的红色加在一起);「红色的一」—— 只有 0 或 1: 时, 这一份红色算进去; 时,乘上 0 直接归零。所以分子是 :
的更新:同理,绿色是 ,绿色的一是 :
这一步,就是 M step(Maximization,最大化):根据 的估计,对 做最大化的估计。
完整算法:互相迭代
把两步接起来,算法的全貌是:
- 随机给定初始值 ——「随便比如给 0.3、0.4、0.7 都可以」;
- 用第 时刻的参数 代入 的公式,算出第 时刻的 (E 步);
- 用 数数,更新出 (M 步);
- 重复 2–3——「就是一个互相迭代的一个算法」。当 不再发生任何变化时,我们就得到了对整个系统的估计。
(板书花絮:讲师写到迭代轮次时,在上角标与下角标之间纠结了一阵——「哎呀,这个 notation 有点乱了……不然还是这么写吧」——最终把迭代轮次放在上角标: 指第 轮迭代的 ,别和幂次混淆。)
这就是 EM algorithm,EM 算法——Expectation Maximization,期望最大化:分两个部分,E step 求期望(每个结果由 B 掷出来的概率),M step 求最大化(给定 ,更新 ),不断迭代,最后得到对 最好的估计。「这就是我给大家所讲述的 EM 算法」——本节视频到此收尾。
亲手跑一遍:三硬币的 EM
下面把整个算法落成代码(纯标准库)。先用已知的「真实参数」模拟生成一串观测——然后把这串观测交给 EM,看它能不能把参数恢复出来:
import random
def em_coin(observations, init_params, max_iters=20, tol=1e-6):
"""三硬币 EM: E 步算 mu_j(第 j 次由 B 掷出的概率), M 步按比例数红绿"""
pi, p, q = init_params
N = len(observations)
history = [(0, pi, p, q)]
for it in range(1, max_iters + 1):
# E-step: 逐个计算 mu_j
mu = []
for y in observations:
prob_b = pi * (p ** y) * ((1 - p) ** (1 - y)) # B 的那一半
prob_c = (1 - pi) * (q ** y) * ((1 - q) ** (1 - y)) # C 的那一半
mu.append(prob_b / (prob_b + prob_c)) # B / (B + C)
# M-step: 按比例数数
sum_mu = sum(mu) # 红色总数
pi_new = sum_mu / N # 红色占比
p_new = sum(m * y for m, y in zip(mu, observations)) / sum_mu # 红色的一 / 红色
q_new = sum((1 - m) * y for m, y in zip(mu, observations)) / (N - sum_mu)
if max(abs(pi_new - pi), abs(p_new - p), abs(q_new - q)) < tol:
pi, p, q = pi_new, p_new, q_new
history.append((it, pi, p, q))
break
pi, p, q = pi_new, p_new, q_new
history.append((it, pi, p, q))
return (pi, p, q), history
# 模拟生成观测: 真实参数 pi=0.6, p=0.7, q=0.3
random.seed(42)
true_pi, true_p, true_q = 0.6, 0.7, 0.3
obs = []
for _ in range(10):
if random.random() < true_pi: # 掷 A: 正面 -> 用 B
obs.append(1 if random.random() < true_p else 0)
else: # A 反面 -> 用 C
obs.append(1 if random.random() < true_q else 0)
print("观测序列:", obs)
print("序列中1的比例:", sum(obs) / len(obs))
# EM: 初始参数故意偏离真实值
params, history = em_coin(obs, init_params=(0.4, 0.6, 0.3))
print(f"\n真实参数: pi={true_pi:.4f}, p={true_p:.4f}, q={true_q:.4f}")
print(f"EM估计: pi={params[0]:.4f}, p={params[1]:.4f}, q={params[2]:.4f}")
print("\n迭代过程:")
print(" 迭代 pi p q")
for it, pi_v, p_v, q_v in history:
print(f"{it:5d} {pi_v:.4f} {p_v:.4f} {q_v:.4f}")观测序列: [1, 1, 0, 1, 1, 1, 1, 0, 1, 1]
序列中1的比例: 0.8
真实参数: pi=0.6000, p=0.7000, q=0.3000
EM估计: pi=0.5123, p=0.8923, q=0.7030
迭代过程:
迭代 pi p q
0 0.4000 0.6000 0.3000
1 0.5123 0.8923 0.7030
2 0.5123 0.8923 0.7030读一读这个结果:观测里 1 占了八成,EM 的解读是——大约一半的试验用了 B,而两枚硬币都被判成偏正面(、)。只有 10 个观测点,EM 找到的是「能解释这串数据」的一组参数,它跟生成数据的真实参数不必相同;换成更长的序列,估计才有机会贴近真值。另外注意:这个初始值下第 1 轮迭代就到达了不动点(第 2 轮参数完全不变)——小数据上 EM 收敛得很快。
📝 动手练一练
- 极端情形:假设初始参数恰好让每个 算出来都等于 0 或 1,那么 E 步和 M 步会退化成什么样?对照上一节「红绿标色」的思想实验想一想:软归属( 取 0 到 1 之间的分数)的价值在哪里?
👉 点击查看参考答案
全为 0 或 1 时,E 步相当于把每个观测完全分给 B 或 C——「带着比例的红色」退化成了纯红、纯绿。M 步的三个分式随之退化成数数:
- 红色个数 / 总数( 求和时每个只贡献 0 或 1);
- 红色的一的个数 / 红色个数(分子里 只在 且 时计入);
- 绿色的一的个数 / 绿色个数。
这正是上一节「假设知道每个结果来自哪枚硬币」的完全数据情形——参数估计变成纯粹的频率统计。软归属的价值:当我们并不确定某次结果属于谁时,硬性二选一会把信息用尽扔掉;而 这样的分数让同一个数据点按比例同时滋养两枚硬币的估计——0.7 份算给红色、0.3 份算给绿色,没有浪费任何一点证据。
- 换个序列跑一跑:把观测换成偏反面的序列 (1 只占四成),初始参数不变。EM 会给出什么样的「解读」?再验证一个漂亮的恒等式:模型算出的「1 的比例」是否恰好等于序列里 1 的频率?
👉 点击查看参考答案
# 自包含精简版: 与正文 em_coin 同一套 E/M 公式, 跑到参数不动为止
def em_coin_flat(observations, init_params, max_iters=50, tol=1e-6):
pi, p, q = init_params
for _ in range(max_iters):
mu = [pi * (p ** y) * ((1 - p) ** (1 - y))
/ (pi * (p ** y) * ((1 - p) ** (1 - y))
+ (1 - pi) * (q ** y) * ((1 - q) ** (1 - y)))
for y in observations]
pi_n = sum(mu) / len(mu)
p_n = sum(m * y for m, y in zip(mu, observations)) / sum(mu)
q_n = sum((1 - m) * y for m, y in zip(mu, observations)) / (len(mu) - sum(mu))
if max(abs(pi_n - pi), abs(p_n - p), abs(q_n - q)) < tol:
return pi_n, p_n, q_n
pi, p, q = pi_n, p_n, q_n
return pi, p, q
obs_new = [1, 0, 0, 1, 0, 0, 1, 0, 0, 1]
params = em_coin_flat(obs_new, init_params=(0.4, 0.6, 0.3))
print(f"EM估计: pi={params[0]:.4f}, p={params[1]:.4f}, q={params[2]:.4f}")EM估计: pi=0.3941, p=0.5800, q=0.2829解读:EM 认为——约 39% 的试验用了 B(),B 略偏正面(),C 偏反面()。对比正文的序列(1 占八成,EM 判两枚都偏正面),数据形态决定了混合成分的分工。
恒等式验证:——模型算出的 1 的概率,恰好等于序列里 1 的频率 。这不是巧合:M 步的分子分母天然保证它——
红色的「一」加上绿色的「一」,怎么分账,总数都是数据里 1 的个数。模型对数据边缘频率的复现,一步不差。
本章小结
- 问题:三硬币是一个有参数模型,;目标是从观测序列做极大似然、预测下一个 。
- 似然:边缘化隐含变量 (A 的结果)后,——一个以 、 为权重的伯努利混合模型。
- 钥匙:如果知道每个结果来自哪枚硬币(红绿标色),参数估计就是三次数数——难点全在「不知道」。
- E 步:用当前参数算 ——第 次结果由 B 掷出来的概率(B 的概率 / B+C 的概率),红色绿色的「期望版」。
- M 步:按 的比例数红绿,更新 三个分式。
- 迭代:随机给定 ,E、M 交替, 不再变化即得到估计。这套框架里,把伯努利换成别的分布,就是第 13 章的混合模型家族。
📋 行动清单
学完本节,你可以立即:
- 手推一遍 :从贝叶斯公式出发,写出「B 的概率 / B+C 的概率」,确认分子分母的每一项来自混合模型的哪一半。
- 换数据做实验:修改正文代码的观测序列与初始参数,观察 EM 给出的「解读」怎么变——并检查 是否总是等于序列的 1 频率。
- 红绿笔手算:取 5 个观测,手算一轮 E 步的 与 M 步的 ——每个分式的分子分母都对应「哪种颜色的什么」。
- 预习下一节《琴生不等式》:EM 为什么「每次迭代都不亏」——那把数学钥匙,下一节配齐。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。