从“完全连接”到“稀疏连接”
\[
\begin{aligned}
\text{BN: }&p(\mathbf x)=\prod_i p(x_i\mid x_{\mathrm{pa}(i)}),\\
\text{MRF: }&p(\mathbf x)=\frac{1}{Z}\prod_{C\in\mathcal C}\psi_C(x_C).
\end{aligned}
\]
而“图”结构,正是用来直观地表示哪些变量是“局部”相关的,哪些是条件独立的。
什么是贝叶斯网络 (BN)?
贝叶斯网络 (Bayesian Networks, BN),也称为概率有向图模型 (PDGM),使用 有向无环图 (Directed Acyclic Graph, DAG) 来编码变量间的依赖关系。
它由两部分组成:
- 图结构 (Qualitative): 一个DAG,描述变量间的条件独立关系。
- 参数 (Quantitative): 一系列局部条件概率分布(CPDs),量化这些依赖关系的强度。
核心结构:有向无环图 (DAG)
- 有向 (Directed):箭头规定局部条件概率的父子顺序,例如 \(A\rightarrow B\) 使 B 的局部分布写作 \(P(B\mid A)\)。普通概率 BN 并不由此自动证明 A 导致 B。
- 无环 (Acyclic):沿箭头不能回到起点,因此联合分布可按拓扑顺序分解。只有结构另有因果依据时,“无环”才同时具有因果含义。
概率 DAG 与因果 DAG:同一图形,不同承诺
因此本讲 pgmpy 的 query 都是观测条件推断,除非另行建立结构因果模型。
DAG 示例:合法的 vs. 非法的
案例引入:一个简化的学生模型
让我们用图结构来构建一个关于学生表现的简化模型。
解读图的语言:家族关系
在有向图中,我们使用家族关系来描述节点间的关系:
- 父节点 (Parents): 一个节点的父节点是指所有直接指向该节点的节点集合。
parents(X3) 是 {X1, X2}。
parents(X6) 是 {X4, X5}。
- 子节点 (Children): 一个节点的子节点是指所有被该节点直接指向的节点集合。
- 没有父节点的节点(如
X1, X2)只是该因子分解中的根节点;只有另有结构因果解释时,才能称为外生原因。
贝叶斯网络的基石:局部马尔可夫性质
DAG的结构直接定义了一个核心的条件独立假设: 局部马尔可夫性质:
一个节点在给定其父节点的情况下,条件独立于其所有的非后代节点。
案例分析:从图中读取条件独立性
让我们再次审视图 Figure 1:
- 节点
X3:
- 父节点:
{X1, X2}
- 后代:
{X4, X6}
- 非后代:
{X5} (注意X1,X2是它的祖先,也算非后代)
- 应用性质: 根据局部马尔可夫性质,我们可以断言:在给定
X1 和 X2 的条件下,X3 与 X5 是条件独立的。
- 数学表达: \(P(X_3 | X_1, X_2, X_5) = P(X_3 | X_1, X_2)\)。
联合概率的因子分解:BN的魔力所在
基于局部马尔可夫性质,任何一个符合DAG的联合概率分布都可以被分解为所有节点关于其父节点的条件概率的乘积。
\[ \large{P(x_1, \dots, x_d) = \prod_{i=1}^d P(x_i | \text{parents}(x_i))}
\tag{1}\]
案例计算:分解图9.1的联合概率
应用 Equation 1 公式到 Figure 1 的图结构上:
\[
\large{
\begin{aligned}
& P(X_1, X_2, X_3, X_4, X_5, X_6) \\
& = P(X_1) \cdot P(X_2) \cdot P(X_3|X_1, X_2) \cdot P(X_4|X_3) \\
& \quad \cdot P(X_5|X_1) \cdot P(X_6|X_4, X_5)
\end{aligned}
}
\]
- 对比: 如果使用标准的链式法则,最后一项会是 \(P(X_6|X_1, X_2, X_3, X_4, X_5)\),计算它需要巨大的参数空间。
- 优势: 因子分解大大减少了我们需要估计的参数数量,使模型学习成为可能。
参数化:用条件概率表(CPT)填充模型
现在我们有了结构,还需要为每个局部概率模型提供具体的参数。对于离散变量,这通常通过 条件概率表 (Conditional Probability Table, CPT) 来完成。
- 一个CPT列出了在一个节点的所有父节点取值的每一种组合下,该节点取不同值的概率。
- 对于根节点 (如 \(X_1\)),CPT就是一个简单的先验概率分布 \(P(X_1)\)。
- 对于有父节点的节点 (如 \(X_3\)),CPT就是 \(P(X_3 | X_1, X_2)\)。
9.2.2 有向分离 (D-Separation)
我们为何需要一套通用规则?
局部马尔可夫性质告诉我们一个节点与其“非后代”的独立性。但我们经常需要回答更一般性的问题:
任意两个不相干的节点集合 A 和 B,在给定第三个集合 E 的条件下,是否独立?
D-分离 (Directed Separation) 就是一套完整的、通用的规则,让我们能从图结构中直接“读取”任意条件独立性。
D-分离的核心思想
D-分离的核心思想是检查两组节点之间的所有路径是否被“阻断 (blocked)”。
如果 A 到 B 的 所有 路径都被观测变量集合 E 所阻断,那么 A 和 B 就是条件独立的。
若至少有 一条 路径是通的 (unblocked),图结构就不能保证 A 与 B 条件独立;
只有再假设分布对图忠实(不存在参数抵消)时,才能把 d-连接解释为条件依赖。
D-分离的三种基本结构
任何复杂的DAG中的路径都可以被分解为三种基本连接结构。理解这三种结构是掌握D-分离的关键。
结构1: Tail-to-Tail (共同原因)
b <- a -> c
- 路径:
b 和 c 通过它们的共同父节点 a 连接。
- 规则: 当
a 被观测到 (给定) 时,从 b 到 c 的路径被 阻断。
- 例子:
冰淇淋销量 \(\leftarrow\) 天气炎热 \(\rightarrow\) 中暑人数
- 解释:
结构2: Head-to-Tail (链式结构)
b -> a -> c
- 路径:
b 通过中间节点 a 影响 c。
- 规则: 当
a 被观测到 (给定) 时,从 b 到 c 的路径被 阻断。
- 例子:
美联储政策 \(\rightarrow\) 市场利率 \(\rightarrow\) 房地产价格
- 解释:
结构3: Head-to-Head (V型结构)
b -> a <- c
- 路径:
b 和 c 都是 a 的父节点。a 是它们的共同效应。
- 规则 (注意! 这是反的!):
- 当
a (或a的任何后代) 未被观测到 时,路径是 阻断 的。
- 当
a (或a的任何后代) 被观测到 时,路径被 打通!
- 例子:
学术才华 \(\rightarrow\) 获得终身教职 \(\leftarrow\) 学术政治手腕
- 解释:
这个现象被称为 “解释得通 (explaining away)”。
知道一个教授有才华并不能告诉我们任何关于他政治手腕的信息(两者先验独立)。
但是,如果我们知道他获得了终身教职,然后又发现他其实没什么才华,这就强烈暗示他一定非常有政治手腕。
D-分离总结:路径是否被阻断?
一条从节点集合 A 到 B 的路径被一个节点集合 E (我们观测到的变量) 阻断,如果路径上存在一个节点 v 满足以下任一条件:
v 是 tail-to-tail 或 head-to-tail 结构,并且 v 在 观测集 E 中。
v 是 head-to-head 结构,并且 v 以及它的所有后代 都 不在 观测集 E 中。
如果 A 到 B 的 所有路径 都被 E 阻断,那么我们就说 A 和 B 在给定 E 的条件下是 D-分离 的,即条件独立: A \(\perp\) B | E。
转折检查:观测碰撞点会发生什么?
- 先作答: 在 \(A\rightarrow B\leftarrow C\) 中,未观测 B 时 A 与 C 是否独立?观测 B 后呢?
9.2.3案例研究:一个更完整的学生模型
现在,我们把这些概念应用到教材第8页的经典“学生”贝叶斯网络中。这个网络模拟了影响学生最终获得推荐信(Letter)的各个因素。
- 变量:
- D (Difficulty): 课程难度 (0=低, 1=高)
- I (Intelligence): 学生智商 (0=不高, 1=高)
- G (Grade): 学生成绩 (0=C, 1=B, 2=A)
- S (SAT): SAT分数 (0=低, 1=高)
- L (Letter): 推荐信质量 (0=差, 1=好)
学生模型之图结构
这个图的结构编码了我们关于学生表现的先验信念。
学生模型之因子分解
核心内容任务
先按“每个节点只条件于其父节点”写出 \(P(I,D,G,S,L)\),再揭示。
. . .
根据上页的图结构和 Equation 1,联合概率分解为:
\[ \large{P(I, D, G, S, L) = P(I) \cdot P(D) \cdot P(S|I) \cdot P(G|I, D) \cdot P(L|G)} \]
请注意,我们大大简化了问题!例如,我们只需要 \(P(L|G)\),而不是 \(P(L|I, D, G, S)\)。
学生模型之参数化 (CPTs)
现在我们需要为每个因子填充CPT。这些概率通常从领域专家或历史数据中估计得到。
1. 根节点 (先验概率)
- \(P(I)\): P(I=0) = 0.7, P(I=1) = 0.3
- \(P(D)\): P(D=0) = 0.6, P(D=1) = 0.4
2. 条件概率
- \(P(S|I)\): 智商如何影响SAT分数
- \(P(G|I,D)\): 智商和课程难度如何共同影响成绩
- \(P(L|G)\): 成绩如何影响推荐信质量
CPT 示例: P(G | I, D)
这张表展示了在不同智商和课程难度组合下,学生取得A/B/C三种成绩的概率。
| 0 (不高) |
0 (低) |
0.30 |
0.40 |
0.30 |
| 0 (不高) |
1 (高) |
0.05 |
0.25 |
0.70 |
| 1 (高) |
0 (低) |
0.90 |
0.08 |
0.02 |
| 1 (高) |
1 (高) |
0.50 |
0.30 |
0.20 |
贝叶斯网络推理:回答“观测到以后”
这回答的是 \(P(Y\mid X=x)\):在样本中观察到 \(X=x\) 后,Y 如何分布;它不是“把 X 强制设为 x 会怎样”。
Conditioning 与 Intervention:一个混杂例子
设市场情绪 \(U\) 同时影响融资约束 \(X\) 与投资 \(Y\):\(U\rightarrow X, U\rightarrow Y\),且 \(X\rightarrow Y\)。
观测条件:\(P(Y\mid X=x)\) 同时包含 X 的路径与共同原因 U 带来的选择差异。
干预:\(P(Y\mid do(X=x))\) 切断指向 X 的箭头,再比较强制设定 X 后的 Y。
结论:若 U 未观测且没有其他识别策略,普通 BN 查询不能把前者替代为后者。
检查 2: 删除指向 X 的箭头属于 conditioning 还是 intervention?普通 pgmpy 查询做了这一步吗?先回答。
推理问题示例
- 一个学生拿到了一封很好的推荐信(L=1),那么他很聪明的概率是多少?
- 一个很聪明的学生(I=1)在一门很难的课(D=1)上,他拿到A的概率是多少?
- \(P(G=A | I=1, D=1) = ?\) (这个可以直接查CPT)
- 一个学生SAT成绩很高(S=1),但他成绩很差(G=C),那么课程很难的概率是多少?
- \(P(D=1 | S=1, G=C) = ?\)
实战:用 Python pgmpy 库构建并查询学生模型
理论讲完了,让我们用代码把它变成现实。我们将使用一个强大的Python库 pgmpy 来实现学生模型。
核心内容任务
运行并检查模型验证与 \(P(D=1\mid I=1,L=1)\) 的观测查询输出;说明普通查询没有删除任何入边,因此不等于干预。
步骤:
- 定义模型结构 (添加节点和边)
- 定义CPTs
- 将CPTs与结构关联,形成完整模型
- 创建推理引擎
- 进行查询
pgmpy 实战:构建并验证模型
首先,我们用一个完整的代码块来构建学生模型。
Code
# 导入所需的库
from pgmpy.models import DiscreteBayesianNetwork
# 导入依赖以支持本页的数据处理、建模或可视化。
from pgmpy.factors.discrete import TabularCPD
# 1. 定义模型结构 (边)
student_model = DiscreteBayesianNetwork([('D', 'G'), ('I', 'G'), ('I', 'S'), ('G', 'L')])
# 2. 定义CPDs
# 根节点
cpd_d = TabularCPD('D', 2, [[0.6], [0.4]])
cpd_i = TabularCPD('I', 2, [[0.7], [0.3]])
# 条件节点
cpd_s = TabularCPD('S', 2,
values=[[0.95, 0.2], [0.05, 0.8]],
evidence=['I'], evidence_card=[2])
再补齐其余条件概率表并验证各列归一化与图结构一致。
Code
# 状态约定:D=0简单/1困难,I=0低/1高,G=0为C、1为B、2为A,L=0弱/1强。
# evidence=['D','I'] 的列顺序是 (D=0,I=0), (D=0,I=1), (D=1,I=0), (D=1,I=1)。
cpd_g = TabularCPD('G', 3,
values=[[0.30, 0.02, 0.70, 0.20], # G=0:C。
[0.40, 0.08, 0.25, 0.30], # G=1:B。
[0.30, 0.90, 0.05, 0.50]], # G=2:A。
evidence=['D', 'I'], evidence_card=[2, 2])
# 注意:pgmpy的CPT中,变量状态默认从0开始。
# 推荐信表按 G=C、B、A 的列顺序给出弱/强概率。
cpd_l = TabularCPD('L', 2,
values=[[0.9, 0.4, 0.01], [0.1, 0.6, 0.99]], # 教学说明:L=0, L=1。
evidence=['G'], evidence_card=[3])
# 3. 添加CPDs到模型中
student_model.add_cpds(cpd_d, cpd_i, cpd_s, cpd_g, cpd_l)
# 4. 验证模型是否有效
assert student_model.check_model() # 确认概率表与网络结构一致。
# 执行 `print`,生成当前步骤需要的结果或可视化。
print('模型构建成功并通过验证!') # 展示当前步骤的结果。
pgmpy 实战:创建推理引擎并查询
最激动人心的部分来了!我们创建一个推理引擎(这里使用变量消除法),然后提出我们的问题。
问题
Code
# 这是一个完整的、可运行的代码块 (接上页)
from pgmpy.inference import VariableElimination
# (模型构建代码已在上页运行,这里不再重复)
# 5. 创建推理引擎
inference = VariableElimination(student_model)
# 6. 进行查询
query_result = inference.query(variables=['D'], evidence={'I': 1, 'L': 1})
# 执行 `print`,生成当前步骤需要的结果或可视化。
print(query_result) # 展示当前步骤的结果。
+------+----------+
| D | phi(D) |
+======+==========+
| D(0) | 0.6701 |
+------+----------+
| D(1) | 0.3299 |
+------+----------+
结果解读与经济直觉
查询结果显示 \(P(D=1 | I=1, L=1) \approx 0.3299\)。
- 先验概率: 在没有任何信息的情况下,课程很难的概率是 \(P(D=1)=0.4\)。
- 后验概率: 当我们得知这个聪明的学生拿到了一封好信,我们对课程很难的信念下降到约33.0%。
- 直觉:
- 聪明学生即使在难课上也可能取得好成绩并拿到好信。
- 但在简单课程中,取得好成绩的概率更高。
- 因而“好信”会略微提高我们对“课程简单”的后验信念。
- 贝叶斯推理把这种信念更新定量化。
9.2.4 动态贝叶斯网络:当BN遇到时间
课后选学:以下内容包括 HMM、无向图模型与一般推断;学习核心内容时可先跳到真实数据练习和本讲回顾。
如果我们将贝叶斯网络在时间维度上“展开”,就得到了 动态贝叶斯网络 (Dynamic Bayesian Network, DBN)。
最简单也最著名的DBN就是 隐马尔可夫模型 (Hidden Markov Model, HMM)。
HMM的直观理解:洞穴中的天气预报
想象你被困在一个洞穴里,无法看到外面的天气。但洞穴里每天都会渗水。
- 你的观测 (可见): 今天洞穴里是 “干燥”、“潮湿” 还是 “滴水”。
- 真实状态 (隐): 外面的天气是 “晴天”、“多云” 还是 “雨天”。
你的任务是,根据连续几天的渗水情况,推断出外面最可能的天气变化序列。
HMM的核心应用
对时间序列数据建模,其中系统的真实状态是不可见的 (隐),我们只能通过一些可见的观测来推断它。
- 经济学应用:
- 真实状态 (隐): 经济处于“扩张期”还是“衰退期”。
- 观测 (可见): 每季度的GDP增长率、失业率数据。
HMM 的两个核心假设
HMM建立在两个关键的简化假设之上,这使得模型变得 tractable。
- 马尔可夫假设 (状态转移)
- 观测独立性假设 (发射概率)
假设1:马尔可夫假设 (状态转移)
当前的真实状态 \(z_t\) 只取决于前一个时刻的真实状态 \(z_{t-1}\)。
\[ \large{P(z_t | z_{t-1}, z_{t-2}, \dots, z_1) = P(z_t | z_{t-1})} \]
- 经济学解释: 经济是处于衰退还是扩张,主要取决于上一个季度是衰退还是扩张,而与更早之前的历史无关(在一阶模型中)。
假设2:观测独立(发射概率)
当前的观测值 \(x_t\) 只取决于当前的真实状态 \(z_t\)。
\[ \large{P(x_t | z_t, x_{t-1}, z_{t-1}, \dots) = P(x_t | z_t)} \]
- 经济学解释: 本季度的GDP增长率,只取决于本季度经济是处于衰退还是扩张,而与之前的状态和观测都无关。
HMM 的图结构
这两个假设共同定义了一个非常简洁的链式图结构。
HMM 的三要素
要完全定义一个HMM,我们需要三个参数,通常记为 \(\lambda = (A, B, \pi)\)。
- 状态转移矩阵 A: \(A_{ij} = P(z_t = j | z_{t-1} = i)\)
- 观测发射矩阵 B: \(B_{jk} = P(x_t = k | z_t = j)\)
- 初始状态分布 \(\pi\): \(\pi_i = P(z_1 = i)\)
经济学案例:用HMM识别商业周期
让我们用一个简化的模型来识别经济是处于 扩张(Expansion) 还是 衰退(Recession)。
- 隐状态 Z: {0: 扩张, 1: 衰退}
- 观测 X: 我们观察每个季度的GDP增长率,并将其简化为三个等级:{0: 负增长, 1: 低增长(0-2%), 2: 高增长(>2%)}
我们的任务是
根据观测到的GDP增长序列,推断出最可能的经济状态(扩张/衰退)序列。
HMM 参数设置: 转移矩阵 A
矩阵 A 代表了经济周期的“惯性”。
\[
\begin{aligned}
A&=\begin{pmatrix} P(\text{扩}|\text{扩}) & P(\text{衰}|\text{扩}) \\ P(\text{扩}|\text{衰}) & P(\text{衰}|\text{衰}) \end{pmatrix}\\[4pt]
&=\begin{pmatrix} 0.9 & 0.1 \\ 0.3 & 0.7 \end{pmatrix}.
\end{aligned}
\]
- 解读:
- 如果本季度是扩张,那么下个季度有90%的概率继续扩张。
- 如果本季度是衰退,那么下个季度有70%的概率继续衰退(衰退比扩张更“不稳定”)。
HMM 参数设置: 发射矩阵 B
矩阵 B 代表了不同经济状态下的典型产出表现。
\[
\begin{aligned}
B_{jk}&=P(x_t=k\mid z_t=j),\\[2pt]
B&=\begin{pmatrix}0.05&0.45&0.50\\0.60&0.35&0.05\end{pmatrix}.
\end{aligned}
\]
- 解读:
- 在扩张期,最可能出现高增长(50%);在衰退期,最可能出现负增长(60%)。
HMM 参数设置: 初始分布 \(\pi\)
\(\pi\) 代表我们对 t=1 时刻经济状态的先验信念。
\[ \large{\pi = \begin{pmatrix} P(z_1=\text{扩}) \\ P(z_1=\text{衰}) \end{pmatrix} = \begin{pmatrix} 0.8 \\ 0.2 \end{pmatrix}} \]
- 解读: 我们认为在序列开始时,经济有80%的可能处于扩张期。
HMM 要解决的三个核心问题
有了模型 \(\lambda = (A, B, \pi)\) 后,HMM理论主要解决三个问题。
HMM 总结
- HMM是分析时间序列的强大工具,是DBN的一个重要特例。
- 它通过区分“隐状态”和“观测”来对复杂系统建模。
- 其核心是三个参数 \((A, B, \pi)\) 和解决三个核心问题(评估、解码、学习)的经典算法。
- 在经济学中,它被广泛用于识别商业周期、金融市场状态切换(牛市/熊市)等。
从有向分解到无向分解
贝叶斯网络的箭头适合表示有向的条件概率分解;当相互作用是对称的,或者我们不愿指定有向父子顺序时,无向图更自然。
因果语义是另一层建模承诺,不能由“有向/无向”二分替代。
社交网络: 我是你的朋友,你也是我的朋友。
图像像素: 一个像素的颜色和它周围的像素颜色高度相关,但谁也不是谁的“原因”。
空间经济学: 一个地区的房价与邻近地区的房价相互影响。
什么是马尔可夫随机场 (MRF)?
对于这类问题,马尔可夫随机场 (Markov Random Field, MRF) 或称为 概率无向图模型 (PUGM) 是更自然的选择。
一个MRF由两部分定义:
- 一个 无向图 \(G=(\mathcal{V}, \mathcal{E})\),节点代表随机变量,边代表它们之间的直接依赖关系。
- 一组 势函数 (Potential Functions) \(\phi_C(\mathbf{x}_C)\),定义在图的“团 (clique)”上,用于量化变量间的“相容性”。
无向图中的条件独立性:简单得多!
与D-分离的复杂规则不同,无向图中的条件独立性非常直观:
如果从节点集合 A 到节点集合 B 的所有路径都必须经过节点集合 C,那么 A 和 B 在给定 C 的条件下是条件独立的。
换句话说,C 分隔 (separates) 了 A 和 B。
案例:从无向图中读取独立性
MRF 条件独立性:三种马尔可夫性质
- 全局马尔可夫性:
- \(A \perp B | C\) 如果 C 分隔了 A 和 B。 (刚才讲的)
- 局部马尔可夫性:
- 一个节点在给定其所有 邻居 的条件下,与其所有其他节点条件独立。
- 邻居 (Neighbors) 或 马尔可夫毯 (Markov Blanket) 是指直接与该节点有边相连的节点集合。
- 成对马尔可夫性:
- 任何两个 不直接相连 的节点,在给定所有其他节点的条件下,是条件独立的。
联合概率分解:团与势函数
无向图的联合概率如何分解?答案是通过 团 (Clique)。
- 团 (Clique): 图中的一个节点子集,其中任意两个节点之间都有一条边。它们是图中的“全连接”子图。
- 极大团 (Maximal Clique): 一个团,如果再加入任何一个节点,它就不再是团了。
MRF的联合概率分布可以被分解为定义在 极大团 上的势函数的乘积。
案例:识别极大团
势函数 (Potential Function)
- 对于图中的每个极大团 \(C\),我们定义一个 势函数 \(\psi_C(\mathbf{x}_C)\)。
- 这个函数输入该团中所有变量的一种特定取值组合 \(\mathbf{x}_C\),输出一个 非负的实数。
- 直观意义:
- 重要: 它不是概率!它只是一个分数。
Hammersley-Clifford 定理
这个重要的定理建立了MRF的联合概率分布与势函数之间的桥梁:
正性条件: 联合分布必须在完整状态空间上严格为正,即 \(P(\mathbf{x})>0\)。
图结构条件: 该分布满足无向图 \(G\) 编码的条件独立性。
分解结论: 联合概率可写成所有极大团 \(C\) 上势函数 \(\psi_C\) 的乘积:
\[
\large{P(\mathbf{x}) = \frac{1}{Z} \prod_{C \in \mathcal{C}} \psi_C(\mathbf{x}_C)}
\]
其中 \(\mathcal{C}\) 是所有极大团的集合。
归一化常数 (Partition Function) Z
公式中的 \(Z\) 被称为 配分函数 (Partition Function) 或归一化常数。
\[
\large{Z = \sum_{\mathbf{x}} \prod_{C \in \mathcal{C}} \psi_C(\mathbf{x}_C)}
\]
BN vs. MRF 总结
| 图结构 |
有向无环图 (DAG) |
无向图 |
| 核心思想 |
条件概率因子分解 |
势函数/能量函数因子分解 |
| 参数化 |
条件概率分布 (CPDs) |
极大团上的势函数 |
| 归一化 |
自动满足 (局部归一化) |
需要全局的配分函数 Z |
| 适用场景 |
有向生成模型;加上因果假设后可表达因果模型 |
对称相互作用、空间或判别模型 |
| 可解释性 |
强,易于理解 |
较弱,势函数不直观 |
生成模型 vs. 判别模型
- 生成模型 (Generative): 对联合概率 \(P(X, Z)\) 建模。它学习数据是如何“生成”的。
- 例子: HMM, 贝叶斯网络。
- 能力: 可以用来生成新的样本数据。
- 判别模型 (Discriminative): 直接对我们更关心的条件概率 \(P(Z|X)\) 建模。它学习如何“区分”不同的Z。
- 例子: 逻辑回归, CRF。
- 能力: 通常在分类和预测任务上表现更好。
CRF 的核心优势
条件随机场 (Conditional Random Field, CRF) 是一种特殊的MRF,它是一个判别模型。
线性链CRF (Linear-Chain CRF)
最常见的CRF是线性链CRF,专门用于处理序列数据。
它的条件概率 \(P(Z|X)\) 的形式为:
\[
\large{P(Z|X) = \frac{1}{Z(X)} \exp\left( \sum_{t,k} \lambda_k f_k(z_{t-1}, z_t, X, t) \right)}
\]
- \(f_k\) 称为 特征函数,它可以是关于状态和观测的任何函数 (例如,“如果当前词是’银行’,且前一个词是’国家’”)。
- \(\lambda_k\) 是每个特征的权重,需要从数据中学习。
- \(Z(X)\) 是依赖于观测序列 \(X\) 的配分函数。
为何需要一个统一的框架?
我们已经学习了有向图和无向图,它们都表示了联合概率的因子分解,但方式不同。
- 有向图: \(P(\mathbf{x}) = \prod_i P(x_i | \text{parents}(x_i))\)
- 无向图: \(P(\mathbf{x}) = \frac{1}{Z} \prod_C \psi_C(\mathbf{x}_C)\)
有没有一种更通用的表示法,能够统一这两种模型,并为通用推理算法提供基础?
答案是 因子图 (Factor Graph)。
因子图:一种更精细的表示
因子图是一种二部图,它显式地表示了全局函数(如联合概率)是如何分解成一系列局部函数(因子)的乘积的。
- 两类节点:
- 变量节点 (Variable Nodes): 通常画成圆形,代表随机变量。
- 因子节点 (Factor Nodes): 通常画成方形,代表全局函数中的一个因子。
- 边: 一条边只存在于变量节点和因子节点之间。一个变量节点与一个因子节点相连,当且仅当该变量出现在该因子中。
案例:将贝叶斯网络转换为因子图
回顾学生BN的分解:\(P(\cdot) = P(I) P(D) P(S|I) P(G|I,D) P(L|G)\)
案例:MRF 转换为因子图
回顾MRF的分解:\(P(\mathbf{x}) \propto \psi_1(A,B,E) \psi_2(B,C) \psi_3(E,D)\)
因子图的优势
- 显式展示一种分解:
- 通用算法: 许多重要的推理算法,如 置信传播,在因子图上定义最为清晰和通用。
通用推理算法:置信传播 (Belief Propagation)
置信传播 (Belief Propagation, BP),也称为 和积算法 (Sum-Product Algorithm),是一种在图模型上进行高效精确推理的通用算法。
- 目标: 计算每个单变量的 边际概率 (Marginal Probability) \(P(x_i)\)。
- 核心思想: 算法通过在因子图的边上传递“消息 (messages)”来工作。这可以看作是节点之间相互“告知”它们对变量状态的“信念”。
- 收敛:
和积算法的直觉:分配律
为什么这个算法高效?因为它巧妙地利用了分配律来避免重复计算。
考虑计算边际概率 \(P(x_1) = \sum_{x_2, x_3, x_4} P(x_1,x_2,x_3,x_4)\) 假设 \(P(\mathbf{x}) \propto f_1(x_1,x_2) f_2(x_2,x_3) f_3(x_3,x_4)\)。
暴力计算
对每个 \(x_1\) 的取值,遍历所有 \(x_2, x_3, x_4\) 的组合。
和积算法 (智能计算):
\[
\large{P(x_1) \propto \sum_{x_2} f_1(x_1, x_2) \left( \sum_{x_3} f_2(x_2, x_3) \left( \sum_{x_4} f_3(x_3, x_4) \right) \right)}
\]
我们把求和符号尽可能地向内推,先对最里面的变量求和,然后将结果作为一个“消息”传递出去。这正是和积算法消息传递的数学本质。
本地真实数据小练习:观测条件概率,不是干预效应
使用江苏恒瑞医药 600276.XSHG 的本地前复权日行情,估计“今天下跌且成交量偏高”条件下“下一交易日下跌”的经验概率。
Code
from pathlib import Path # 使用统一路径对象定位数据文件
import pandas as pd # 读取HDF5并计算离散条件概率表
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
price_columns = ['close', 'volume'] # 只选择本练习所需字段以减少内存
hengrui_prices = pd.read_hdf(price_path, key='data', where='order_book_id == "600276.XSHG"', columns=price_columns).reset_index() # 选择长三角代表公司
hengrui_prices['date'] = pd.to_datetime(hengrui_prices['date']) # 统一交易日类型
hengrui_prices = hengrui_prices.query("'2015-01-01' <= date <= '2024-12-31'").sort_values('date') # 固定样本期并保持时序
today_return = hengrui_prices['close'].pct_change() # 先保留首日不可得收益为缺失
rolling_volume_median = hengrui_prices['volume'].rolling(20).median() # 先保留热身窗口为缺失
next_return = today_return.shift(-1) # 直接对齐下一交易日收益并保留末日缺失
hengrui_prices['today_down'] = today_return.lt(0).where(today_return.notna()).astype('Int64') # 仅在收益可得时离散化
hengrui_prices['volume_high'] = hengrui_prices['volume'].gt(rolling_volume_median).where(rolling_volume_median.notna()).astype('Int64') # 仅在20日窗口完整时离散化
hengrui_prices['next_day_down'] = next_return.lt(0).where(next_return.notna()).astype('Int64') # 仅在下一日收益可得时构造结果
observational_table = hengrui_prices.dropna().groupby(['today_down', 'volume_high'])['next_day_down'].agg(['mean', 'size']) # 计算经验条件概率与样本量
display(observational_table) # 展示所有条件组合而不预填运行数值
| today_down |
volume_high |
|
|
| 0 |
0 |
0.505942 |
589 |
| 1 |
0.496933 |
652 |
| 1 |
0 |
0.465008 |
643 |
| 1 |
0.472486 |
527 |
- 解释答案:
表中 mean 是 \(P(\text{next down}\mid\text{today state, volume state})\) 的样本估计。
它不等于强制改变成交量后的 \(P(\text{next down}\mid do(\text{volume high}))\),因为消息、波动和流动性等共同原因未被识别。
- 真实输出: 四格
(today_down, volume_high)=(0,0),(0,1),(1,0),(1,1) 的下一日下跌率为 0.5059、0.4969、0.4650、0.4725,样本量为 589、652、643、527。
本讲回顾:先作答再揭示
- 在链 \(A\rightarrow B\rightarrow C\) 中,给定 B 后 A 与 C 是否 d-分离?
- 在碰撞点 \(A\rightarrow B\leftarrow C\) 中,不给定 B 与给定 B 时分别如何?
揭示与补救
第 1 题是;第 2 题是不观测时分离、观测 B 或其后代时路径打开。任一题错时回到“三种基本结构”,逐路径标记非碰撞点与碰撞点。
综合练习:另一家长三角公司
Code
from pathlib import Path # 使用统一路径对象定位数据文件
transfer_code = '600104.XSHG' # 选择上海汽车集团作为长三角非金融迁移公司
# 公网下载:https://assets.qiufei.site/data/stock/stock_price_pre_adjusted.h5
# 下载后把下一行改为本机文件位置;按课程结构存放时可用 Path("data/stock/stock_price_pre_adjusted.h5")。
# Windows:Path(r"C:\qiufei\data\stock\stock_price_pre_adjusted.h5")
# macOS:Path("/Users/你的用户名/data/stock/stock_price_pre_adjusted.h5")
# Linux:Path("/home/你的用户名/data/stock/stock_price_pre_adjusted.h5")
price_path = Path("/home/ubuntu/r2_data_mount/data/stock/stock_price_pre_adjusted.h5")
transfer_prices = pd.read_hdf(price_path, key='data', where=f'order_book_id == "{transfer_code}"', columns=price_columns).reset_index() # 选择性读取同一最小字段
transfer_prices['date'] = pd.to_datetime(transfer_prices['date']) # 统一交易日类型
transfer_prices = transfer_prices.query("'2015-01-01' <= date <= '2024-12-31'").sort_values('date') # 固定与示范相同样本期
transfer_return = transfer_prices['close'].pct_change() # 保留首日不可得收益为缺失
transfer_volume_median = transfer_prices['volume'].rolling(20).median() # 保留热身窗口为缺失
transfer_next_return = transfer_return.shift(-1) # 对齐下一交易日收益并保留末日缺失
transfer_prices['today_down'] = transfer_return.lt(0).where(transfer_return.notna()).astype('Int64') # 只离散化可得当日收益
transfer_prices['volume_high'] = transfer_prices['volume'].gt(transfer_volume_median).where(transfer_volume_median.notna()).astype('Int64') # 只离散化完整滚动窗口
transfer_prices['next_day_down'] = transfer_next_return.lt(0).where(transfer_next_return.notna()).astype('Int64') # 只离散化可得下一日收益
transfer_table = transfer_prices.dropna().groupby(['today_down', 'volume_high'])['next_day_down'].agg(['mean', 'size']) # 计算四个经验条件单元
display(transfer_table.round(4)) # 展示完整参考输出
| today_down |
volume_high |
|
|
| 0 |
0 |
0.5044 |
563 |
| 1 |
0.5046 |
656 |
| 1 |
0 |
0.4817 |
683 |
| 1 |
0.4872 |
509 |
综合练习:结果与解释
- 完整参考输出:
四格 (today_down, volume_high)=(0,0),(0,1),(1,0),(1,1) 的下一日下跌率分别为 0.5044、0.5046、0.4817、0.4872,样本量为 563、656、683、509。
高成交量组与低成交量组差异都很小;
即使差异较大,也只能解释为观测关联,因为消息、波动和流动性可能同时影响成交量与下一日收益。
- 答题提示: 若写成“提高成交量导致次日下跌”,回到 conditioning/intervention;若未报告四格样本量,回到经验条件概率的支持度。
来源与延伸阅读
- Koller, D. and Friedman, N. (2009), Probabilistic Graphical Models, MIT Press。
- Pearl, J. (2009), Causality, 2nd ed., Cambridge University Press;邻近支持 conditioning 与 intervention 的区分。
- Lauritzen, S. L. (1996), Graphical Models, Oxford University Press。
- 数据:本地
stock_price_pre_adjusted.h5 / data;本页经验表由代码生成。
核心内容总结:有向概率图模型
- 维度灾难 促使我们寻找简化联合概率分布的方法。
- 概率图模型 利用 条件独立性 将复杂分布分解为局部函数的乘积;d-分离保证图蕴含的独立性,而 d-连接本身不证明统计或因果依赖。
- 贝叶斯网络 (有向图) 使用条件概率编码因子分解;只有额外结构因果假设成立时才可解释为因果 DAG。
拓展内容 总结:无向图与通用推理
- 马尔可夫网络 (无向图) 使用势函数,适合建模对称关系,其联合概率由极大团上的势函数乘积给出(Hammersley-Clifford定理)。
- 因子图 为两种模型提供了统一的、更精细的表示,是通用推理算法的基础。
- 置信传播 (和积算法) 是在图模型上进行高效推理的核心算法,其本质是利用分配律避免重复计算。
本章关键要点
- 结构就是假设:图中的每一个节点和每一条边(或缺失的边)都是一个关于世界如何运作的假设。
- 分解是关键:将一个大的、棘手的问题分解成许多小的、可管理的问题。
- 推理先分语义:普通 BN 查询回答“观察到以后”,干预问题需要
do(·) 与因果可识别性。