贝叶斯网络—MATLAB学习笔记(1)

一、贝叶斯网络的原理

  • 贝叶斯网络的原理是贝叶斯定理。利用贝叶斯网络解决推理问题的核心就是,利用已知的“正向概率”求解“逆向概率”。

二、构建贝叶斯网络

1. matlab中添加贝叶斯网络构建工具FullBNT

FULLBNT是matlab自带贝叶斯网络工具箱,下载地址:http://www.cs.ubc.ca/~murphyk/Software/BNT/FullBNT-1.0.4.zip

  • a. 解压FullBNT-1.0.4.zip,将整个目录FullBNT-1.0.4复制到MATLAB的安装目录的TOOLBOX目录下。我的 目录是’C:\Program Files\MATLAB\R2016a\toolbox’;
  • b. 打开Matlab,在MATLAB命令窗口中进入上述目录,输入以下命令:
>> cd ('C:\Program Files\MATLAB\R2016a\toolbox\FullBNT-1.0.4') %添加括号是为了防止出现参数过多的错误。
  • c. TOOLBOX下的BNT工具箱加到MATLAB路径中,代码如下:
>> addpath(genpathKPM(pwd))
警告: 函数 assert 与某个 MATLAB 内置函数同名。建议您重命名该函数以避免潜在的名称冲突。 
> In path at 109
  In addpath at 86 
警告: 函数 isscalar 与某个 MATLAB 内置函数同名。建议您重命名该函数以避免潜在的名称冲突。 
> In path at 109
  In addpath at 86 
警告: 函数 isvector 与某个 MATLAB 内置函数同名。建议您重命名该函数以避免潜在的名称冲突。 
> In path at 109
  In addpath at 86 
  • d. 永久保存上面的路径,以免下次重启MATLAB时重新添加,命令:
>>savepath
  • e. 检验是否成功,命令行窗口输入:
>> which test_BNT.m
C:\Program Files\MATLAB\R2016a\toolbox\FullBNT-1.0.4\BNT\test_BNT.m
>> 

显示正确,成功添加工具箱。

2、实例分析

【实例1】

如下图所示,给出了贝叶斯网络的图和相应的条件概率:
在这里插入图片描述
对上述信息建立贝叶斯网络,代码如下:

  • (1)创建贝叶斯网络的matlab程序:
N=8; %8个节点,也就是8个特征
A=1; %visit to Asia到过亚洲
S=2; %somking抽烟
T=3; %tuberculosis肺结核
L=4; %lung cancer肺癌
B=5; %bronchitis支气管炎
E=6; %either tub. or lung cancer肺结核或者肺癌
X=7; %positive X-rayX光片呈阳性
D=8; %dyspnoea呼吸困难

%定义网络结构
dag=zeros(N,N);%创建无环图对应的矩阵
dag(A,T)=1;%按拓扑结构关系赋值
dag(S,[L,B])=1;
dag([T,L],E)=1;
dag(B,D)=1;
dag(E,[X,D])=1;
discrete_nodes=1:N;%从1取到N,也就是1-8,赋予各个节点类型,用1:N表示各个节点种类不同
node_sizes=2*ones(1,N);%定义节点状态,元素值为2的1*N行向量,赋予节点的大小,节点独立地有几种可能
bnet=mk_bnet(dag,node_sizes,'names',{
    
    'A','S','T','L','B','E','X','D'},'discrete',discrete_nodes);

%设置各个节点的边缘概率;
%对于A和S,定义顺序是False True;
%对于T、L和B这类,顺序是FF  FT TF TT;
%对于D这类,顺序是FFF FFT FTF FTT TFF TFT TTF TTT
bnet.CPD{
    
    A}=tabular_CPD(bnet,A,[0.99,0.01]);
bnet.CPD{
    
    S}=tabular_CPD(bnet,S,[0.5,0.5]);  
bnet.CPD{
    
    T}=tabular_CPD(bnet,T,[0.99,0.95,0.01,0.05]);  
bnet.CPD{
    
    L}=tabular_CPD(bnet,L,[0.99,0.9,0.01,0.1]);  
bnet.CPD{
    
    B}=tabular_CPD(bnet,B,[0.7,0.4,0.3,0.6]);  
bnet.CPD{
    
    E}=tabular_CPD(bnet,E,[1,0,0,0,0,1,1,1]);  
bnet.CPD{
    
    X}=tabular_CPD(bnet,X,[0.95,0.02,0.05,0.98]);  
bnet.CPD{
    
    D}=tabular_CPD(bnet,D,[0.9,0.2,0.3,0.1,0.1,0.8,0.7,0.9]); 

draw_graph(dag);%画出网络

  • (2)构建完成的贝叶斯网络:
    在这里插入图片描述
    至此,一个简单的贝叶斯网络就构建完毕。
  • (3)简单检查下A的概率
engine=jtree_inf_engine(bnet);%结树,贝叶斯网络,创建一个"引擎"
evidence=cell(1,N);
[engine,loglik]=enter_evidence(engine,evidence);
m=marginal_nodes(engine,A);
m.T()

结果如下图:
在这里插入图片描述
现在可以给定任意条件,然后计算概率了。

  • (4) 使用联合树推断引擎,对贝叶斯网络进行推断
%网络推断,使用联合树引擎,计算P(T=True|A=False,S=True,X=True,D=False)的概率 
%即病人在没有到过亚洲并且抽烟,在做检查之后发现X-ray光片呈阳性,但日常生活不伴有呼吸困难的前提下,患有肺结核的概率有多大?

engine=jtree_inf_engine(bnet);
evidence=cell(1,N);%1*N的空cell类型向量,元素可以是任意类型数据
evidence{
    
    A}=1;  
evidence{
    
    S}=2;  
evidence{
    
    X}=2;  
evidence{
    
    D}=1; 
[engine,loglik]=enter_evidence(engine,evidence);
m=marginal_nodes(engine,T);
m.T

得出:
在这里插入图片描述
由此可见,T为TRUE,即患者患有肺结核的概率比较大。

【实例2】

在这里插入图片描述

  • (1)创建贝叶斯网络的matlab程序:
N=4;
dag=zeros(N,N);%无向环用矩阵表示
C=1;S=2;R=3;W=4;%按拓扑矩阵给各个节点编号,方便下一步赋值
dag(C,[R S])=1;%按逻辑关系赋值
dag([S R],W)=1;
discrete_nodes = 1:N;%定义类型
node_sizes = 2*ones(1,N);%分配大小
bnet=mk_bnet(dag,node_sizes,'names',{
    
    'C','S','R','W'},'discrete',discrete_nodes);%创建网络
bnet.CPD{
    
    C}=tabular_CPD(bnet,C,[0.5 0.5]);%赋上各个事件的概率值
bnet.CPD{
    
    S}=tabular_CPD(bnet,S,[0.5 0.9 0.5 0.1]);
bnet.CPD{
    
    R}=tabular_CPD(bnet,R,[0.8 0.2 0.2 0.8]);
bnet.CPD{
    
    W}=tabular_CPD(bnet,W,[1.0 0.1 0.1 0.01 0 0.9 0.9 0.99]);
draw_graph(dag) %绘制出贝叶斯网络图

  • (2)构建完成的贝叶斯网络:
    在这里插入图片描述
  • (3)简单检查下在C为True时S发生的概率;
engine=jtree_inf_engine(bnet);
evidence=cell(1,N);%1*N的空cell类型向量,元素可以是任意类型数据
evidence{
    
    C}=2;  
[engine,loglik]=enter_evidence(engine,evidence);
m=marginal_nodes(engine,S);
m.T

结果如下图:
在这里插入图片描述
现在可以给定任意条件,然后计算概率了。

  • (4) 使用联合树推断引擎,对贝叶斯网络进行推断
    在建立贝叶斯网络之后,可以根据观察到的现象推测原因;下面是计算当观察到玻璃是湿的时候,下雨的可能性有多大的matlab程序片段:
engine=jtree_inf_engine(bnet); %结树,贝叶斯网络,创建一个"引擎"
evidence=cell(1,N);
evidence{
    
    W}=2;%计算当观察到玻璃是湿的时候,下雨的可能性有多大
[engine,loglik]=enter_evidence(engine,evidence);
m=marginal_nodes(engine,C);
m.T

计算结果如下图所示,表明当观察到玻璃是湿的的时候,没有下雨的可能性是42.42%,下过雨的可能性是57.58%。
在这里插入图片描述
也可以用柱状图表示出来:

bar(m.T)

在这里插入图片描述

三、注意事项

要点1:
在这里插入图片描述
在表达这个逻辑关系时,是 dag(A,T)=1,而不是dag(T,A)=1.

要点2:
节点的大小仅表示节点在独立情况下有多少种可能性,比如像上图中的节点A,是否去过亚洲,可能的结果有两种,去过和没去过,那么节点的大小就是2.

要点3:
这里的概率值是有一定的先后顺序的,
(1)只有两个概率值时:F T(其实也就是 0 1)
(2)有四个概率值时,按下面这个例子,PC:FF FT TF TT(其实也就是00 01 10 11)
在这里插入图片描述

在这里插入图片描述

bnet.CPD{
    
    S}=tabular_CPD(bnet,S,[0.5 0.9 0.5 0.1]);

(3)有八个概率值时,按下面的这个例子,WRS:FFF FFT FTF FTT TFF TFT TTF TTT(其实也就是000 001 010 011 100 101 110 111)
在这里插入图片描述

bnet.CPD{
    
    W}=tabular_CPD(bnet,W,[1.0 0.1 0.1 0.01 0 0.9 0.9 0.99]);

总结:
By the way,这里PC、WRS遵循的规律是:
不同级时,下面的排在前;
同一级时,右面的排在前。

四、所遇问题及解决方案

MATLAB在生成贝叶斯网络时报错:

1. 问题一 (贝叶斯网络无箭头)

未定义与 ‘matlab.graphics.axis.Axes’ 类型的输入参数相对应的运算符 ‘*’

问题描述:
使用matlab生成贝叶斯网络的时候,可以生成,但生成的贝叶斯网络没有边,如下图:
在这里插入图片描述
在这里插入图片描述

解决方案:

用如下文件替换原C:\Program Files\MATLAB\R2016a\toolbox\FullBNT-1.0.4\GraphViz下的arrow.m

新版arrow.m文件链接:https://pan.baidu.com/s/1lcaY_58oNNgCSGK375Hv0g
提取码:tikt

2. 问题二(draw_graph函数调用报错)

问题描述:报错如下

>> BN_weather
错误使用 set
Patch 类中没有 Color 属性。

出错 draw_graph (line 103)
set(h_edge,'Color',color.edge)

出错 BN_weather (line 14)
draw_graph(dag) %绘制出贝叶斯网络图

解决方案:
draw_graph函数被调用的时候出了问题,没有办法识别set(h_edge,‘Color’,color.edge),

因为h_edge是一条边,而‘Color’是图形的颜色,在draw_graph函数中将报错的103行的color改成EdgeColor就可以了。
在这里插入图片描述

比如也可以设置箭头的颜色:color.edge=‘green’

在这里插入图片描述
运行结果如下:
在这里插入图片描述

参考:
[1] http://t.csdn.cn/dB5Bt
[2] http://t.csdn.cn/StObM
[3] http://t.csdn.cn/HEOpI
[4]https://blog.csdn.net/corinne0623/article/details/124435366

猜你喜欢

转载自blog.csdn.net/weixin_45075135/article/details/129108204
今日推荐