基于Matlab的贝叶斯网络工具箱BNT是kevinp.murphy基于Matlab语言开发的关于贝叶斯网络学习的开源软件包,提供了许多贝叶斯网络学习的底层基础函数库,支持多种类型的节点(概率分布)、精确推理和近似推理、参数学习及结构学习、静态模型和动态模型,是学习贝叶斯网络的主要仿真工具。
贝叶斯网络学习由结构学习和参数学习两部分组成:结构学习是利用训练样本集,尽可能结合先验知识,确定合适的贝叶斯网络拓扑结构;参数学习是在给定贝叶斯网络拓扑结构的情况下,确定各节点处的条件概率。BNT工具箱中提供了较为丰富的学习函数,现将其归纳如下:
Learning参数学习
Full obs全部结点可观察 Partial obs局部可观测 |
Learn_params最大似然估计 Learn_params_em最大期望EM法 |
Bayes_update_params贝叶斯方法 Learn_struct_SEM结构最大期望法 |
Learn_struct_K2 K2算法 Learn_struct_EM学习树扩展贝叶斯网络结构 Learn_struct_gs贪婪搜索GS算法 Learn_struct_EM最大期望EM算法 Learn_struct_he爬山算法 Learn_struct_mcmc马尔科夫链蒙特卡罗算法 |
除了确定贝叶斯网络的结构和学习方法以外,为了提高运算速度,使各种推理算法能够有效应用,BNT工具箱还采用了多种推理引擎机制,不同的引擎根据不同的算法来完成模型转换、细化和求解。总结下来包括以下四种引擎:a)联合树推理引擎jtree—inf_engine();b)全局联合树推理引擎global_joint_inf_engine();c)信念传播推理引擎belprop_inf_engine();d)变量消元推理引擎var_elim_inf_engine()。其中运算速度最快的是全局联合树推理引擎。
创造贝叶斯网络
为了去定义一个贝叶斯网络,我们必须具体化图结构和变量。
图结构
为了说明这个有向无环图(dag),我们创建了一个邻接矩阵:
对应的贝叶斯网络的矩阵的表达形式为:
并对节点进行了编号:Cloudy = 1, Sprinkler = 2, Rain = 3, WetGrass = 4。这些节点的编号必须拓扑有序,也就是说,父节点必须在子节点之前。但是对于复杂的图,这也许有点不方便。
创建贝叶斯网络框架
为了定义图结构,我们必须定义每个节点的大小和类型。如果节点是离散的,它的大小是它每个节点可以选取值的数量。如果这个值是连续的,它可以是一个向量,它的大小是这个向量的长度。在这种情况下,我们假设所有节点是离散和二元的。
现在手工创建一个贝叶斯网络:
同时,我们可以定义哪些节点是可以被观察的。如果不清楚或者提前没有确定,那么可以使用空列表(默认)。
变量
一个模型包括图结构和变量。变量是通过CPD来表达的(CPD= Conditional ProbabilityDistribution),它定义了父节点所给出的概率分布。最简单的CPD的种类是一个表(多维数组),它适合于所有节点都是离散值。需要注意的是离散值并没有假设成有序的。也就是说,它们表述了明确的数量,例如男性和女性,而不是序数数量,例如低、中、高。
TabularCPDs,也叫做CPTs(条件概率表),它存储了多维数组,维数和节点是排列成相同的顺序。例如:对于节点4(WetGrass)是被Sprinkler洒水(2)
、Rain (3)和WetGrass (4)本身所索引的。因此孩子节点总是最后一维。如果一个节点没有父节点,那么它的CPT是列向量来代表它的前面节点。在MATLAB中,数列是从1开始检索的,并且顺序排列在内存中,因此第一个被最快触发索引。节点4的CPT如下:
在这里,我们使用惯例false=1,true=2.在MATLAB中创建了这个CPT:
实际上,我们并不需要重塑这个数列,因为CPD构造器可以为我们构造。因此我们可以执行:
其它的节点也可以相似的建立:
画出建立好的贝叶斯网络:
如图所示:
推理
当创建完贝叶斯网络时,我们就可以用它来推断。这里有许多的算法用于贝叶斯网络推断,这就可以在速度、复杂性、一般性和精确性之间做出不同的权衡。BNT因此提出了不同的推断“引擎”。在这里,我们使用的是推断树引擎,它是所有扩展的推断算法中的母算法。可以被如下创建:
其它的引擎也有相同的构造器,但是会加上额外的,具体算法的变量。一旦它们被创建,所有的引擎都以相同的方式被使用。我们通过下面一部分来表述这些:
计算边缘分布
假设我们想要计算在已知草坪湿的情况下是洒水原因的概率。证据包括W=2(草坪是湿的)。所有其它的节点是隐藏的(不可观察的)、我们可以如下定义:
我们使用了一维细胞(cell)序列而不是向量去处理是因为这些节点可能是不同长度的向量。除此之外,值[]可以用来表示“没有证据”,而不是定义观察模型作为一个独立的论点。
我们对引擎添加一个证据:
这个函数的功能是具体化算法。在jtree引擎的情况下,enter_evidence实现了双行程信息通过的模式。第一个返回的变量包括了合并证据的改进后的引擎。第二个返回的变量包括证据的对数似然函数。
最后,我们计算p=P(S=2|W=2)如下:
我们可以看出p=0.4298。
现在添加下雨的证据,来计算它们之间的不同之处:
可以看出p = P(S=2|W=2,R=2) =0.1945,这比之前的要低很多,这是因为下雨可以解释草坪是湿的的事实。
我们通过使用bar函数来绘制一个离散变量的边缘分布的条形图:
条形图如下:
已观察到的节点
一个已观察到的离散节点通常只有1值(已观察到的那一个),其它的值都是0.BNT对于以观察到的点都是假设它们设置为1:
另外我们添加一个证据通过一个可选变元:
结果显示P(W=1|W=2) = 0和 P(W=2|W=2) = 1。
计算联合分布
我们也可以在一组节点上计算联合概率:
m是一个结构,T字段代表一个包含在特定节点上的联合概率分布的多维数组(在这个案例中,是3维的数组)
我们可以看出P(S=1,R=1,W=2) = 0,这是因为如果既没有下雨有没有洒水,草坪不可能是湿的。
参考文献:
1. https://code.google.com/p/bnt/
2. 张慧莹 宁媛 邵晓非 机器学习中的贝叶斯网络及其推理分析 2012