def setup(self): self.rng = utils.RandomState(seed=0) self.reflectance = bayesnet.DistRealBayesNetNode( index=0, distribution=dist.GaussianDistribution(self.rng, 1, 1)) self.illumination_1 = bayesnet.DistRealBayesNetNode( index=1, distribution=dist.GammaDistribution(self.rng, 9, 0.5)) self.illumination_2 = bayesnet.DistRealBayesNetNode( index=2, distribution=dist.GaussianDistribution(self.rng, 1, 0.5)) self.illumination = bayesnet.DistRealBayesNetNode( index=3, distribution=dist.FunctionDistribution( self.rng, lambda parents: dist.GaussianDistribution( self.rng, parents[0] + parents[1], 0.2))) self.observation = bayesnet.DistRealBayesNetNode( index=4, distribution=dist.FunctionDistribution( self.rng, lambda parents: dist.GaussianDistribution( self.rng, parents[0] * parents[1], 2))) self.net = bayesnet.BayesNet( self.rng, nodes=[ self.reflectance, self.illumination_1, self.illumination_2, self.illumination, self.observation ], edges=[(self.reflectance, self.observation), (self.illumination_1, self.illumination), (self.illumination_2, self.illumination), (self.illumination, self.observation)]) self.net.compile()
def test_dist_bayesnet_node(): rng = utils.RandomState(seed=0) distribution = dist.CategoricalDistribution([0, 1], [.3, .7], rng) node = bayesnet.DistBayesNetNode( index=0, name="Foo", domain_size=2, distribution=distribution) net = bayesnet.BayesNet(rng, nodes=[node]) net.compile() np.testing.assert_almost_equal(node.log_probability([], 1), math.log(.7))
def get_v2(rng): """Return second factorization of binary network.""" node_2 = bayesnet.TableBayesNetNode(index=1, domain_size=3, cpt_probabilities=[0.0, 0.0, 1.0]) node_1 = bayesnet.TableBayesNetNode( index=0, domain_size=2, cpt_probabilities=[1.0, 0.0, 1.0, 0.0, 0.0, 1.0]) net = bayesnet.BayesNet(rng=rng, nodes=[node_1, node_2], edges=[(node_2, node_1)]) net.compile() return net
def network_eval(stack, rng, epsilon=0.0): """Turn random state and stack of (UAI) net numbers into Bayesian network.""" net = bayesnet.BayesNet(rng=rng) num_vars = stack.popleft() for index in range(num_vars): domain_size = stack.popleft() node = bayesnet.TableBayesNetNode(index) node.set_domain_size(domain_size) net.add_node(node) num_cliques = stack.popleft() assert num_cliques == num_vars clique_order = {} for _ in range(num_vars): clique_size = stack.popleft() current_clique_order = utils.pop_n(stack, clique_size) node = net.nodes_by_index[current_clique_order[-1]] for index in current_clique_order[:-1]: assert index != node.index net.add_edge(net.nodes_by_index[index], node) clique_order[node] = current_clique_order for node in net.nodes_by_index: cpt_size = stack.popleft() cpt_probabilities = utils.pop_n(stack, cpt_size) for j, cpt_prob in enumerate(cpt_probabilities): assert 0 <= cpt_prob <= 1 if cpt_prob > 1.0 - epsilon: cpt_probabilities[j] = 1.0 - epsilon if cpt_prob < epsilon: cpt_probabilities[j] = epsilon old_domain_sizes = [net.nodes_by_index[i].domain_size for i in clique_order[node]] parent_indices = sorted([i for i in clique_order[node] if i != node.index]) new_clique_order = parent_indices + [node.index] new_cpt_probabilities = reorder_cpt( clique_order[node], old_domain_sizes, cpt_probabilities, new_clique_order) node.set_cpt_probabilities(new_cpt_probabilities) assert not stack net.compile() return net
def get(rng): """Return three-node sprinkler Bayes net.""" rain_node = bayesnet.TableBayesNetNode(index=0, domain_size=2, cpt_probabilities=[.8, .2], name="Rain") sprinkler_node = bayesnet.TableBayesNetNode( index=1, domain_size=2, cpt_probabilities=[0.01, 0.99, 0.6, 0.4], name="Sprinkler") grass_node = bayesnet.TableBayesNetNode( index=2, domain_size=2, cpt_probabilities=[0.9, 0.1, 0.3, 0.7, 0.15, 0.85, 0.05, 0.95], name="Grass") nodes = [rain_node, sprinkler_node, grass_node] edges = [(rain_node, sprinkler_node), (rain_node, grass_node), (sprinkler_node, grass_node)] net = bayesnet.BayesNet(rng=rng, nodes=nodes, edges=edges) net.compile() return net
def test_representation(self): """Check that calling string methods works.""" assert str(self.net) == repr(self.net) empty_net = bayesnet.BayesNet(self.rng) assert repr(empty_net) == "<<BN>>"
def compute_inverse_net(net, start_nodes, end_node, rng, max_inverse_size): """Compute a single Bayes net inverse given start and end nodes. Args: net: a BayesNet start_nodes: a list of BayesNetNodes in net end_node: a BayesNetNode rng: a RandomState max_inverse_size: going topologically backwards from end node, only include up to this number of nodes in computed inverse edges Returns: inverse_net: a BayesNet with the same number of nodes as input net """ for node in start_nodes + [end_node]: assert node in net.nodes_by_index assert node.support assert end_node not in start_nodes # Compute distance-based scorer for Bayes net nodes. scorer = distance_scorer(net, start_nodes) # Sort nodes s.t. nodes close to evidence are first, focal node is last. scored_indices = [] for node in net.nodes_by_index: if node not in start_nodes: scored_indices.append((node.index, scorer(node, end_node))) sorted_pairs = sorted(scored_indices, key=lambda (i, s): -s) sorted_indices = [index for (index, _) in sorted_pairs] def node_to_inverse(node): if isinstance(node, bayesnet.DiscreteBayesNetNode): return bayesnet.DistBayesNetNode(node.index, name=node.name, domain_size=node.domain_size) if isinstance(node, bayesnet.RealBayesNetNode): return bayesnet.DistRealBayesNetNode(node.index, name=node.name) raise Exception("Unknown node type %s" % type(node)) # Create inverse net with nodes, no edges. inverse_nodes = [node_to_inverse(node) for node in net.nodes_by_index] inverse_net = bayesnet.BayesNet(rng, nodes=inverse_nodes) # Add edges to inverse network. # Start nodes will not have any incoming edges. We keep track of a # set of "observed nodes", which is the set of nodes that we have # already added to the network (with incoming edges). observed_nodes = set(start_nodes) # Go through node indices, starting with nodes that are close to the # evidence and far away from the end node, moving towards nodes that # are far from the evidence and close to the end node. for i, node_index in enumerate(sorted_indices): node = net.nodes_by_index[node_index] # Check that we are close enough to final node to start adding # dependencies. if len(sorted_indices) - i <= max_inverse_size: # Compute which of the observed nodes our new node depends on (by # looking at structure of forward network). deps = dependent_nodes(node, observed_nodes) # For each such dependence, create an incoming link in the inverse # network to our node. for dep in deps: inverse_net.add_edge(inverse_nodes[dep.index], inverse_nodes[node_index]) # Add node to observed nodes. observed_nodes.add(node) # Verify that the last node we add is the chosen end node. assert node_index == end_node.index inverse_net.nodes_by_topology = ( [inverse_nodes[node.index] for node in start_nodes] + [inverse_nodes[index] for index in sorted_indices]) return inverse_net