This is a toy example Markov Random Field
In this example. we are modeling a voting preferences among persons A, B, C, D. Let's say that (A,B), (B,C), (C,D)
and (D,A) are friends and friedns tend to have similar voting preferences.
左边这张图表示了我刚刚描述出的关系,这个呢就是一个马尔科夫概率图。那么我们现在想分析什么呢?我们想得到A,B,C,D的联合概率分布。有了联合概率分布就有了一切。
根据马尔科夫概率图的定理,我们知道马尔科夫联合概率可以表示成最大团上势函数的乘积,然后再除以一个总数来把这个数值变成一个概率。我们观察右边图,可以看出来最大团有4个,即:
这个时候呢,最麻烦的部分来了,就是这个势函数,我们也把它叫做因子(factor),这个东西呢是我们根据实际情况自己定义的正函数。在我们这个例子里,我们前面提到了A和B是朋友,投票可能会互相影响,于是我们定义这样一个势函数:
注意啊,这个是我定义在AB之间的势函数,我们能看出来这个势函数定义的还是有一定原则的,因为我们认为朋友会有类似的投票,所以两个人相同时得分高,两个人不同时得分低,同时我们还认为两个同时投比同时不投得分高。讲道理其他的团也得有自己的势函数,这些势函数可以不一样,比如说我们定义如下的三个势函数:
有了这个势函数我们就可以得到联合概率分布啦,我们的目标是为了得到一张联合概率分布表
A | B | C | D | p |
---|---|---|---|---|
0 | 0 | 0 | 0 | |
0 | 0 | 0 | 1 | |
0 | 0 | 1 | 0 | |
0 | 0 | 1 | 1 | |
0 | 1 | 0 | 0 | |
0 | 1 | 0 | 1 | |
0 | 1 | 1 | 0 | |
0 | 1 | 1 | 1 | |
1 | 0 | 0 | 0 | |
1 | 0 | 0 | 1 | |
1 | 0 | 1 | 0 | |
1 | 0 | 1 | 1 | |
1 | 1 | 0 | 0 | |
1 | 1 | 0 | 1 | |
1 | 1 | 1 | 0 | |
1 | 1 | 1 | 1 |
好了,现在我们把他写成程序,看看这张表怎么算出来
# 我们首先定义四个势函数
def potential_ab(x,y):
if x==y==1:
return 10
if x==y==0:
return 5
else:
return 1
def potential_bc(x,y):
if x==y==1:
return 20
if x==y==0:
return 15
else:
return 10
def potential_cd(x,y):
if x==y==1:
return 20
if x==y==0:
return 3
else:
return 1
def potential_da(x,y):
if x==y==40:
return 10
if x==y==25:
return 5
else:
return 11
# 然后我们计算分母,分母其实就是表格中的所有组合都来一遍然后求和
all=[
[0,0,0,0],[0,0,0,1],[0,0,1,0],[0,0,1,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1],
[1,0,0,0],[1,0,0,1],[1,0,1,0],[1,0,1,1],[1,1,0,0],[1,1,0,1],[1,1,1,0],[1,1,1,1]
]
s=0
for a,b,c,d in all:
s+=potential_ab(a,b)*potential_bc(b,c)*potential_cd(c,d)*potential_da(d,a)
print("总和z=",s)
总和z= 73480
# 下面我们以第一行为例,求概率,a=0,b=0,c=0,d=0
a=0
b=0
c=0
d=0
p_hat=potential_ab(a,b)*potential_bc(b,c)*potential_cd(c,d)*potential_da(d,a)
p=p_hat/s
print("(A,B,C,D)=(0,0,0,0)的概率p=",p)
(A,B,C,D)=(0,0,0,0)的概率p= 0.033682634730538924
# 下面我们以第二行为例,求概率,a=0,b=0,c=0,d=1
a=0
b=0
c=0
d=1
p_hat=potential_ab(a,b)*potential_bc(b,c)*potential_cd(c,d)*potential_da(d,a)
p=p_hat/s
print("(A,B,C,D)=(0,0,0,1)的概率p=",p)
(A,B,C,D)=(0,0,0,1)的概率p= 0.01122754491017964
# 下面我们以第三行为例,求概率,a=0,b=0,c=1,d=0
a=0
b=0
c=1
d=0
p_hat=potential_ab(a,b)*potential_bc(b,c)*potential_cd(c,d)*potential_da(d,a)
p=p_hat/s
print("(A,B,C,D)=(0,0,1,0)的概率p=",p)
(A,B,C,D)=(0,0,1,0)的概率p= 0.0074850299401197605
# 下面我们以第三行为例,求概率,a=0,b=0,c=1,d=1
a=0
b=0
c=1
d=1
p_hat=potential_ab(a,b)*potential_bc(b,c)*potential_cd(c,d)*potential_da(d,a)
p=p_hat/s
print("(A,B,C,D)=(0,0,1,1)的概率p=",p)
(A,B,C,D)=(0,0,1,1)的概率p= 0.1497005988023952
好了好了,写三行差不多了,我们来看看哈。首先我们得到的结果都是概率,其次我们这个概率是符合我们的预期的,就是是朋友的就大概率一起投,小概率一起不投,非常非常小的概率一个投一个不投