Example #1
0
def test_multiple_pa_ch_table():
    """
    Tests create table with multiple parent.
    :return: None.
    """
    d_probs = [
        0.23323615160349853, 0.7667638483965015, 0.7563025210084033,
        0.24369747899159663
    ]
    r_probs = [
        0.31000000000000005, 0.69, 0.27, 0.73, 0.13, 0.87, 0.06999999999999995,
        0.93
    ]
    g_probs = [0.49, 0.51]

    g = BbnNode(Variable(0, 'gender', ['female', 'male']), g_probs)
    d = BbnNode(Variable(1, 'drug', ['false', 'true']), d_probs)
    r = BbnNode(Variable(2, 'recovery', ['false', 'true']), r_probs)

    table = Table(r, parents=[d, g])

    assert table.has_parents()
    lhs = np.array(list(table.probs.values()))
    rhs = np.array([[0.31, 1.0], [0.27, 1.0], [0.13, 1.0], [0.07, 1.0]])
    assert_almost_equal(lhs, rhs)

    lhs = list(table.probs.keys())
    rhs = [
        '0=female,1=false', '0=female,1=true', '0=male,1=false',
        '0=male,1=true'
    ]
    assert len(lhs) == len(rhs)
    for l, r in zip(lhs, rhs):
        assert l == r
Example #2
0
def test_inference_4():
    """
    Tests inference on simple customized graph.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.7, 0.3])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']),
                [0.9, 0.1, 0.3, 0.7, 0.5, 0.5, 0.1, 0.9])
    e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.6, 0.4, 0.2, 0.8])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_node(e) \
        .add_edge(Edge(a, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, e, EdgeType.DIRECTED))

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.7, 0.3],
        'b': [0.4, 0.6],
        'c': [0.456, 0.544],
        'e': [0.3824, 0.6176]
    }

    __validate_posterior__(expected, join_tree)
Example #3
0
def test_jointree_creation():
    """
    Tests join tree creation.
    :return: None.
    """
    n0 = BbnNode(Variable(0, 'n0', ['t', 'f']), [])
    n1 = BbnNode(Variable(1, 'n1', ['t', 'f']), [])
    n2 = BbnNode(Variable(2, 'n2', ['t', 'f']), [])

    clique0 = Clique([n0, n1])
    clique1 = Clique([n1, n2])
    sep_set0 = clique0.get_sep_set(clique1)
    sep_set1 = clique0.get_sep_set(clique1)
    sep_set2 = clique1.get_sep_set(clique0)
    sep_set3 = clique0.get_sep_set(clique0)

    e0 = JtEdge(sep_set0)
    e1 = JtEdge(sep_set1)
    e2 = JtEdge(sep_set2)
    e3 = JtEdge(sep_set3)

    g = JoinTree().add_edge(e0).add_edge(e1).add_edge(e2).add_edge(e3)

    nodes = g.get_nodes()
    edges = g.get_edges()

    assert len(nodes) == 3
    assert len(edges) == 1
    assert len(g.get_flattened_edges()) == 2
Example #4
0
def test_deepcopy():
    """
    Tests deep copy of join tree.
    :return: None
    """
    a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    bbn = Bbn().add_node(a).add_node(b) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED))
    lhs = InferenceController.apply(bbn)
    rhs = copy.deepcopy(lhs)

    lhs_nodes, rhs_nodes = lhs.get_nodes(), rhs.get_nodes()
    lhs_edges, rhs_edges = lhs.get_edges(), rhs.get_edges()
    lhs_neighbors, rhs_neighbors = lhs.neighbors, rhs.neighbors
    lhs_evidences, rhs_evidences = lhs.evidences, rhs.evidences
    lhs_potentials, rhs_potentials = lhs.potentials, rhs.potentials

    assert len(lhs_nodes) == len(rhs_nodes)
    assert len(lhs_edges) == len(rhs_edges)
    assert len(lhs_neighbors) == len(rhs_neighbors)
    assert len(lhs_evidences) == len(rhs_evidences)
    assert len(lhs_potentials) == len(rhs_potentials)

    list(lhs.get_nodes())[0].nodes[0].variable.values[0] = 'true'
    lhs_v = list(lhs.get_nodes())[0].nodes[0].variable.values[0]
    rhs_v = list(rhs.get_nodes())[0].nodes[0].variable.values[0]
    assert lhs_v != rhs_v
Example #5
0
def test_str():
    """
    Tests str function.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
    abc = Clique([a, b, c])
    bcd = Clique([b, c, d])
    sepset = abc.get_sep_set(bcd)

    print(a)
    print(b)
    print(c)
    print(d)
    print(abc)
    print(bcd)
    print(sepset)

    assert a.__str__() == '0|a|on,off'
    assert b.__str__() == '1|b|on,off'
    assert c.__str__() == '2|c|on,off'
    assert d.__str__() == '3|d|on,off'
    assert abc.__str__() == '(a,b,c)'
    assert bcd.__str__() == '(b,c,d)'
    assert sepset.__str__() == '|b,c|'
Example #6
0
def test_clique_is_superset():
    """
    Tests if clique is a superset of another clique.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])

    abc = Clique([a, b, c])
    abc2 = Clique([a, b, c])
    ab = Clique([a, b])
    ac = Clique([a, c])
    bc = Clique([b, c])
    cd = Clique([c, d])

    assert abc.is_superset(Clique([a])) == 1
    assert abc.is_superset(Clique([b])) == 1
    assert abc.is_superset(Clique([c])) == 1
    assert abc.is_superset(Clique([d])) == 0
    assert abc.is_superset(abc2) == 1
    assert abc.is_superset(ab) == 1
    assert abc.is_superset(ac) == 1
    assert abc.is_superset(bc) == 1
    assert abc.is_superset(cd) == 0
Example #7
0
def test_sampling_with_rejection():
    """
    Tests sampling a serial graph with rejection and evidence set.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn)

    n_samples = 10000
    samples = pd.DataFrame(
        sampler.get_samples(evidence={0: 'on'}, n_samples=n_samples, seed=37))
    samples.columns = ['a', 'b', 'c']

    assert n_samples == samples.shape[0]
    assert 3 == samples.shape[1]

    s_a = samples.a.value_counts()
    s_b = samples.b.value_counts()
    s_c = samples.c.value_counts()

    s_a = s_a / s_a.sum()
    s_b = s_b / s_b.sum()
    s_c = s_c / s_c.sum()

    s_a = s_a.sort_index().values
    s_b = s_b.sort_index().values
    s_c = s_c.sort_index().values

    assert_almost_equal(s_a, np.array([1.0]))
    assert_almost_equal(s_b, np.array([0.5006, 0.4994]))
    assert_almost_equal(s_c, np.array([0.5521, 0.4479]))

    join_tree = InferenceController.apply(bbn)
    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('a')) \
        .with_evidence('on', 1.0) \
        .build()
    join_tree.set_observation(ev)
    posteriors = join_tree.get_posteriors()

    assert_almost_equal(s_a, np.array([posteriors['a']['on']]), decimal=1)
    assert_almost_equal(s_b,
                        np.array(
                            [posteriors['b']['off'], posteriors['b']['on']]),
                        decimal=1)
    assert_almost_equal(s_c,
                        np.array(
                            [posteriors['c']['off'], posteriors['c']['on']]),
                        decimal=1)
Example #8
0
def test_sampling():
    """
    Tests sampling a serial graph.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn)

    n_samples = 10000
    samples = pd.DataFrame(sampler.get_samples(n_samples=n_samples, seed=37))
    samples.columns = ['a', 'b', 'c']

    assert n_samples == samples.shape[0]
    assert 3 == samples.shape[1]

    s_a = samples.a.value_counts()
    s_b = samples.b.value_counts()
    s_c = samples.c.value_counts()

    s_a = s_a / s_a.sum()
    s_b = s_b / s_b.sum()
    s_c = s_c / s_c.sum()

    s_a = s_a.sort_index()
    s_b = s_b.sort_index()
    s_c = s_c.sort_index()

    assert_almost_equal(s_a.values, np.array([0.4985, 0.5015]))
    assert_almost_equal(s_b.values, np.array([0.5502, 0.4498]))
    assert_almost_equal(s_c.values, np.array([0.5721, 0.4279]))

    join_tree = InferenceController.apply(bbn)
    posteriors = join_tree.get_posteriors()

    assert_almost_equal(s_a.values,
                        np.array(
                            [posteriors['a']['off'], posteriors['a']['on']]),
                        decimal=1)
    assert_almost_equal(s_b.values,
                        np.array(
                            [posteriors['b']['off'], posteriors['b']['on']]),
                        decimal=1)
    assert_almost_equal(s_c.values,
                        np.array(
                            [posteriors['c']['off'], posteriors['c']['on']]),
                        decimal=1)
Example #9
0
def test_clique_creation():
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    clique = Clique([a, b, c])

    assert clique.id == 45718137
    assert len(clique.nodes) == 3
    assert clique.get_weight() == 8
    assert clique.contains(0)
    assert clique.contains(1)
    assert clique.contains(2)
    assert clique.contains(3) == 0
Example #10
0
    def get_huang_graph():
        """
        Gets the Huang reference BBN graph.

        :return: BBN.
        """
        a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
        b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
        c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
        d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
        e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4])
        f = BbnNode(Variable(5, 'f', ['on', 'off']), [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01])
        g = BbnNode(Variable(6, 'g', ['on', 'off']), [0.8, 0.2, 0.1, 0.9])
        h = BbnNode(Variable(7, 'h', ['on', 'off']), [0.05, 0.95, 0.95, 0.05, 0.95, 0.05, 0.95, 0.05])

        bbn = Bbn() \
            .add_node(a) \
            .add_node(b) \
            .add_node(c) \
            .add_node(d) \
            .add_node(e) \
            .add_node(f) \
            .add_node(g) \
            .add_node(h) \
            .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
            .add_edge(Edge(a, c, EdgeType.DIRECTED)) \
            .add_edge(Edge(b, d, EdgeType.DIRECTED)) \
            .add_edge(Edge(c, e, EdgeType.DIRECTED)) \
            .add_edge(Edge(d, f, EdgeType.DIRECTED)) \
            .add_edge(Edge(e, f, EdgeType.DIRECTED)) \
            .add_edge(Edge(c, g, EdgeType.DIRECTED)) \
            .add_edge(Edge(e, h, EdgeType.DIRECTED)) \
            .add_edge(Edge(g, h, EdgeType.DIRECTED))

        return bbn
Example #11
0
def test_bbn_node_creation():
    """
    Tests BBN node creation.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
    e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4])
    f = BbnNode(Variable(5, 'f', ['on', 'off']),
                [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01])
    g = BbnNode(Variable(6, 'g', ['on', 'off']), [0.8, 0.2, 0.1, 0.9])
    h = BbnNode(Variable(7, 'h', ['on', 'off']),
                [0.05, 0.95, 0.95, 0.05, 0.95, 0.05, 0.95, 0.05])

    assert a.id == 0
    assert b.id == 1
    assert c.id == 2
    assert d.id == 3
    assert e.id == 4
    assert f.id == 5
    assert g.id == 6
    assert h.id == 7

    assert a.get_weight() == 2
    assert b.get_weight() == 2
    assert c.get_weight() == 2
    assert d.get_weight() == 2
    assert e.get_weight() == 2
    assert f.get_weight() == 2
    assert g.get_weight() == 2
    assert h.get_weight() == 2
Example #12
0
def build_bbn(variable_profiles, g, p):
    """
    Builds a BBN from a DAG, g, and paremeters, p.
    :param variable_profiles: Variable profiles.
    :param g: DAG.
    :param p: Parameters.
    :return: BBN.
    """
    bbn = Bbn()
    nodes = list(g.nodes)
    bbn_node_dict = {}
    for idx in nodes:
        name = g.nodes[idx]['name']
        domain = variable_profiles[name]
        cpt = p[idx]

        v = Variable(idx, name, domain)
        n = BbnNode(v, cpt)
        bbn.add_node(n)
        bbn_node_dict[idx] = n

    edges = list(g.edges)
    for edge in edges:
        pa = bbn_node_dict[edge[0]]
        ch = bbn_node_dict[edge[1]]
        e = Edge(pa, ch, EdgeType.DIRECTED)
        bbn.add_edge(e)

    return bbn
Example #13
0
def convert_for_exact_inference(g, p):
    """
    Converts the graph and parameters to a BBN.
    :param g: Directed acyclic graph (DAG in the form of networkx).
    :param p: Parameters.
    :return: BBN.
    """
    bbn = Bbn()

    bbn_nodes = {}

    for node in g.nodes:
        id = node
        params = p[id]['params'].flatten()
        states = [
            'state{}'.format(state) for state in range(p[id]['shape'][1])
        ]
        v = Variable(id, str(id), states)
        n = BbnNode(v, params)
        bbn.add_node(n)
        bbn_nodes[id] = n

    for e in g.edges:
        pa = bbn_nodes[e[0]]
        ch = bbn_nodes[e[1]]
        bbn.add_edge(Edge(pa, ch, EdgeType.DIRECTED))

    return bbn
Example #14
0
def test_from_data_simple():
    """
    Tests create BBN from data.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])

    bbn1 = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn1)
    samples = sampler.get_samples(n_samples=10000, seed=37)

    i2n = {n.variable.id: n.variable.name for n in bbn1.get_nodes()}
    samples = pd.DataFrame(samples).rename(columns=i2n)

    parents = {
        'a': [],
        'b': ['a'],
        'c': ['b']
    }

    bbn2 = Factory.from_data(parents, samples)

    join_tree1 = InferenceController.apply(bbn1)
    join_tree2 = InferenceController.apply(bbn2)

    posteriors1 = join_tree1.get_posteriors()
    posteriors2 = join_tree2.get_posteriors()

    for k, v1 in posteriors1.items():
        assert k in posteriors2

        v2 = posteriors2[k]
        assert len(v1) == len(v2)

        for k2 in v1:
            assert k2 in v2
            diff = abs(v1[k2] - v2[k2])
            assert diff < 0.01
Example #15
0
def test_sep_set_creation():
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
    abc = Clique([a, b, c])
    bcd = Clique([b, c, d])
    sepset = abc.get_sep_set(bcd)

    assert len(sepset.nodes) == 2

    names = [node.variable.name for node in sepset.nodes]
    assert 'b' in names
    assert 'c' in names

    assert sepset.get_cost() == 16
    assert sepset.get_mass() == 2
Example #16
0
def test_clique_creation():
    """
    Tests clique creation.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    clique = Clique([a, b, c])

    assert clique.id == '0-1-2'
    assert len(clique.nodes) == 3
    assert clique.get_weight() == 8
    assert clique.contains(0)
    assert clique.contains(1)
    assert clique.contains(2)
    assert clique.contains(3) == 0
Example #17
0
def test_pa_ch_table():
    """
    Tests create table with a single parent.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    table = Table(b, parents=[a])

    assert table.has_parents()
    lhs = np.array(list(table.probs.values()))
    rhs = np.array([[0.5, 1.0], [0.4, 1.0]])
    assert_almost_equal(lhs, rhs)
    assert 'on' == table.get_value(0.4, sample={0: 'on'})
    assert 'off' == table.get_value(0.7, sample={0: 'on'})
    assert 'on' == table.get_value(0.3, sample={0: 'off'})
    assert 'off' == table.get_value(0.6, sample={0: 'off'})
Example #18
0
def test_toplogical_sort_reversed():
    """
    Tests topological sorting of graph with nodes in reverse order.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.5, 0.5])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(c, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, a, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn)

    assert_almost_equal([2, 1, 0], sampler.nodes)
Example #19
0
def test_toplogical_sort_mixed():
    """
    Tests topological sort of diverging structure.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(b, a, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn)

    assert_almost_equal([1, 0, 2], sampler.nodes)
Example #20
0
        def get_nodes(bn, domain_spaces=True):
            def get_parent_domains(name, bn):
                parents = bn.Vdata[name]['parents']
                domains = []

                if parents is None or len(parents) == 0:
                    return domains

                for parent in parents:
                    domain = bn.Vdata[parent]['vals'][:]
                    domains.append(domain)
                return domains

            def cross_product(domains):
                products = []

                if domains is None or len(domains) == 0:
                    return products

                for e in itertools.product(*domains):
                    products.append(e)
                return products

            def stringify_cross_product(pa_domains, domain_spaces=True):
                joiner_delim = ', ' if domain_spaces is True else ','
                s = []
                for pa_domain in pa_domains:
                    r = joiner_delim.join(
                        ["'{}'".format(v) for v in pa_domain])
                    r = '[{}]'.format(r)
                    s.append(r)
                return s

            def get_cond_probs(name, bn, domain_spaces=True):
                probs = []
                pa_domains = stringify_cross_product(
                    cross_product(get_parent_domains(name, bn)), domain_spaces)
                if len(pa_domains) == 0:
                    probs = bn.Vdata[name]['cprob'][:]
                else:
                    for pa_domain in pa_domains:
                        cprob = bn.Vdata[name]['cprob'][pa_domain]
                        probs.extend(cprob)

                return probs

            nodes = {}
            idx = 0
            for name in bn.V:
                domain = bn.Vdata[name]['vals'][:]
                probs = get_cond_probs(name, bn, domain_spaces)
                node = BbnNode(Variable(idx, name, domain), probs)
                nodes[name] = node
                idx += 1
            return nodes
Example #21
0
def test_reapply():
    """
    Tests reinitializing join tree after updating CPTs.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    bbn = Bbn().add_node(a).add_node(b) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED))

    lhs = InferenceController.apply(bbn)
    rhs = InferenceController.reapply(lhs, {
        0: [0.3, 0.7],
        1: [0.2, 0.8, 0.8, 0.2]
    })

    lhs_pot = [lhs.get_bbn_potential(n) for n in lhs.get_bbn_nodes()]
    rhs_pot = [rhs.get_bbn_potential(n) for n in rhs.get_bbn_nodes()]

    lhs_d = Potential.to_dict(lhs_pot)
    rhs_d = Potential.to_dict(rhs_pot)

    # lhs should not match rhs after CPT update
    for k, prob in lhs_d.items():
        assert k in rhs_d
        assert prob != rhs_d[k]

    # now create lhs with same params as param used to update old
    # should match with rhs since params are now the same
    a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.3, 0.7])
    b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.2, 0.8, 0.8, 0.2])
    bbn = Bbn().add_node(a).add_node(b) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED))

    lhs = InferenceController.apply(bbn)
    lhs_pot = [lhs.get_bbn_potential(n) for n in lhs.get_bbn_nodes()]
    lhs_d = Potential.to_dict(lhs_pot)

    for k, prob in lhs_d.items():
        assert k in rhs_d
        assert_almost_equals(prob, rhs_d[k], 0.001)
Example #22
0
def test_table():
    """
    Tests creating table without parent.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    table = Table(a)

    assert not table.has_parents()
    assert_almost_equal(table.probs, np.array([0.5, 1.0]))
    assert 'on' == table.get_value(0.4)
    assert 'off' == table.get_value(0.6)
Example #23
0
    def get_simple():
        """
        Gets a simple BBN graph.

        :return: BBN.
        """
        a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
        b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
        c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
        d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
        e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4])
        f = BbnNode(Variable(5, 'f', ['on', 'off']),
                    [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01])

        bbn = Bbn() \
            .add_node(a) \
            .add_node(b) \
            .add_node(c) \
            .add_node(d) \
            .add_node(e) \
            .add_node(f) \
            .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
            .add_edge(Edge(a, c, EdgeType.DIRECTED)) \
            .add_edge(Edge(b, d, EdgeType.DIRECTED)) \
            .add_edge(Edge(c, e, EdgeType.DIRECTED)) \
            .add_edge(Edge(d, f, EdgeType.DIRECTED)) \
            .add_edge(Edge(e, f, EdgeType.DIRECTED))

        return bbn
Example #24
0
def test_inference_1():
    """
    Tests inference on the Huang graph with manual construction.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.9, 0.1, 0.5, 0.5])
    e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.3, 0.7, 0.6, 0.4])
    f = BbnNode(Variable(5, 'f', ['on', 'off']),
                [0.01, 0.99, 0.01, 0.99, 0.01, 0.99, 0.99, 0.01])
    g = BbnNode(Variable(6, 'g', ['on', 'off']), [0.8, 0.2, 0.1, 0.9])
    h = BbnNode(Variable(7, 'h', ['on', 'off']),
                [0.05, 0.95, 0.95, 0.05, 0.95, 0.05, 0.95, 0.05])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_node(d) \
        .add_node(e) \
        .add_node(f) \
        .add_node(g) \
        .add_node(h) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(a, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, d, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, e, EdgeType.DIRECTED)) \
        .add_edge(Edge(d, f, EdgeType.DIRECTED)) \
        .add_edge(Edge(e, f, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, g, EdgeType.DIRECTED)) \
        .add_edge(Edge(e, h, EdgeType.DIRECTED)) \
        .add_edge(Edge(g, h, EdgeType.DIRECTED))

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.5, 0.5],
        'b': [0.45, 0.55],
        'c': [0.45, 0.55],
        'd': [0.680, 0.32],
        'e': [0.465, 0.535],
        'f': [0.176, 0.824],
        'g': [0.415, 0.585],
        'h': [0.823, 0.177]
    }

    __validate_posterior__(expected, join_tree)
Example #25
0
def test_inference_libpgm2():
    """
    Tests libpgm graph where ordering messes up computation.
    :return: None.
    """
    letter = BbnNode(Variable(4, 'Letter', ['weak', 'strong']),
                     [0.1, 0.9, 0.4, 0.6, 0.99, 0.01])
    grade = BbnNode(
        Variable(2, 'Grade', ['a', 'b', 'c']),
        [0.3, 0.4, 0.3, 0.9, 0.08, 0.02, 0.05, 0.25, 0.7, 0.5, 0.3, 0.2])
    intelligence = BbnNode(Variable(3, 'Intelligence', ['low', 'high']),
                           [0.7, 0.3])
    sat = BbnNode(Variable(1, 'SAT', ['low', 'high']), [0.95, 0.05, 0.2, 0.8])
    difficulty = BbnNode(Variable(0, 'Difficulty', ['easy', 'hard']),
                         [0.6, 0.4])

    bbn = Bbn() \
        .add_node(letter) \
        .add_node(grade) \
        .add_node(intelligence) \
        .add_node(sat) \
        .add_node(difficulty) \
        .add_edge(Edge(difficulty, grade, EdgeType.DIRECTED)) \
        .add_edge(Edge(intelligence, grade, EdgeType.DIRECTED)) \
        .add_edge(Edge(intelligence, sat, EdgeType.DIRECTED)) \
        .add_edge(Edge(grade, letter, EdgeType.DIRECTED))

    join_tree = InferenceController.apply(bbn)

    __validate_posterior__(
        {
            'Difficulty': [0.6, 0.4],
            'Intelligence': [0.7, 0.3],
            'Grade': [0.362, 0.288, 0.350],
            'SAT': [0.725, 0.275],
            'Letter': [0.498, 0.502]
        },
        join_tree,
        debug=False)
Example #26
0
def test_simple_serde():
    """
    Tests join tree serde with only 1 clique.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    bbn = Bbn().add_node(a).add_node(b) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED))
    lhs = InferenceController.apply(bbn)

    d = JoinTree.to_dict(lhs)

    rhs = JoinTree.from_dict(d)
    rhs = InferenceController.apply_from_serde(rhs)

    lhs_pot = [lhs.get_bbn_potential(n) for n in lhs.get_bbn_nodes()]
    rhs_pot = [rhs.get_bbn_potential(n) for n in rhs.get_bbn_nodes()]

    lhs_pot = Potential.to_dict(lhs_pot)
    rhs_pot = Potential.to_dict(rhs_pot)

    assert len(lhs_pot) == len(rhs_pot)
Example #27
0
def test_sampler_tables():
    """
    Tests sampler creation of tables.
    :return: None.
    """
    a = BbnNode(Variable(0, 'a', ['on', 'off']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'b', ['on', 'off']), [0.5, 0.5, 0.4, 0.6])
    c = BbnNode(Variable(2, 'c', ['on', 'off']), [0.7, 0.3, 0.2, 0.8])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED))

    sampler = LogicSampler(bbn)

    assert_almost_equal([0, 1, 2], sampler.nodes)

    tables = sampler.tables
    assert 3 == len(tables)
    assert 0 in tables
    assert 1 in tables
    assert 2 in tables

    lhs = np.array(tables[0].probs)
    rhs = np.array([0.5, 1.0])
    assert_almost_equal(lhs, rhs)

    lhs = np.array(list(tables[1].probs.values()))
    rhs = np.array([[0.5, 1.0], [0.4, 1.0]])
    assert_almost_equal(lhs, rhs)

    lhs = np.array(list(tables[2].probs.values()))
    rhs = np.array([[0.7, 1.0], [0.2, 1.0]])
    assert_almost_equal(lhs, rhs)
Example #28
0
def get_drug_network():
    gender_probs = [0.49, 0.51]
    drug_probs = [
        0.23323615160349853, 0.7667638483965015, 0.7563025210084033,
        0.24369747899159663
    ]
    recovery_probs = [
        0.31000000000000005, 0.69, 0.27, 0.73, 0.13, 0.87, 0.06999999999999995,
        0.93
    ]

    X = BbnNode(Variable(1, 'drug', ['false', 'true']), drug_probs)
    Y = BbnNode(Variable(2, 'recovery', ['false', 'true']), recovery_probs)
    Z = BbnNode(Variable(0, 'gender', ['female', 'male']), gender_probs)

    bbn = Bbn() \
        .add_node(X) \
        .add_node(Y) \
        .add_node(Z) \
        .add_edge(Edge(Z, X, EdgeType.DIRECTED)) \
        .add_edge(Edge(Z, Y, EdgeType.DIRECTED)) \
        .add_edge(Edge(X, Y, EdgeType.DIRECTED))

    return bbn
Example #29
0
def test_deep_copy():
    """
    Tests variable deepcopy.
    :return: None.
    """
    lhs = Variable(0, 'a', ['t', 'f'])
    rhs = copy.deepcopy(lhs)

    assert lhs.id == rhs.id
    assert lhs.name == rhs.name
    assert len(lhs.values) == len(rhs.values)
    for lhs_v, rhs_v in zip(lhs.values, rhs.values):
        assert lhs_v == rhs_v

    lhs.values[0] = 'true'
    assert lhs.values[0] != rhs.values[0]
Example #30
0
def test_github_issue_4():
    """
    Tests issue #4 https://github.com/vangj/py-bbn/issues/4
    :return: None.
    """
    a = BbnNode(Variable(0, 'A', ['T', 'F']), [0.5, 0.5])
    b = BbnNode(Variable(1, 'B', ['T', 'F']), [0.2, 0.8, 0.1, 0.9])
    c = BbnNode(Variable(2, 'C', ['T', 'F']), [0.5, 0.5, 0.5, 0.5])
    d = BbnNode(Variable(3, 'D', ['T', 'F']), [0.5, 0.5, 0.5, 0.5])
    e = BbnNode(Variable(4, 'E', ['T', 'F']), [0.5, 0.5, 0.5, 0.5])
    f = BbnNode(Variable(5, 'F', ['T', 'F']), [0.5, 0.5, 0.5, 0.5])
    g = BbnNode(Variable(6, 'G', ['T', 'F']), [
        0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
        0.5, 0.5
    ])

    bbn = Bbn() \
        .add_node(a) \
        .add_node(b) \
        .add_node(c) \
        .add_node(d) \
        .add_node(e) \
        .add_node(f) \
        .add_node(g) \
        .add_edge(Edge(a, b, EdgeType.DIRECTED)) \
        .add_edge(Edge(a, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, d, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, e, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, f, EdgeType.DIRECTED)) \
        .add_edge(Edge(e, g, EdgeType.DIRECTED)) \
        .add_edge(Edge(d, g, EdgeType.DIRECTED)) \
        .add_edge(Edge(f, g, EdgeType.DIRECTED))

    join_tree = InferenceController.apply(bbn)

    expected = {
        'A': [0.5, 0.5],
        'B': [0.15, 0.85],
        'C': [0.5, 0.5],
        'D': [0.5, 0.5],
        'E': [0.5, 0.5],
        'F': [0.5, 0.5],
        'G': [0.5, 0.5]
    }

    __validate_posterior__(expected, join_tree)

    __print_potentials__(join_tree)