3
3
4
4
from utils import *
5
5
from logic import extend
6
- from random import random , seed
6
+ from random import choice , seed
7
7
8
8
#______________________________________________________________________________
9
9
@@ -160,6 +160,8 @@ def add(self, node):
160
160
assert every (lambda parent : parent in self .variables (), node .parents )
161
161
self .nodes .append (node )
162
162
self .vars .append (node .variable )
163
+ for parent in node .parents :
164
+ self .variable_node (parent ).children .append (node )
163
165
164
166
def variable_node (self , var ):
165
167
"""Return the node for the variable named var.
@@ -224,7 +226,7 @@ def __init__(self, X, parents, cpt):
224
226
assert every (lambda v : isinstance (v , bool ), vs )
225
227
assert 0 <= p <= 1
226
228
227
- update (self , variable = X , parents = parents , cpt = cpt )
229
+ update (self , variable = X , parents = parents , cpt = cpt , children = [] )
228
230
229
231
def p (self , value , event ):
230
232
"""Return the conditional probability
@@ -243,7 +245,7 @@ def sample(self, event):
243
245
on event's values for parent_vars. That is, return True/False
244
246
at random according with the conditional probability given the
245
247
parents."""
246
- return random () <= self .p (True , event )
248
+ return probability ( self .p (True , event ) )
247
249
248
250
node = BayesNode
249
251
@@ -391,24 +393,36 @@ def weighted_sample(bn, e):
391
393
#_______________________________________________________________________________
392
394
393
395
def gibbs_ask (X , e , bn , N ):
394
- """[Fig. 14.16]"""
395
- counts = {True : 0 , False : 0 } # boldface N in Fig. 14.16
396
- Z = [var for var in bn .variables if var not in e ]
396
+ """[Fig. 14.16]
397
+ >>> seed(1017)
398
+ >>> gibbs_ask('Burglary', dict(JohnCalls=T, MaryCalls=T), burglary, 1000
399
+ ... ).show_approx()
400
+ 'False: 0.738, True: 0.262'
401
+ """
402
+ counts = dict ((x , 0 ) for x in bn .variable_values (X )) # bold N in Fig. 14.16
403
+ Z = [var for var in bn .variables () if var not in e ]
397
404
state = dict (e ) # boldface x in Fig. 14.16
398
405
for Zi in Z :
399
- state [Zi ] = choice ([ True , False ] )
406
+ state [Zi ] = choice (bn . variable_values ( Zi ) )
400
407
for j in xrange (N ):
401
408
for Zi in Z :
402
- state [Zi ] = ( random () < P_markov_blanket ( Zi , state , bn ) )
409
+ state [Zi ] = markov_blanket_sample ( Zi , state , bn )
403
410
counts [state [X ]] += 1
404
411
return ProbDist (X , counts )
405
412
406
- def P_markov_blanket (X , e , bn ):
407
- """Return P(X | mb) where mb denotes that the variables in the
408
- Markov blanket of X take their values from event e (which must
409
- assign a value to each). The Markov blanket of X is X's parents,
410
- children, and children's parents."""
411
- unimplemented ()
413
+ def markov_blanket_sample (X , e , bn ):
414
+ """Return a sample from P(X | mb) where mb denotes that the
415
+ variables in the Markov blanket of X take their values from event
416
+ e (which must assign a value to each). The Markov blanket of X is
417
+ X's parents, children, and children's parents."""
418
+ Xnode = bn .variable_node (X )
419
+ Q = ProbDist (X )
420
+ for xi in bn .variable_values (X ):
421
+ ei = extend (e , X , xi )
422
+ # [Equation 14.12:]
423
+ Q [xi ] = Xnode .p (xi , e ) * product (Yj .p (ei [Yj .variable ], ei )
424
+ for Yj in Xnode .children )
425
+ return probability (Q .normalize ()[True ]) # (assuming a Boolean variable here)
412
426
413
427
#_______________________________________________________________________________
414
428
0 commit comments