深夜的刑侦办公室里,侦探面前摊着一张巨大的嫌疑人关系网:名字之间画满了可能的连线。他接到的任务是——仅仅依靠一叠日常的“行为观测记录”,把“谁在暗中推动谁”的因果链条还原出来。因果看不见摸不着,但它会在数据里留下蛛丝马迹。PC算法就是一套无数学者打磨过的“因果刑侦手册”:先假设所有人都有可能互相影响(全连接图),然后逐一核对“不在场证明”(统计独立性检验),发现两个人毫无关联就果断划掉连线;接着通过“两个素不相识的人却共同认识同一个中间人”这类特殊结构,锁定连线的方向;最后用“因果不能循环、指证不能回环”的逻辑,把剩余方向一一补齐。整条破案流水线,就是PC算法的完整流程。
掌握PC算法,你就能从观测数据中直接画出因果结构图,为后续因果效应估计、风险归因与决策干预提供最底层的地图——这是因果推断从业者绕不开的第一块基石。
目录
可视化演示
展示PC因果发现算法完整流程,从完全图出发通过条件独立性检验删边得到骨架,再利用v-结构碰撞子定向和Meek规则确定因果方向。
本节配有交互动效(进入视口后自动加载,约 3KB)。
PC因果发现算法 骨架发现:从完全图出发,条件独立性检验删除无关边 v-结构定向:碰撞子X→Z←Y,Z不在分离集中则定向 Meek规则:已定向边传播方向约束,避免环和新碰撞 PC: Complete → CI-test → Skeleton → v-struct → Meek PC算法通过约束范式从数据中发现因果结构
算法总览:案件的宏观蓝图
刑警队接到一桩奇特的大案:他们要仅凭一份“城市行为观测记录”——比如每个人的出行轨迹、消费记录、社交活动——还原出“谁在背后推动谁”的完整因果链条。指挥官先把任务拆解成三步:先画出所有嫌疑人的关系网(不管方向),再找出“信息交汇点”确定部分箭头,最后用逻辑推理补齐全图。这份破案蓝图,就是PC算法的骨架。
PC算法的全称叫Peter-Clark算法,是因果发现领域最经典的“基于约束”方法。所谓“基于约束”,意思是它不猜方程、不拟合曲线,而是把“条件独立性”当作一票否决的证据:如果数据显示两个变量在控制其他条件后互不相干,那就把这条边划掉。它和“基于分数”的方法不同——后者像评委打分选最优模型,PC则像侦探取证排嫌疑。
从输入输出看,PC算法吃进一个观测数据矩阵(每列是一个变量,每行是一个样本),加上一个显著性水平α,吐出一个“部分有向无环图”(CPDAG)。它不关心影响的具体大小,只负责回答两个问题:哪些变量之间有关系?箭头指向哪个方向?这正是因果推断的第一张地图。
记住这张蓝图:先画网、再定向、后补全。接下来每一节,就是对这个破案过程的一次特写。
前置准备:给侦探校准测谎仪
出发之前,老刑警对新人反复叮嘱两件事:一是确认案情假设成立,二是把测谎仪校准到位。PC算法的“案情假设”就是忠实性假设(faithfulness):如果真实世界里两个变量之间没有因果路径,那么数据统计上就一定看不出它们有关联;反过来,统计上发现的任何关联,也都真实存在于因果结构之中。这个假设是整个删边逻辑的基石。
除了假设,还要选一把好用的“测谎仪”——条件独立性检验。它的任务是回答一个精确的问题:当我控制住一组变量 S 之后,X 和 Y 之间还存不存在统计联系?对于连续型数据,最常用的测谎仪是偏相关检验:先把 X、Y 分别对 S 做回归,取残差,再看两个残差的相关性。相关性越弱,越倾向于“独立”。
为了把“弱到什么程度算独立”量化,人们构造了一个t统计量:
校准完毕的测谎仪,即将投入大规模的“不在场证明”筛查中。
- 偏相关系数 $r_{XY \cdot S}$控制住 S 之后,X 与 Y 之间净剩的相关强度,越接近 0 越独立。
- 样本量修正 $n - |S| - 2$分子中的自由度调整,样本越少、控制变量越多,判断就越要谨慎。
- 标准化 $\sqrt{\frac{n - |S| - 2}{1 - r^2}}$把偏相关系数放大到服从已知分布的标准尺度,这样就能查表得到 p 值。
- 查表判定算出 t 后查正态分布表得到 p 值。若 p > α,判为“独立”;若 p < α,判为“不独立”。
骨架发现:不在场证明逐一核对
侦探把完整关系网铺开:起初,每个嫌疑人都和其他所有人之间画了一条线,表示“暂不能排除关联”。然后审讯开始。第一轮,只问最简单的问题:“你们俩没有任何直接交集的证据吗?”这就是零阶条件独立性检验(d=0)。如果两人互不相干,直接划掉连线。第二轮,侦探换了个问法:“在某个证人在场的情况下,你们还有联系吗?”这就是一阶检验(d=1)。条件集中变量个数逐轮增加:d=0, 1, 2, …,直到网络不再变化。
每一轮删边,都必须登记一张“证据卡”:当时是用哪组条件变量证明他俩无关的。这张卡片叫分离集(Sepset),它记录了使两个变量条件独立的变量集合。别小看这张卡片,后面定向 v 结构时它是决定性证据。骨架发现阶段的算法逻辑可以用一句话概括:
经过若干轮筛查,全连接图瘦身成一个精简的“最小嫌疑网”——骨架。但此时所有线条都还没有方向,下一步才是关键。
- p-value条件独立性检验返回的显著性概率,代表“数据给'独立'这个判断的支持度”。
- 与 α 比较p值大于设定的显著性水平 α 时,说明没有足够证据推翻“独立”的零假设。
- 独立性记号 $X \perp\!\!\!\perp Y \mid S$读作“在控制 S 的条件下 X 与 Y 独立”,这是删边的合法依据。
- 执行删边把骨架中 X 与 Y 之间的无向连线移除,并把 S 记入分离集。
方向判定:对撞结构的秘密
侦探发现一个有趣的三角关系:A 和 B 素不相识、毫无交集,但他们居然都认识 C。在这个三角形里,C 是唯一的信息汇合点——A 和 B 各自独立地把情报汇入 C。这种“两个互不相干的人共同指向同一个中间人”的结构,在因果图中叫对撞子(v结构),它是定向最重要的天然路标:箭头必然指向中间那个点。
为什么?回到数据生成逻辑:如果真实结构是 X→Z←Y,那么 X 和 Y 在“出生”时是独立的,它们之间没有边;而 Z 同时受到两者的影响。反过来,如果数据告诉我们 X 和 Z 相关、Y 和 Z 相关,但 X 和 Y 相互独立,那么 X 和 Y 之间不可能有因果边,唯一的解释就是:它们俩共同“撞”向了 Z。把无向的 X—Z—Y 定向为 X→Z←Y,逻辑就闭合了。
正式判定条件需要精确表述——不仅要 X—Z—Y 在骨架上,还要检查 Z 是否出现在 X 和 Y 的分离集中:
v结构就像案件报告里最硬的物证,一块就能定死两个箭头。但剩下的“无向线头”还要靠规则推理。
- 路径存在 $X - Z - Y$骨架中 Z 同时连着 X 与 Y,构成 V 字形的两条无向边。
- 分离集检查 $Z \notin \text{Sep}(X, Y)$分离集是让 X、Y 变独立的变量集合,如果 Z 不在其中,说明 X、Y 的独立性不需要依赖 Z。
- 对撞判定X 与 Y 独立,却都与 Z 相关,唯一自洽的解释是箭头汇聚于 Z。
- 定向写入把两条无向边写成有向边,得到对撞结构。
方向传播:口供互证,补全残余箭头
有了几块物证,剩下的方向靠“口供一致性”推出来。如果 A 已经证实指向 B,而 B 和 C 之间还有一条未定向的连线,且 A 与 C 素无往来,那么侦探手册强制规定:方向只能是 B→C。为什么?因为如果 C 指向 B,就会凭空造出一个新的对撞子 A→B←C,这与证据矛盾;推理必须避免在已知边上引入新的对撞结构。
这套推理规则在学术上叫 Meek 规则,共四条。最常用的是前两条:R1 处理“已定向边 + 无向边”的链式传递,R2 处理“两条有向边 + 一条无向边”的闭合。它们共同遵守一条铁律:任何时刻不得把图推成有向环,因为因果不可能循环——你不可能既是自己祖父的父亲又是自己祖父的儿子。
R1 规则的逻辑链如下:
R2 则处理另一种常见场景:已知 X→Y→Z,且 X 与 Z 之间还有一条无向边,那么这条边必然定向为 X→Z,否则会出现环:
规则一条条套用,直到再也推不出新方向为止。最终剩下的图中,部分无向边是数据“诚实的沉默”——留给下一节解读。
- 链式前提 $X \to Y \to Z$已经有了完整的有向链。
- 待定向边 $X - Z$骨架上还残留的这条无向边必须补上方向。
- 无环约束推导若 Z→X 则会形成 X→Y→Z→X 的有向环,违反因果基本法则,故只能 X→Z。
结果解读:案件报告里的留白
经验丰富的侦探知道,有些案件无论证据多充分,都会留下“无法判定”的遗憾。如果数据显示 A 和 B 只是简单相关,且没有对撞结构提供方向线索,那么“A 推动了 B”和“B 推动了 A”在统计上就是一对双胞胎,长得一模一样,无法区分。PC 算法不会硬猜,而是把这类边保留为无向,输出一张“部分有向无环图”(CPDAG)。
学术上,这一对长得一模一样的图叫“马尔可夫等价类”:只要两个因果图的骨架相同、对撞结构集合相同,它们对所有观测数据的解释力就完全相同。CPDAG 正是所有这些等价图“共同事实”的浓缩——公共箭头是实心箭头,有争议的边保持无向。用集合论的语言:
读懂留白,是因果推断从业者的专业素养。下一节,我们把整套流程交给自动化系统,让它变成一把量产工具。
- 等价类集合 $\mathcal{E}(\mathcal{G})$与图 G 不可区分的一族因果图的总称。
- 骨架一致条件所有等价图拥有的边(无论方向)完全相同。
- 对撞结构一致条件所有等价图的 v 结构指向完全一致,这是方向信息的唯一锚点。
- CPDAG 的生成把等价类里所有图都同意的箭头保留,其余边标为无向,得到最终输出。
工程实现:让自动破案系统上岗
手工推演在变量超过五个时就累得够呛,更别说真实场景里动辄几十上百个变量。好在PC算法早已被封装成成熟的软件库,就像把侦探手册变成了全自动“无人警局”:输入数据,选好测谎仪,设好置信度,一键出图。Python生态里最常用的是 causal-learn,R 语言中有 pcalg,都是学界验证过的工业级实现。
用起来只有三行核心逻辑:调用 pc() 函数,传入数据矩阵、显著性水平和独立性检验方法,然后打印返回的因果图对象。参数调优的核心旋钮就是 α——它控制删边的手感:α大,更容易“判独立”,图更稀疏;α小,更容易“保留关联”,图更密。此外还有是否启用“稳定版”(stable=True)这类细节选项,它能保证边的删除顺序不影响最终结果。
整个骨架发现过程的时间代价可以粗略表达为:
至此,破案手册全卷读完。从手工推演到自动化工具,你已经有能力独立完成一次完整的因果发现任务。
- 变量对数 $p^2$任意两个变量都要配对检查,变量越多检查越重。
- 条件集组合 $2^{d_{\max}}$每个候选条件集都要做一次检验,条件变量组合是指数级的。
- 最大条件阶数 $d_{\max}$实际推进到的最深验证轮次,因为边不断被删除它通常很小。
- 工程含义尽早删边能显著降本,这也是 PC 从低阶到高阶逐轮推进的设计初衷。
AI 应用场景
电商增长分析:定位真正的“增长引擎”
阶段:因果结构学习 / 特征关系建模
解决的问题:运营团队积累了大量指标——优惠券发放量、浏览时长、加购率、复购率。传统相关性分析只能看到“这些数字一起涨跌”,却分不清谁是因谁是果:是发券拉动了复购,还是高复购用户恰好更容易领券?用PC算法对用户行为数据做骨架发现,可以直接排除大量虚假相关,只保留真正的因果链路。
具体案例:某电商对 2000 万条用户行为数据跑 PC,输出的因果图显示“优惠券发放→加购意愿→实际下单”是一条完整因果链,而“复购率”其实是被“满意度”驱动的结果而非原因。团队据此把营销资源从盲目撒券转向提升加购体验,次季复购率提升 12%。
医学观察性研究:撕掉虚假相关的伪装
阶段:因果方向确认 / 混杂因素识别
解决的问题:电子病历中,“服药”和“血压下降”高度相关,但真实世界可能是“生活方式改善”同时导致了两者;更隐蔽的是,某些变量(如“就诊频率”)会同时被疾病严重度和患者依从性影响,形成对撞子,制造出根本不存在的“相关”。PC 的 v 结构定向正好用来识别这类陷阱。
具体案例:某临床研究团队用 PC 分析高血压患者随访数据,发现“初次就诊时的血压值”与“后续用药依从性”之间存在对撞结构——它们共同指向“就诊频率”。如果不做因果发现直接回归,就会得到“初诊血压影响依从性”的错误结论;正确定向后,研究改为关注依从性的直接前因,从而修正了试验设计方案。
金融风控特征甄别:用因果图给模型瘦身
阶段:特征因果结构解读 / 可解释建模
解决的问题:风控模型里几百个特征高度相关,直接堆进模型既冗余又难解释,还可能把“结果变量”当作“原因特征”造成泄漏。PC 输出的 CPDAG 能帮算法工程师区分“根因特征”和“下游结果特征”,从而筛选出真正值得建模的变量。
具体案例:某消费金融公司对申请人特征做 PC 分析,发现“近三月查询次数”是“贷款审批结果”的下游结果而非原因(存在对撞路径),将其剔除出模型后,模型在保持 AUC 的同时变量数从 120 个降为 38 个,且通过监管对“特征可解释性”的审查。
Python 演示
# 教学版 PC 算法:从观测数据中发现骨架并定向 v 结构import mathfrom itertools import combinationsimport numpy as np def ncdf(x): # 标准正态分布的累积分布函数 return 0.5 * (1.0 + math.erf(x / math.sqrt(2.0))) def pcorr(x, y, Z): # 偏相关系数: 控制 Z 后 x 与 y 的相关 if Z.shape[1] == 0: return np.corrcoef(x, y)[0, 1] bx, _, _, _ = np.linalg.lstsq(Z, x, rcond=None) by, _, _, _ = np.linalg.lstsq(Z, y, rcond=None) rx = x - Z.dot(bx) ry = y - Z.dot(by) return np.corrcoef(rx, ry)[0, 1] def ci_test(x, y, Z, n, alpha=0.05): # 条件独立性检验: 返回 True 表示 x 与 y 在控制 Z 后独立 r = pcorr(x, y, Z) k = Z.shape[1] t = r * math.sqrt((n - k - 2) / max(1e-12, 1 - r * r)) p = 2.0 * (1.0 - ncdf(abs(t))) return p > alpha def pc_skeleton(data, alpha=0.05): # 第一步: 从全连接图出发逐阶删边, 得到骨架 n, p = data.shape adj = [set(range(p)) - {i} for i in range(p)] sep = {} d = 0 while True: changed = False for i, j in combinations(range(p), 2): if j not in adj[i]: continue for cond in combinations(list(adj[i] - {j}), d): if ci_test(data[:, i], data[:, j], data[:, list(cond)], n, alpha): adj[i].remove(j) adj[j].remove(i) sep[(i, j)] = sep[(j, i)] = set(cond) changed = True break if not changed or d > max(len(a) for a in adj): break d += 1 return adj, sep def orient_v(adj, sep): # 第二步: 用 v 结构定向, 返回有向边集合 directed = set() for z in range(len(adj)): for x, y in combinations(list(adj[z]), 2): if z not in sep.get((x, y), set()): directed.add((x, z)) directed.add((y, z)) return directed def main(): rng = np.random.default_rng(42) n = 3000 X = rng.normal(size=n) Z = rng.normal(size=n) Y = 0.8 * X + 0.6 * Z + rng.normal(size=n) W = 0.5 * X + rng.normal(size=n) data = np.column_stack([X, Y, Z, W]) adj, sep = pc_skeleton(data, alpha=0.05) print("骨架邻接:") for i in range(data.shape[1]): print(" ", i, "->", sorted(adj[i])) directed = orient_v(adj, sep) print("v 结构定向的有向边:") for a, b in sorted(directed): print(" ", a, "->", b) if __name__ == "__main__": main()
adj = [set(range(p)) - {i} for i in range(p)]初始化全连接无向图,每个节点先与所有其他节点相连。for cond in combinations(list(adj[i] - {j}), d)枚举邻域中 d 个候选条件变量,这是“逐阶排查”的核心循环。if ci_test(data[:, i], data[:, j], data[:, list(cond)], n, alpha):执行条件独立性检验,返回 True 表示判为独立。sep[(i, j)] = sep[(j, i)] = set(cond)把使二者独立的条件集同时记入双向分离集,留给 v 结构定向使用。if not changed or d > max(len(a) for a in adj): break当一轮没有删掉任何边,或条件阶数超过邻域规模时,骨架发现终止。if z not in sep.get((x, y), set()):v 结构定向的闸门判断:中间节点不在分离集中,才允许定向。directed.add((x, z)); directed.add((y, z))把 X→Z 和 Y→Z 两条有向边加入结果集,完成对撞定向。
常见误区
误区PC 算法跑完拿到的就是“真正的因果图”,箭头指哪就一定是哪。看到还有无向边就觉得自己代码写错了。
正解PC 输出的是与数据一致的马尔可夫等价类(CPDAG),很多方向本来就无法用纯观测数据区分。侦探报告里写“现有证据无法判定方向”不是办案失败,而是证据约束下的诚实上限;看到无向边,应该先怀疑“数据是否有方向信息”,而不是“程序是否有 bug”。
为何常见:教程为了直观,总用恰好能完全定向的小图做演示,让初学者误以为定向是必然结局。
误区条件独立性检验的 p 值越小,说明两个变量的因果关系越强,p 值可以被当作因果效应大小的指标。
正解p 值是“反对独立假设”的证据强度,与因果效应的大小毫无关系。测谎仪只能告诉你“这人没说实话”,不能告诉你他偷了多少钱。效应大小要用后续的因果效应估计方法(如干预计算)来量化,p 值只是删边决策的输入。
为何常见:统计检验的思维惯性——人们习惯把显著性理解为重要性,而忘了它只是“意外性”的度量。
误区既然条件集越大检验越严谨,不如直接从 d=3、d=5 开始做条件独立性检验,省去前面几轮。
正解PC 的精髓就是 d 从 0 逐阶推进,利用“删掉的边越多,后续候选条件集越小”的正反馈来压缩计算量。跳过低阶直接上高阶,会让原本低阶就能删除的边白白参与大量无谓检验,还可能因为有限样本的噪声把真实边误删。低阶通过是继续高阶的前提,这是算法设计的一部分而非偷懒。
为何常见:直觉上“考虑条件越多越严谨”,但忽略了统计检验的样本消耗和组合爆炸风险。
误区看到 X—Z—Y 且 X 和 Y 独立,就直接定向为 X→Z←Y。这口诀省事,应该没错。
正解还差一个决定性步骤——检查 Z 是否在 Sep(X,Y) 分离集中。如果 Z 在分离集里,说明控制 Z 之后 X、Y 才独立,此时它们是“被 Z 解释的间接独立”,不是对撞结构。这就像侦探发现 A、B 虽无交集,但要先确认 C 是否就是那个“不在场证人”,如果 C 是证人,三角关系就另当别论了。
为何常见:口诀只记住了前半句,把最关键的前提条件遗漏了,导致误定向。
误区α 就像收音机音量,调大一点,算法就能检到更多信息,因果图更准。
正解α 是“判独立”的门槛:α 越大,越容易判独立,删边越狠,骨架越稀疏,容易漏掉真实边;α 越小,判独立越保守,边删得少,容易把虚假相关当成因果。它是个权衡旋钮,需要结合样本量、变量噪声水平和领域知识来选择,绝非越大越好。
为何常见:把“显著性水平”误解为“检验灵敏度”,忽略了它本质上是假阳性率的上限控制。
面试题
Q1. PC算法属于哪一类因果发现方法?
- A.基于约束的方法← 正确答案
- B.基于深度学习的回归
- C.基于专家规则的推理
- D.基于时间序列的预测
答案:A。PC 算法通过条件独立性检验来约束候选因果结构,属于基于约束的方法。它不像深度学习那样拟合预测函数,也不依赖人工专家规则,而是用统计检验作为一票否决的证据。
Q2. PC算法正确的执行顺序是?
- A.方向传播、骨架发现、v结构定向
- B.骨架发现、v结构定向、方向传播← 正确答案
- C.v结构定向、骨架发现、方向传播
- D.骨架发现、方向传播、v结构定向
答案:B。PC 算法必须先用独立性检验把全连接图删成骨架,再用 v 结构确定第一批方向,最后用 Meek 规则补全剩余方向。方向传播依赖已定方向的 v 结构,v 结构定向依赖骨架,顺序不可颠倒。
Q3. 条件独立性检验得到 p>α 时,通常意味着什么?
- A.两个变量一定强相关
- B.没有足够证据拒绝独立性← 正确答案
- C.两个变量存在因果关系
- D.样本量一定不足
答案:B。p>α 表示在显著性水平 α 下没有足够证据推翻“独立”的零假设,因此 PC 算法会判它们独立并删除边。这类似测谎仪显示“没有说谎迹象”,不代表绝对清白,只是证据不足。
Q4. 分离集(Sepset)在PC算法中的核心作用是?
- A.记录使两变量独立的条件集← 正确答案
- B.记录使两变量相关的条件集
- C.存放所有待检验的变量对
- D.存放方向传播的最终结果
答案:A。骨架发现阶段每删除一条边,都会记录当时使两变量条件独立的变量集合,这就是分离集。在 v 结构定向时,需要判断中间节点是否属于分离集,因此它直接决定定向的正确性。
Q5. 一个合法的 v 结构 X→Z←Y 需要满足哪些条件?
- A.X 和 Y 之间有直接因果边
- B.X 和 Y 之间没有直接边← 正确答案
- C.Z 不在分离集 Sep(X,Y) 中← 正确答案
- D.Z 在分离集 Sep(X,Y) 中
答案:BC。v 结构的本质是 X 和 Y 相互独立却共同指向 Z,所以 X、Y 之间不能有直接边;同时 Z 不能出现在 X、Y 的分离集中,否则“独立”可以被 Z 解释,就不是真正的对撞结构。
Q6. Meek 规则 R1 的正确表述是?
- A.X→Y—Z 且 X与Z不相邻,则 X→Y→Z← 正确答案
- B.X—Y—Z 且 X与Z相邻,则 X→Y→Z
- C.X→Y—Z 且 X与Z相邻,则 X←Y—Z
- D.X—Y←Z 且 X与Z不相邻,则 X←Y←Z
答案:A。R1 描述的是“一条有向边加一条无向边”的传播:X 已指向 Y,若 Y—Z 无向且 X、Z 不相邻,则必须定向为 Y→Z。否则 Z→Y 会新增对撞子 X→Y←Z,与现有骨架信息矛盾。
Q7. PC算法输出 CPDAG(部分有向无环图)意味着什么?
- A.所有边的方向都被数据唯一确定
- B.部分无向边方向无法由数据唯一确定← 正确答案
- C.骨架发现阶段一定出现了错误
- D.样本量不足导致算法彻底失败
答案:B。CPDAG 是马尔可夫等价类的浓缩表示。当多个因果图拥有相同骨架和对撞结构时,它们在数据上不可区分,有争议的边就保留为无向。这是数据的信息上限,不是算法缺陷。
Q8. 以下哪项不是 PC 算法的输入参数?
- A.观测数据矩阵
- B.显著性水平 α
- C.独立性检验方法
- D.真实的因果图← 正确答案
答案:D。PC 算法是从数据中发现因果结构,输入自然是数据、显著性水平和检验方法。如果已经知道真实因果图,就等于考试前拿到了答案,不需要再“发现”了。
Q9. PC算法正常工作依赖的核心假设包括?
- A.忠实性假设(数据反映真实结构)← 正确答案
- B.马尔可夫条件(无路径则条件独立)← 正确答案
- C.样本量足够大(统计检验有效)← 正确答案
- D.变量必须全部服从正态分布
答案:ABC。忠实性假设保证统计独立性对应图中无路径,马尔可夫条件保证图中无路径对应统计独立性,二者互为表里;大样本保证检验可靠。D 错,因为 PC 也支持卡方检验等非参数独立性检验,不限于正态分布。
Q10. 当忠实性假设被违反时(如存在确定性函数关系),PC算法可能发生什么?
- A.错误保留虚假的依赖边← 正确答案
- B.错误删除真实的因果边← 正确答案
- C.定向结果产生偏差← 正确答案
- D.输出结果完全正确不受影响
答案:ABC。忠实性违背意味着数据里的独立性与因果结构脱钩:确定性关系可能让真实因果边被误判为独立而删除,也可能让虚假依赖被保留,后续 v 结构定向自然跟着出错。它动摇的是 PC 删边逻辑的根基,D 显然不成立。