在一场热闹的聚会上,小A和小B经常同时出现,朋友圈照片里也总有他俩。你能因此断定“小A喜欢小B”吗?也许他们只是共同朋友多,也许两人都在追求同一位女神——小A在女神面前献殷勤,小B也在女神面前刷存在感,而小A和小B彼此之间却毫无交集。真正的情感侦探都知道:相关不等于动心,方向才是爱情的真相。因果发现(causal discovery)做的正是这件事:从一堆观测数据里,还原“谁在影响谁”的因果网络。其中,基于约束的方法是一套严谨的“侦探工作流”:先用条件独立性检验筛掉虚假关系、画出可疑的关系网;再通过“情敌现形”式的碰撞器结构锁定第一批箭头方向;最后靠“八卦传播”式的推理规则,把剩余方向一个个推出来。这篇文章,我们就跟着这位情感侦探,学会如何从同框记录里严谨地确定因果方向。
方向确定是因果发现从“相关”走向“因果”的关键一跃。掌握它,你才能从数据中得到可解释的因果结论,而不是停留在相关性报表上。
可视化演示
展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T
方向确定概论
作为新上任的情感侦探,你的第一课是:别急着下结论。委托人递来厚厚一沓“社交出席记录”——谁在哪场聚会上出现过。你发现小X和小Z每场必同框,于是兴奋地在报告上写“X喜欢Z”。老侦探摇了摇头:同框只能说明有关联,也许是Z在追X,也许是两人都爱参加同一类活动(共同原因)。在因果发现的世界里,道理一模一样:观测数据里的相关关系,永远无法直接告诉你箭头的指向。
因果发现用有向无环图(DAG)描述变量间的因果结构:X→Z表示X是Z的原因。基于约束的方法(constraint-based methods)是因果发现中的一大流派。它不像评分搜索那样“大海捞针”地找图,而是像侦探一样按证据链推进:先用条件独立检验过滤掉虚假的“同框”,得到一张无方向的骨架,再通过方向确定(orientation)规则给边赋上箭头。
约束方法的理论根基是因果马尔可夫条件(Causal Markov Condition):给定一个变量的直接原因(父节点)后,它与所有非后代变量条件独立。这等于说:只要你把“真正的心动对象”控住,当事人对其他人的反应就只剩随机波动。这个性质把“数据中的条件独立”与“图中的结构信息”一一挂钩——它既是删边依据,也是方向确定的出发点。
因果马尔可夫条件,就是侦探手册开篇的第一条铁律:想判断一段关系是不是“真感情”,先控制住可疑的中间人。有了这条铁律,你才能在后面的排查中,理直气壮地删掉那些“只是朋友”的边。
- 父节点集合$\mathrm{Pa}(X)$ 表示X的直接原因。在情感比喻里,父节点就是真正让X“心动”的因素。
- 非后代集合$\mathrm{NonDesc}(X)$ 表示除X的后代外所有变量,即不受X因果影响的对象。
- 条件独立$X \perp\!\!\!\perp \mathrm{NonDesc}(X)$ 表示在给定父节点后,X与这些变量统计独立。
- 因果应用若数据发现X与某变量在给定候选父节点下条件独立,则它们之间不存在直接因果边。
骨架构建基础
侦探的第一份实操作业:画关系草稿图。先把所有“怀疑有直接联系”的人两两连一条虚线——不看方向,只看有没有边。这就像警察办案先画嫌疑人关系网:谁和谁有交集先连上,至于谁指挥谁,后面再说。草稿图画得越准,后面破案就越省力。
在因果图里,这张只有无向边的“草稿图”叫骨架(skeleton)。构建骨架的核心工具是条件独立性检验:如果X和Y在给定某个变量集合S后变成独立,就说明X和Y之间没有直接因果边,虚线可以擦掉;如果控制谁都无法让它们独立,这条边就要留住。
技术细节在于如何找条件集S。经典PC算法用“由小到大”的搜索策略:先做0阶(无条件)检验,再把条件集扩大到1个、2个……直到穷尽所有候选。条件独立的定义如下:
回到侦探视角:当你发现“小A和小B总是同框,但只要小C不在场,两人就毫无互动”,就能排除A和B之间有直接的“业务往来”。骨架阶段删掉的边越多,后续定向就越省力——这步做扎实,方向确定就成功了一半。
- 联合条件概率$P(X, Y \mid Z)$ 是给定Z条件下X和Y同时发生的概率。
- 乘积分解$P(X \mid Z) \cdot P(Y \mid Z)$ 表示在Z条件下X、Y各自独立地发生的概率之积。
- 独立性判据等式成立意味着给定Z后X与Y不再互相传递信息。
- 骨架决策找到这样的Z就删除X—Y边,并记录Z为分离集。
碰撞器定向
重大突破!你发现小X和小Y从不一起出现,但每当女神Z在场,两人都会活跃起来——一个抢着搬椅子,一个抢着递话筒。更妙的是,一旦Z不在,两人又回到“互不认识”。你一拍大腿:这不是巧合,这是情敌结构!
因果图里,这种“两个原因共同指向一个结果”的结构叫碰撞器(collider),也叫v-structure:X→Z←Y。它的统计指纹独一无二:X和Y无条件独立,但给定Z后反而条件依赖。原因在于X和Y都影响Z,当你“固定”Z时,X和Y之间就出现了由Z传导过来的信息竞争通道。
这个“独立→依赖”的翻转,是方向确定最关键的实锤。它的形式化表达如下:
老侦探把这招叫作“情敌现形法”:想确认两个看似无关的人是否指向同一个目标,就看看在“目标在场”时他们是否会反常地相关。这第一条箭头一旦落地,后面的方向就能连环解锁。
- 无条件独立$X \perp\!\!\!\perp Y$ 表示两个原因原本独立(情敌互不相识)。
- 条件依赖$X \not\!\perp\!\!\!\perp Y \mid Z$ 表示给定共同结果Z后反而出现依赖(竞争关系暴露)。
- 合取条件$\wedge$ 表示上述两个条件同时成立时触发推断。
- 定向结论$\Longrightarrow$ 推出箭头指向Z,即Z是共同结果。
传播定向规则
有了第一条实锤箭头,剩余虚线边不需要一个个蹲点。职业侦探的杀手锏是“八卦传播”:既然X→Z已实锤,又知道Z和W经常互动、且X与W毫无交集,那么Z指向W几乎是必然——否则就会凭空造出一个与证据冲突的“情敌结构”。
这就是Meek规则(R1–R4)的思想内核。它们把“已知箭头 + 无向边 + 无环约束”组合起来,用排除法为剩余边定向。四条规则中最核心的R1表述为:若X→Y且Y—Z是无向边,且X与Z不相邻,则只能定向为Y→Z。
为什么只能这样?若反着假设Z→Y,那么X→Y←Z就会构成碰撞器。但碰撞器已经在上一阶段被全网扫描过——Y并不是碰撞器。反向假设与已有证据冲突,因此只有Y→Z这一种解释。R1的公式如下:
Meek规则就像朋友圈的八卦推理:“A暗恋B”是实锤,“B和C走得很近”,“A和C根本不认识”——那B指向C还有什么悬念?四条规则合起来,能够完全定向所有可定向的边,构成方向确定的“完备推理机”。
- 已知箭头$X \to Y$ 是已确定方向的边(侦探手上的实锤)。
- 无向边$Y - Z$ 是尚不知道方向、等待定夺的边。
- 不相邻条件$(X, Z \notin E)$ 表示X和Z之间没有边,排除了反向形成碰撞器的可能。
- 传播结论$\Longrightarrow$ 推出Y→Z,方向沿路径向前传递一格。
PC算法解析
现在把侦探的手艺整理成一本标准化办案手册。PC算法(Peter-Clark)是目前最经典的基于约束的因果发现算法,把方向确定拆成三个清晰阶段:骨架发现、碰撞器识别、Meek传播。
第一阶段,骨架发现:算法从全连接图出发,对每对变量做条件独立性检验;每找到一个让X⊥Y|S成立的条件集S,就删除这条边并记录S(分离集),供后续定向使用。搜索遵循“从低阶到高阶”:先查无条件独立,再查1个条件变量、2个……直到穷尽所有候选。
骨架阶段的形式化判据如下:
第二阶段,碰撞器识别:对每个“三节点组”(X—Z—Y且X与Y不相邻),检查Z是否为碰撞器——用分离集判断:如果X⊥Y(无条件)且X不⊥Y|Z,则定向X→Z←Y。第三阶段,Meek规则传播剩余方向。三步走完,能识别的方向全部落袋。PC算法让“情感侦探”从凭直觉断案升级为标准化流水线:骨架发现是全城排查,碰撞器识别是锁定情敌,Meek传播是八卦连锁——可靠、高效、可复现。
- 邻接集合$\mathrm{Adj}(X)$ 是当前骨架中X的所有邻居。
- 候选条件集$S \subseteq \mathrm{Adj}(X) \setminus \{Y\}$ 表示从X的邻居中排除Y后取子集。
- 存在性检验$\exists\, S$ 表示只要存在任何一个这样的条件集使条件独立成立。
- 删边动作满足上述存在性即删除边X—Y,算法进入下一对变量。
马尔可夫等价类
侦探也有认怂的时候。你查清了一条“三角暗恋”:X→Z←Y。可是,另一条链X→Y→Z呢?数据显示X和Y总同框、Y和Z也总同框、X和Z不同框……所有条件独立关系都对得上,但你永远无法用观测数据区分X→Y→Z、X←Y←Z和X←Y→Z这三种解释。这是一桩“数据无法定罪”的悬案。
数学上,这些共享相同条件独立关系的DAG构成一个马尔可夫等价类(Markov equivalence class)。图论给出简洁判据:两个DAG等价,当且仅当它们的骨架相同且碰撞器集合相同。也就是说,方向确定能解决的是“骨架 + 碰撞器”决定的部分,剩下的方向只能悬置。
老侦探会在结案报告里写清楚:“本案箭头已确定到最大可识别程度,剩余方向需补充干预实验或纵向跟踪数据。”在实际输出中,我们用部分有向无环图(CPDAG)表达等价类:可识别的边画成箭头,不可识别的边保持无向。敢于承认不确定性,才是真正专业的因果分析。
- 骨架相同$\mathrm{Skel}(\mathcal{G}_1) = \mathrm{Skel}(\mathcal{G}_2)$ 表示两个图的无向边集合完全一致。
- 碰撞器相同$\mathrm{VStr}(\mathcal{G}_1) = \mathrm{VStr}(\mathcal{G}_2)$ 表示两个图的v-structure集合一致。
- 等价判定$\iff$ 表示上述两个条件同时满足时两图属于同一等价类。
- 方向边界等价类内的方向差异不可识别,只能输出到部分有向图为止。
工程实践挑战
走出教科书,真实委托现场乱象丛生:目击记录只有一小段(有限样本),人群里藏着从未露面的神秘人(潜在混淆变量),而侦探自己还得决定“多像才算可疑”(显著性水平α)。方向确定在真实世界中远没有理论那么优雅。
有限样本下,条件独立性检验的统计功效下降,很容易误删或漏删边:样本越少,检验统计量的方差越大,p值的波动越剧烈。更棘手的是潜在混淆变量:一个没被观测的U同时影响X和Y,会让“条件独立”和“条件依赖”的检验结果失真——明明没有直接边却显示依赖,或者明明有边却被误判为独立。
条件独立性检验的常用统计量之一是基于列联表的G²似然比统计量。它衡量观测频数与“独立假设下期望频数”的偏离程度:
工程上的应对策略包括:样本少时适当放宽α(保守删边)、用BIC等准则校正多重比较、对可疑混淆场景改用FCI等对潜在混淆稳健的算法、以及做参数敏感性分析。方向确定不是一键生成的魔术,而是在噪声中最大化“真相暴露概率”的精细活。
- 观测频数$O_{xyz}$ 是实际数据中(x, y, z)组合的计数。
- 期望频数$E_{xyz}$ 是假设独立条件下应有的理论计数。
- 对数似然比$\ln(O_{xyz} / E_{xyz})$ 度量每个格子的偏离方向与强度。
- 阈值判定$G^2$ 超过临界值时拒绝独立假设,反之则接受独立性。
AI 应用场景
基因调控网络推断
阶段:数据预处理 → 因果发现建模 → 调控关系解析
解决的问题:传统差异表达分析只能列出“哪些基因在肿瘤里高表达”,给不出“哪个基因调控哪个基因”。基于约束方法从基因表达数据中推断调控方向,帮助锁定上游调控子。
具体案例:研究团队用PC算法分析乳腺癌RNA-seq数据,先构建基因共表达骨架,再通过碰撞器识别(两个转录因子共同调控某靶基因),定向出关键调控子FOXA1与靶基因GATA3的上下游关系,为后续功能实验提供候选靶点。
电商转化因果归因
阶段:业务数据采集 → 因果推理 → 增长策略决策
解决的问题:“领取优惠券的客户购买率更高”——是优惠券拉动购买,还是原本就想买的人才领券?相关性分析无法回答,方向确定可以。
具体案例:某电商平台用基于约束的方向确定分析“浏览详情页”“领取优惠券”“下单购买”三者的因果结构,发现“浏览→购买←领券”的碰撞器模式,确认优惠券确实促进了冲动消费,据此优化了发券策略。
工业设备故障根因定位
阶段:传感器时序处理 → 因果结构发现 → 根因诊断
解决的问题:风电机组SCADA系统中,多个传感器(温度、振动、转速)同时告警,传统规则只能报“系统异常”,无法定位根因。约束方法可以从告警数据中定向故障传播路径。
具体案例:工程师将传感器变量离散化后,用约束方法建立告警变量间的因果骨架并定向,锁定“轴承温度”是引发“齿轮箱振动”与“功率下降”的根因变量。维修团队据此优先更换轴承,故障停机时间下降了40%。
Python 演示
"""基于约束方法:方向确定(简化演示) 模拟四变量因果图 X -> Z <- Y 且 Z -> W,完整演示PC算法方向确定三阶段:1. 骨架构建:条件独立性检验删边;2. 碰撞器定向:识别 v-structure;3. Meek 规则传播:沿网络推导剩余方向。"""import mathimport itertoolsimport numpy as np def simulate_data(n_samples=2000, seed=42): """生成 X -> Z <- Y 且 Z -> W 的模拟数据""" rng = np.random.default_rng(seed) x = rng.normal(0, 1, n_samples) y = rng.normal(0, 1, n_samples) z = 0.8 * x + 0.8 * y + rng.normal(0, 0.5, n_samples) w = 0.8 * z + rng.normal(0, 0.5, n_samples) return np.column_stack([x, y, z, w]) def _norm_cdf(x): """标准正态分布累积分布函数(利用 erf)""" return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0))) def partial_corr(data, i, j, cond): """偏相关系数:控制 cond 后 i 与 j 的相关""" cols = [i, j] + list(cond) cov = np.cov(data[:, cols], rowvar=False) try: prec = np.linalg.inv(cov) except np.linalg.LinAlgError: return 1.0 r = -prec[0, 1] / math.sqrt(prec[0, 0] * prec[1, 1]) return float(np.clip(r, -1.0, 1.0)) def cond_indep(data, i, j, cond, alpha=0.05): """Fisher Z 变换条件独立性检验:p > alpha 判独立""" n = data.shape[0] r = partial_corr(data, i, j, cond) r = max(-0.9999, min(0.9999, r)) z = 0.5 * math.log((1 + r) / (1 - r)) denom = n - len(cond) - 3 if denom <= 0: return False p_value = 2.0 * (1.0 - _norm_cdf(abs(z) * math.sqrt(denom))) return p_value > alpha def build_skeleton(data, alpha=0.05): """阶段一:逐级增大条件集的骨架构建""" n_vars = data.shape[1] edges = {(i, j) for i in range(n_vars) for j in range(i + 1, n_vars)} for size in range(n_vars - 1): for (i, j) in list(edges): others = [k for k in range(n_vars) if k not in (i, j)] for cond in itertools.combinations(others, size): if cond_indep(data, i, j, list(cond), alpha): edges.discard((i, j)) break return edges def orient_colliders(data, edges, alpha=0.05): """阶段二:碰撞器定向(X丄Y 且 X不丄Y|Z -> X->Z<-Y)""" directed = set() unoriented = set(edges) nodes = set() for i, j in edges: nodes.add(i) nodes.add(j) for z in nodes: neighbors = [n for n in nodes if (min(n, z), max(n, z)) in unoriented] for (x, y) in itertools.combinations(neighbors, 2): if (min(x, y), max(x, y)) in unoriented: continue if cond_indep(data, x, y, [], alpha) and \ not cond_indep(data, x, y, [z], alpha): directed.add((x, z)) directed.add((y, z)) unoriented.discard((min(x, z), max(x, z))) unoriented.discard((min(y, z), max(y, z))) return directed, unoriented def apply_meek_rules(directed, unoriented, n_vars): """阶段三:Meek规则R1传播(X->Y, Y-Z, X与Z不相邻 => Y->Z)""" changed = True while changed: changed = False for (x, y) in list(directed): for z in range(n_vars): if z == x or z == y: continue if (min(y, z), max(y, z)) not in unoriented: continue if (min(x, z), max(x, z)) in unoriented or \ (x, z) in directed or (z, x) in directed: continue directed.add((y, z)) unoriented.discard((min(y, z), max(y, z))) changed = True return directed, unoriented def main(): data = simulate_data() print("模拟数据:X -> Z <- Y 且 Z -> W(真实结构)") skel = build_skeleton(data) print("① 骨架构建:", sorted(skel)) directed, rest = orient_colliders(data, skel) print("② 碰撞器定向:", sorted(directed)) print(" 剩余无向边:", sorted(rest)) directed, rest = apply_meek_rules(directed, rest, data.shape[1]) print("③ Meek传播后:", sorted(directed)) print(" 最终无向边:", sorted(rest)) if __name__ == "__main__": main()
z = 0.5 * math.log((1 + r) / (1 - r))Fisher Z 变换,把相关系数映射到近似正态分布域,方便算p值p_value > alphap 值大于显著性水平时,判定“没有证据拒绝独立”edges.discard((i, j))找到使 X⊥Y|S 的条件集,果断删除这条边cond_indep(data, x, y, [], alpha)检查无条件独立,对应“情敌是否互不相识”not cond_indep(data, x, y, [z], alpha)检查给定 Z 后是否依赖,对应“女神在场是否暴露竞争”directed.add((x, z))碰撞器确认,定向 x→z,第一枚箭头落地if (min(x, z), max(x, z)) in unoriented确保 X 与 Z 不相邻,排除碰撞器后只能 Y→Z
常见误区
误区刚学完PC算法,觉得只要做一个条件独立性检验,就能立刻知道谁指向谁。跑完代码直接看相关性矩阵就想画箭头。
正解条件独立性检验只能回答“有没有边”,不能回答“指向哪边”。方向确定需要额外的两步:先靠碰撞器拿到第一批箭头,再用Meek规则传播。就像侦探看到两个人经常同框,只能说有关联,不能直接说谁喜欢谁。
为何常见:很多教程把“删边”和“定向”放在同一张流程图里讲,初学者误以为检验本身就输出箭头。
误区骨架里存留的无向边,是不是代表X和Y互相影响(双向因果)?
正解无向边只是“方向未知”,不代表双向因果。在部分有向图(CPDAG)里,无向边指的是“数据无法确定方向”,实际可能是X→Y或Y→X。双向箭头(↔)在因果发现里有另一套语义(通常表示存在未观测混淆),不是一回事。
为何常见:“无向”这个词容易让人联想到“可以双向”,但它其实只是“待定”。
误区模型输出了一些无向边,为了拿到完整DAG,就随便指定方向,或者用“领域经验”强行补全。
正解如果两个DAG属于同一等价类,观测数据在统计上完全无法区分它们,任意选择一个都是一种武断。专业做法是明确输出CPDAG并说明哪些边不可识别,或引入干预数据来打破等价类。
为何常见:下游任务经常需要完整DAG,导致从业者不愿意面对“方向识别不了”的现实。
误区把条件独立性检验的显著性水平固定在0.05,跑一遍PC算法就能得到可靠结果,不管样本多小、潜在混淆是否存在。
正解α决定删边严格程度。样本少时α过小会导致漏删(该删的边没删),α过大导致误删(真边被删)。存在潜在混淆时,标准PC算法的假设被违背,需要FCI等更稳健的方法。实际工程必须做多重比较校正和敏感性分析。
为何常见:"α=0.05"是统计学的默认习惯,但因果发现涉及海量检验,直接套用默认值会带来系统性偏差。
面试题
Q1. 基于约束的因果发现方法,其第一阶段输出的核心结果是什么?
- A.完整有向无环图DAG
- B.无向骨架图与边集← 正确答案
- C.变量间相关系数矩阵
- D.马尔可夫等价类列表
答案:B。基于约束方法(如PC算法)第一阶段通过条件独立性检验删边,输出无向骨架。方向确定在后续阶段进行。完整DAG是最终目标而非第一阶段输出,相关矩阵只是中间统计量。
Q2. 碰撞器(v-structure)的统计特征是什么?
- A.无条件依赖,给定Z后仍依赖
- B.无条件独立,给定Z后条件依赖← 正确答案
- C.无条件独立,给定Z后仍独立
- D.无条件依赖,给定Z后条件独立
答案:B。X→Z←Y中,两个原因X、Y在无条件下独立(情敌互不相识),给定共同结果Z后变成条件依赖(竞争关系暴露)。这正是方向确定中最可靠的“实锤”,对应“独立→依赖”的翻转。
Q3. 在PC算法中,“分离集”(separating set)的主要作用是什么?
- A.用于初始化骨架图
- B.供碰撞器定向使用← 正确答案
- C.用于计算变量方差
- D.替代条件独立性检验
答案:B。删边时记录的条件集S就是分离集。定向阶段判断“X⊥Y且X不⊥Y|Z”时,需要知道X与Y之间的边是在什么条件下被删除的,分离集是碰撞器识别的重要依据。
Q4. 以下哪些DAG与 X→Y→Z 属于同一个马尔可夫等价类?
- A.X→Y→Z 与 X←Y→Z← 正确答案
- B.X→Y→Z 与 X→Y←Z
- C.X→Y→Z 与 X←Y←Z← 正确答案
- D.X→Y→Z 与 X→Z→Y
答案:AC。X→Y→Z、X←Y→Z、X←Y←Z具有相同骨架(X—Y、Y—Z)且无碰撞器。X→Y←Z含碰撞器Y,不等价;X→Z→Y的骨架是X—Z、Z—Y,与原骨架不同。
Q5. Meek规则R1的完整表述是哪一项?
- A.X→Y,Y—Z,X与Z相邻 ⇒ Y→Z
- B.X→Y,Y—Z,X与Z不相邻 ⇒ Y→Z← 正确答案
- C.X—Y,Y→Z,X与Z不相邻 ⇒ X→Y
- D.X→Y,Y→Z,X与Z不相邻 ⇒ X→Z
答案:B。若反设Z→Y,则X→Y←Z构成碰撞器。但碰撞器已在上一阶段被全网扫描完毕,Y不是碰撞器,因此反设矛盾,只能定向Y→Z。R1本质是“排除法定向”。
Q6. 关于马尔可夫等价类的正确说法包括哪些?
- A.等价DAG的骨架完全相同← 正确答案
- B.等价DAG碰撞器集合相同← 正确答案
- C.观测数据可区分等价DAG
- D.等价类用CPDAG表示← 正确答案
答案:ABD。C错误——等价类的定义正是“观测数据无法区分”。A、B是等价判据的两个必要条件,D是标准表示方式。方向确定的最终输出上限就是CPDAG。
Q7. 当数据中存在未观测的混淆变量时,标准PC算法的方向确定可能失效,最根本的原因是什么?
- A.条件独立检验直接报错中断
- B.虚假条件独立或依赖致误判← 正确答案
- C.混淆变量会自动删除所有边
- D.只有定向受影响,骨架不受
答案:B。潜在混淆U同时影响X与Y,使X与Y即使没有直接边也显示依赖(虚假相关),或掩盖真实依赖(虚假独立),破坏“独立⇒无直接边”和碰撞器判据的基础。PC算法默认无隐藏变量,此假设被违背时需改用FCI等方法。
Q8. 在方向确定中,显著性水平α的取值偏小时,最容易导致什么问题?
- A.误删真实存在的因果边
- B.保留过多实际独立的边← 正确答案
- C.定向规则将完全失效
- D.骨架构建跳过碰撞器检测
答案:B。α偏小意味着更难拒绝独立性假设,p值更难超过阈值,于是“判为独立”更困难,该删的边没删,骨架保留了过多实际独立的边。反之α偏大则容易误删真边。
Q9. 一份方向确定报告中保留了若干无向边,可能的原因包括哪些?
- A.等价类内方向不可识别← 正确答案
- B.样本量不足以支撑检测← 正确答案
- C.噪声导致检验不显著← 正确答案
- D.算法代码必然写错了
答案:ABC。无向边可能是马尔可夫等价类内的本质不可识别(A),也可能是样本量小导致检验功效不足(B),还可能是噪声使条件依赖检验不显著(C)。D是操作层面的工具问题,不属于方法论上的合理原因。
Q10. 给定三变量X、Y、Z的观测数据,若检验发现X⊥Y,且X不⊥Y|Z,方向应如何确定?
- A.定向为X→Y链式结构
- B.定向为Y→X分叉结构
- C.定向为X→Z←Y碰撞结构← 正确答案
- D.无法给出任何方向判断
答案:C。无条件独立加上条件依赖的“翻转”,是碰撞器的标志性指纹,方向只能是X→Z←Y(Z是X和Y的共同结果)。A、B都是链式/分叉结构,不具备这种统计特征。