Exemple #1
0
 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()
Exemple #2
0
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))
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
 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>>"
Exemple #7
0
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