class TestDynamicBayesianNetworkCreation(unittest.TestCase):
    def setUp(self):
        self.network = DynamicBayesianNetwork()

    def test_add_single_node(self):
        self.network.add_node('a')
        self.assertListEqual(self.network.nodes(), ['a'])

    def test_add_multiple_nodes(self):
        self.network.add_nodes_from(['a', 'b', 'c'])
        self.assertListEqual(sorted(self.network.nodes()), ['a', 'b', 'c'])

    def test_add_single_edge_with_timeslice(self):
        self.network.add_edge(('a', 0), ('b', 0))
        self.assertListEqual(sorted(self.network.edges()), [(('a', 0), ('b', 0)), (('a', 1), ('b', 1))])
        self.assertListEqual(sorted(self.network.nodes()), ['a', 'b'])

    def test_add_edge_with_different_number_timeslice(self):
        self.network.add_edge(('a', 2), ('b', 2))
        self.assertListEqual(sorted(self.network.edges()), [(('a', 0), ('b', 0)), (('a', 1), ('b', 1))])

    def test_add_edge_going_backward(self):
        self.assertRaises(NotImplementedError, self.network.add_edge, ('a', 1), ('b', 0))

    def test_add_edge_with_farther_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 2), ('b', 4))

    def test_add_edge_with_self_loop(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 0), ('a', 0))

    def test_add_edge_with_varying_length(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 1, 1), ('b', 2))
        self.assertRaises(ValueError, self.network.add_edge, ('b', 2), ('a', 2, 3))

    def test_add_edge_with_closed_path(self):
        self.assertRaises(ValueError, self.network.add_edges_from,
                          [(('a', 0), ('b', 0)), (('b', 0), ('c', 0)), (('c', 0), ('a', 0))])

    def test_add_single_edge_without_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, 'a', 'b')

    def test_add_single_edge_with_incorrect_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 'b'), ('b', 'c'))

    def test_add_multiple_edges(self):
        self.network.add_edges_from([(('a', 0), ('b', 0)), (('a', 0), ('a', 1)), (('b', 0), ('b', 1))])
        self.assertListEqual(sorted(self.network.edges()),
                             [(('a', 0), ('a', 1)), (('a', 0), ('b', 0)), (('a', 1), ('b', 1)), (('b', 0), ('b', 1))])

    def tearDown(self):
        del self.network
class TestDynamicBayesianNetworkCreation(unittest.TestCase):
    def setUp(self):
        self.network = DynamicBayesianNetwork()

    def test_add_single_node(self):
        self.network.add_node('a')
        self.assertListEqual(self.network.nodes(), ['a'])

    def test_add_multiple_nodes(self):
        self.network.add_nodes_from(['a', 'b', 'c'])
        self.assertListEqual(sorted(self.network.nodes()), ['a', 'b', 'c'])

    def test_add_single_edge_with_timeslice(self):
        self.network.add_edge(('a', 0), ('b', 0))
        self.assertListEqual(sorted(self.network.edges()), [(('a', 0), ('b', 0)), (('a', 1), ('b', 1))])
        self.assertListEqual(sorted(self.network.nodes()), ['a', 'b'])

    def test_add_edge_with_different_number_timeslice(self):
        self.network.add_edge(('a', 2), ('b', 2))
        self.assertListEqual(sorted(self.network.edges()), [(('a', 0), ('b', 0)), (('a', 1), ('b', 1))])

    def test_add_edge_going_backward(self):
        self.assertRaises(NotImplementedError, self.network.add_edge, ('a', 1), ('b', 0))

    def test_add_edge_with_farther_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 2), ('b', 4))

    def test_add_edge_with_self_loop(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 0), ('a', 0))

    def test_add_edge_with_varying_length(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 1, 1), ('b', 2))
        self.assertRaises(ValueError, self.network.add_edge, ('b', 2), ('a', 2, 3))

    def test_add_edge_with_closed_path(self):
        self.assertRaises(ValueError, self.network.add_edges_from,
                          [(('a', 0), ('b', 0)), (('b', 0), ('c', 0)), (('c', 0), ('a', 0))])

    def test_add_single_edge_without_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, 'a', 'b')

    def test_add_single_edge_with_incorrect_timeslice(self):
        self.assertRaises(ValueError, self.network.add_edge, ('a', 'b'), ('b', 'c'))

    def test_add_multiple_edges(self):
        self.network.add_edges_from([(('a', 0), ('b', 0)), (('a', 0), ('a', 1)), (('b', 0), ('b', 1))])
        self.assertListEqual(sorted(self.network.edges()),
                             [(('a', 0), ('a', 1)), (('a', 0), ('b', 0)), (('a', 1), ('b', 1)), (('b', 0), ('b', 1))])

    def tearDown(self):
        del self.network
class DynamicBayesianNetwork(Process):

    defaults = {
        'nodes': [],
        'edges': [],
        'conditional_probabilities': {
            'node_id': []
        }
    }

    def __init__(self, parameters=None):
        super().__init__(parameters)

        # set up the network based on the parameters
        self.model = DBN()
        self.model.add_nodes_from(self.parameters['nodes'])
        self.model.add_edges_from(self.parameters['edges'])

        print(f'EDGES: {sorted(self.model.edges())}')

        import ipdb
        ipdb.set_trace()

        # TODO -- add 'evidence' -- get from network?
        cpds = (TabularCPD(variable=node_id,
                           variable_card=len(values),
                           values=values,
                           evidence=[]) for node_id, values in
                self.parameters['conditional_probabilities'])
        self.model.add_cpds(cpds)

        # make an inference instance for sampling the model
        self.inference = BayesianModelSampling(self.model)

        # get a sample
        sample = self.inference.forward_sample(size=2)

    def ports_schema(self):
        return {}

    def next_update(self, timestep, states):
        return {}
Esempio n. 4
0
def main():
    data, string = readData()
    genes = np.array(data.columns[1:])
    labels = np.array(data.columns)

    bayesianModel = BayesianModel()
    transitionModel = DBN()

    bayesianModel.add_nodes_from(genes)
    transitionModel.add_nodes_from(genes)

    bData, tData = getData(data, labels)
    
    print "\nDynamic Bayesian Network inference", 
    print "\nB_0 network relations:  "
    
    hcb = HillClimbSearch(bData, genes, scoring_method=BicScore(bData, labels, bk1=string, weight=4))
    best_model_b = hcb.estimate(start=bayesianModel, tabu_length=15, max_indegree=2)
    print(best_model_b.edges())

    printOutputB(best_model_b)

    print "\nLocal Probability Model: "
    best_model_b.fit(bData, BayesianEstimator)
    for cpd in best_model_b.get_cpds():
        print(cpd)

    print "\nB_transition network relations: "

    hct = HillClimbSearch(tData, genes, scoring_method=BicScore(tData, labels, bk1=string, weight=4))
    best_model_t = hct.estimate_dynamic(start=transitionModel, tabu_length=15, max_indegree=2)
    print(best_model_t.edges())

    printOutputT(best_model_t)

    print "\nLocal Probability Model: "
    best_model_t.fit(tData, BayesianEstimator)
    for cpd in best_model_t.get_cpds():
        print(cpd)
Esempio n. 5
0
class TestDynamicBayesianNetworkMethods(unittest.TestCase):
    def setUp(self):
        self.network = DynamicBayesianNetwork()
        self.grade_cpd = TabularCPD(
            ('G', 0), 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25, 0.08, 0.3],
                          [0.3, 0.7, 0.2, 0.2]], [('D', 0), ('I', 0)], [2, 2])
        self.d_i_cpd = TabularCPD(('D', 1), 2, [[0.6, 0.3], [0.4, 0.7]],
                                  [('D', 0)], 2)
        self.diff_cpd = TabularCPD(('D', 0), 2, [[0.6, 0.4]])
        self.intel_cpd = TabularCPD(('I', 0), 2, [[0.7, 0.3]])
        self.i_i_cpd = TabularCPD(('I', 1), 2, [[0.5, 0.4], [0.5, 0.6]],
                                  [('I', 0)], 2)
        self.grade_1_cpd = TabularCPD(
            ('G', 1), 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25, 0.08, 0.3],
                          [0.3, 0.7, 0.2, 0.2]], [('D', 1), ('I', 1)], [2, 2])

    def test_get_intra_and_inter_edges(self):
        self.network.add_edges_from([(('a', 0), ('b', 0)),
                                     (('a', 0), ('a', 1)),
                                     (('b', 0), ('b', 1))])
        self.assertListEqual(sorted(self.network.get_intra_edges()),
                             [(('a', 0), ('b', 0))])
        self.assertListEqual(sorted(self.network.get_intra_edges(1)),
                             [(('a', 1), ('b', 1))])
        self.assertRaises(ValueError, self.network.get_intra_edges, -1)
        self.assertRaises(ValueError, self.network.get_intra_edges, '-')
        self.assertListEqual(sorted(self.network.get_inter_edges()),
                             [(('a', 0), ('a', 1)), (('b', 0), ('b', 1))])

    def test_get_interface_nodes(self):
        self.network.add_edges_from([
            (('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)),
            (('I', 0), ('I', 1))
        ])
        self.assertListEqual(sorted(self.network.get_interface_nodes()),
                             [('D', 0), ('I', 0)])
        self.assertRaises(ValueError, self.network.get_interface_nodes, -1)
        self.assertRaises(ValueError, self.network.get_interface_nodes, '-')

    def test_get_slice_nodes(self):
        self.network.add_edges_from([
            (('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)),
            (('I', 0), ('I', 1))
        ])
        self.assertListEqual(sorted(self.network.get_slice_nodes()),
                             [('D', 0), ('G', 0), ('I', 0)])
        self.assertListEqual(sorted(self.network.get_slice_nodes(1)),
                             [('D', 1), ('G', 1), ('I', 1)])
        self.assertRaises(ValueError, self.network.get_slice_nodes, -1)
        self.assertRaises(ValueError, self.network.get_slice_nodes, '-')

    def test_add_single_cpds(self):
        self.network.add_edges_from([(('D', 0), ('G', 0)),
                                     (('I', 0), ('G', 0))])
        self.network.add_cpds(self.grade_cpd)
        self.assertListEqual(self.network.get_cpds(), [self.grade_cpd])

    def test_get_cpds(self):
        self.network.add_edges_from([
            (('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)),
            (('I', 0), ('I', 1))
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(set(self.network.get_cpds()),
                         set([self.diff_cpd, self.intel_cpd, self.grade_cpd]))
        self.assertEqual(
            self.network.get_cpds(time_slice=1)[0].variable, ('G', 1))

    def test_add_multiple_cpds(self):
        self.network.add_edges_from([
            (('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)),
            (('I', 0), ('I', 1))
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.assertEqual(self.network.get_cpds(('G', 0)).variable, ('G', 0))
        self.assertEqual(self.network.get_cpds(('D', 1)).variable, ('D', 1))
        self.assertEqual(self.network.get_cpds(('D', 0)).variable, ('D', 0))
        self.assertEqual(self.network.get_cpds(('I', 0)).variable, ('I', 0))
        self.assertEqual(self.network.get_cpds(('I', 1)).variable, ('I', 1))

    def test_initialize_initial_state(self):

        self.network.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        self.network.add_edges_from([
            (('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)),
            (('I', 0), ('I', 1))
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(len(self.network.cpds), 6)
        self.assertEqual(self.network.get_cpds(('G', 1)).variable, ('G', 1))

    def test_moralize(self):
        self.network.add_edges_from(([(('D', 0), ('G', 0)),
                                      (('I', 0), ('G', 0))]))
        moral_graph = self.network.moralize()
        self.assertListEqual(hf.recursive_sorted(moral_graph.edges()),
                             [[('D', 0),
                               ('G', 0)], [('D', 0),
                                           ('I', 0)], [('D', 1), ('G', 1)],
                              [('D', 1),
                               ('I', 1)], [('G', 0),
                                           ('I', 0)], [('G', 1), ('I', 1)]])

    def tearDown(self):
        del self.network
Esempio n. 6
0
from pgmpy.factors.discrete import TabularCPD
from pgmpy.estimators import HillClimbSearchDBN, BicScore
import networkx as nx
import random as rand
import pandas as pd

# CREATES SIMULATED DBN MODEL

dbn = DynamicBayesianNetwork()

#   Node    Name                Values
#   I       Subject Interest    engaged, neutral, off
#   A       Subject Action      response, no response
#   R       Robot Action        prompt, fail, reward
#   O       Observation         q values
dbn.add_nodes_from(['I', 'A', 'R', 'O'])

# Check diagram for details
# I -----------> I2
# |  ------------^
# v /            |
# A ---> R -------
# |
# v
# O
dbn.add_edges_from([(('I', 0), ('A', 0)), (('I', 0), ('R', 0)),
                    (('I', 0), ('I', 1)), (('A', 0), ('O', 0)),
                    (('A', 0), ('R', 0)), (('A', 0), ('I', 1)),
                    (('R', 0), ('I', 1))])

# engaged, neutral, off
class TestDynamicBayesianNetworkMethods(unittest.TestCase):
    def setUp(self):
        self.network = DynamicBayesianNetwork()
        self.grade_cpd = TabularCPD(('G', 0), 3, [[0.3, 0.05, 0.8, 0.5],
                                             [0.4, 0.25, 0.1, 0.3],
                                             [0.3, 0.7, 0.1, 0.2]], [('D', 0), ('I', 0)], [2, 2])
        self.d_i_cpd = TabularCPD(('D', 1), 2, [[0.6, 0.3], [0.4, 0.7]], [('D', 0)], 2)
        self.diff_cpd = TabularCPD(('D', 0), 2, [[0.6, 0.4]])
        self.intel_cpd = TabularCPD(('I', 0), 2, [[0.7, 0.3]])
        self.i_i_cpd = TabularCPD(('I', 1), 2, [[0.5, 0.4], [0.5, 0.6]], [('I', 0)], 2)
        self.grade_1_cpd = TabularCPD(('G', 1), 3, [[0.3, 0.05, 0.8, 0.5],
                                             [0.4, 0.25, 0.1, 0.3],
                                             [0.3, 0.7, 0.1, 0.2]], [('D', 1), ('I', 1)], [2, 2])

    def test_get_intra_and_inter_edges(self):
        self.network.add_edges_from([(('a', 0), ('b', 0)), (('a', 0), ('a', 1)), (('b', 0), ('b', 1))])
        self.assertListEqual(sorted(self.network.get_intra_edges()), [(('a', 0), ('b', 0))])
        self.assertListEqual(sorted(self.network.get_intra_edges(1)), [(('a', 1), ('b', 1))])
        self.assertRaises(ValueError, self.network.get_intra_edges, -1)
        self.assertRaises(ValueError, self.network.get_intra_edges, '-')
        self.assertListEqual(sorted(self.network.get_inter_edges()), [(('a', 0), ('a', 1)), (('b', 0), ('b', 1))])

    def test_get_interface_nodes(self):
        self.network.add_edges_from(
            [(('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)), (('I', 0), ('I', 1))])
        self.assertListEqual(sorted(self.network.get_interface_nodes()), [('D', 0), ('I',0)])
        self.assertRaises(ValueError, self.network.get_interface_nodes, -1)
        self.assertRaises(ValueError, self.network.get_interface_nodes, '-')

    def test_get_slice_nodes(self):
        self.network.add_edges_from(
            [(('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)), (('I', 0), ('I', 1))])
        self.assertListEqual(sorted(self.network.get_slice_nodes()), [('D', 0), ('G', 0), ('I', 0)])
        self.assertListEqual(sorted(self.network.get_slice_nodes(1)), [('D', 1), ('G', 1), ('I', 1)])
        self.assertRaises(ValueError, self.network.get_slice_nodes, -1)
        self.assertRaises(ValueError, self.network.get_slice_nodes, '-')

    def test_add_single_cpds(self):
        self.network.add_edges_from([(('D', 0), ('G', 0)), (('I', 0), ('G', 0))])
        self.network.add_cpds(self.grade_cpd)
        self.assertListEqual(self.network.get_cpds(), [self.grade_cpd])

    def test_get_cpds(self):
        self.network.add_edges_from(
            [(('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)), (('I', 0), ('I', 1))])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd, self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(set(self.network.get_cpds()), set([self.diff_cpd, self.intel_cpd, self.grade_cpd]))
        self.assertEqual(self.network.get_cpds(time_slice=1)[0].variable, ('G', 1))

    def test_add_multiple_cpds(self):
        self.network.add_edges_from(
            [(('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)), (('I', 0), ('I', 1))])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd, self.intel_cpd, self.i_i_cpd)
        self.assertEqual(self.network.get_cpds(('G', 0)).variable, ('G', 0))
        self.assertEqual(self.network.get_cpds(('D', 1)).variable, ('D', 1))
        self.assertEqual(self.network.get_cpds(('D', 0)).variable, ('D', 0))
        self.assertEqual(self.network.get_cpds(('I', 0)).variable, ('I', 0))
        self.assertEqual(self.network.get_cpds(('I', 1)).variable, ('I', 1))

    def test_initialize_initial_state(self):

        self.network.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        self.network.add_edges_from(
            [(('D', 0), ('G', 0)), (('I', 0), ('G', 0)), (('D', 0), ('D', 1)), (('I', 0), ('I', 1))])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd, self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(len(self.network.cpds), 6)
        self.assertEqual(self.network.get_cpds(('G', 1)).variable, ('G', 1))

    def test_moralize(self):
        self.network.add_edges_from(([(('D',0), ('G',0)), (('I',0), ('G',0))]))
        moral_graph = self.network.moralize()
        self.assertListEqual(hf.recursive_sorted(moral_graph.edges()),
                             [[('D', 0), ('G', 0)], [('D', 0), ('I', 0)],
                              [('D', 1), ('G', 1)], [('D', 1), ('I', 1)],
                              [('G', 0), ('I', 0)], [('G', 1), ('I', 1)]])

    def tearDown(self):
        del self.network
Esempio n. 8
0
class TestDynamicBayesianNetworkMethods(unittest.TestCase):
    def setUp(self):
        self.network = DynamicBayesianNetwork()
        self.grade_cpd = TabularCPD(
            ("G", 0),
            3,
            values=[[0.3, 0.05, 0.8, 0.5], [0.4, 0.25, 0.1, 0.3],
                    [0.3, 0.7, 0.1, 0.2]],
            evidence=[("D", 0), ("I", 0)],
            evidence_card=[2, 2],
        )
        self.d_i_cpd = TabularCPD(
            ("D", 1),
            2,
            values=[[0.6, 0.3], [0.4, 0.7]],
            evidence=[("D", 0)],
            evidence_card=[2],
        )
        self.diff_cpd = TabularCPD(("D", 0), 2, values=[[0.6, 0.4]])
        self.intel_cpd = TabularCPD(("I", 0), 2, values=[[0.7, 0.3]])
        self.i_i_cpd = TabularCPD(
            ("I", 1),
            2,
            values=[[0.5, 0.4], [0.5, 0.6]],
            evidence=[("I", 0)],
            evidence_card=[2],
        )
        self.grade_1_cpd = TabularCPD(
            ("G", 1),
            3,
            values=[[0.3, 0.05, 0.8, 0.5], [0.4, 0.25, 0.1, 0.3],
                    [0.3, 0.7, 0.1, 0.2]],
            evidence=[("D", 1), ("I", 1)],
            evidence_card=[2, 2],
        )

    def test_get_intra_and_inter_edges(self):
        self.network.add_edges_from([(("a", 0), ("b", 0)),
                                     (("a", 0), ("a", 1)),
                                     (("b", 0), ("b", 1))])
        self.assertListEqual(sorted(self.network.get_intra_edges()),
                             [(("a", 0), ("b", 0))])
        self.assertListEqual(sorted(self.network.get_intra_edges(1)),
                             [(("a", 1), ("b", 1))])
        self.assertRaises(ValueError, self.network.get_intra_edges, -1)
        self.assertRaises(ValueError, self.network.get_intra_edges, "-")
        self.assertListEqual(
            sorted(self.network.get_inter_edges()),
            [(("a", 0), ("a", 1)), (("b", 0), ("b", 1))],
        )

    def test_get_interface_nodes(self):
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        self.assertListEqual(sorted(self.network.get_interface_nodes()),
                             [("D", 0), ("I", 0)])
        self.assertRaises(ValueError, self.network.get_interface_nodes, -1)
        self.assertRaises(ValueError, self.network.get_interface_nodes, "-")

    def test_get_slice_nodes(self):
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        self.assertListEqual(sorted(self.network.get_slice_nodes()),
                             [("D", 0), ("G", 0), ("I", 0)])
        self.assertListEqual(sorted(self.network.get_slice_nodes(1)),
                             [("D", 1), ("G", 1), ("I", 1)])
        self.assertRaises(ValueError, self.network.get_slice_nodes, -1)
        self.assertRaises(ValueError, self.network.get_slice_nodes, "-")

    def test_add_single_cpds(self):
        self.network.add_edges_from([(("D", 0), ("G", 0)),
                                     (("I", 0), ("G", 0))])
        self.network.add_cpds(self.grade_cpd)
        self.assertListEqual(self.network.get_cpds(), [self.grade_cpd])

    def test_get_cpds(self):
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(
            set(self.network.get_cpds()),
            set([self.diff_cpd, self.intel_cpd, self.grade_cpd]),
        )
        self.assertEqual(
            {cpd.variable
             for cpd in self.network.get_cpds(time_slice=1)},
            {("D", 1), ("I", 1), ("G", 1)},
        )

    def test_add_multiple_cpds(self):
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.assertEqual(self.network.get_cpds(("G", 0)).variable, ("G", 0))
        self.assertEqual(self.network.get_cpds(("D", 1)).variable, ("D", 1))
        self.assertEqual(self.network.get_cpds(("D", 0)).variable, ("D", 0))
        self.assertEqual(self.network.get_cpds(("I", 0)).variable, ("I", 0))
        self.assertEqual(self.network.get_cpds(("I", 1)).variable, ("I", 1))

    def test_initialize_initial_state(self):

        self.network.add_nodes_from(["D", "G", "I", "S", "L"])
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        self.network.add_cpds(self.grade_cpd, self.d_i_cpd, self.diff_cpd,
                              self.intel_cpd, self.i_i_cpd)
        self.network.initialize_initial_state()
        self.assertEqual(len(self.network.cpds), 6)
        self.assertEqual(self.network.get_cpds(("G", 1)).variable, ("G", 1))

    def test_moralize(self):
        self.network.add_edges_from(([(("D", 0), ("G", 0)),
                                      (("I", 0), ("G", 0))]))
        moral_graph = self.network.moralize()
        self.assertListEqual(
            hf.recursive_sorted(moral_graph.edges()),
            [
                [("D", 0), ("G", 0)],
                [("D", 0), ("I", 0)],
                [("D", 1), ("G", 1)],
                [("D", 1), ("I", 1)],
                [("G", 0), ("I", 0)],
                [("G", 1), ("I", 1)],
            ],
        )

    def test_copy(self):
        self.network.add_edges_from([
            (("D", 0), ("G", 0)),
            (("I", 0), ("G", 0)),
            (("D", 0), ("D", 1)),
            (("I", 0), ("I", 1)),
        ])
        cpd = TabularCPD(
            ("G", 0),
            3,
            values=[[0.3, 0.05, 0.8, 0.5], [0.4, 0.25, 0.1, 0.3],
                    [0.3, 0.7, 0.1, 0.2]],
            evidence=[("D", 0), ("I", 0)],
            evidence_card=[2, 2],
        )
        self.network.add_cpds(cpd)
        copy = self.network.copy()
        self.assertIsInstance(copy, DynamicBayesianNetwork)
        self.assertListEqual(sorted(self.network._nodes()),
                             sorted(copy._nodes()))
        self.assertListEqual(sorted(self.network.edges()),
                             sorted(copy.edges()))
        self.assertListEqual(self.network.get_cpds(), copy.get_cpds())
        self.assertListEqual(sorted(self.network.get_intra_edges()),
                             sorted(copy.get_intra_edges()))
        self.assertListEqual(sorted(self.network.get_inter_edges()),
                             sorted(copy.get_inter_edges()))
        self.assertListEqual(sorted(self.network.get_slice_nodes()),
                             sorted(copy.get_slice_nodes()))

        copy.cpds[0].values = np.array([[0.4, 0.05, 0.3, 0.5],
                                        [0.3, 0.25, 0.5, 0.3],
                                        [0.3, 0.7, 0.2, 0.2]])
        self.assertNotEqual(self.network.get_cpds(), copy.get_cpds())
        self.network.add_cpds(self.i_i_cpd, self.d_i_cpd)

        copy.add_cpds(self.diff_cpd, self.intel_cpd)
        self.network.add_node("A")
        copy.add_node("Z")
        self.network.add_edge(("A", 0), ("D", 0))
        copy.add_edge(("Z", 0), ("D", 0))
        self.assertNotEqual(sorted(self.network._nodes()),
                            sorted(copy._nodes()))
        self.assertNotEqual(sorted(self.network.edges()), sorted(copy.edges()))
        self.assertNotEqual(self.network.get_cpds(), copy.get_cpds())
        self.assertNotEqual(sorted(self.network.get_intra_edges()),
                            sorted(copy.get_intra_edges()))
        self.assertListEqual(sorted(self.network.get_inter_edges()),
                             sorted(copy.get_inter_edges()))
        self.assertNotEqual(sorted(self.network.get_slice_nodes()),
                            sorted(copy.get_slice_nodes()))

        self.network.add_edge(("A", 0), ("D", 1))
        copy.add_edge(("Z", 0), ("D", 1))
        self.assertNotEqual(sorted(self.network.get_inter_edges()),
                            sorted(copy.get_inter_edges()))

    def tearDown(self):
        del self.network
Esempio n. 9
0
    def estimate_dynamic(self, start=None, tabu_length=0, max_indegree=None):
        """
        Performs local hill climb search to estimates the `BayesianModel` structure
        that has optimal score, according to the scoring method supplied in the constructor.
        Starts at model `start` and proceeds by step-by-step network modifications
        until a local maximum is reached. Only estimates network structure, no parametrization.

        Parameters
        ----------
        start: DynamicBayesianNetwork instance
            The starting point for the local search. By default a completely disconnected network is used.
        tabu_length: int
            If provided, the last `tabu_length` graph modifications cannot be reversed
            during the search procedure. This serves to enforce a wider exploration
            of the search space. Default value: 100.
        max_indegree: int or None
            If provided and unequal None, the procedure only searches among models
            where all nodes have at most `max_indegree` parents. Defaults to None.

        Returns
        -------
        model: `DynamicBayesianNetwork` instance
            A `DynamicBayesianModel` at a (local) score maximum.

        Examples
        --------
        >>> import pandas as pd
        >>> import numpy as np
        >>> from pgmpy.estimators import HillClimbSearch, BicScore
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> # create data sample with 9 random variables:
        ... data = pd.DataFrame(np.random.randint(0, 5, size=(5000, 9)), c   olumns=list('ABCDEFGHI'))
        >>> # add 10th dependent variable
        ... data['J'] = data['A'] * data['B']
        >>> labels = np.array(data.columns)
        >>> transitionModel = DBN()
        >>> transitionModel.add_nodes_from(labels)
        >>> est = HillClimbSearch(data, labels, scoring_method=BicScore(data, labels))
        >>> best_model = est.estimate_dynamic(start=transitionModel)
        >>> sorted(best_model.nodes())
        ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
        >>> best_model.edges()
        [(('A', 1), ('J', 1)), (('A', 1), ('B', 1)), (('J', 1), ('B', 1))]
        """

        epsilon = 1e-8
        if self.nodes is None:
            nodes = self.state_names.keys()
        else:
            nodes = self.nodes
        if start is None:
            start = DB()
            start.add_nodes_from(nodes)
        elif not isinstance(start, DB) or not set(start.nodes()) == set(nodes):
            raise ValueError(
                "'start' should be a DynamicBayesianModel with the same variables as the data set, or 'None'."
            )

        tabu_list = []
        current_model = start

        while True:
            best_score_delta = 0
            best_operation = None

            for operation, score_delta in self._legal_operations_dynamic(
                    current_model, tabu_list, max_indegree):
                if score_delta > best_score_delta:
                    best_operation = operation
                    best_score_delta = score_delta

            if best_operation is None or best_score_delta < epsilon:
                break
            elif best_operation[0] == '+':
                current_model.add_edges_from([(best_operation[1][0],
                                               best_operation[1][1])])

                tabu_list = ([('-', best_operation[1])] +
                             tabu_list)[:tabu_length]
            elif best_operation[0] == '-':
                current_model.remove_edge((best_operation[1][0]),
                                          (best_operation[1][1]))
                tabu_list = ([('+', best_operation[1])] +
                             tabu_list)[:tabu_length]
            elif best_operation[0] == 'flip':
                ((X, A), (Y, B)) = best_operation[1]
                current_model.remove_edge((X, A), (Y, B))
                current_model.add_edge((Y, A), (X, B))
                tabu_list = ([best_operation] + tabu_list)[:tabu_length]
        return current_model