def enumerate_joint(vars, values, P): "As in Fig 13.4, except x and e are already incorporated in values." if not vars: return P[values] Y = vars[0]; rest = vars[1:] return sum([enumerate_joint(rest, extend(values, Y, y), P) for y in P.values(Y)])
def enumerate_all(vars, e, bn): """Returns the probability that X = xi given e. vars is a list of variables, the parents of X in bn. e is a dictionary of variable-name: value pairs bn is an instance of BayesNet. Precondition: no variable in vars precedes its parents.""" if vars == []: return 1.0 else: Y = vars[0] rest = vars[1:] Ynode = bn.variable_node(Y) parents = Ynode.parents cpt = Ynode.cpt if e.has_key(Y): y = e[Y] cp = cpt.p(y, parents, e) # P(y | parents(Y)) result = cp * enumerate_all(rest, e, bn) else: result = 0 for y in bn.variable_values(Y): cp = cpt.p(y, parents, e) # P(y | parents(Y)) result += cp * enumerate_all(rest, extend(e, Y, y), bn) return result
def enumerate_all (vars, e, bn): """Returns the probability that X = xi given e. vars is a list of variables, the parents of X in bn. e is a dictionary of variable-name: value pairs bn is an instance of BayesNet. Precondition: no variable in vars precedes its parents.""" if vars == []: return 1.0 else: Y = vars[0] rest = vars[1:] Ynode = bn.variable_node(Y) parents = Ynode.parents cpt = Ynode.cpt if e.has_key(Y): y = e[Y] cp = cpt.p(y, parents, e) # P(y | parents(Y)) result = cp * enumerate_all(rest, e, bn) else: result = 0 for y in bn.variable_values(Y): cp = cpt.p(y, parents, e) # P(y | parents(Y)) result += cp * enumerate_all(rest, extend(e, Y, y), bn) return result
def sum_out(self, var, bn): """Make a factor eliminating var by summing over its values.""" variables = [X for X in self.variables if X != var] cpt = {event_values(e, variables): sum(self.p(extend(e, var, val)) for val in bn.variable_values(var)) for e in all_events(variables, bn, {})} return Factor(variables, cpt)
def enumerate_joint(variables, e, P): """Return the sum of those entries in P consistent with e, provided variables is P's remaining variables (the ones not in e).""" if not variables: return P[e] Y, rest = variables[0], variables[1:] return sum([enumerate_joint(rest, extend(e, Y, y), P) for y in P.values(Y)])
def enumerate_joint(variables, e, P): """Return the sum of those entries in P consistent with e, provided variables is P's remaining variables (the ones not in e).""" if not variables: return P[e] Y, rest = variables[0], variables[1:] return sum( [enumerate_joint(rest, extend(e, Y, y), P) for y in P.values(Y)])
def all_events(variables, bn, e): """Yield every way of extending e with values for all variables.""" if not variables: yield e else: X, rest = variables[0], variables[1:] for e1 in all_events(rest, bn, e): for x in bn.variable_values(X): yield extend(e1, X, x)
def all_events(variables, bn, e): "Yield every way of extending e with values for all variables." if not variables: yield e else: X, rest = variables[0], variables[1:] for e1 in all_events(rest, bn, e): for x in bn.variable_values(X): yield extend(e1, X, x)
def enumerate_joint_ask(X, e, P): """Return a probability distribution over the values of the variable X, given the {var:val} observations e, in the JointProbDist P. Works for Boolean variables only. [Fig. 13.4]""" Q = ProbDist(X) ## A probability distribution for X, initially empty Y = [v for v in P.variables if v != X and v not in e] for xi in P.values(X): Q[xi] = enumerate_joint(Y, extend(e, X, xi), P) return Q.normalize()
def enumeration_ask(X, e, bn): """Return the conditional probability distribution of variable X given evidence e, from BayesNet bn. [Fig. 14.9] >>> enumeration_ask('Burglary', dict(JohnCalls=T, MaryCalls=T), burglary ... ).show_approx() 'False: 0.716, True: 0.284'""" assert X not in e, "Query variable must be distinct from evidence" Q = ProbDist(X) for xi in bn.variable_values(X): Q[xi] = enumerate_all(bn.variables, extend(e, X, xi), bn) return Q.normalize()
def enumeration_ask(X, e, bn): """Return the conditional probability distribution of variable X given evidence e, from BayesNet bn. [Figure 14.9] >>> enumeration_ask('Burglary', dict(JohnCalls=T, MaryCalls=T), burglary ... ).show_approx() 'False: 0.716, True: 0.284'""" assert X not in e, "Query variable must be distinct from evidence" Q = ProbDist(X) for xi in bn.variable_values(X): Q[xi] = enumerate_all(bn.variables, extend(e, X, xi), bn) return Q.normalize()
def markov_blanket_sample(X, e, bn): """Return a sample from P(X | mb) where mb denotes that the variables in the Markov blanket of X take their values from event e (which must assign a value to each). The Markov blanket of X is X's parents, children, and children's parents.""" Xnode = bn.variable_node(X) Q = ProbDist(X) for xi in bn.variable_values(X): ei = extend(e, X, xi) # [Equation 14.12:] Q[xi] = Xnode.p(xi, e) * product(Yj.p(ei[Yj.variable], ei) for Yj in Xnode.children) return probability(Q.normalize()[True]) # (assuming a Boolean variable here)
def enumerate_all(vars, e, bn): """Return the sum of those entries in P(vars | e{others}) consistent with e, where P is the joint distribution represented by bn, and e{others} means e restricted to bn's other variables (the ones other than vars). Parents must precede children in vars.""" if not vars: return 1.0 Y, rest = vars[0], vars[1:] Ynode = bn.variable_node(Y) if Y in e: return Ynode.p(e[Y], e) * enumerate_all(rest, e, bn) else: return sum(Ynode.p(y, e) * enumerate_all(rest, extend(e, Y, y), bn) for y in bn.variable_values(Y))
def enumerate_joint_ask(X, e, P): """Return a probability distribution over the values of the variable X, given the {var:val} observations e, in the JointProbDist P. [Section 13.3] >>> P = JointProbDist(['X', 'Y']) >>> P[0,0] = 0.25; P[0,1] = 0.5; P[1,1] = P[2,1] = 0.125 >>> enumerate_joint_ask('X', dict(Y=1), P).show_approx() '0: 0.667, 1: 0.167, 2: 0.167' """ assert X not in e, "Query variable must be distinct from evidence" Q = ProbDist(X) # probability distribution for X, initially empty Y = [v for v in P.variables if v != X and v not in e] # hidden variables. for xi in P.values(X): Q[xi] = enumerate_joint(Y, extend(e, X, xi), P) return Q.normalize()
def markov_blanket_sample(X, e, bn): """Return a sample from P(X | mb) where mb denotes that the variables in the Markov blanket of X take their values from event e (which must assign a value to each). The Markov blanket of X is X's parents, children, and children's parents.""" Xnode = bn.variable_node(X) Q = ProbDist(X) for xi in bn.variable_values(X): ei = extend(e, X, xi) # [Equation 14.12:] Q[xi] = Xnode.p(xi, e) * product( Yj.p(ei[Yj.variable], ei) for Yj in Xnode.children) # (assuming a Boolean variable here) return probability(Q.normalize()[True])
def enumerate_all(variables, e, bn): """Return the sum of those entries in P(variables | e{others}) consistent with e, where P is the joint distribution represented by bn, and e{others} means e restricted to bn's other variables (the ones other than variables). Parents must precede children in variables.""" if not variables: return 1.0 Y, rest = variables[0], variables[1:] Ynode = bn.variable_node(Y) if Y in e: return Ynode.p(e[Y], e) * enumerate_all(rest, e, bn) else: return sum(Ynode.p(y, e) * enumerate_all(rest, extend(e, Y, y), bn) for y in bn.variable_values(Y))
def enumerate_joint_ask(X, e, P): """Return a probability distribution over the values of the variable X, given the {var:val} observations e, in the JointProbDist P. Works for Boolean variables only. [Fig. 13.4]. X is a string (variable name). e is a dictionary of variable-name value pairs. P is an instance of JointProbDist.""" Q = ProbDist(X) # probability distribution for X, initially empty Y = [v for v in P.variables if v != X and v not in e] # hidden vars. for xi in P.values(X): ext = extend(e, X, xi) # copies e and adds X: xi Q[xi] = enumerate_joint(Y, ext, P) return Q.normalize()
def max_out(self, var, bn): """ Make a factor eliminating var by summing over its values. :param var: :param bn: :return: """ variables = [X for X in self.variables if X != var] cpt_with_assignement = {event_values(e, variables): max((self.p(extend(e, var, val)), val) for val in bn.variable_values(var)) for e in all_events(variables, bn, {})} assignement = {} cpt = {} for key, (value, assgn) in cpt_with_assignement.items(): cpt[key] = value assignement[key] = assgn factor = Factor(variables, cpt, assignement, self) factor.last_max_out = bn.last_max_out bn.last_max_out = factor return factor
def enumeration_ask (X, e, bn): """Returns a distribution of X given e from bayes net bn. [Fig. 14.9] X is a string (variable name). e is a dictionary of variablename: value pairs. bn is an instance of BayesNet. >>> p = enumeration_ask('Earthquake', {}, burglary) >>> [p[True], p[False]] [0.002, 0.998] >>> p = enumeration_ask('Burglary', ... {'JohnCalls': True, 'MaryCalls': True}, burglary) >>> p.show_approx() 'False: 0.716, True: 0.284'""" Q = ProbDist(X) # empty probability distribution for X for xi in bn.variable_values(X): Q[xi] = enumerate_all(bn.variables(), extend(e, X, xi), bn) # Assume that parents precede children in bn.variables. # Otherwise, in enumerate_all, the values of Y's parents # may be unspecified. return Q.normalize()
def all_events_jpd(vars, jpd, e): """ e is evidence, it is a dict containing 'variable:value' pairs vars is a list of variables jpd is an object of JointProbDist The function generates all events of variables in vars with all possible value assignments and variables in e with fixed values >>>P = JointProbDist(['X', 'Y', 'Z'], {'X':[1,2], 'Y': [True, False], 'Z' : ['a', 'b']}) >>>events = all_events_jpd(['X', 'Y'], P, {'Z':'a'}) >>>for each in events: print each {'Y': True, 'X': 1, 'Z': 'a'} {'Y': True, 'X': 2, 'Z': 'a'} {'Y': False, 'X': 1, 'Z': 'a'} {'Y': False, 'X': 2, 'Z': 'a'} """ if not vars: ## if vars is empty yield e else: X, rest = vars[0], vars[1:] for e1 in all_events_jpd(rest, jpd, e): for x in jpd.values(X): yield extend(e1, X, x)
def all_events_jpd(vars, jpd, e): """ e is evidence, it is a dict containing 'variable:value' pairs vars is a list of variables jpd is an object of JointProbDist The function generates all events of variables in vars with all possible value assignments and variables in e with fixed values >>>P = JointProbDist(['X', 'Y', 'Z'], {'X':[1,2], 'Y': [True, False], 'Z' : ['a', 'b']}) >>>events = all_events_jpd(['X', 'Y'], P, {'Z':'a'}) >>>for each in events: print each {'Y': True, 'X': 1, 'Z': 'a'} {'Y': True, 'X': 2, 'Z': 'a'} {'Y': False, 'X': 1, 'Z': 'a'} {'Y': False, 'X': 2, 'Z': 'a'} """ if not vars: ## if vars is empty yield e else: X, rest = vars[0], vars[1:] for e1 in all_events_jpd(rest, jpd,e): for x in jpd.values(X): yield extend(e1, X,x)
def enumeration_ask(X, e, bn): """Returns a distribution of X given e from bayes net bn. [Fig. 14.9] X is a string (variable name). e is a dictionary of variablename: value pairs. bn is an instance of BayesNet. >>> p = enumeration_ask('Earthquake', {}, burglary) >>> [p[True], p[False]] [0.002, 0.998] >>> p = enumeration_ask('Burglary', ... {'JohnCalls': True, 'MaryCalls': True}, burglary) >>> p.show_approx() 'False: 0.716, True: 0.284' """ Q = ProbDist(X) # empty probability distribution for X for xi in bn.variable_values(X): Q[xi] = enumerate_all(bn.variables(), extend(e, X, xi), bn) # Assume that parents precede children in bn.variables. # Otherwise, in enumerate_all, the values of Y's parents # may be unspecified. return Q.normalize()