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 {}
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)
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
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
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
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