def eventValue_test_5(self): """ Test value() method """ event = Event(var=self.X, val=self.X.domain[0]) assert(event.value(self.X) == self.X.domain[0])
def sample(self, pre_inst=None): """ Returns a random sample of the network in the form of an Event. An event will contain a list of tuples. Each tuple is a pair between a random variable and it's instance, in the form: >>> ret = [(X, "T"), (Y, "F")] :param pre_inst: Default=None. Should be a list of tuples. Each tuple is a pair between a random variable and a value of it's domain. That value will be the value in the sample instead of leaving it to random chance. """ net = self.network[:] inst_vars = Event() for i in net: insted = i.factor.instVar(inst_vars) var = i.node if pre_inst is not None: val = pre_inst.value(i.node) if pre_inst is None or val is None: val = self.pickRandomValue(var.domain, insted.values, random.random()) inst_vars.setValue(var, val) return inst_vars
def eventValue_test_5(self): """ Test value() method """ event = Event(var=self.X, val=self.X.domain[0]) assert (event.value(self.X) == self.X.domain[0])
def eventVarInEvent_test_4(self): """ Test varInEvent() method """ event = Event(var=self.X, val=self.X.domain[0]) assert(event.varInEvent(self.X)) assert(not event.varInEvent(self.Y))
def eventVarInEvent_test_4(self): """ Test varInEvent() method """ event = Event(var=self.X, val=self.X.domain[0]) assert (event.varInEvent(self.X)) assert (not event.varInEvent(self.Y))
def eventRemoveVar_test_7(self): """ Test setValue method """ event = Event(var=self.X, val=self.X.domain[0]) event.removeVar(self.X) event.removeVar(self.Y) # Already not in event assert(not event.varInEvent(self.X)) assert(not event.varInEvent(self.Y))
def eventRemoveVar_test_7(self): """ Test setValue method """ event = Event(var=self.X, val=self.X.domain[0]) event.removeVar(self.X) event.removeVar(self.Y) # Already not in event assert (not event.varInEvent(self.X)) assert (not event.varInEvent(self.Y))
def eventSetValue_test_6(self): """ Test setValue method """ event = Event(var=self.X, val=self.X.domain[0]) event.setValue(self.X, self.X.domain[1]) event.setValue(self.Y, self.Y.domain[1]) assert(len(event.event.keys()) == 2) assert(event.value(self.X) == self.X.domain[1]) assert(event.value(self.Y) == self.Y.domain[1])
def eventSetValue_test_6(self): """ Test setValue method """ event = Event(var=self.X, val=self.X.domain[0]) event.setValue(self.X, self.X.domain[1]) event.setValue(self.Y, self.Y.domain[1]) assert (len(event.event.keys()) == 2) assert (event.value(self.X) == self.X.domain[1]) assert (event.value(self.Y) == self.Y.domain[1])
def eventEqual_test_10(self): """ Test when two event are different in their values, one variable """ tlist1 = [(self.X, self.X.domain[0])] tlist2 = [(self.X, self.X.domain[1])] event1 = Event(tlist=tlist1) event2 = Event(tlist=tlist2) assert (event1 != event2)
def eventNotEqual_test_13(self): """ Test when variables in events are not the same, two variables """ tlist1 = [(self.X, self.X.domain[0]), (self.Y, self.Y.domain[0])] tlist2 = [(self.X, self.X.domain[0]), (self.Z, self.Z.domain[0])] event1 = Event(tlist=tlist1) event2 = Event(tlist=tlist2) assert (event1 != event2)
def eventNotEqual_test_11(self): """ Test when two event are different in their values, two variables """ tlist1 = [(self.X, self.X.domain[0]), (self.Y, self.Y.domain[0])] tlist2 = [(self.X, self.X.domain[1]), (self.Y, self.Y.domain[0])] tlist3 = [(self.Y, self.Y.domain[0]), (self.X, self.X.domain[1])] event1 = Event(tlist=tlist1) event2 = Event(tlist=tlist2) event3 = Event(tlist=tlist3) assert (event1 != event2) assert (event1 != event3)
def argmin(self): """ Returns event with the lesser value :returns: Returns an Event object with the event that minimizes the value of this factor """ # Find the maximum value minval = self.values[0] index = 0 for i, value in enumerate(self.values, 1): if value < minval: minval = value index = i - 1 # Make the event event = [] div = 1 for i, var in enumerate(self.rand_vars): doml = len(var.domain) val = int(index / div) % doml event.append((var, var.domain[val])) div *= len(var.domain) return Event(event)
def eventConst_test_0(self): """ Empty constructor """ event = Event() assert (event.event == {})
def gibbsAsk(self, query_var, observed, samples_num): # Result is a list of counts for each value in the domain of the query # variable. Initialized with 0 res = {i: 0 for i in query_var.domain} # Assure the observed argument is an Event if type(observed) != Event: observed = Event(observed) # Create non evidence variable list, which are all the variables not # present in the observations non_evidence_vars = [i for i in self.network if not observed.varInEvent(i.node)] # Get markov blankets for each non evidence variable mbs = dict() for i in non_evidence_vars: mbs[i.node.name] = self.markovBlanket(i) # Make an initial sample sample = self.sample(observed) # Execute for samples_num samples for i in range(samples_num): for j in non_evidence_vars: # Get distribution P(j | mb(j)) dist = j.factor for k in mbs[j.node.name]: dist *= k.factor # Instantiate with previous sample, except for current j # variable sample.removeVar(j.node) dist = dist.instVar(sample) # Set new random value of current variable in sample rvalue = self.pickRandomValue(dist.rand_vars[0].domain, dist.values, random.random()) sample.setValue(j.node, rvalue) # Increment count res[rvalue] += 1 # Return the count list normalized values = [res[i] for i in query_var.domain] return Factor(query_var, values).normalize(query_var)
def eventConst_test_3(self): """ var and val """ event = Event(var=self.X, val=self.X.domain[0]) assert (len(event.event.keys()) == 1) assert (event.event[self.X] == self.X.domain[0])
def eventEqual_test_9(self): """ Test if two equal event are actually equal """ tlist1 = [(self.X, self.X.domain[0])] tlist2 = [(self.X, self.X.domain[0]), (self.Y, self.Y.domain[0])] tlist3 = [(self.Y, self.Y.domain[0]), (self.X, self.X.domain[0])] event1a = Event(tlist=tlist1) event1b = Event(tlist=tlist1) event2a = Event(tlist=tlist2) event2b = Event(tlist=tlist2) event2c = Event(tlist=tlist3) assert (event1a == event1b) assert (event2a == event2b) assert (event2a == event2c)
def eventConst_test_1(self): """ tlist test, one element """ tlist = [(self.X, self.X.domain[0])] event = Event(tlist=tlist) assert (len(event.event.keys()) == 1) assert (event.event[self.X] == self.X.domain[0])
def _compute_event_prob(self, event: ppy.Event): HashableFac.next_id = 0 # create factors factors = set() num_to_eliminate = 0 for i in self.network: # Append factor to factors list, removing observations fac = self.makeFactor(i.factor, event) factors.add(HashableFac(fac)) if not event.varInEvent(i.node): num_to_eliminate += 1 # run variable elimination for n in range(0, num_to_eliminate): new_factor_vars = { } # for each variable, the set of variables in the factor if that variable is eliminated factors_for_var = { } # for each variable, the list of factors containing the variable for hfac in factors: fac = hfac.fac rvset = set(fac.rand_vars) for var in fac.rand_vars: if var not in new_factor_vars: new_factor_vars[var] = rvset.copy() factors_for_var[var] = [] else: new_factor_vars[var] = new_factor_vars[var].union( rvset) factors_for_var[var].append(hfac) # find best variable to eliminate next according to min-degree strategy best_var = None best_size = -1 for var, s in new_factor_vars.items(): if best_var is None or len(s) < best_size: best_var = var best_size = len(s) # eliminate the variable rm_factors = factors_for_var[best_var] new_factor = self.sumOut(best_var, rm_factors) factors = factors.difference(rm_factors) factors.add(HashableFac(new_factor)) prod = None for f in factors: if prod is None: prod = f.fac else: prod = prod.mult(f.fac) return prod.values[0]
def eventIter_test_8(self): tlist = [(self.X, self.X.domain[0]), (self.Y, self.Y.domain[0]), (self.Z, self.Z.domain[0])] event = Event(tlist=tlist) iter_res = [i for i in event] for i in range(len(tlist)): if tlist[i][0].name != iter_res[i][0].name and \ tlist[i][1] != iter_res[i][1]: assert (False) assert (True)
def eventConst_test_2(self): """ tlist test, two element """ tlist = [] tlist.append((self.X, self.X.domain[0])) tlist.append((self.Y, self.Y.domain[0])) event = Event(tlist=tlist) assert (len(event.event.keys()) == 2) assert (event.event[self.X] == self.X.domain[0]) assert (event.event[self.Y] == self.Y.domain[0])
# Factors representing the conditional distributions of this network factor_cloudy = Factor(cloudy, [0.5, 0.5]) factor_sprinkler = Factor([sprinkler, cloudy], [0.1, 0.9, 0.5, 0.5]) factor_rain = Factor([rain, cloudy], [0.8, 0.2, 0.2, 0.8]) factor_wet_grass = Factor([wet_grass, rain, sprinkler], [0.99, 0.01, 0.9, 0.1, 0.9, 0.1, 0.0, 1.0]) # Actual network representation network = [(cloudy, factor_cloudy), (sprinkler, factor_sprinkler), (rain, factor_rain), (wet_grass, factor_wet_grass)] # Create a Bayesian Network BN = bn.BayesianNetwork(network) # Set one observation observed = Event(var=sprinkler, val="True") # Run Rejection Sample algorithm estimate = BN.eliminationAsk(rain, observed) print("P(Rain | Sprinkler=true)") print(estimate) # Run Rejection Sample algorithm estimate = BN.rejectionSample(rain, observed, 1000) print("P(Rain | Sprinkler=true)") print(estimate) # Run Gibbs Ask algorithm estimate = BN.gibbsAsk(rain, observed, 1000) print("P(Rain | Sprinkler=true)") print(estimate)
# tuple, the first argument is the variable of that node, the second is the # distribution. Note that the nodes were place in the list at random network = [ (earthq, factor_earthq), (alarm, factor_alarm), (john, factor_john), (burglary, factor_burglary), (mary, factor_mary) ] # The network object BN = bn.BayesianNetwork(network) # An event with the observations In this example the variable john was # observed being true. Same for variable mary observed = Event() observed.setValue(john, "True") observed.setValue(mary, "True") # Run the elimination ask algorithm (Variable Elimination) for the example. # Result should be approximately [0.284, 0.716] burglary_k_john_mary = BN.eliminationAsk(burglary, observed) print("P(Burglary | John=true, Mary=true)") print(burglary_k_john_mary) # Another example with the same network. The observation and query variable # changed, but the order of the distributions is the same. The result # should be approximately [0.849, 0.150] observed = Event(var=burglary, val="True") john_k_burglary = BN.eliminationAsk(john, observed)
def instNode(self, event): """ Makes observation over a network creating a new network in which every factor containing one of the observed variables gets instantiated Supposing the network (The edges would be "pointing" from top to bottom since this is a Bayesian Network):: X Y |\ | | A |/ | W Z The factors that describe this network are the following:: P(X) = f(X) P(Y) = f(Y) P(A | X, Y) = f(A, X, Y) P(W | X, A) = f(W, X, A) P(Z | A) = f(Z, A) If the A variable is observed, every factor will have its A variable instantiated and the network will be composed of the following factors, which don't have any A variable:: f(X) f(Y) f(A=a, X, Y) = f'(X, Y) f(W, X, A=a) = f'(W, X) f(Z, A=a) = f'(Z) Or similarly, if X is instantiated:: f(X=x) = scalar f(Y) f(A, X=x, Y) = f'(A, Y) f(W, X=x, A) = f'(W, A) f(Z, A) = f'(Z, A) Note that the node which only contained X will be reduced to a single scalar value. """ # Resulting network list res_network = [] # Assure the event argument is an Event object if type(event) != Event: event = Event(event) # Take each node and instantiate it's factor according to the event for i in self.network: new_node = BayesianNetworkNode(i.node, i.factor.instVar(event)) new_node.parents = i.parents res_network.append(new_node) # Create the network and place the new list directly in the # attribute because it is already sorted res = BayesianNetwork() res.network = res_network return res