通过结构学习,我们希望确定最能捕捉数据集中变量之间因果依赖关系的图结构。换句话说:什么样的 DAG 最适合数据?一种朴素的方法是简单地创建所有可能的图结构组合,即创建成十个、几百个甚至几千个不同的 DAG,直到所有组合都耗尽为止。然后,可以根据数据的适应度对每个 DAG 进行评分。最后,返回得分最高的 DAG。在仅有变量X的情况下,可以创建如图 2 所示的图形以及更多的图形,因为不仅可以是 X>Z>Y(图 2a),还可以是 Z>X>Y 等等。变量X可以是布尔值(True 或 False),也可以有多个状态。DAG 的搜索空间在最大化得分的变量数量上呈指数增长。这意味着在大量节点的情况下,穷举搜索是不可行的,因此已经提出了各种贪婪策略来浏览 DAG 空间。通过基于优化的搜索方法,可以浏览更大的 DAG 空间。这种方法需要一个评分函数和一个搜索策略。常见的评分函数是给定训练数据的结构的后验概率,例如BIC或BDeu。
BIC是贝叶斯信息准则(Bayesian Information Criterion)的缩写。它是一种用于模型选择的统计量,可以用于比较不同模型的拟合能力。BIC值越小,表示模型越好。在贝叶斯网络中,BIC是一种常用的评分函数之一,用于评估贝叶斯网络与数据的拟合程度。
一种不同但相当直观的构建 DAG 的方法是使用假设检验(如卡方检验统计量)来识别数据集中的独立性。这种方法依赖于统计检验和条件假设,以学习模型中变量之间的独立性。卡方检验的 值是观察到的计算卡方统计量的概率,假设空设为 和 在给定 的条件下是独立的。这可以用于在给定显著性水平的情况下进行独立判断。约束性方法的一个示例是 PC 算法,它从一个完全连接的图开始,并根据测试的结果删除边,如果节点是独立的,直到达到停止准则。
让我们从一个简单而直观的示例开始,以演示结构学习的工作原理。假设你在后院安装了一个洒水系统,并且在过去的 1000 天里,你测量了四个变量,每个变量有两个状态:雨(是或否),多云(是或否),洒水系统(开启或关闭)和湿草(是或否)。下面,导入 bnlearn 库,加载洒水器数据集,并确定哪个 DAG 最适合该数据。
使用 bnlearn 库,用几行代码就能确定因果关系。
请注意,洒水器数据集已经过处理,没有缺失值,所有值都处于 1 或 0 的状态。
图 3:洒水器系统的最佳 DAG 示例。它表示以下逻辑:草地潮湿的概率取决于洒水器和雨水。洒水器打开的概率取决于多云的状态。下雨的概率取决于多云的状态这样,我们有了如图 3 所示的学习到的结构。检测到的 DAG 由四个通过边连接的节点组成,每条边表示一种因果关系。
湿草的状态取决于两个节点,即雨水和洒水器;
雨水的状态由多云的状态决定;
而洒水器的状态也由多云的状态决定。
这个 DAG 表示了(因式分解的)概率分布,其中 S 是洒水器的随机变量,R 是雨水的随机变量,G 是湿草的随机变量,C 是多云的随机变量。通过检查图形,很快就会发现模型中唯一的独立变量是 C。其他变量都取决于多云、下雨和/或洒水器的概率。一般来说,贝叶斯网络的联合分布是每个节点在给定其父节点的条件下的条件概率的乘积:bnlearn 在结构学习方面的默认设置是使用hillclimbsearch方法和BIC评分。值得注意的是,可以指定不同的方法和评分类型。请参考下面的示例以指定搜索和评分类型:
# Examples to illustrate how to manually compute MLE for the node Cloudy and Rain:# Compute CPT for the Cloudy Node:# This node has no conditional dependencies and can easily be computed as following:# P(Cloudy=0)sum(df['Cloudy']==0) / df.shape[0] # 0.488# P(Cloudy=1)sum(df['Cloudy']==1) / df.shape[0] # 0.512# Compute CPT for the Rain Node:# This node has a conditional dependency from Cloudy and can be computed as following:# P(Rain=0 | Cloudy=0)sum( (df['Cloudy']==0) & (df['Rain']==0) ) / sum(df['Cloudy']==0) # 394/488 = 0.807377049# P(Rain=1 | Cloudy=0)sum( (df['Cloudy']==0) & (df['Rain']==1) ) / sum(df['Cloudy']==0) # 94/488 = 0.192622950# P(Rain=0 | Cloudy=1)sum( (df['Cloudy']==1) & (df['Rain']==0) ) / sum(df['Cloudy']==1) # 91/512 = 0.177734375# P(Rain=1 | Cloudy=1)sum( (df['Cloudy']==1) & (df['Rain']==1) ) / sum(df['Cloudy']==1) # 421/512 = 0.822265625
如果仅使用数据来计算因果图,很难完全验证因果图的有效性和完整性。然而,有一些解决方案可以帮助增加对因果图的信任。例如,可以对变量集之间的某些条件独立性或依赖性关系进行经验性测试。如果它们在数据中不存在,则表明因果模型的正确性 。或者,可以添加先前的专家知识,例如 DAG 或 CPT,以在进行推理时增加对模型的信任。