概率图模型-原理与技术 第三章 贝叶斯网表示 习题与编程
概率图模型-原理与技术 总目录
http://blog.youkuaiyun.com/icefire_tyh/article/details/54026071#t3
9.关于一个一般的贝叶斯网络结构,证明定理3.2。
定理3.2:如果分布
P
根据

考虑上图结构, Pa 指s的父节点集合, Nd 指s的非邻接非后代节点集合,那么只需要证明:
P(s|Pa,ND)=P(s,Pa,ND)P(Pa,ND)
由于 Nd 与s没有直接连线,那么 P(s,Pa,ND)=P(Pa,ND)P(s|Pa)
于是有 P(s|Pa)=P(s|Pa,ND)
11.贝叶斯网在许多情况下的一个常用操作是对网络中某些节点的边缘化。
a.考虑下图所示的防盗铃网络
G
。构建一个除Alarm以外的所有节点上的贝叶斯网
b.将前面解决问题的过程归纳为一个节点消除算法。即,定义一个将结构
G
转换为

- a:
寻找出经过Alarm的有效迹 ...X,A,Y... [使迹有效的条件不包括Alarm],保证去掉Alarm后 ...X,Y... 任然是有效轨即可。
结果如图所示:

- b:
一种简单的做法是归纳出被删除节点所有入度与出度的集合,为入度集合中的每个节点与出度集合中每个节点连上一条边。[如果已经有边则不操作]
这样使得原本边缘独立的非正规结构依然边缘独立,原本基于被删除节点条件独立的结构变成不独立。
12.贝叶斯网的另外一个常见的操作是边的反向。这个操作将包含节点
X,Y
以及边
X→Y
的贝叶斯网
G
转换成一个包含反向边Y→X 的贝叶斯网
G′
。然而,我们希望
G′
与
G
能表示相同的分布;因此,G′ 需要是原始分布的一个
I−map。
a.考虑11题的图所示的贝叶斯网络结构。假设将
B→A
反向。为了保证新的网络是原始网络的一个
I−map
,需要对这个新网络结构做哪些修改?不能再反向别的边,可以添加或删除边。
b.考虑一个一般的贝叶斯网
G
。为简单起见,假设
c.加入用上述方法生成了
G′
,现在又将被反转的边反转回原始方向生产
G′′
。可以保证最终的结构与原始结构等价吗?
将
B→A
反向后的图

每当有一条边反向,影响主要是两种
1:生成新的非正规结构
如例1:
X→Z→Y
变为
X→Z←Y
,那么一开始的
(X⊥Y)
,将变为
(X⊥Y|Z)
。
2:旧的非正规结构变成一般结构
如例2:
X→Z←Y
变为
X→Z→Y
,那么一开始的
(X⊥Y)
,将变为
(X⊥Y|Z)
。
- a:
当 B,A 反向后,原有的独立性 (B⊥E) 变为 (B⊥E|A) ,为了消除这条独立性,引入边 A←E 。
b:
由于 X→Y 是 X,Y 之间唯一一条有向迹,说明如果有节点与 X,Y 构成了v结构,那么他们就是非正规结构。后续操作如上所述。c:
如果引入了新的边, I(G′′) 将会是 I(G) 的真子集,从而不会再 I− 等价。如果图的骨架没变,则两图 I− 等价。
13.并没有看太明白题目。
14.证明定理3.6。
定理3.6:证明算法
Reachable(G,X,Z)
返回所有从X出发,经由
G
中所有有效迹的节点集合。[我的理解就是,在给定

第12行:由于程序会从上至下和从下至上两次扫描,所以只需要加入节点X一个扫描方向如带扫描队列即可。
第22-26行[上下两轮扫描]:如果只进行一次遍历[向上],则无法得出v结构所带来的有效迹。
第32-34行[v结构]:由于当Z已知时,只有v结构的迹才是有效的,所以当扫描是从上至下时,如果发现当前的节点Y是已知节点Z的祖先节点,则可以继续影响到Y的祖先节点。
16.证明定理3.7。
定理3.7:如果
G1
和
G2
有相同的骨架和相同的v结构集,那么它们是
I−
等价的。
由于
G1
和
G2
有相同的骨架和相同的v结构集,那么在它们的非v结构区域,边的方向不会影响迹的有效性。那么对于任何
G1
中
d−
分离的两个节点X,Y,在
G2
中也是
d−
分离的,所以它们是
I−
等价的。
17略
18略
19.证明引理3.2。
引理3.2:令
G
是分布
做个一般性假设:Y如果和X有关系,Y是X的后代
Pa
:
X,Y
共同的父节点
PaYX
:
Y
的父节点且是X的后代
显然在
G
中
当
PaYX=∅
两者都成立,否则
(X⊥Y|PaGY)
成立。
代码篇:
- 有效轨迹可达算法:
该算法在上述算法描述中有详细描述。
输入:
A B
C B
B D
C D
B
D
输出:
{'D', 'C', 'A'}
参考代码:
# -*- coding: utf-8 -*-
"""
Created on Sat Jan 21 12:34:06 2017
@author: icefire
"""
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
import random
class nodetype:
def __init__(self,n,index):
self.fathers=set()
self.children=set()
self.nodirect=set()
self.name=n
self.index=index
def solution_3_1():
#节点列表
node_list = []
#节点值得字典
name_map ={}
'''
输入格式
A C表示A->C的有向边
第一次空行表示开始输入已知节点
B C E D 表示B C E D已知
第一次空行表示开始输入起始
A 从A开始
'''
file = open('p3-1-graph', 'r')
Z=set() #已知的节点
A=set() #已知的节点及其祖先节点
#输入处理
node_flag=0 #判断输入的是边,已知节点还是起始节点
while 1:
line = file.readline()
if not line:
break
data = line.split()
if len(data)==0: #每次遇到空行就加一
node_flag+=1
continue
if node_flag==0:
for i in [0,1]:
#查看当前节点值是否在字典中存在
index=name_map.get(data[i], -1)
if(index==-1):
node_list.append(nodetype(data[i],len(node_list)))
name_map[data[i]]=len(node_list)-1
data[i]=len(node_list)-1
else:
data[i]=index
node_list[data[0]].children.add(node_list[data[1]])
node_list[data[1]].fathers.add(node_list[data[0]])
elif node_flag==1:
for f in data:
Z.add(node_list[name_map[f]])
else:
start=node_list[name_map[data[0]]]
#将每条边对应节点的父亲,儿子,无向节点集合更新
#利用集合[队列]来生成祖先节点集合A
T=Z.copy()
while(len(T)>0):
tmp_node = random.sample(T, 1)
tmp_node = tmp_node[0]
T.remove(tmp_node)
if tmp_node not in A:
A.add(tmp_node)
for node in tmp_node.fathers:
if node not in A:
T.add(node)
V=set() #已遍历的集合
R=set() #有效迹的节点标识集合
#用数字来表示遍历过程,公式2*node.index+d d表示方向 0向上,1向下
T.add(2*start.index)
#参考本页算法注释
while(len(T)>0):
tmp = random.sample(T, 1)
tmp=tmp[0]
d = tmp%2
cnode=node_list[tmp//2]
T.remove(tmp)
if tmp not in V:
if cnode not in Z:
R.add(cnode.name)
V.add(tmp)
if d==0 and cnode not in Z:
for node in cnode.fathers:
T.add(2*node.index)
for node in cnode.children:
T.add(2*node.index+1)
elif d==1:
if cnode not in Z:
for node in cnode.children:
T.add(2*node.index+1)
if cnode in A:
for node in cnode.fathers:
T.add(2*node.index)
print(R)
solution_3_1()
- p-map生产算法: