城市里来了一位擅长从观察中找真相的侦探。他接到一个古怪的委托:不看任何人际档案,只凭一群人日常活动的同步记录,画出一张“谁真正影响谁”的有向关系网。侦探的思路很朴素:第一步,先假设所有人两两之间都可能有关联,画一张密不透风的嫌疑网,再用统计证据把“伪关联”一条条划掉——比如两个人总是同时出现,但控制住他们共同的上线后,两人的默契立刻消失,于是这条线就是假的。第二步,对剩下的关系判断方向。他先嗅出“两个互不往来的人却都汇聚到同一个人身上”的罕见结构,再像推多米诺骨牌一样,把箭头方向逐步传播到全网。 这套破案流程,正是因果发现领域大名鼎鼎的 PC 算法:先用条件独立性检验找出因果图的骨架,再用 V 结构和 Meek 规则把无向边定向为因果箭头。本文就用侦探的视角,带你完整走一遍这两个阶段,并亲手实现一个能跑的 PC 算法。
掌握 PC 算法的骨架发现与 Meek 规则定向,是进入因果结构学习的第一道门槛。无论你要做可解释 AI、反事实推理还是政策评估,这项技能都能让你从纯观测数据中逼出因果方向。
可视化演示
动态演示PC算法骨架发现与Meek规的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
PC算法骨架发现与Meek规:PC算法 PC算法骨架发现的独立性检验策 骨架学习的具体算法流程与优化 核心机制可视化 PC算法骨架发现与Meek规整体架构与关键组件
算法整体流程
侦探接手案子后,并不急着追问“谁指挥谁”。他心里清楚,方向判断是难题,得放在后面。第一轮工作只是“盘关系网”:先假设所有人都两两有联系,再用证据一条条划掉虚假联系。等网眼稀疏了,才进入第二轮,研究每个联系的箭头指向。这种“先结构、后方向”的分工,正是 PC 算法的灵魂。
PC 算法由 Peter Spirtes、Clark Glymour 和 Richard Scheines 提出,名字取自两位作者的首字母。它把因果发现拆成两个可独立优化的子问题:第一阶段,从完全无向图出发,通过条件独立性检验逐条删除“可以被其他变量解释掉”的边,得到骨架;第二阶段,先识别对撞结构(V 结构)作为定向的种子,再反复套用 Meek 规则把方向传递给剩余的无向边。整个过程如图:
侦探的这份报告分两卷:第一卷是无向关系图,第二卷才标箭头。PC 算法也是一样,先保证结构不出错,再安心定方向——两阶段的严谨分工,是它几十年仍是因果发现基准算法的原因。
- G0 完全图初始状态,每个变量都与其他所有变量有一条无向边,代表“暂时无法排除任何联系”。
- 第一次箭头对每对变量,在给定其他某些变量的条件下做独立性检验。若条件独立成立,就删除这对变量之间的边。
- Gs 骨架删边后的剩余无向图,只保留“数据还不足以否认直接关联”的边。
- 第二次箭头先找出 V 结构定出第一批方向,再让 Meek 规则把方向一条条传播出去。
- P̂ 输出最终得到部分有向无环图,有的边带箭头,有的边仍是无向,表示数据无法再区分的方向。
条件独立性检验
侦探手里需要一件“测谎仪”,用来判断两人在某个中间人在场时是否还真的同步。如果他发现“控制住上线后,两人的默契就消失了”,那就说明他们之间没有直接关系。这件测谎仪,就是统计里的条件独立性检验。
在连续型数据且近似高斯分布的场景下,PC 算法最常用的检验工具是偏相关检验。偏相关系数衡量的是“剔除 Z 的影响后,X 和 Y 还剩下多少线性关联”。如果偏相关为零,就说 X 和 Y 在给定 Z 的条件下独立:
实际做假设检验时,样本偏相关 $\hat{\rho}$ 的分布有偏,通常先做 Fisher Z 变换再查正态分布:
侦探的测谎仪校准好了:只要控制条件集后测得“偏相关为零”,他就在嫌疑网中划掉一条线。这个判断标准贯穿整个骨架发现阶段。
- 样本偏相关$\hat{\rho}$ 是从观测样本中估计出的偏相关系数,是真实值的近似。
- 对数变换把 [-1, 1] 区间上的相关系数映到整个实数轴,分布更接近正态。
- 正态近似零假设下 T 近似服从均值为 0、方差为 $1/(n-|\mathbf{Z}|-3)$ 的正态分布,n 是样本量。
- 决策规则若 |T| 超过正态分布临界值,则拒绝“条件独立”;否则接受独立性,删掉这条边。
骨架发现算法
侦探拿着测谎仪,开始动手清理嫌疑网。他给自己定下规矩:先从最简单的场景查起——不带任何中间人的对话。两人若毫无互动,直接划掉线;若互动显著,则暂保留。接着升级难度,每轮“约谈”时引入一个中间人、两个中间人……直到所有可疑关系都被审过。
PC 的骨架发现正是这种从低阶到高阶的层进搜索。记 $k$ 为条件集大小,算法从 $k=0$ 开始,对每对还有边的变量,尝试所有大小为 $k$ 的候选条件集。只要找到一个条件集使它们条件独立,就删除这条边,并把该条件集记为分离集:
在每次删除边的同时,算法会悄悄记下一笔:“X 和 Y 之所以无关,是因为给定 $\mathbf{S}$ 之后它们才独立”。这笔记录就是分离集 $\mathrm{Sep}(X,Y)=\mathbf{Z}$。别小看它,V 结构定向全靠这份“不在场证明”。当所有剩余边的邻居数都小于当前 k 时,就再也没有更大的条件集可试,骨架阶段提前终止。
侦探画完了稀疏的关系网,但他没急着高兴,因为每条被划掉的线旁边都标着“他们在谁在场时反而不交流”——这些备注,就是后面判断箭头方向的破案线索。
- 邻接集合Adj(X) 是当前骨架中 X 的邻居集合,初始时等于除 X 外的所有变量。
- 条件集限制条件集 Z 只能从 X 的邻居中挑选,且不包含 Y。这是 PC 算法控制搜索量的关键。
- k 阶检验k 从 0 开始逐级递增,先做无条件独立性检验,再做一阶、二阶……逐层加码。
- 删除边只要找到一组 Z 让两者条件独立,边就永久删除,邻接关系随之更新,后续搜索范围也跟着缩小。
V结构定向
侦探盯着关系网,发现了一个奇特的三人局面:A 和 C 从无直接往来,却都不约而同地与 B 保持频繁互动。这意味着 B 是那个“汇合点”——在因果结构里,这可能是最关键的对撞结构(V 结构):两个独立的箭头同时指向同一个节点。
在骨架图中识别 V 结构,要寻找“非相邻对 X、Y 的共同邻居 Z”。如果 Z 不在 X 和 Y 的分离集中,说明 Z 并不能解释两者的独立性,反而会让两者在给定 Z 时变得相关——这正是对撞子的特征。于是定向为:
识别出第一个 V 结构后,定向工作就有了“种子”。就像侦探抓住了一个关键证人,突破口一旦打开,剩下的方向就可以顺着逻辑链条层层推进。
- 非相邻对在骨架中 X 与 Y 之间没有边,这是对撞结构的前提条件。
- 共同邻居 ZZ 同时与 X 和 Y 相连,构成“人字形”结构。
- 分离集判据骨架阶段记录了 Sep(X,Y),即“能让 X、Y 独立的变量集合”。
- 定向结论若 Z 不在分离集中,说明 Z 是典型的对撞子,两条边都应指向 Z。
Meek规则定向
侦探拿到了第一批箭头,但网里还剩不少无向边。他总结出几条铁律:只要满足某些局部图案,方向就能唯一确定。这组铁律由 Meek 于 1995 年系统整理,称为 Meek 规则。其中最核心的是 R1、R2、R3 三条。
除了 R1-R3 之外,还存在一条处理复杂嵌套路径的 R4 补充规则,它在实际数据中触发频率极低,多数教科书把它作为完整性的收尾。
侦探的箭头像多米诺骨牌:R1 推出一个方向,这个方向又触发新的 R2、R3 条件,直到所有能定的方向都定完。当然,总有些边无论怎么推都定不出方向——那就留下来,成为“悬案”。
- 同源节点A 同时指向 B 和 C,A 是两个箭头的共同源头。
- 待定向边B 与 C 之间是无向边。
- 一致性若反过来定向 C→B,会改变 A 与 B、A 与 C 的既有父子关系,破坏条件独立集。
- 结论定向为 B→C。
马尔可夫等价类
侦探最后发现,有些箭头无论证据多充分都分不清。比如“甲影响乙”和“乙影响甲”这两张因果图,只要它们的骨架一样、对撞结构一样,观察数据就永远无法区分。这组“无法被数据区分的因果图”,被称为同一个马尔可夫等价类。
Verma 与 Pearl 给出了一个漂亮的定理:两个 DAG 等价,当且仅当它们的骨架相同且 V 结构集合相同:
PC 算法输出的 PDAG(部分有向无环图)正是对等价类的紧凑表示:有向边就是等价类中所有图都一致的方向,无向边则表示“这条边的方向在等价类里可以取两种可能”。
侦探的最终报告没有强行编造无法确定的箭头,而是在那些边上标注“未定向”。这不是无能,而是诚实——观测数据的信息量本身就有限。
- 骨架 Sk(G)去掉所有箭头方向后得到的无向图,代表变量间是否存在直接关联。
- V 结构集合 Vstr(G)图中所有对撞结构的集合,每个对撞结构都对应一条独特的条件独立模式。
- 等价条件两个条件同时成立,两个 DAG 编码的条件独立关系就完全相同。
- 实践含义观测数据最多把因果图定位到一个等价类,而不是单张图。
复杂度与优化
侦探的搜查策略如果太笨,会对所有嫌疑人的任意组合都做一次测谎,嫌疑人数一多,工作量立刻爆炸。PC 算法在最坏情况下也是如此:条件集要从所有其余变量中任意挑选,检验次数随变量数呈指数增长。
这让“邻接集合约束”成了 PC 最重要的剪枝手段:条件集只从当前邻居中取,而不是从所有变量中随便挑。每删一条边,所有相关节点的邻居数就减少一轮,后续搜索成本跟着骤降。再加上按 k 从低到高的层级终止策略,以及各变量对之间彼此独立的检验可并行化,PC 算法在高维稀疏问题上依然实用。
侦探的经验是:先锁定小圈子,再深入调查。现实世界的大多数因果图是稀疏的,PC 算法正是借了“稀疏”这个东风。
- p 为变量数参与因果发现的变量个数,直接决定搜索空间大小。
- 组合数从 p-2 个候选变量中选 k 个作为条件集,组合数随 k 变化。
- 求和最坏情况下需要对所有可能的 k 都做一次穷举检验。
- 改进空间如果真实因果图的邻居数很小,条件集大小 k 被邻居数限制,检验次数会降到多项式级。
应用与局限
侦探在报告末尾总会加一行小字:“本结论假设不存在隐藏的干扰者。”这不是推卸责任,而是 PC 算法赖以成立的基石——忠实性假设:数据分布中的条件独立关系,必须与图结构中的 d-分离关系完全一致。
在基因调控网络推断中,研究者用基因表达数据跑 PC 算法,识别转录因子到靶基因的调控方向;在经济政策分析里,经济学家从宏观时间序列中寻找政策变量与消费、投资之间的因果方向。但无论场景多诱人,都要警惕:PC 输出的是等价类而非唯一真相,而且它对独立性检验的错误极其敏感——一次假阳性删边就可能传导出完全不同的结构。
侦探合上卷宗,总结道:PC 算法是观测数据中探索因果方向的强大工具,但它更像一张精心绘制的“嫌疑地图”,而不是盖了章的判决书。
- I(G)图中所有由 d-分离推导出的条件独立关系集合。
- I(P)观测数据分布中所有真实存在的条件独立关系集合。
- 等式成立图里的每个分离关系都能在数据中验证,反之亦然,二者一一对应。
- 条件脆弱如果存在隐藏的共同原因、选择偏差或严重的检验误差,等式可能被破坏。
AI 应用场景
基因调控网络推断
阶段:科学发现(因果结构学习)
解决的问题:传统相关性分析只能给出“哪些基因一起变化”,无法区分调控方向。生物学家想知道“哪个转录因子驱动了哪个靶基因”,这需要因果方向。PC 算法通过条件独立性检验删除间接关联,再用 V 结构和 Meek 规则推导出调控箭头,直接输出可解释的基因调控网络。
具体案例:某课题组拿到乳腺癌细胞系的 RNA-seq 表达矩阵(约 8000 个基因、300 个样本),先筛选出 50 个候选转录因子,再用 PC 算法学习子网络。结果发现某个已知癌基因被多个转录因子共同指向,形成清晰的 V 结构,这为后续湿实验验证提供了精准的靶点清单。
经济政策因果分析
阶段:因果推断(观测数据反事实分析)
解决的问题:经济学家无法对货币政策做随机对照实验,只能观察宏观时间序列。PC 算法可以从利率、通胀、就业等指标中梳理出“谁先变化、谁跟着变化”的因果次序,为政策评估提供骨架支撑,避免把相关性误当因果。
具体案例:某智库分析 2000-2020 年的季度宏观数据,用 PC 算法构建利率、货币供应量、CPI 和 GDP 之间的因果骨架。算法识别出“利率→货币供应量→CPI”的传导链,并借助 Meek 规则确定了方向,为后续结构向量自回归模型提供了先验结构。
推荐系统因果纠偏
阶段:反事实推理(用户行为因果建模)
解决的问题:推荐系统中的点击数据存在严重的曝光偏差:用户只能点击“被推荐的东西”,直接拟合点击率会把曝光机制当成用户偏好。PC 算法可以在用户特征、曝光物品、点击行为之间建立因果结构,识别出“曝光→点击”这一对撞结构,从而指导做反事实纠偏。
具体案例:某电商平台用用户活跃度、商品热度、是否曝光、是否点击四类变量跑 PC 算法,发现“用户活跃度→点击”和“商品热度→点击”构成 V 结构,而曝光是独立干扰项。基于这个结构,团队调整了排序模型的样本权重,离线 AUC 提升 3 个百分点。
Python 演示
import mathfrom itertools import combinations import numpy as np def gen_data(n=500, seed=42): rng = np.random.default_rng(seed) A = rng.normal(size=n) C = rng.normal(size=n) B = 0.5 * A + 0.5 * C + rng.normal(size=n) * 0.3 D = 0.5 * B + rng.normal(size=n) * 0.3 return np.column_stack([A, B, C, D]) def partial_corr(data, i, j, cond): if not cond: r = np.corrcoef(data[:, i], data[:, j])[0, 1] else: idx = [i, j] + list(cond) cov = np.cov(data[:, idx].T) prec = np.linalg.inv(cov) r = -prec[0, 1] / math.sqrt(prec[0, 0] * prec[1, 1]) return r def indep_pvalue(data, i, j, cond): n = data.shape[0] r = partial_corr(data, i, j, cond) z = 0.5 * math.log((1 + r) / max(1 - r, 1e-12)) stat = abs(z) * math.sqrt(n - len(cond) - 3) return 2 * (1 - 0.5 * (1 + math.erf(stat / math.sqrt(2)))) def skeleton(data, alpha=0.05): n, p = data.shape adj = [[True if i != j else False for j in range(p)] for i in range(p)] sepset = {} for k in range(p - 1): changed = False for i in range(p): for j in range(i + 1, p): if not adj[i][j]: continue neigh = [c for c in range(p) if adj[i][c] and c != j] if len(neigh) < k: continue for cond in combinations(neigh, k): if indep_pvalue(data, i, j, list(cond)) > alpha: adj[i][j] = adj[j][i] = False sepset[(i, j)] = list(cond) changed = True break if not changed and k >= 2: break return adj, sepset def orient(adj, sepset): p = len(adj) E = [['' for _ in range(p)] for _ in range(p)] for i in range(p): for j in range(i + 1, p): if adj[i][j]: E[i][j] = 'u' E[j][i] = 'u' for x in range(p): for y in range(p): if x == y or adj[x][y]: continue for z in range(p): if z == x or z == y: continue if adj[x][z] and adj[y][z] and z not in sepset.get((x, y), []): E[x][z] = 'd' E[z][x] = '' E[y][z] = 'd' E[z][y] = '' changed = True while changed: changed = False for a in range(p): for b in range(p): if E[a][b] != 'd': continue for c in range(p): if E[b][c] == 'u' and not adj[a][c]: E[b][c] = 'd' E[c][b] = '' changed = True if E[a][c] == 'd' and E[b][c] == 'u': E[b][c] = 'd' E[c][b] = '' changed = True if E[c][b] == 'd' and E[a][c] == 'u': E[a][c] = 'd' E[c][a] = '' changed = True return E def report(adj, E): p = len(adj) print('骨架边:') for i in range(p): for j in range(i + 1, p): if adj[i][j]: print(f' {chr(65+i)} - {chr(65+j)}') print('定向结果:') for i in range(p): for j in range(p): if E[i][j] == 'd': print(f' {chr(65+i)} -> {chr(65+j)}') if __name__ == '__main__': data = gen_data() adj, sepset = skeleton(data, alpha=0.05) E = orient(adj, sepset) report(adj, E)
B = 0.5 * A + 0.5 * C + rng.normal(size=n) * 0.3生成数据时植入真实因果结构:A 和 C 共同驱动 B,B 再驱动 D。prec = np.linalg.inv(cov)对协方差矩阵求逆得到精度矩阵,偏相关可由精度矩阵元素一步导出。r = -prec[0, 1] / math.sqrt(prec[0, 0] * prec[1, 1])用精度矩阵计算偏相关,正负号来自矩阵求逆的代数结构。neigh = [c for c in range(p) if adj[i][c] and c != j]候选条件集只从当前邻居中取,这是 PC 算法控制搜索量的关键。for cond in combinations(neigh, k)遍历所有大小为 k 的条件集,从低阶到高阶逐一检验。sepset[(i, j)] = list(cond)记录分离集:这组变量能让 i 与 j 独立,是后续 V 结构定向的重要证据。if adj[x][z] and adj[y][z] and z not in sepset.get((x, y), [])V 结构判定核心:Z 是共同邻居且不在分离集中,则定向为对撞结构。if E[b][c] == 'u' and not adj[a][c]Meek 规则 R1:A→B 且 B-C 无向,而 A 与 C 不相邻时,定向 B→C。
常见误区
误区我以为 PC 的骨架发现就是计算所有变量两两之间的相关系数,显著的保留,不显著的删掉。条件独立性检验听起来很高级,但好像只是锦上添花。
正解零阶无条件检验只是第一层筛子。真实场景中,两个变量可能因为共同原因而表现出虚假相关,比如“夏天冰淇淋销量”和“溺水人数”高度相关,但它们之间没有直接因果边。PC 算法的核心是高阶条件独立性检验:在控制中间变量后,若两者仍相关才保留边。只做零阶检验会把大量间接关联误判为直接关联,骨架必然失真。
为何常见:零阶检验最容易理解,初学者往往先入为主地把它当成全部;且没有意识到“控制中间人后关系消失”恰恰是伪关联的信号。
误区我以为跑完 PC 算法,所有边都会被标上箭头,得到一张完整的因果有向图,可以直接交给业务方当最终结论。
正解当多个 DAG 属于同一马尔可夫等价类时,观测数据根本无法区分某些边的方向。PC 算法输出的是 PDAG/CPDAG,无向边表示“等价类内方向可翻转”。强行定向反而会给出无法用数据支撑的伪因果结论,误导后续分析。
为何常见:“因果发现”这个名字太有迷惑性,让人觉得输出就是确定答案;加上很多教程展示的玩具例子恰好所有边都能定向,掩盖了等价类的存在。
误区我总觉得只要独立性检验的 p 值大于 0.05,就证明两个变量百分之百条件独立,删掉这条边是绝对安全的。
正解假设检验只能给出概率证据,不能给出绝对结论。p 值大于阈值只表示“没有足够证据拒绝独立”,样本量小、信噪比低、分布偏离假设时都可能误判。PC 算法对检验错误极其敏感——一条边误删,后续分离集和 V 结构定向都会连锁出错,这被称为“检验误差传播”。
为何常见:统计检验中的“不拒绝原假设”与“接受原假设”在直觉上很难区分,初学者容易把两者画上等号。
误区我听说 PC 算法用 Meek 规则定向,就以为只要不断套用 R1、R2、R3,所有边都能自动定出方向,V 结构只是可选的补充。
正解V 结构定向是整个定向阶段的起点。Meek 规则只是一套传播机制,它需要已有的一些有向边作为“种子”。如果全图没有任何 V 结构可识别,Meek 规则面对一个完全无向的骨架也无从下手。先有 V 结构定出初始箭头,Meek 规则才能把方向逐条传播出去。
为何常见:文章标题常突出 Meek 规则,读者自然以为它是主角,忽略了它只是“放大器”而非“发电机”。
误区我认为 PC 算法是通用因果发现工具,不管有没有隐藏变量、不管数据是高斯的还是离散的,拿过来就能跑出正确答案。
正解PC 算法建立在两个关键假设上:忠实性假设(数据中的条件独立关系与图结构完全一致)和因果充足性假设(不存在未观测的共同原因)。如果存在隐藏变量,PC 会输出错误骨架;数据高度非线性或混合类型时,偏相关检验也不再适用,需要换用核方法或互信息类检验。面对复杂数据,应使用 FCI 算法或更稳健的非参数检验。
为何常见:很多教程只展示理想化数据上的成功案例,让人误以为 PC 是万能黑箱,忽略了它背后的强假设。
面试题
Q1. PC 算法的骨架发现阶段,初始图是什么?
- A.空图,边逐步添加
- B.完全无向图,边逐步删除← 正确答案
- C.随机有向图
- D.由先验知识决定
答案:B。PC 算法从完全无向图出发,假设所有变量都可能有直接关联,再通过条件独立性检验逐步删边。这与从空图加边的思路相反,也是它作为“约束方法”的典型特征。
Q2. 高斯数据下,PC 算法判断条件独立的主要工具是什么?
- A.直接比较直方图
- B.检验偏相关系数是否为零← 正确答案
- C.最大似然估计参数
- D.删除缺失值样本
答案:B。高斯分布中,偏相关为零等价于条件独立。PC 算法通常用 Fisher Z 变换检验偏相关系数的显著性,这也是它在连续数据场景下最常用的条件独立判定方式。
Q3. 关于分离集(Sepset)的描述,正确的是?
- A.能使两变量条件独立的变量集合← 正确答案
- B.使两变量相关性最强的变量集合
- C.只在删边后丢弃不用的中间量
- D.等于所有变量的全集
答案:A。骨架阶段删除边时记录的那组条件变量就是分离集。它随后用于 V 结构定向:如果共同邻居不在分离集中,说明该邻居是对撞子。分离集贯穿两阶段,绝非无用信息。
Q4. 识别 V 结构时,对三元组 X-Z-Y 的判定条件是什么?
- A.X 与 Y 不相邻,且 Z 不在分离集中← 正确答案
- B.X 与 Y 相邻,且 Z 在分离集中
- C.X 与 Z 不相邻
- D.三个变量完全相互独立
答案:A。V 结构 X→Z←Y 中,X 与 Y 在骨架中不相邻,且 Z 出现在两者共同邻居中。若 Z 不在 Sep(X,Y) 中,说明给定 Z 时 X 与 Y 反而相关,这是对撞子独有的特征。
Q5. 以下哪些属于 Meek 规则的定向逻辑?
- A.已知 A→B 且 B-C 无向,A 与 C 不相邻,则 B→C← 正确答案
- B.已知 A→B→C 且 A-C 无向,则定向 A→C← 正确答案
- C.已知 A→B 且 A→C,B-C 无向,则定向 B→C← 正确答案
- D.两变量无条件独立时直接删除该边
答案:ABC。A 是 R1(防新增对撞),B 是 R2(防有向环),C 是 R3(同源一致性)。D 属于骨架发现阶段的删边规则,不是 Meek 定向规则。
Q6. 两个 DAG 属于同一马尔可夫等价类的充要条件是?
- A.有向边的数量相同
- B.骨架相同且 V 结构集合相同← 正确答案
- C.变量数量相同
- D.条件概率表参数相同
答案:B。Verma-Pearl 定理指出,骨架和 V 结构集合共同决定条件独立关系,两者相同则 DAG 等价。边数、变量数或参数都远不足以刻画等价性。
Q7. PC 算法输出 PDAG 中的无向边表示?
- A.该边方向无法由观测数据区分← 正确答案
- B.等价类内该边可朝两个方向之一← 正确答案
- C.该变量不在因果结构内
- D.该边方向由先验知识强制确定
答案:AB。无向边是等价类中“方向未被确定”的边,可以在两个方向上翻转而不改变条件独立关系。它不是无关变量,也不是被先验固定的边。
Q8. PC 骨架搜索中,条件集 Z 为什么只从 X 的邻居中选取?
- A.减少检验次数且保持算法统计性质← 正确答案
- B.邻居变量更容易通过检验
- C.随机选择会引入偏差
- D.条件集大小必须固定为 1
答案:A。PC 的核心剪枝策略就是条件集仅从当前邻居中取。这大大缩小了候选集合的规模,使算法在高维稀疏图上可行,同时不破坏条件独立性判定的可靠性。
Q9. 在忠实性假设下,以下哪项描述成立?
- A.图中 d-分离与数据条件独立一一对应← 正确答案
- B.所有变量间都必须存在边
- C.条件独立关系只与样本量有关
- D.因果方向总可以被完全确定
答案:A。忠实性假设要求 I(G)=I(P),即图中的 d-分离关系与数据中的条件独立关系完全一致。它保证了 PC 算法的正确性,但并不能突破等价类限制,方向仍可能无法完全确定。
Q10. 在高维小样本场景(p 接近甚至大于 n)下,PC 算法面临哪些困难?
- A.独立性检验误差迅速累积← 正确答案
- B.候选条件集组合数量爆炸← 正确答案
- C.输出结果反而更加精确
- D.不再需要任何统计假设
答案:AB。高维下样本信息不足,偏相关估计不稳,检验错误会沿删边过程传导放大;同时条件集组合随邻居数指数增长。PC 并不会因此变得更准,忠实性等假设依旧不可或缺。