예제 #1
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
예제 #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)
예제 #3
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)
예제 #4
0
    def __init__(self, bbn):
        """
        ctor

        :param bbn: Bayesian belief network.
        """
        self.bbn = bbn
        self.jt = InferenceController.apply(bbn)
예제 #5
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
예제 #6
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)
예제 #7
0
def test_trivial_inference():
    """
    Tests inference on trivial graphs.
    :return: None.
    """
    a1 = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b1 = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    bbn1 = Bbn().add_node(a1).add_node(b1).add_edge(
        Edge(a1, b1, EdgeType.DIRECTED))
    jt1 = InferenceController.apply(bbn1)

    a2 = BbnNode(Variable(1, 'a', ['t', 'f']), [0.2, 0.8])
    b2 = BbnNode(Variable(0, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    bbn2 = Bbn().add_node(a2).add_node(b2).add_edge(
        Edge(a2, b2, EdgeType.DIRECTED))
    jt2 = InferenceController.apply(bbn2)

    a3 = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b3 = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9])
    bbn3 = Bbn().add_node(a3).add_node(b3)
    jt3 = InferenceController.apply(bbn3)

    __validate_posterior__({
        'a': [0.2, 0.8],
        'b': [0.74, 0.26]
    },
                           jt1,
                           debug=False)

    __validate_posterior__({
        'a': [0.2, 0.8],
        'b': [0.74, 0.26]
    },
                           jt2,
                           debug=False)

    __validate_posterior__({
        'a': [0.2, 0.8],
        'b': [0.1, 0.9]
    },
                           jt3,
                           debug=False)
예제 #8
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)
예제 #9
0
def test_inference_var_permutation():
    """
    Tests inference on graphs where id are reversed.
    :return: None.
    """
    a1 = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
    b1 = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    c1 = BbnNode(Variable(2, 'c', ['t', 'f']), [0.2, 0.8, 0.7, 0.3])
    bbn1 = Bbn().add_node(a1).add_node(b1).add_node(c1) \
        .add_edge(Edge(a1, b1, EdgeType.DIRECTED)) \
        .add_edge(Edge(b1, c1, EdgeType.DIRECTED))
    jt1 = InferenceController.apply(bbn1)

    a2 = BbnNode(Variable(2, 'a', ['t', 'f']), [0.2, 0.8])
    b2 = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    c2 = BbnNode(Variable(0, 'c', ['t', 'f']), [0.2, 0.8, 0.7, 0.3])
    bbn2 = Bbn().add_node(a2).add_node(b2).add_node(c2) \
        .add_edge(Edge(a2, b2, EdgeType.DIRECTED)) \
        .add_edge(Edge(b2, c2, EdgeType.DIRECTED))
    jt2 = InferenceController.apply(bbn2)

    __validate_posterior__(
        {
            'a': [0.2, 0.8],
            'b': [0.74, 0.26],
            'c': [0.33, 0.67]
        },
        jt1,
        debug=False)

    __validate_posterior__(
        {
            'a': [0.2, 0.8],
            'b': [0.74, 0.26],
            'c': [0.33, 0.67]
        },
        jt2,
        debug=False)
def main():
    # defining bbn variable to create a bayesian belief network
    global machine_name
    global join_tree

    # enter 1 or 2 as per your choice
    machine_type = int(
        input(
            "Choose : \n 1. Use Existing Machine \n 2. Configure a new machine \n\n"
        ))

    # if existing machine then ask for machine name and open it and process further
    if machine_type == 1:
        machine_name = str(input("Please input your machine name: "))
        machine_name_file = '%s.sav' % machine_name

        try:
            join_tree = pickle.load(open(machine_name_file, 'rb'))
            for node in join_tree.get_bbn_nodes():
                print(node)
            check(machine_name)

            potential_func()

        except:
            print("Machine name does not exists")
            main()

    else:
        machine_name = str(input("Please input your machine name: "))

        globals()['machine_%s' % machine_name] = Bbn()

        # create the nodes
        create_bbn_nodes()

        # create the network structure by edges and nodes
        create_bbn_edges()

        join_tree = InferenceController.apply(globals()['machine_%s' %
                                                        machine_name])

        filename = '%s.sav' % machine_name
        pickle.dump(join_tree, open(filename, 'wb'))

        print(globals()['machine_%s' % machine_name])

        check(machine_name)

        potential_func()
예제 #11
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)
예제 #12
0
def get_bbn(fpath):
    with open(fpath, 'r') as f:
        start = time.time()
        bbn = Bbn.from_dict(json.loads(f.read())) if fpath.endswith('.json') else Bbn.from_csv(fpath)
        stop = time.time()
        diff = stop - start
        print(f'{diff:.5f} : load time')

        start = time.time()
        jt = InferenceController.apply(bbn)
        stop = time.time()
        diff = stop - start
        print(f'{diff:.5f} : inference time')

        return bbn, jt
예제 #13
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)
예제 #14
0
def test_inference_controller():
    bbn = BbnUtil.get_huang_graph()
    join_tree = InferenceController.apply(bbn)

    print('INIT')
    print_potentials(join_tree)

    ev = EvidenceBuilder()\
        .with_node(join_tree.get_bbn_node(0))\
        .with_evidence('on', 1.0)\
        .build()

    join_tree.set_observation(ev)

    print('FIRST')
    print_potentials(join_tree)
예제 #15
0
def test_huang_inference_with_multiple_evidence():
    """
    Tests inference on the Huang graph with a multiple evidence.
    :return: None.
    """
    bbn = BbnUtil.get_huang_graph()

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.5, 0.5],
        'b': [0.45, 0.55],
        'c': [0.45, 0.55],
        'd': [0.68, 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)

    ev1 = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('a')) \
        .with_evidence('on', 1.0) \
        .build()
    ev2 = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('f')) \
        .with_evidence('on', 1.0) \
        .build()

    join_tree.unobserve_all()
    join_tree.update_evidences([ev1, ev2])

    expected = {
        'a': [1.0, 0.0],
        'b': [0.184, 0.816],
        'c': [0.798, 0.202],
        'd': [0.0370, 0.963],
        'e': [0.0206, 0.979],
        'f': [1.0, 0.0],
        'g': [0.658, 0.342],
        'h': [0.941, 0.0588]
    }

    __validate_posterior__(expected, join_tree)
예제 #16
0
def test_from_libpgm_discrete_dictionary():
    """
    Tests create py-bbn BBN from dictionary specifying libpgm BBN.
    :return: None.
    """
    d = get_dict()
    bbn = Factory.from_libpgm_discrete_dictionary(d)

    assert len(bbn.nodes) == 5
    assert len(bbn.edges) == 4

    # FIXME this is not working right somehow
    join_tree = InferenceController.apply(bbn)

    for node in join_tree.get_bbn_nodes():
        potential = join_tree.get_bbn_potential(node)
        print(node)
        print(potential)
        print('>')
예제 #17
0
def test_inference_2():
    """
    Tests inference on 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])
    d = BbnNode(Variable(3, 'd', ['on', 'off']), [0.3, 0.7, 0.8, 0.2])
    e = BbnNode(Variable(4, 'e', ['on', 'off']), [0.6, 0.4, 0.2, 0.8])
    f = BbnNode(Variable(5, 'f', ['on', 'off']), [0.7, 0.3, 0.1, 0.9])
    g = BbnNode(Variable(6, 'g', ['on', 'off']), [0.4, 0.6, 0.9, 0.1])

    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, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(b, c, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, d, EdgeType.DIRECTED)) \
        .add_edge(Edge(c, e, EdgeType.DIRECTED)) \
        .add_edge(Edge(d, f, EdgeType.DIRECTED)) \
        .add_edge(Edge(d, g, EdgeType.DIRECTED))

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.7, 0.3],
        'b': [0.4, 0.6],
        'c': [0.456, 0.544],
        'd': [0.572, 0.428],
        'e': [0.382, 0.618],
        'f': [0.443, 0.557],
        'g': [0.614, 0.386]
    }

    __validate_posterior__(expected, join_tree)
예제 #18
0
def test_from_libpgm_discrete_dictionary():
    """
    Tests create py-bbn BBN from dictionary specifying libpgm BBN.
    :return: None.
    """
    d = get_dict()
    bbn = Factory.from_libpgm_discrete_dictionary(d)

    assert len(bbn.nodes) == 5
    assert len(bbn.edges) == 4

    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=True)
예제 #19
0
def test_huang_inference_with_single_evidence():
    """
    Tests inference on the Huang graph with a single evidence.
    :return: None.
    """
    bbn = BbnUtil.get_huang_graph()

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.5, 0.5],
        'b': [0.45, 0.55],
        'c': [0.45, 0.55],
        'd': [0.68, 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)

    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('a')) \
        .with_evidence('on', 1.0) \
        .build()
    join_tree.unobserve_all()
    join_tree.set_observation(ev)

    expected = {
        'a': [1.0, 0.0],
        'b': [0.5, 0.5],
        'c': [0.7, 0.3],
        'd': [0.7, 0.3],
        'e': [0.39, 0.61],
        'f': [0.18934, 0.81066],
        'g': [0.59, 0.41],
        'h': [0.7826, 0.2174]
    }

    __validate_posterior__(expected, join_tree)
예제 #20
0
def test_simple_inference():
    """
    Tests inference on the Huang graph.
    :return: None.
    """
    bbn = BbnUtil.get_simple()

    join_tree = InferenceController.apply(bbn)

    expected = {
        'a': [0.5, 0.5],
        'b': [0.45, 0.55],
        'c': [0.45, 0.55],
        'd': [0.68, 0.32],
        'e': [0.465, 0.535],
        'f': [0.176, 0.824]
    }

    __validate_posterior__(expected, join_tree)

    __print_potentials__(join_tree)
예제 #21
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)
예제 #22
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)
예제 #23
0
def test_forest_inference():
    """
    Tests inference on a disconnected DAG; sub-DAGs are a -> b, c -> d and e -> f.
    :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])
    c = BbnNode(Variable(2, 'c', ['t', 'f']), [0.2, 0.8])
    d = BbnNode(Variable(3, 'd', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    e = BbnNode(Variable(4, 'e', ['t', 'f']), [0.2, 0.8])
    f = BbnNode(Variable(5, 'f', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
    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(c, d, EdgeType.DIRECTED)) \
        .add_edge(Edge(e, f, EdgeType.DIRECTED))

    jt = InferenceController.apply(bbn)
    pot = [jt.get_bbn_potential(n) for n in jt.get_bbn_nodes()]
    o = Potential.to_dict(pot)
    e = {
        '0=t': 0.2,
        '0=f': 0.8,
        '1=t': 0.7400000000000001,
        '1=f': 0.26,
        '2=t': 0.2,
        '2=f': 0.8,
        '3=t': 0.7400000000000001,
        '3=f': 0.26,
        '4=t': 0.2,
        '4=f': 0.8,
        '5=t': 0.7400000000000001,
        '5=f': 0.26
    }

    for k, p in e.items():
        assert_almost_equals(p, o[k], 0.001)
def do_it(bbn):
    InferenceController.apply(bbn)
예제 #25
0
        .add_edge(Edge(ap, sir, EdgeType.DIRECTED)) \
        .add_edge(Edge(p, sir, EdgeType.DIRECTED)) \
        .add_edge(Edge(sir, wbc, EdgeType.DIRECTED))
    options = {
        "font_size": 16,
        "node_size": 3000,
        "node_color": "white",
        "edgecolors": "black",
        "edge_color": "red",
        "linewidths": 5,
        "width": 5,
    }

    n, d = bbn.to_nx_graph()
    nx.draw(n, with_labels=True, labels=d, **options)
    join_tree = InferenceController.apply(bbn)
    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('ap')) \
        .with_evidence('yes', 1) \
        .build()

    ev2 = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('p')) \
        .with_evidence('yes', 1) \
        .build()

    ev3 = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('wbc')) \
        .with_evidence('high', 1) \
        .build()
예제 #26
0
def test_inference_libpgm():
    """
    Tests inference with evidence on libpgm graph.
    :return: None.
    """
    difficulty = BbnNode(Variable(0, 'difficulty', ['easy', 'hard']),
                         [0.6, 0.4])
    intelligence = BbnNode(Variable(1, 'intelligence', ['low', 'high']),
                           [0.7, 0.3])
    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])
    sat = BbnNode(Variable(3, 'sat', ['low', 'high']), [0.95, 0.05, 0.2, 0.8])
    letter = BbnNode(Variable(4, 'letter', ['weak', 'strong']),
                     [0.1, 0.9, 0.4, 0.6, 0.99, 0.01])

    bbn = Bbn() \
        .add_node(difficulty) \
        .add_node(intelligence) \
        .add_node(grade) \
        .add_node(sat) \
        .add_node(letter) \
        .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)

    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('sat')) \
        .with_evidence('high', 1.0) \
        .build()
    join_tree.unobserve_all()
    join_tree.set_observation(ev)

    __validate_posterior__(
        {
            'difficulty': [0.6, 0.4],
            'intelligence': [0.127, 0.873],
            'grade': [0.671, 0.190, 0.139],
            'sat': [0.0, 1.0],
            'letter': [0.281, 0.719]
        }, join_tree)

    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('sat')) \
        .with_evidence('low', 1.0) \
        .build()
    join_tree.unobserve_all()
    join_tree.set_observation(ev)

    __validate_posterior__(
        {
            'difficulty': [0.6, 0.4],
            'intelligence': [0.917, 0.0828],
            'grade': [0.245, 0.326, 0.430],
            'sat': [1.0, 0.0],
            'letter': [0.58, 0.42]
        }, join_tree)
def bayesian_belief_network():

    deadline = BbnNode(Variable(0, 'deadline', ['long', 'medium', 'short']),
                       [0.33, 0.33, 0.33])
    goal = BbnNode(Variable(1, 'goal', ['large', 'medium', 'small']),
                   [0.33, 0.33, 0.33])
    backers = BbnNode(Variable(3, 'backers', ['many', 'medium', 'few']),
                      [0.6, 0.3, 0.2, 0.3, 0.4, 0.4, 0.1, 0.3, 0.4])
    pledges = BbnNode(Variable(4, 'pledges', ['large', 'medium', 'small']),
                      [0.6, 0.3, 0.1, 0.2, 0.5, 0.2, 0.2, 0.2, 0.7])
    state = BbnNode(Variable(5, 'state', ['success', 'fail']), [
        0.7, 0.5, 0.2, 0.8, 0.6, 0.2, 0.9, 0.7, 0.3, 0.3, 0.5, 0.8, 0.2, 0.4,
        0.8, 0.1, 0.3, 0.7
    ])

    global Bbn
    Bbn = Bbn() \
    .add_node(deadline) \
    .add_node(goal) \
    .add_node(backers) \
    .add_node(pledges) \
    .add_node(state) \
    .add_edge(Edge( goal, backers, EdgeType.DIRECTED)) \
    .add_edge(Edge( goal, pledges, EdgeType.DIRECTED)) \
    .add_edge(Edge( backers, state, EdgeType.DIRECTED)) \
    .add_edge(Edge( deadline, state, EdgeType.DIRECTED))

    with warnings.catch_warnings():
        warnings.simplefilter('ignore')

        graph = convert_for_drawing(Bbn)
        pos = nx.nx_agraph.graphviz_layout(graph, prog='dot')

        #uncomment this section to print BBN
        #plt.figure(figsize=(8, 8))
        #plt.subplot(121)
        #labels = dict([(k, node.variable.name) for k, node in Bbn.nodes.items()])
        #nx.draw(graph, pos=pos, with_labels=True, labels=labels)
        #plt.title('Bayesian Belief Network Diagram')
        #plt.show()

    join_tree = InferenceController.apply(Bbn)

    print("BBN - Original Probabilities")
    for node in join_tree.get_bbn_nodes():
        potential = join_tree.get_bbn_potential(node)
        print(node)
        print(potential)
        print('--------------------->')

    # insert an observation evidence
    ev = EvidenceBuilder() \
        .with_node(join_tree.get_bbn_node_by_name('goal')) \
        .with_evidence('large', 1.0) \
        .build()
    join_tree.set_observation(ev)
    #print the marginal probabilities

    print()
    print()
    print("BBN - Set Goal = Large")
    for node in join_tree.get_bbn_nodes():
        potential = join_tree.get_bbn_potential(node)
        print(node)
        print(potential)
        print('--------------------->')
예제 #28
0
def test_to_dict():
    """
    Tests serializing join tree to dictionary.
    :return: None.
    """
    n0 = BbnNode(Variable(0, 'n0', ['t', 'f']), [0.2, 0.8])
    n1 = BbnNode(Variable(1, 'n1', ['t', 'f']), [0.9, 0.1, 0.9, 0.1])
    n2 = BbnNode(Variable(2, 'n2', ['t', 'f']), [0.6, 0.4, 0.4, 0.6])
    bbn = Bbn().add_node(n0).add_node(n1).add_node(n2) \
        .add_edge(Edge(n0, n1, EdgeType.DIRECTED)) \
        .add_edge(Edge(n1, n2, EdgeType.DIRECTED))
    jt = InferenceController.apply(bbn)
    d = JoinTree.to_dict(jt)
    lhs = json.dumps(d, sort_keys=True, indent=2)
    rhs = """{
  "bbn_nodes": {
    "0": {
      "probs": [
        0.2,
        0.8
      ],
      "variable": {
        "id": 0,
        "name": "n0",
        "values": [
          "t",
          "f"
        ]
      }
    },
    "1": {
      "probs": [
        0.9,
        0.1,
        0.9,
        0.1
      ],
      "variable": {
        "id": 1,
        "name": "n1",
        "values": [
          "t",
          "f"
        ]
      }
    },
    "2": {
      "probs": [
        0.6,
        0.4,
        0.4,
        0.6
      ],
      "variable": {
        "id": 2,
        "name": "n2",
        "values": [
          "t",
          "f"
        ]
      }
    }
  },
  "jt": {
    "edges": [
      "0-1-1-1-2"
    ],
    "nodes": {
      "0-1": {
        "node_ids": [
          0,
          1
        ],
        "type": "clique"
      },
      "0-1-1-1-2": {
        "left": "0-1",
        "right": "1-2",
        "type": "sepset"
      },
      "1-2": {
        "node_ids": [
          1,
          2
        ],
        "type": "clique"
      }
    },
    "parent_info": {
      "0": [],
      "1": [
        0
      ],
      "2": [
        1
      ]
    }
  }
}"""
    assert lhs == rhs
예제 #29
0
def test_from_dict():
    """
    Tests deserializing from dictionary.
    :return:
    """
    s = """{
  "bbn_nodes": {
    "0": {
      "probs": [
        0.2,
        0.8
      ],
      "variable": {
        "id": 0,
        "name": "n0",
        "values": [
          "t",
          "f"
        ]
      }
    },
    "1": {
      "probs": [
        0.9,
        0.1,
        0.9,
        0.1
      ],
      "variable": {
        "id": 1,
        "name": "n1",
        "values": [
          "t",
          "f"
        ]
      }
    },
    "2": {
      "probs": [
        0.6,
        0.4,
        0.4,
        0.6
      ],
      "variable": {
        "id": 2,
        "name": "n2",
        "values": [
          "t",
          "f"
        ]
      }
    }
  },
  "jt": {
    "edges": [
      "0-1-1-1-2"
    ],
    "nodes": {
      "0-1": {
        "node_ids": [
          0,
          1
        ],
        "type": "clique"
      },
      "0-1-1-1-2": {
        "left": "0-1",
        "right": "1-2",
        "type": "sepset"
      },
      "1-2": {
        "node_ids": [
          1,
          2
        ],
        "type": "clique"
      }
    },
    "parent_info": {
      "0": [],
      "1": [
        0
      ],
      "2": [
        1
      ]
    }
  }
}"""
    d = json.loads(s)
    lhs = JoinTree.from_dict(d)
    lhs = InferenceController.apply_from_serde(lhs)

    n0 = BbnNode(Variable(0, 'n0', ['t', 'f']), [0.2, 0.8])
    n1 = BbnNode(Variable(1, 'n1', ['t', 'f']), [0.9, 0.1, 0.9, 0.1])
    n2 = BbnNode(Variable(2, 'n2', ['t', 'f']), [0.6, 0.4, 0.4, 0.6])
    bbn = Bbn().add_node(n0).add_node(n1).add_node(n2) \
        .add_edge(Edge(n0, n1, EdgeType.DIRECTED)) \
        .add_edge(Edge(n1, n2, EdgeType.DIRECTED))
    rhs = InferenceController.apply(bbn)

    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)

    for k, p in lhs_pot.items():
        assert_almost_equals(p, rhs_pot[k], 0.001)
예제 #30
0
import json

from pybbn.graph.dag import Bbn
from pybbn.graph.edge import EdgeType, Edge
from pybbn.graph.jointree import JoinTree
from pybbn.graph.node import BbnNode
from pybbn.graph.variable import Variable
from pybbn.pptc.inferencecontroller import InferenceController

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))
jt = InferenceController.apply(bbn)

with open('simple-join-tree.json', 'w') as f:
    d = JoinTree.to_dict(jt)
    j = json.dumps(d, sort_keys=True, indent=2)
    f.write(j)