class TestInferenceBase(unittest.TestCase): def setUp(self): self.bayesian = BayesianModel([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')]) a_cpd = TabularCPD('a', 2, [[0.4, 0.6]]) b_cpd = TabularCPD('b', 2, [[0.2, 0.4], [0.3, 0.4]], evidence='a', evidence_card=[2]) c_cpd = TabularCPD('c', 2, [[0.1, 0.2], [0.3, 0.4]], evidence='b', evidence_card=[2]) d_cpd = TabularCPD('d', 2, [[0.4, 0.3], [0.2, 0.1]], evidence='c', evidence_card=[2]) e_cpd = TabularCPD('e', 2, [[0.3, 0.2], [0.4, 0.1]], evidence='d', evidence_card=[2]) self.bayesian.add_cpd([a_cpd, b_cpd, c_cpd, d_cpd, e_cpd]) self.markov = MarkovModel([('a', 'b'), ('b', 'd'), ('a', 'c'), ('c', 'd')]) factor_1 = Factor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])) factor_2 = Factor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])) factor_3 = Factor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])) factor_4 = Factor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) self.markov.add_factors(factor_1, factor_2, factor_3, factor_4) def test_bayesian_inference_init(self): infer_bayesian = Inference(self.bayesian) self.assertEqual(set(infer_bayesian.variables), {'a', 'b', 'c', 'd', 'e'}) self.assertEqual(infer_bayesian.cardinality, {'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 2}) # self.assertEqual(infer_bayesian.factors, {'a': [self.bayesian.get_cpd('a').to_factor(), # self.bayesian.get_cpd('b').to_factor()], # 'b': [self.bayesian.get_cpd('b').to_factor(), # self.bayesian.get_cpd('c').to_factor()], # 'c': [self.bayesian.get_cpd('c').to_factor(), # self.bayesian.get_cpd('d').to_factor()], # 'd': [self.bayesian.get_cpd('d').to_factor(), # self.bayesian.get_cpd('e').to_factor()], # 'e': [self.bayesian.get_cpd('e').to_factor()]}) def test_markov_inference_init(self): infer_markov = Inference(self.markov) self.assertEqual(set(infer_markov.variables), {'a', 'b', 'c', 'd'}) self.assertEqual(infer_markov.cardinality, {'a': 2, 'b': 2, 'c': 2, 'd': 2})
def test_markovmodel(): """ >>> from ibeis.algo.hots.pgm_ext import * # NOQA """ from pgmpy.models import MarkovModel from pgmpy.factors import Factor markovmodel = MarkovModel([('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A')]) factor_a_b = Factor(variables=['A', 'B'], cardinality=[2, 2], values=[100, 5, 5, 100]) factor_b_c = Factor(variables=['B', 'C'], cardinality=[2, 2], values=[100, 3, 2, 4]) factor_c_d = Factor(variables=['C', 'D'], cardinality=[2, 2], values=[3, 5, 1, 6]) factor_d_a = Factor(variables=['D', 'A'], cardinality=[2, 2], values=[6, 2, 56, 2]) markovmodel.add_factors(factor_a_b, factor_b_c, factor_c_d, factor_d_a) pgm_viz.show_markov_model(markovmodel) pgm_viz.show_junction_tree(markovmodel)
def setUp(self): self.maxDiff = None edges = [['family-out', 'dog-out'], ['bowel-problem', 'dog-out'], ['family-out', 'light-on'], ['dog-out', 'hear-bark']] cpds = {'bowel-problem': np.array([[0.01], [0.99]]), 'dog-out': np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), 'family-out': np.array([[0.15], [0.85]]), 'hear-bark': np.array([[0.7, 0.3], [0.01, 0.99]]), 'light-on': np.array([[0.6, 0.4], [0.05, 0.95]])} states = {'bowel-problem': ['true', 'false'], 'dog-out': ['true', 'false'], 'family-out': ['true', 'false'], 'hear-bark': ['true', 'false'], 'light-on': ['true', 'false']} parents = {'bowel-problem': [], 'dog-out': ['bowel-problem', 'family-out'], 'family-out': [], 'hear-bark': ['dog-out'], 'light-on': ['family-out']} self.bayesmodel = BayesianModel(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD(var, len(states[var]), values, evidence=parents[var], evidence_card=[len(states[evidence_var]) for evidence_var in parents[var]]) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {('var_0', 'var_1'), ('var_0', 'var_2'), ('var_1', 'var_2')} self.markovmodel = MarkovModel(edges) tables = [(['var_0', 'var_1'], ['4.000', '2.400', '1.000', '0.000']), (['var_0', 'var_1', 'var_2'], ['2.2500', '3.2500', '3.7500', '0.0000', '0.0000', '10.0000', '1.8750', '4.0000', '3.3330', '2.0000', '2.0000', '3.4000'])] domain = {'var_1': '2', 'var_2': '3', 'var_0': '2'} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = DiscreteFactor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel)
def __init__(self, adj_mat=None, struct=None): DEBUG = False self.G = MarkovModel() self.n_nodes = adj_mat.shape[0] if DEBUG: print 'struct', struct if struct == 'complete': self._complete_graph(adj_mat) if struct == 'nodes': self._nodes_only(adj_mat) if struct is None: self._import_adj(adj_mat) self._ising_factors(Wf=5, Wi=5, f_type='mixed') if DEBUG: print 'generate_init', self.G, self.G.nodes()
def to_markov_model(self): """ Converts bayesian model to markov model. The markov model created would be the moral graph of the bayesian model. Examples -------- >>> from pgmpy.models import BayesianModel >>> G = BayesianModel([('diff', 'grade'), ('intel', 'grade'), ... ('intel', 'SAT'), ('grade', 'letter')]) >>> mm = G.to_markov_model() >>> mm.nodes() ['diff', 'grade', 'intel', 'SAT', 'letter'] >>> mm.edges() [('diff', 'intel'), ('diff', 'grade'), ('intel', 'grade'), ('intel', 'SAT'), ('grade', 'letter')] """ from pgmpy.models import MarkovModel moral_graph = self.moralize() mm = MarkovModel(moral_graph.edges()) mm.add_factors(*[cpd.to_factor() for cpd in self.cpds]) return mm
def setUp(self): self.bayesian = BayesianModel([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')]) a_cpd = TabularCPD('a', 2, [[0.4, 0.6]]) b_cpd = TabularCPD('b', 2, [[0.2, 0.4], [0.3, 0.4]], evidence='a', evidence_card=[2]) c_cpd = TabularCPD('c', 2, [[0.1, 0.2], [0.3, 0.4]], evidence='b', evidence_card=[2]) d_cpd = TabularCPD('d', 2, [[0.4, 0.3], [0.2, 0.1]], evidence='c', evidence_card=[2]) e_cpd = TabularCPD('e', 2, [[0.3, 0.2], [0.4, 0.1]], evidence='d', evidence_card=[2]) self.bayesian.add_cpd([a_cpd, b_cpd, c_cpd, d_cpd, e_cpd]) self.markov = MarkovModel([('a', 'b'), ('b', 'd'), ('a', 'c'), ('c', 'd')]) factor_1 = Factor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])) factor_2 = Factor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])) factor_3 = Factor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])) factor_4 = Factor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) self.markov.add_factors(factor_1, factor_2, factor_3, factor_4)
def setUp(self): # A test Bayesian model diff_cpd = TabularCPD('diff', 2, [[0.6], [0.4]]) intel_cpd = TabularCPD('intel', 2, [[0.7], [0.3]]) grade_cpd = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25, 0.08, 0.3], [0.3, 0.7, 0.02, 0.2]], evidence=['diff', 'intel'], evidence_card=[2, 2]) self.bayesian_model = BayesianModel() self.bayesian_model.add_nodes_from(['diff', 'intel', 'grade']) self.bayesian_model.add_edges_from([('diff', 'grade'), ('intel', 'grade')]) self.bayesian_model.add_cpds(diff_cpd, intel_cpd, grade_cpd) # A test Markov model self.markov_model = MarkovModel([('A', 'B'), ('C', 'B'), ('B', 'D')]) factor_ab = Factor(['A', 'B'], [2, 3], [1, 2, 3, 4, 5, 6]) factor_cb = Factor(['C', 'B'], [4, 3], [3, 1, 4, 5, 7, 8, 1, 3, 10, 4, 5, 6]) factor_bd = Factor(['B', 'D'], [3, 2], [5, 7, 2, 1, 9, 3]) self.markov_model.add_factors(factor_ab, factor_cb, factor_bd) self.gibbs = GibbsSampling(self.bayesian_model)
def setUp(self): # It is just a moralised version of the above Bayesian network so all the results are same. Only factors # are under consideration for inference so this should be fine. self.markov_model = MarkovModel([('A', 'J'), ('R', 'J'), ('J', 'Q'), ('J', 'L'), ('G', 'L'), ('A', 'R'), ('J', 'G')]) factor_a = TabularCPD('A', 2, values=[[0.2], [0.8]]).to_factor() factor_r = TabularCPD('R', 2, values=[[0.4], [0.6]]).to_factor() factor_j = TabularCPD('J', 2, values=[[0.9, 0.6, 0.7, 0.1], [0.1, 0.4, 0.3, 0.9]], evidence=['A', 'R'], evidence_card=[2, 2]).to_factor() factor_q = TabularCPD('Q', 2, values=[[0.9, 0.2], [0.1, 0.8]], evidence=['J'], evidence_card=[2]).to_factor() factor_l = TabularCPD('L', 2, values=[[0.9, 0.45, 0.8, 0.1], [0.1, 0.55, 0.2, 0.9]], evidence=['J', 'G'], evidence_card=[2, 2]).to_factor() factor_g = TabularCPD('G', 2, [[0.6], [0.4]]).to_factor() self.markov_model.add_factors(factor_a, factor_r, factor_j, factor_q, factor_l, factor_g) self.markov_inference = VariableElimination(self.markov_model)
def to_markov_model(self): """ Converts the factor graph into markov model. A markov model contains nodes as random variables and edge between two nodes imply interaction between them. Examples -------- >>> from pgmpy.models import FactorGraph >>> from pgmpy.factors import Factor >>> G = FactorGraph() >>> G.add_nodes_from(['a', 'b', 'c']) >>> phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4)) >>> phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4)) >>> G.add_factors(phi1, phi2) >>> G.add_nodes_from([phi1, phi2]) >>> G.add_edges_from([('a', phi1), ('b', phi1), ... ('b', phi2), ('c', phi2)]) >>> mm = G.to_markov_model() """ from pgmpy.models import MarkovModel mm = MarkovModel() variable_nodes = self.get_variable_nodes() if len(set(self.nodes()) - set(variable_nodes)) != len(self.factors): raise ValueError('Factors not associated with all the factor nodes.') mm.add_nodes_from(variable_nodes) for factor in self.factors: scope = factor.scope() mm.add_edges_from(itertools.combinations(scope, 2)) mm.add_factors(factor) return mm
class TestUndirectedGraphFactorOperations(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_add_factor_raises_error(self): self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles'), ('Charles', 'Debbie'), ('Debbie', 'Alice')]) factor = Factor(['Alice', 'Bob', 'John'], [2, 2, 2], np.random.rand(8)) self.assertRaises(ValueError, self.graph.add_factors, factor) def test_add_single_factor(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi = Factor(['a', 'b'], [2, 2], range(4)) self.graph.add_factors(phi) six.assertCountEqual(self, self.graph.factors, [phi]) def test_add_multiple_factors(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) six.assertCountEqual(self, self.graph.factors, [phi1, phi2]) def test_get_factors(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) six.assertCountEqual(self, self.graph.get_factors(), []) self.graph.add_factors(phi1, phi2) six.assertCountEqual(self, self.graph.get_factors(), [phi1, phi2]) def test_remove_single_factor(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.remove_factors(phi1) six.assertCountEqual(self, self.graph.factors, [phi2]) def test_remove_multiple_factors(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.remove_factors(phi1, phi2) six.assertCountEqual(self, self.graph.factors, []) def test_partition_function(self): self.graph.add_nodes_from(['a', 'b', 'c']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertEqual(self.graph.get_partition_function(), 22.0) def test_partition_function_raises_error(self): self.graph.add_nodes_from(['a', 'b', 'c', 'd']) phi1 = Factor(['a', 'b'], [2, 2], range(4)) phi2 = Factor(['b', 'c'], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.get_partition_function) def tearDown(self): del self.graph
class TestMarkovModelCreation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_class_init_without_data(self): self.assertIsInstance(self.graph, MarkovModel) def test_class_init_with_data_string(self): self.g = MarkovModel([('a', 'b'), ('b', 'c')]) self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c']) self.assertListEqual(hf.recursive_sorted(self.g.edges()), [['a', 'b'], ['b', 'c']]) def test_class_init_with_data_nonstring(self): self.g = MarkovModel([(1, 2), (2, 3)]) def test_add_node_string(self): self.graph.add_node('a') self.assertListEqual(self.graph.nodes(), ['a']) def test_add_node_nonstring(self): self.graph.add_node(1) def test_add_nodes_from_string(self): self.graph.add_nodes_from(['a', 'b', 'c', 'd']) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd']) def test_add_nodes_from_non_string(self): self.graph.add_nodes_from([1, 2, 3, 4]) def test_add_edge_string(self): self.graph.add_edge('d', 'e') self.assertListEqual(sorted(self.graph.nodes()), ['d', 'e']) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['d', 'e']]) self.graph.add_nodes_from(['a', 'b', 'c']) self.graph.add_edge('a', 'b') self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['d', 'e']]) def test_add_edge_nonstring(self): self.graph.add_edge(1, 2) def test_add_edge_selfloop(self): self.assertRaises(ValueError, self.graph.add_edge, 'a', 'a') def test_add_edges_from_string(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c']) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['b', 'c']]) self.graph.add_nodes_from(['d', 'e', 'f']) self.graph.add_edges_from([('d', 'e'), ('e', 'f')]) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd', 'e', 'f']) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), hf.recursive_sorted([('a', 'b'), ('b', 'c'), ('d', 'e'), ('e', 'f')])) def test_add_edges_from_nonstring(self): self.graph.add_edges_from([(1, 2), (2, 3)]) def test_add_edges_from_self_loop(self): self.assertRaises(ValueError, self.graph.add_edges_from, [('a', 'a')]) def test_number_of_neighbors(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertEqual(len(self.graph.neighbors('b')), 2) def tearDown(self): del self.graph
def setUp(self): self.graph = MarkovModel()
class generate(object): def __init__(self, adj_mat=None, struct=None): DEBUG = False self.G = MarkovModel() self.n_nodes = adj_mat.shape[0] if DEBUG: print 'struct', struct if struct == 'complete': self._complete_graph(adj_mat) if struct == 'nodes': self._nodes_only(adj_mat) if struct is None: self._import_adj(adj_mat) self._ising_factors(Wf=5, Wi=5, f_type='mixed') if DEBUG: print 'generate_init', self.G, self.G.nodes() def get_model(self): return self.G def _complete_graph(self, adj_mat): """ generate the complete graph over len(adj_mat) """ self._nodes_only(adj_mat) for i in range(self.n_nodes): self.G.add_edges_from([(i, j) for j in range(self.n_nodes)]) def _import_adj(self, adj_mat): """ add nodes and edges to graph adj_mat - square matrix, numpy array like """ DEBUG = False assert (adj_mat is not None), "can't import empty adj mat" # add nodes self._nodes_only(adj_mat) # add edges for i in range(self.n_nodes): edges_list = ([(i, j) for j in range(self.n_nodes) if adj_mat[i][j]]) if DEBUG: print edges_list self.G.add_edges_from(edges_list) if DEBUG: print len(self.G) def _nodes_only(self, adj_mat): """ add nodes to graph adj_mat - aquare matrix, numpy array like """ global DEBUG assert (adj_mat is not None), "can't import empty adj mat" assert (self.n_nodes == adj_mat.shape[1]), "adj_mat is not sqaure" self.G.add_nodes_from([i for i in range(self.n_nodes)]) if DEBUG: print '_nodes_only', [i for i in range(self.n_nodes)] if DEBUG: print '_nodes_only print G', self.G.nodes() assert (self.n_nodes == len(self.G)), "graph size is incosistent with adj_mat" def _ising_factors(self, Wf=1, Wi=1, f_type='mixed'): """ Add ising-like factors to model graph cardinality is the number of possible values in our case we have boolean nodes, thus cardinality = 2 Wf = \theta_i = ~U[-Wf, Wf] type = 'mixed' = ~U[-Wi,Wi] 'attractive' = ~U[0,Wi] """ self._field_factors(Wf) self._interact_factors(Wi, f_type) def _field_factors(self, w, states=2): """ this function assigns factor for single node currently states=2 for ising model generation """ for i in self.G.nodes(): phi_i = Factor([i], [states], self._wf(w, states)) self.G.add_factors(phi_i) def _interact_factors(self, w, f_type, states=2): """ this function assigns factor for two interacting nodes currently states=2 for ising model generation """ for e in self.G.edges(): # if DEBUG: print 'interact_factors edges,states, values',e,[e[0], # e[1]],len(e)*[states], self._wi(w, f_type, states) phi_ij = Factor([e[0], e[1]], [states] * len(e), self._wi(w, f_type, states)) self.G.add_factors(phi_ij) def _wf(self, w, k): """ generate field factor """ # if DEBUG: print 'w',type(w),w return np.random.uniform(low=-1 * w, high=w, size=k) def _wi(self, w, f_type, k): """ generate interaction factor current support only for k=2 """ # if DEBUG: print 'w',type(w),w a_ij = np.random.uniform(low=-1 * w, high=w) if f_type == 'mixed': dis_aij = -a_ij else: # f_type == 'attractive': dis_aij = 0 # else: # print 'f_type error' return [a_ij, dis_aij, dis_aij, a_ij]
from pgmpy.models import MarkovModel from pgmpy.factors import Factor model = MarkovModel() # Fig 2.7(a) represents the Markov model model.add_nodes_from(['A', 'B', 'C', 'D']) model.add_edges_from([('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A')]) # Adding some factors. phi_A_B = Factor(['A', 'B'], [2, 2], [1, 100, phi_B_C = Factor(['B', 'C'], [2, 2], [100, 1, phi_C_D = Factor(['C', 'D'], [2, 2], [1, 100, phi_D_A = Factor(['D', 'A'], [2, 2], [100, 1, model.add_factors(phi_A_B, phi_B_C, phi_C_D, bayesian_model = model.to_bayesian_model() bayesian_model.edges()
def main(): # maximum size of segments grid cell map_size = 50 # minimum number of pixels to consider segment pixels_thresh = 500 # number of image in the database num_images = 70 # counter for incorrectly classified segments num_incorrect = 0 for idx in range(num_images): print('\n\nImage ', idx) # read image from disk image = cv2.imread('export/image_%04d.jpg' % idx) # read ground truth classes labels_gt_im = cv2.imread('export/labels_%04d.png' % idx, cv2.IMREAD_ANYDEPTH).astype(np.int) labels_gt_im[labels_gt_im == 65535] = -1 # read a priori probabilities from classifier prob_im = cv2.imread('export/prob_%04d.png' % idx, cv2.IMREAD_ANYDEPTH) / 65535.0 # read image division into segments segments_im = cv2.imread('export/segments_%04d.png' % idx, cv2.IMREAD_ANYDEPTH) # display image cv2.imshow('original image', image) cv2.waitKey(1) # mean R, G, B values for each segment mean_rgb = np.zeros([map_size, map_size, 3], dtype=np.float) # number of pixels for each segment num_pixels = np.zeros([map_size, map_size], dtype=np.uint) # a priori probabilities for each segment prob = np.zeros([map_size, map_size, 2], dtype=np.float) # ground truth classes for each segment labels_gt = -1 * np.ones([map_size, map_size], dtype=np.int) for y in range(map_size): for x in range(map_size): # segment identifier cur_seg = y * map_size + x # indices of pixels belonging to the segment cur_pixels = np.nonzero(segments_im == cur_seg) if len(cur_pixels[0]) > 0: num_pixels[y, x] = len(cur_pixels[0]) # flip because opencv stores images as BGR by default mean_rgb[y, x, :] = np.flip(np.mean(image[cur_pixels], axis=0)) # average results from the classifier - should not be necessary prob[y, x, 0] = np.mean(prob_im[cur_pixels]) prob[y, x, 1] = 1.0 - prob[y, x, 0] # labeling boundaries don't have to be aligned with segments boundaties # count which label is the most common in this segment labels_unique, count = np.unique(labels_gt_im[cur_pixels], return_counts=True) labels_gt[y, x] = labels_unique[np.argmax(count)] pass # build model # PUT YOUR CODE HERE nodes = [] # if segment size is bigger than pixels_thresh, add current segment to node list for y in range(map_size): for x in range(map_size): if num_pixels[y, x] > pixels_thresh: nodes.append("s_" + str(y) + "_" + str(x)) factors_unary = [] # if segment size is bigger than pixels_thresh, add unary factor of segment to list for y in range(map_size): for x in range(map_size): if num_pixels[y, x] > pixels_thresh: # print(prob[y, x] * 0.9/1 + 0.05) cur_f = create_factor(["s_" + str(y) + "_" + str(x)], [[0, 1]], [0.945212], [unary_feat], [prob[y, x]]) factors_unary.append(cur_f) factors_pairway = [] edges_pairway = [] # if segment size is bigger than pixels_thresh and his neighbour too, add pairway factor to list for y in range(map_size - 1): for x in range(map_size - 1): if num_pixels[y, x] > pixels_thresh: # check neighnour to the right if num_pixels[y, x + 1] > pixels_thresh: cur_f = create_factor([ "s_" + str(y) + "_" + str(x), "s_" + str(y) + "_" + str(x + 1) ], [[0, 1], [0, 1]], [1.86891, 1.07741, 1.89271], [ pairway_feat_red, pairway_feat_green, pairway_feat_blue ], [mean_rgb[y, x], mean_rgb[y, x + 1]]) factors_pairway.append(cur_f) edges_pairway.append( ("s_" + str(y) + "_" + str(x), "s_" + str(y) + "_" + str(x + 1))) # check neighbour under if num_pixels[y + 1, x] > pixels_thresh: cur_f = create_factor([ "s_" + str(y) + "_" + str(x), "s_" + str(y + 1) + "_" + str(x) ], [[0, 1], [0, 1]], [1.86891, 1.07741, 1.89271], [ pairway_feat_red, pairway_feat_green, pairway_feat_blue ], [mean_rgb[y, x], mean_rgb[y + 1, x]]) factors_pairway.append(cur_f) edges_pairway.append( ("s_" + str(y) + "_" + str(x), "s_" + str(y + 1) + "_" + str(x))) # use Markov model, because MPLP doesn't support factor graphs G = MarkovModel() G.add_nodes_from(nodes) # add nodes G.add_factors(*factors_unary) # add unary factors G.add_factors(*factors_pairway) # add pairway factors G.add_edges_from(edges_pairway) # add edges # check if everything is ok print("Check model: ", G.check_model()) # ------------------ # inferred image pixels labels_infer = -1 * np.ones([map_size, map_size], dtype=np.int) # read results of the inference # PUT YOUR CODE HERE mplp_infer = Mplp(G) q = mplp_infer.map_query() segment_cnt = 0 for y in range(map_size): for x in range(map_size): if num_pixels[y, x] > pixels_thresh: val = q["s_" + str(y) + "_" + str(x)] rv = None if val == factors_unary[segment_cnt].values[0]: rv = 0 else: rv = 1 labels_infer[y, x] = rv segment_cnt += 1 # ------------------ labels_class = -1 * np.ones([map_size, map_size], dtype=np.int) for y in range(map_size - 1): for x in range(map_size - 1): if num_pixels[y, x] > pixels_thresh: # label as the class with the highest probability if prob[y, x, 0] >= 0.5: labels_class[y, x] = 0 else: labels_class[y, x] = 1 # count correct pixels cnt_corr = np.sum( np.logical_and(labels_gt == labels_infer, labels_gt != -1)) print('Accuracy = ', cnt_corr / np.sum(labels_gt != -1)) num_incorrect += np.sum(labels_gt != -1) - cnt_corr # transfer results for segments onto image labels_infer_im = -1 * np.ones_like(labels_gt_im) labels_class_im = -1 * np.ones_like(labels_gt_im) for y in range(map_size - 1): for x in range(map_size - 1): if labels_infer[y, x] >= 0: cur_seg = y * map_size + x cur_pixels = np.nonzero(segments_im == cur_seg) labels_infer_im[cur_pixels] = labels_infer[y, x] labels_class_im[cur_pixels] = labels_class[y, x] # class 0 - green, class 1 - red in BGR colors = np.array([[0, 255, 0], [0, 0, 255]], dtype=np.uint8) image_infer = image.copy() image_class = image.copy() image_gt = image.copy() # color pixels according to label for l in range(2): image_infer[labels_infer_im == l] = colors[l] image_class[labels_class_im == l] = colors[l] image_gt[labels_gt_im == l] = colors[l] # show inferred, classified, and gt image by blending the original image with the colored one image_infer_vis = (0.75 * image + 0.25 * image_infer).astype(np.uint8) cv2.imshow('inferred', image_infer_vis) image_class_vis = (0.75 * image + 0.25 * image_class).astype(np.uint8) cv2.imshow('classified', image_class_vis) image_gt_vis = (0.75 * image + 0.25 * image_gt).astype(np.uint8) cv2.imshow('ground truth', image_gt_vis) # uncomment to stop after each image # cv2.waitKey() cv2.waitKey(10) print('Incorrectly inferred ', num_incorrect, ' segments')
class TestGibbsSampling(unittest.TestCase): def setUp(self): # A test Bayesian model diff_cpd = TabularCPD('diff', 2, [[0.6], [0.4]]) intel_cpd = TabularCPD('intel', 2, [[0.7], [0.3]]) grade_cpd = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25, 0.08, 0.3], [0.3, 0.7, 0.02, 0.2]], evidence=['diff', 'intel'], evidence_card=[2, 2]) self.bayesian_model = BayesianModel() self.bayesian_model.add_nodes_from(['diff', 'intel', 'grade']) self.bayesian_model.add_edges_from([('diff', 'grade'), ('intel', 'grade')]) self.bayesian_model.add_cpds(diff_cpd, intel_cpd, grade_cpd) # A test Markov model self.markov_model = MarkovModel([('A', 'B'), ('C', 'B'), ('B', 'D')]) factor_ab = DiscreteFactor(['A', 'B'], [2, 3], [1, 2, 3, 4, 5, 6]) factor_cb = DiscreteFactor(['C', 'B'], [4, 3], [3, 1, 4, 5, 7, 8, 1, 3, 10, 4, 5, 6]) factor_bd = DiscreteFactor(['B', 'D'], [3, 2], [5, 7, 2, 1, 9, 3]) self.markov_model.add_factors(factor_ab, factor_cb, factor_bd) self.gibbs = GibbsSampling(self.bayesian_model) def tearDown(self): del self.bayesian_model del self.markov_model @patch('pgmpy.sampling.GibbsSampling._get_kernel_from_bayesian_model', autospec=True) @patch('pgmpy.models.MarkovChain.__init__', autospec=True) def test_init_bayesian_model(self, init, get_kernel): model = MagicMock(spec_set=BayesianModel) gibbs = GibbsSampling(model) init.assert_called_once_with(gibbs) get_kernel.assert_called_once_with(gibbs, model) @patch('pgmpy.sampling.GibbsSampling._get_kernel_from_markov_model', autospec=True) def test_init_markov_model(self, get_kernel): model = MagicMock(spec_set=MarkovModel) gibbs = GibbsSampling(model) get_kernel.assert_called_once_with(gibbs, model) def test_get_kernel_from_bayesian_model(self): gibbs = GibbsSampling() gibbs._get_kernel_from_bayesian_model(self.bayesian_model) self.assertListEqual(list(gibbs.variables), self.bayesian_model.nodes()) self.assertDictEqual(gibbs.cardinalities, { 'diff': 2, 'intel': 2, 'grade': 3 }) def test_get_kernel_from_markov_model(self): gibbs = GibbsSampling() gibbs._get_kernel_from_markov_model(self.markov_model) self.assertListEqual(list(gibbs.variables), self.markov_model.nodes()) self.assertDictEqual(gibbs.cardinalities, { 'A': 2, 'B': 3, 'C': 4, 'D': 2 }) def test_sample(self): start_state = [State('diff', 0), State('intel', 0), State('grade', 0)] sample = self.gibbs.sample(start_state, 2) self.assertEquals(len(sample), 2) self.assertEquals(len(sample.columns), 3) self.assertIn('diff', sample.columns) self.assertIn('intel', sample.columns) self.assertIn('grade', sample.columns) self.assertTrue(set(sample['diff']).issubset({0, 1})) self.assertTrue(set(sample['intel']).issubset({0, 1})) self.assertTrue(set(sample['grade']).issubset({0, 1, 2})) @patch("pgmpy.sampling.GibbsSampling.random_state", autospec=True) def test_sample_less_arg(self, random_state): self.gibbs.state = None random_state.return_value = [ State('diff', 0), State('intel', 0), State('grade', 0) ] sample = self.gibbs.sample(size=2) random_state.assert_called_once_with(self.gibbs) self.assertEqual(len(sample), 2) def test_generate_sample(self): start_state = [State('diff', 0), State('intel', 0), State('grade', 0)] gen = self.gibbs.generate_sample(start_state, 2) samples = [sample for sample in gen] self.assertEqual(len(samples), 2) self.assertEqual( {samples[0][0].var, samples[0][1].var, samples[0][2].var}, {'diff', 'intel', 'grade'}) self.assertEqual( {samples[1][0].var, samples[1][1].var, samples[1][2].var}, {'diff', 'intel', 'grade'}) @patch("pgmpy.sampling.GibbsSampling.random_state", autospec=True) def test_generate_sample_less_arg(self, random_state): self.gibbs.state = None gen = self.gibbs.generate_sample(size=2) samples = [sample for sample in gen] random_state.assert_called_once_with(self.gibbs) self.assertEqual(len(samples), 2)
class TestInferenceBase(unittest.TestCase): def setUp(self): self.bayesian = BayesianModel([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')]) a_cpd = TabularCPD('a', 2, [[0.4, 0.6]]) b_cpd = TabularCPD('b', 2, [[0.2, 0.4], [0.3, 0.4]], evidence='a', evidence_card=[2]) c_cpd = TabularCPD('c', 2, [[0.1, 0.2], [0.3, 0.4]], evidence='b', evidence_card=[2]) d_cpd = TabularCPD('d', 2, [[0.4, 0.3], [0.2, 0.1]], evidence='c', evidence_card=[2]) e_cpd = TabularCPD('e', 2, [[0.3, 0.2], [0.4, 0.1]], evidence='d', evidence_card=[2]) self.bayesian.add_cpds(a_cpd, b_cpd, c_cpd, d_cpd, e_cpd) self.markov = MarkovModel([('a', 'b'), ('b', 'd'), ('a', 'c'), ('c', 'd')]) factor_1 = Factor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])) factor_2 = Factor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])) factor_3 = Factor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])) factor_4 = Factor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) self.markov.add_factors(factor_1, factor_2, factor_3, factor_4) def test_bayesian_inference_init(self): infer_bayesian = Inference(self.bayesian) self.assertEqual(set(infer_bayesian.variables), {'a', 'b', 'c', 'd', 'e'}) self.assertEqual(infer_bayesian.cardinality, { 'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 2 }) self.assertIsInstance(infer_bayesian.factors, defaultdict) self.assertEqual( set(infer_bayesian.factors['a']), set([ self.bayesian.get_cpds('a').to_factor(), self.bayesian.get_cpds('b').to_factor() ])) self.assertEqual( set(infer_bayesian.factors['b']), set([ self.bayesian.get_cpds('b').to_factor(), self.bayesian.get_cpds('c').to_factor() ])) self.assertEqual( set(infer_bayesian.factors['c']), set([ self.bayesian.get_cpds('c').to_factor(), self.bayesian.get_cpds('d').to_factor() ])) self.assertEqual( set(infer_bayesian.factors['d']), set([ self.bayesian.get_cpds('d').to_factor(), self.bayesian.get_cpds('e').to_factor() ])) self.assertEqual(set(infer_bayesian.factors['e']), set([self.bayesian.get_cpds('e').to_factor()])) def test_markov_inference_init(self): infer_markov = Inference(self.markov) self.assertEqual(set(infer_markov.variables), {'a', 'b', 'c', 'd'}) self.assertEqual(infer_markov.cardinality, { 'a': 2, 'b': 2, 'c': 2, 'd': 2 }) self.assertEqual( infer_markov.factors, { 'a': [ Factor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])), Factor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])) ], 'b': [ Factor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])), Factor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])) ], 'c': [ Factor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])), Factor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) ], 'd': [ Factor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])), Factor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) ] })
def setUp(self): self.maxDiff = None variables = [ "kid", "bowel-problem", "dog-out", "family-out", "hear-bark", "light-on", ] edges = [ ["family-out", "dog-out"], ["bowel-problem", "dog-out"], ["family-out", "light-on"], ["dog-out", "hear-bark"], ] cpds = { "kid": np.array([[0.3], [0.7]]), "bowel-problem": np.array([[0.01], [0.99]]), "dog-out": np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), "family-out": np.array([[0.15], [0.85]]), "hear-bark": np.array([[0.7, 0.3], [0.01, 0.99]]), "light-on": np.array([[0.6, 0.4], [0.05, 0.95]]), } states = { "kid": ["true", "false"], "bowel-problem": ["true", "false"], "dog-out": ["true", "false"], "family-out": ["true", "false"], "hear-bark": ["true", "false"], "light-on": ["true", "false"], } parents = { "kid": [], "bowel-problem": [], "dog-out": ["bowel-problem", "family-out"], "family-out": [], "hear-bark": ["dog-out"], "light-on": ["family-out"], } self.bayesmodel = BayesianModel() self.bayesmodel.add_nodes_from(variables) self.bayesmodel.add_edges_from(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD( var, len(states[var]), values, evidence=parents[var], evidence_card=[ len(states[evidence_var]) for evidence_var in parents[var] ], ) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {("var_0", "var_1"), ("var_0", "var_2"), ("var_1", "var_2")} self.markovmodel = MarkovModel(edges) tables = [ (["var_0", "var_1"], ["4.000", "2.400", "1.000", "0.000"]), ( ["var_0", "var_1", "var_2"], [ "2.2500", "3.2500", "3.7500", "0.0000", "0.0000", "10.0000", "1.8750", "4.0000", "3.3330", "2.0000", "2.0000", "3.4000", ], ), ] domain = {"var_1": "2", "var_2": "3", "var_0": "2"} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = DiscreteFactor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel)
class TestUAIWriter(unittest.TestCase): def setUp(self): self.maxDiff = None variables = [ "kid", "bowel-problem", "dog-out", "family-out", "hear-bark", "light-on", ] edges = [ ["family-out", "dog-out"], ["bowel-problem", "dog-out"], ["family-out", "light-on"], ["dog-out", "hear-bark"], ] cpds = { "kid": np.array([[0.3], [0.7]]), "bowel-problem": np.array([[0.01], [0.99]]), "dog-out": np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), "family-out": np.array([[0.15], [0.85]]), "hear-bark": np.array([[0.7, 0.3], [0.01, 0.99]]), "light-on": np.array([[0.6, 0.4], [0.05, 0.95]]), } states = { "kid": ["true", "false"], "bowel-problem": ["true", "false"], "dog-out": ["true", "false"], "family-out": ["true", "false"], "hear-bark": ["true", "false"], "light-on": ["true", "false"], } parents = { "kid": [], "bowel-problem": [], "dog-out": ["bowel-problem", "family-out"], "family-out": [], "hear-bark": ["dog-out"], "light-on": ["family-out"], } self.bayesmodel = BayesianModel() self.bayesmodel.add_nodes_from(variables) self.bayesmodel.add_edges_from(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD( var, len(states[var]), values, evidence=parents[var], evidence_card=[ len(states[evidence_var]) for evidence_var in parents[var] ], ) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {("var_0", "var_1"), ("var_0", "var_2"), ("var_1", "var_2")} self.markovmodel = MarkovModel(edges) tables = [ (["var_0", "var_1"], ["4.000", "2.400", "1.000", "0.000"]), ( ["var_0", "var_1", "var_2"], [ "2.2500", "3.2500", "3.7500", "0.0000", "0.0000", "10.0000", "1.8750", "4.0000", "3.3330", "2.0000", "2.0000", "3.4000", ], ), ] domain = {"var_1": "2", "var_2": "3", "var_0": "2"} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = DiscreteFactor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel) def test_bayes_model(self): self.expected_bayes_file = """BAYES 6 2 2 2 2 2 2 6 1 0 3 2 0 1 1 2 2 1 3 1 4 2 2 5 2 0.01 0.99 8 0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7 2 0.15 0.85 4 0.7 0.3 0.01 0.99 2 0.3 0.7 4 0.6 0.4 0.05 0.95""" self.assertEqual(str(self.bayeswriter.__str__()), str(self.expected_bayes_file)) def test_markov_model(self): self.expected_markov_file = """MARKOV 3 2 2 3 2 2 0 1 3 0 1 2 4 4.0 2.4 1.0 0.0 12 2.25 3.25 3.75 0.0 0.0 10.0 1.875 4.0 3.333 2.0 2.0 3.4""" self.assertEqual( str(self.markovwriter.__str__()), str(self.expected_markov_file) )
# Computing the cluster belief according the formula stated # above cluster_belief = psi * messages_prod_factor # As cluster belief represents a probability distribution in # this case, thus it should be normalized cluster_belief.normalize() return cluster_belief phi_a_b = Factor(['a', 'b'], [2, 2], [10, 0.1, 0.1, 10]) phi_a_c = Factor(['a', 'c'], [2, 2], [5, 0.2, 0.2, 5]) phi_c_d = Factor(['c', 'd'], [2, 2], [0.5, 1, 20, 2.5]) phi_d_b = Factor(['d', 'b'], [2, 2], [5, 0.2, 0.2, 5]) # Cluster 1 is a MarkovModel A--B cluster_1 = MarkovModel([('a', 'b')]) # Adding factors cluster_1.add_factors(phi_a_b) # Cluster 2 is a MarkovModel A--C--D--B cluster_2 = MarkovModel([('a', 'c'), ('c', 'd'), ('d', 'b')]) # Adding factors cluster_2.add_factors(phi_a_c, phi_c_d, phi_d_b) # Message passed from cluster 1 -> 2 should the M-Projection of psi1 # as the sepset of cluster 1 and 2 is A, B thus there is no need to # marginalize psi1 delta_1_2 = compute_message(cluster_1, cluster_2)
from pgmpy.models import MarkovModel mm = MarkovModel() mm.add_nodes_from(['A', 'B', 'C']) mm.add_edges_from([('A', 'B'), ('B', 'C'), ('C', 'A')]) mm.add_factors(phi1, phi2, phi3) factor_graph_from_mm = mm.to_factor_graph() # While converting a markov model into factor graph, factor nodes # would be automatically added the factor nodes would be in the # form of phi_node1_node2_... factor_graph_from_mm.nodes() factor_graph.edges() # FactorGraph to MarkovModel phi = Factor(['A', 'B', 'C'], [2, 2, 2], np.random.rand(8)) factor_graph = FactorGraph() factor_graph.add_nodes_from(['A', 'B', 'C', 'phi']) factor_graph.add_edges_from([('A', 'phi'), ('B', 'phi'), ('C', 'phi')])
from pgmpy.models import MarkovModel mm = MarkovModel() mm.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']) mm.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'), ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'), ('x4', 'x7'), ('x5', 'x7')]) mm.get_local_independencies()
" ....................................... " -4- # --- factor Division " f(a,b) / f(b) " factor1 = Factor(['a','b'], [2,3], range(6)) factor2 = Factor(['b'], [3], range(3)) factor_divid = factor1 / factor2 # Represent Markov Network Model from pgmpy.models import MarkovModel model = MarkovModel([('A', 'B'), ('B', 'C')]) model.add_node('D') model.add_edges_from([('C', 'D'), ('D', 'A')]) # --- Define factors to associate with model from pgmpy.factors import Factor factor_a_b = Factor(variables=['A', 'B'], cardibality=[2,2], values=[90. 100, 1, 10]) factor_b_c = Factor(variables=['B', 'C'], cardibality=[2,2], values=[10. 80, 70, 20]) factor_c_d = Factor(variables=['C', 'D'], cardibality=[2,2], values=[50. 120, 10, 10]) factor_d_a = Factor(variables=['D', 'A'], cardibality=[2,2], values=[20. 80, 50, 40]) # --- Add factors to model model.add_factors(factor_a_b, factor_b_c, factor_c_d, factor_d_a) model.get_factors() " [<Factor representing phi(A:2, B:2) at aidfoaiudn;aksndf> " " [<Factor representing phi(B:2, C:2) at aidfoaasdfsdfn;aksndf> " " [<Factor representing phi(C:2, D:2) at aidfoaiud234234sndf> " " [<Factor representing phi(D:2, A:2) at aawjdfblasjiudn;aksndf> "
# THIS CODE HAS TO BE RUN ON PYTHON 2 # Otherwise, you will get wrong results from pgmpy.models import MarkovModel from pgmpy.factors.discrete import DiscreteFactor from pgmpy.inference import BeliefPropagation import numpy as np # Construct a graph PGM = MarkovModel() PGM.add_nodes_from(['w1', 'w2', 'w3']) PGM.add_edges_from([('w1', 'w2'), ('w2', 'w3')]) tr_matrix = np.array([1, 10, 3, 2, 1, 5, 3, 3, 2]) tr_matrix = np.array([1, 2, 3, 10, 1, 3, 3, 5, 2]).reshape(3, 3).T.reshape(-1) phi = [DiscreteFactor(edge, [3, 3], tr_matrix) for edge in PGM.edges()] print(phi[0]) print(phi[1]) PGM.add_factors(*phi) # Calculate partition funtion Z = PGM.get_partition_function() print('The partition function is:', Z) # Calibrate the click belief_propagation = BeliefPropagation(PGM) belief_propagation.calibrate() # Output calibration result, which you should get query = belief_propagation.query(variables=['w2']) print('After calibration you should get the following mu(S):\n', query * Z)
def __init__(self, m, v=1, y_edges=[], lambda_y_edges=[], lambda_edges=[], allow_abstentions=True, triplets=None, triplet_seed=0): '''Initialize the LabelModel with a graph G. m: number of LF's v: number of Y tasks y_edges: edges between the tasks. (i, j) in y_edges means that there is an edge between y_i and y_j. lambda_y_edges: edges between LF's and tasks. (i, j) in lambda_y_edges means that there is an edge between lambda_i and y_j. If this list is empty, assume that all labeling functions are connected to Y_0. lambda_edges: edges between LF's. (i, j) in lambda_edges means that there is an edge between lambda_i and lambda_j. allow_abstentions: if True, allow abstentions in L_train. triplets: if specified, use these triplets triplet_seed: if triplets not specified, randomly shuffle the nodes with this seed when generating triplets ''' if lambda_y_edges == []: lambda_y_edges = [(i, 0) for i in range(m)] G = MarkovModel() # Add LF nodes G.add_nodes_from(['lambda_{}'.format(i) for i in range(m)]) G.add_nodes_from(['Y_{}'.format(i) for i in range(v)]) # Add edges G.add_edges_from([('Y_{}'.format(start), 'Y_{}'.format(end)) for start, end in y_edges]) G.add_edges_from([('lambda_{}'.format(start), 'Y_{}'.format(end)) for start, end in lambda_y_edges]) G.add_edges_from([('lambda_{}'.format(start), 'lambda_{}'.format(end)) for start, end in lambda_edges]) self.fully_independent_case = lambda_edges == [] self.m = m if m < 3: raise NotImplementedError( "Triplet method needs at least three LF's to run.") self.v = v self.G = G self.junction_tree = self.G.to_junction_tree() self.nodes = sorted(list(self.G.nodes)) self.triplet_seed = triplet_seed if triplet_seed is not None: random.seed(triplet_seed) random.shuffle(self.nodes) self.separator_sets = set([ tuple(sorted(list((set(clique1).intersection(set(clique2)))))) for clique1, clique2 in self.junction_tree.edges ]) self.allow_abstentions = allow_abstentions self.triplets = triplets if not self._check(): raise NotImplementedError( 'Cannot run triplet method for specified graph.')
class TestUAIWriter(unittest.TestCase): def setUp(self): self.maxDiff = None edges = [['family-out', 'dog-out'], ['bowel-problem', 'dog-out'], ['family-out', 'light-on'], ['dog-out', 'hear-bark']] cpds = { 'bowel-problem': np.array([[0.01], [0.99]]), 'dog-out': np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), 'family-out': np.array([[0.15], [0.85]]), 'hear-bark': np.array([[0.7, 0.3], [0.01, 0.99]]), 'light-on': np.array([[0.6, 0.4], [0.05, 0.95]]) } states = { 'bowel-problem': ['true', 'false'], 'dog-out': ['true', 'false'], 'family-out': ['true', 'false'], 'hear-bark': ['true', 'false'], 'light-on': ['true', 'false'] } parents = { 'bowel-problem': [], 'dog-out': ['bowel-problem', 'family-out'], 'family-out': [], 'hear-bark': ['dog-out'], 'light-on': ['family-out'] } self.bayesmodel = BayesianModel(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD(var, len(states[var]), values, evidence=parents[var], evidence_card=[ len(states[evidence_var]) for evidence_var in parents[var] ]) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {('var_0', 'var_1'), ('var_0', 'var_2'), ('var_1', 'var_2')} self.markovmodel = MarkovModel(edges) tables = [(['var_0', 'var_1'], ['4.000', '2.400', '1.000', '0.000']), (['var_0', 'var_1', 'var_2'], [ '2.2500', '3.2500', '3.7500', '0.0000', '0.0000', '10.0000', '1.8750', '4.0000', '3.3330', '2.0000', '2.0000', '3.4000' ])] domain = {'var_1': '2', 'var_2': '3', 'var_0': '2'} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = Factor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel) def test_bayes_model(self): self.expected_bayes_file = """BAYES 5 2 2 2 2 2 5 1 0 3 2 0 1 1 2 2 1 3 2 2 4 2 0.01 0.99 8 0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7 2 0.15 0.85 4 0.7 0.3 0.01 0.99 4 0.6 0.4 0.05 0.95""" self.assertEqual(str(self.bayeswriter.__str__()), str(self.expected_bayes_file)) def test_markov_model(self): self.expected_markov_file = """MARKOV 3 2 2 3 2 2 0 1 3 0 1 2 4 4.0 2.4 1.0 0.0 12 2.25 3.25 3.75 0.0 0.0 10.0 1.875 4.0 3.333 2.0 2.0 3.4""" self.assertEqual(str(self.markovwriter.__str__()), str(self.expected_markov_file))
class TestUAIWriter(unittest.TestCase): def setUp(self): self.maxDiff = None edges = [['family-out', 'dog-out'], ['bowel-problem', 'dog-out'], ['family-out', 'light-on'], ['dog-out', 'hear-bark']] cpds = {'bowel-problem': np.array([[0.01], [0.99]]), 'dog-out': np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), 'family-out': np.array([[0.15], [0.85]]), 'hear-bark': np.array([[0.7, 0.3], [0.01, 0.99]]), 'light-on': np.array([[0.6, 0.4], [0.05, 0.95]])} states = {'bowel-problem': ['true', 'false'], 'dog-out': ['true', 'false'], 'family-out': ['true', 'false'], 'hear-bark': ['true', 'false'], 'light-on': ['true', 'false']} parents = {'bowel-problem': [], 'dog-out': ['bowel-problem', 'family-out'], 'family-out': [], 'hear-bark': ['dog-out'], 'light-on': ['family-out']} self.bayesmodel = BayesianModel(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD(var, len(states[var]), values, evidence=parents[var], evidence_card=[len(states[evidence_var]) for evidence_var in parents[var]]) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {('var_0', 'var_1'), ('var_0', 'var_2'), ('var_1', 'var_2')} self.markovmodel = MarkovModel(edges) tables = [(['var_0', 'var_1'], ['4.000', '2.400', '1.000', '0.000']), (['var_0', 'var_1', 'var_2'], ['2.2500', '3.2500', '3.7500', '0.0000', '0.0000', '10.0000', '1.8750', '4.0000', '3.3330', '2.0000', '2.0000', '3.4000'])] domain = {'var_1': '2', 'var_2': '3', 'var_0': '2'} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = DiscreteFactor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel) def test_bayes_model(self): self.expected_bayes_file = """BAYES 5 2 2 2 2 2 5 1 0 3 2 0 1 1 2 2 1 3 2 2 4 2 0.01 0.99 8 0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7 2 0.15 0.85 4 0.7 0.3 0.01 0.99 4 0.6 0.4 0.05 0.95""" self.assertEqual(str(self.bayeswriter.__str__()), str(self.expected_bayes_file)) def test_markov_model(self): self.expected_markov_file = """MARKOV 3 2 2 3 2 2 0 1 3 0 1 2 4 4.0 2.4 1.0 0.0 12 2.25 3.25 3.75 0.0 0.0 10.0 1.875 4.0 3.333 2.0 2.0 3.4""" self.assertEqual(str(self.markovwriter.__str__()), str(self.expected_markov_file))
import numpy as np import pandas as pd from pgmpy.models import MarkovModel from pgmpy.estimators import MaximumLikelihoodEstimator # Generating random data raw_data = np.random.randint(low=0, high=2, size=(1000, 2)) data = pd.DataFrame(raw_data, columns=['X', 'Y']) model = MarkovModel() model.fit(data, estimator=MaximumLikelihoodEstimator) model.get_factors() model.nodes() model.edges()
import numpy as np import pandas as pd from pgmpy.models import MarkovModel from pgmpy.estimators import BayesianEstimator # Generating random data raw_data = np.random.randint(low=0, high=2, size=(1000, 2)) data = pd.DataFrame(raw_data, columns=['X', 'Y']) model = MarkovModel() model.fit(data, estimator=BayesianEstimator) model.get_factors() model.get_nodes() model.get_edges()
class TestInferenceBase(unittest.TestCase): def setUp(self): self.bayesian = BayesianModel([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e')]) a_cpd = TabularCPD('a', 2, [[0.4, 0.6]]) b_cpd = TabularCPD('b', 2, [[0.2, 0.4], [0.8, 0.6]], evidence=['a'], evidence_card=[2]) c_cpd = TabularCPD('c', 2, [[0.1, 0.2], [0.9, 0.8]], evidence=['b'], evidence_card=[2]) d_cpd = TabularCPD('d', 2, [[0.4, 0.3], [0.6, 0.7]], evidence=['c'], evidence_card=[2]) e_cpd = TabularCPD('e', 2, [[0.3, 0.2], [0.7, 0.8]], evidence=['d'], evidence_card=[2]) self.bayesian.add_cpds(a_cpd, b_cpd, c_cpd, d_cpd, e_cpd) self.markov = MarkovModel([('a', 'b'), ('b', 'd'), ('a', 'c'), ('c', 'd')]) factor_1 = DiscreteFactor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])) factor_2 = DiscreteFactor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])) factor_3 = DiscreteFactor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])) factor_4 = DiscreteFactor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40])) self.markov.add_factors(factor_1, factor_2, factor_3, factor_4) def test_bayesian_inference_init(self): infer_bayesian = Inference(self.bayesian) self.assertEqual(set(infer_bayesian.variables), {'a', 'b', 'c', 'd', 'e'}) self.assertEqual(infer_bayesian.cardinality, {'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 2}) self.assertIsInstance(infer_bayesian.factors, defaultdict) self.assertEqual(set(infer_bayesian.factors['a']), set([self.bayesian.get_cpds('a').to_factor(), self.bayesian.get_cpds('b').to_factor()])) self.assertEqual(set(infer_bayesian.factors['b']), set([self.bayesian.get_cpds('b').to_factor(), self.bayesian.get_cpds('c').to_factor()])) self.assertEqual(set(infer_bayesian.factors['c']), set([self.bayesian.get_cpds('c').to_factor(), self.bayesian.get_cpds('d').to_factor()])) self.assertEqual(set(infer_bayesian.factors['d']), set([self.bayesian.get_cpds('d').to_factor(), self.bayesian.get_cpds('e').to_factor()])) self.assertEqual(set(infer_bayesian.factors['e']), set([self.bayesian.get_cpds('e').to_factor()])) def test_markov_inference_init(self): infer_markov = Inference(self.markov) self.assertEqual(set(infer_markov.variables), {'a', 'b', 'c', 'd'}) self.assertEqual(infer_markov.cardinality, {'a': 2, 'b': 2, 'c': 2, 'd': 2}) self.assertEqual(infer_markov.factors, {'a': [DiscreteFactor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])), DiscreteFactor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20]))], 'b': [DiscreteFactor(['a', 'b'], [2, 2], np.array([100, 1, 1, 100])), DiscreteFactor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1]))], 'c': [DiscreteFactor(['a', 'c'], [2, 2], np.array([40, 30, 100, 20])), DiscreteFactor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40]))], 'd': [DiscreteFactor(['b', 'd'], [2, 2], np.array([1, 100, 100, 1])), DiscreteFactor(['c', 'd'], [2, 2], np.array([60, 60, 40, 40]))]})
class TestGibbsSampling(unittest.TestCase): def setUp(self): # A test Bayesian model diff_cpd = TabularCPD('diff', 2, [[0.6], [0.4]]) intel_cpd = TabularCPD('intel', 2, [[0.7], [0.3]]) grade_cpd = TabularCPD('grade', 3, [[0.3, 0.05, 0.9, 0.5], [0.4, 0.25, 0.08, 0.3], [0.3, 0.7, 0.02, 0.2]], evidence=['diff', 'intel'], evidence_card=[2, 2]) self.bayesian_model = BayesianModel() self.bayesian_model.add_nodes_from(['diff', 'intel', 'grade']) self.bayesian_model.add_edges_from([('diff', 'grade'), ('intel', 'grade')]) self.bayesian_model.add_cpds(diff_cpd, intel_cpd, grade_cpd) # A test Markov model self.markov_model = MarkovModel([('A', 'B'), ('C', 'B'), ('B', 'D')]) factor_ab = Factor(['A', 'B'], [2, 3], [1, 2, 3, 4, 5, 6]) factor_cb = Factor(['C', 'B'], [4, 3], [3, 1, 4, 5, 7, 8, 1, 3, 10, 4, 5, 6]) factor_bd = Factor(['B', 'D'], [3, 2], [5, 7, 2, 1, 9, 3]) self.markov_model.add_factors(factor_ab, factor_cb, factor_bd) self.gibbs = GibbsSampling(self.bayesian_model) def tearDown(self): del self.bayesian_model del self.markov_model @patch('pgmpy.inference.Sampling.GibbsSampling._get_kernel_from_bayesian_model', autospec=True) @patch('pgmpy.models.MarkovChain.__init__', autospec=True) def test_init_bayesian_model(self, init, get_kernel): model = MagicMock(spec_set=BayesianModel) gibbs = GibbsSampling(model) init.assert_called_once_with(gibbs) get_kernel.assert_called_once_with(gibbs, model) @patch('pgmpy.inference.Sampling.GibbsSampling._get_kernel_from_markov_model', autospec=True) def test_init_markov_model(self, get_kernel): model = MagicMock(spec_set=MarkovModel) gibbs = GibbsSampling(model) get_kernel.assert_called_once_with(gibbs, model) def test_get_kernel_from_bayesian_model(self): gibbs = GibbsSampling() gibbs._get_kernel_from_bayesian_model(self.bayesian_model) self.assertListEqual(list(gibbs.variables), self.bayesian_model.nodes()) self.assertDictEqual(gibbs.cardinalities, {'diff': 2, 'intel': 2, 'grade': 3}) def test_get_kernel_from_markov_model(self): gibbs = GibbsSampling() gibbs._get_kernel_from_markov_model(self.markov_model) self.assertListEqual(list(gibbs.variables), self.markov_model.nodes()) self.assertDictEqual(gibbs.cardinalities, {'A': 2, 'B': 3, 'C': 4, 'D': 2}) def test_sample(self): start_state = [State('diff', 0), State('intel', 0), State('grade', 0)] sample = self.gibbs.sample(start_state, 2) self.assertEquals(len(sample), 2) self.assertEquals(len(sample.columns), 3) self.assertIn('diff', sample.columns) self.assertIn('intel', sample.columns) self.assertIn('grade', sample.columns) self.assertTrue(set(sample['diff']).issubset({0, 1})) self.assertTrue(set(sample['intel']).issubset({0, 1})) self.assertTrue(set(sample['grade']).issubset({0, 1, 2})) @patch("pgmpy.inference.Sampling.GibbsSampling.random_state", autospec=True) def test_sample_less_arg(self, random_state): self.gibbs.state = None random_state.return_value = [State('diff', 0), State('intel', 0), State('grade', 0)] sample = self.gibbs.sample(size=2) random_state.assert_called_once_with(self.gibbs) self.assertEqual(len(sample), 2) def test_generate_sample(self): start_state = [State('diff', 0), State('intel', 0), State('grade', 0)] gen = self.gibbs.generate_sample(start_state, 2) samples = [sample for sample in gen] self.assertEqual(len(samples), 2) self.assertEqual({samples[0][0].var, samples[0][1].var, samples[0][2].var}, {'diff', 'intel', 'grade'}) self.assertEqual({samples[1][0].var, samples[1][1].var, samples[1][2].var}, {'diff', 'intel', 'grade'}) @patch("pgmpy.inference.Sampling.GibbsSampling.random_state", autospec=True) def test_generate_sample_less_arg(self, random_state): self.gibbs.state = None gen = self.gibbs.generate_sample(size=2) samples = [sample for sample in gen] random_state.assert_called_once_with(self.gibbs) self.assertEqual(len(samples), 2)
class TestVariableEliminationMarkov(unittest.TestCase): def setUp(self): # It is just a moralised version of the above Bayesian network so all the results are same. Only factors # are under consideration for inference so this should be fine. self.markov_model = MarkovModel([ ("A", "J"), ("R", "J"), ("J", "Q"), ("J", "L"), ("G", "L"), ("A", "R"), ("J", "G"), ]) factor_a = TabularCPD("A", 2, values=[[0.2], [0.8]]).to_factor() factor_r = TabularCPD("R", 2, values=[[0.4], [0.6]]).to_factor() factor_j = TabularCPD( "J", 2, values=[[0.9, 0.6, 0.7, 0.1], [0.1, 0.4, 0.3, 0.9]], evidence=["A", "R"], evidence_card=[2, 2], ).to_factor() factor_q = TabularCPD("Q", 2, values=[[0.9, 0.2], [0.1, 0.8]], evidence=["J"], evidence_card=[2]).to_factor() factor_l = TabularCPD( "L", 2, values=[[0.9, 0.45, 0.8, 0.1], [0.1, 0.55, 0.2, 0.9]], evidence=["J", "G"], evidence_card=[2, 2], ).to_factor() factor_g = TabularCPD("G", 2, [[0.6], [0.4]]).to_factor() self.markov_model.add_factors(factor_a, factor_r, factor_j, factor_q, factor_l, factor_g) self.markov_inference = VariableElimination(self.markov_model) # All the values that are used for comparision in the all the tests are # found using SAMIAM (assuming that it is correct ;)) def test_query_single_variable(self): query_result = self.markov_inference.query(["J"]) self.assertEqual( query_result, DiscreteFactor(variables=["J"], cardinality=[2], values=np.array([0.416, 0.584])), ) def test_query_multiple_variable(self): query_result = self.markov_inference.query(["Q", "J"]) self.assertEqual( query_result, DiscreteFactor( variables=["Q", "J"], cardinality=[2, 2], values=np.array([[0.3744, 0.1168], [0.0416, 0.4672]]), ), ) def test_query_single_variable_with_evidence(self): query_result = self.markov_inference.query(variables=["J"], evidence={ "A": 0, "R": 1 }) self.assertEqual( query_result, DiscreteFactor(variables=["J"], cardinality=[2], values=[0.6, 0.4]), ) def test_query_multiple_variable_with_evidence(self): query_result = self.markov_inference.query(variables=["J", "Q"], evidence={ "A": 0, "R": 0, "G": 0, "L": 1 }) self.assertEqual( query_result, DiscreteFactor( variables=["Q", "J"], cardinality=[2, 2], values=np.array([[0.081, 0.004], [0.009, 0.016]]), ), ) def test_query_multiple_times(self): # This just tests that the models are not getting modified while querying them query_result = self.markov_inference.query(["J"]) query_result = self.markov_inference.query(["J"]) self.assertEqual( query_result, DiscreteFactor(variables=["J"], cardinality=[2], values=np.array([0.416, 0.584])), ) query_result = self.markov_inference.query(["Q", "J"]) query_result = self.markov_inference.query(["Q", "J"]) self.assertEqual( query_result, DiscreteFactor( variables=["Q", "J"], cardinality=[2, 2], values=np.array([[0.3744, 0.1168], [0.0416, 0.4672]]), ), ) query_result = self.markov_inference.query(variables=["J"], evidence={ "A": 0, "R": 1 }) query_result = self.markov_inference.query(variables=["J"], evidence={ "A": 0, "R": 1 }) self.assertEqual( query_result, DiscreteFactor(variables=["J"], cardinality=[2], values=[0.6, 0.4]), ) query_result = self.markov_inference.query(variables=["J", "Q"], evidence={ "A": 0, "R": 0, "G": 0, "L": 1 }) query_result = self.markov_inference.query(variables=["J", "Q"], evidence={ "A": 0, "R": 0, "G": 0, "L": 1 }) self.assertEqual( query_result, DiscreteFactor( variables=["Q", "J"], cardinality=[2, 2], values=np.array([[0.081, 0.004], [0.009, 0.016]]), ), ) def test_max_marginal(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(), 0.1659, decimal=4) def test_max_marginal_var(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(["G"]), 0.1659, decimal=4) def test_max_marginal_var1(self): np_test.assert_almost_equal(self.markov_inference.max_marginal( ["G", "R"]), 0.1659, decimal=4) def test_max_marginal_var2(self): np_test.assert_almost_equal(self.markov_inference.max_marginal( ["G", "R", "A"]), 0.1659, decimal=4) def test_map_query(self): map_query = self.markov_inference.map_query() self.assertDictEqual(map_query, { "A": 1, "R": 1, "J": 1, "Q": 1, "G": 0, "L": 0 }) def test_map_query_with_evidence(self): map_query = self.markov_inference.map_query(["A", "R", "L"], { "J": 0, "Q": 1, "G": 0 }) self.assertDictEqual(map_query, {"A": 1, "R": 0, "L": 0}) def test_induced_graph(self): induced_graph = self.markov_inference.induced_graph( ["G", "Q", "A", "J", "L", "R"]) result_edges = sorted([sorted(x) for x in induced_graph.edges()]) self.assertEqual( [ ["A", "J"], ["A", "R"], ["G", "J"], ["G", "L"], ["J", "L"], ["J", "Q"], ["J", "R"], ["L", "R"], ], result_edges, ) def test_induced_width(self): result_width = self.markov_inference.induced_width( ["G", "Q", "A", "J", "L", "R"]) self.assertEqual(2, result_width) def tearDown(self): del self.markov_inference del self.markov_model
def test_class_init_with_data_string(self): self.g = MarkovModel([("a", "b"), ("b", "c")]) self.assertListEqual(sorted(self.g.nodes()), ["a", "b", "c"]) self.assertListEqual(hf.recursive_sorted(self.g.edges()), [["a", "b"], ["b", "c"]])
def test_class_init_with_data_string(self): self.g = MarkovModel([('a', 'b'), ('b', 'c')]) self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c']) self.assertListEqual(hf.recursive_sorted(self.g.edges()), [['a', 'b'], ['b', 'c']])
class TestUndirectedGraphFactorOperations(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_add_factor_raises_error(self): self.graph.add_edges_from([ ("Alice", "Bob"), ("Bob", "Charles"), ("Charles", "Debbie"), ("Debbie", "Alice"), ]) factor = DiscreteFactor(["Alice", "Bob", "John"], [2, 2, 2], np.random.rand(8)) self.assertRaises(ValueError, self.graph.add_factors, factor) def test_add_single_factor(self): self.graph.add_nodes_from(["a", "b", "c"]) phi = DiscreteFactor(["a", "b"], [2, 2], range(4)) self.graph.add_factors(phi) six.assertCountEqual(self, self.graph.factors, [phi]) def test_add_multiple_factors(self): self.graph.add_nodes_from(["a", "b", "c"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) six.assertCountEqual(self, self.graph.factors, [phi1, phi2]) def test_get_factors(self): self.graph.add_nodes_from(["a", "b", "c"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) six.assertCountEqual(self, self.graph.get_factors(), []) self.graph.add_factors(phi1, phi2) six.assertCountEqual(self, self.graph.get_factors(), [phi1, phi2]) six.assertCountEqual(self, self.graph.get_factors("a"), [phi1]) def test_remove_single_factor(self): self.graph.add_nodes_from(["a", "b", "c"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.remove_factors(phi1) six.assertCountEqual(self, self.graph.factors, [phi2]) def test_remove_multiple_factors(self): self.graph.add_nodes_from(["a", "b", "c"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.remove_factors(phi1, phi2) six.assertCountEqual(self, self.graph.factors, []) def test_partition_function(self): self.graph.add_nodes_from(["a", "b", "c"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.graph.add_edges_from([("a", "b"), ("b", "c")]) self.assertEqual(self.graph.get_partition_function(), 22.0) def test_partition_function_raises_error(self): self.graph.add_nodes_from(["a", "b", "c", "d"]) phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4)) phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.get_partition_function) def tearDown(self): del self.graph
class TestMarkovModelMethods(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_get_cardinality(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {'a': 1, 'b': 2}) self.graph.remove_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4)) phi2 = Factor(['c', 'd'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertDictEqual(self.graph.get_cardinality(), { 'd': 2, 'a': 2, 'b': 2, 'c': 1 }) phi3 = Factor(['d', 'a'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi3) self.assertDictEqual(self.graph.get_cardinality(), { 'd': 1, 'c': 1, 'b': 2, 'a': 2 }) self.graph.remove_factors(phi1, phi2, phi3) self.assertDictEqual(self.graph.get_cardinality(), {}) def test_get_cardinality_check_cardinality(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.get_cardinality, check_cardinality=True) phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi2) self.assertRaises(ValueError, self.graph.get_cardinality, check_cardinality=True) phi3 = Factor(['c', 'd'], [2, 2], np.random.rand(4)) self.graph.add_factors(phi3) self.assertDictEqual( self.graph.get_cardinality(check_cardinality=True), { 'd': 2, 'c': 2, 'b': 2, 'a': 1 }) def test_check_model(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['c', 'b'], [3, 2], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.assertTrue(self.graph.check_model()) self.graph.remove_factors(phi1, phi4) phi1 = Factor(['a', 'b'], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1) self.assertTrue(self.graph.check_model()) def test_check_model1(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['b', 'c'], [3, 3], np.random.rand(9)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) phi3 = Factor(['c', 'a'], [4, 4], np.random.rand(16)) self.graph.add_factors(phi3) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi3) phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 3], np.random.rand(12)) self.graph.add_factors(phi2, phi3, phi4) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2, phi3, phi4) phi2 = Factor(['a', 'b'], [1, 3], np.random.rand(3)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) def test_check_model2(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4)) phi5 = Factor(['d', 'b'], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1, phi2, phi3, phi4, phi5) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5) def test_factor_graph(self): phi1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6)) phi2 = Factor(['Bob', 'Charles'], [2, 2], np.random.rand(4)) self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')]) self.graph.add_factors(phi1, phi2) factor_graph = self.graph.to_factor_graph() self.assertIsInstance(factor_graph, FactorGraph) self.assertListEqual( sorted(factor_graph.nodes()), ['Alice', 'Bob', 'Charles', 'phi_Alice_Bob', 'phi_Bob_Charles']) self.assertListEqual( hf.recursive_sorted(factor_graph.edges()), [['Alice', 'phi_Alice_Bob'], ['Bob', 'phi_Alice_Bob'], ['Bob', 'phi_Bob_Charles'], ['Charles', 'phi_Bob_Charles']]) self.assertListEqual(factor_graph.get_factors(), [phi1, phi2]) def test_factor_graph_raises_error(self): self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')]) self.assertRaises(ValueError, self.graph.to_factor_graph) def test_junction_tree(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) junction_tree = self.graph.to_junction_tree() self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()), [['a', 'b', 'd'], ['b', 'c', 'd']]) self.assertEqual(len(junction_tree.edges()), 1) def test_junction_tree_single_clique(self): self.graph.add_edges_from([('x1', 'x2'), ('x2', 'x3'), ('x1', 'x3')]) phi = [ Factor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges() ] self.graph.add_factors(*phi) junction_tree = self.graph.to_junction_tree() self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()), [['x1', 'x2', 'x3']]) factors = junction_tree.get_factors() self.assertEqual(factors[0], factor_product(*phi)) def test_markov_blanket(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertListEqual(self.graph.markov_blanket('a'), ['b']) self.assertListEqual(sorted(self.graph.markov_blanket('b')), ['a', 'c']) def test_local_independencies(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) independencies = self.graph.get_local_independencies() self.assertIsInstance(independencies, Independencies) self.assertEqual(independencies, Independencies(['a', 'c', 'b'])) def test_bayesian_model(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd']) self.assertTrue(nx.is_chordal(bm.to_undirected())) def tearDown(self): del self.graph
class TestMarkovModelMethods(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_get_cardinality(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {"a": 1, "b": 2}) self.graph.remove_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4)) phi2 = DiscreteFactor(["c", "d"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertDictEqual(self.graph.get_cardinality(), { "d": 2, "a": 2, "b": 2, "c": 1 }) phi3 = DiscreteFactor(["d", "a"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi3) self.assertDictEqual(self.graph.get_cardinality(), { "d": 1, "c": 1, "b": 2, "a": 2 }) self.graph.remove_factors(phi1, phi2, phi3) self.assertDictEqual(self.graph.get_cardinality(), {}) def test_get_cardinality_with_node(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4)) phi2 = DiscreteFactor(["c", "d"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertEqual(self.graph.get_cardinality("a"), 2) self.assertEqual(self.graph.get_cardinality("b"), 2) self.assertEqual(self.graph.get_cardinality("c"), 1) self.assertEqual(self.graph.get_cardinality("d"), 2) def test_check_model(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.check_model) phi2 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi2) self.assertRaises(ValueError, self.graph.check_model) def test_check_model1(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) phi2 = DiscreteFactor(["c", "b"], [3, 2], np.random.rand(6)) phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12)) phi4 = DiscreteFactor(["d", "a"], [4, 1], np.random.rand(4)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.assertTrue(self.graph.check_model()) self.graph.remove_factors(phi1, phi4) phi1 = DiscreteFactor(["a", "b"], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1) self.assertTrue(self.graph.check_model()) def test_check_model2(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) phi2 = DiscreteFactor(["b", "c"], [3, 3], np.random.rand(9)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) phi3 = DiscreteFactor(["c", "a"], [4, 4], np.random.rand(16)) self.graph.add_factors(phi3) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi3) phi2 = DiscreteFactor(["b", "c"], [2, 3], np.random.rand(6)) phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12)) phi4 = DiscreteFactor(["d", "a"], [4, 3], np.random.rand(12)) self.graph.add_factors(phi2, phi3, phi4) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2, phi3, phi4) phi2 = DiscreteFactor(["a", "b"], [1, 3], np.random.rand(3)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) def test_check_model3(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) phi2 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2) phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2)) phi2 = DiscreteFactor(["b", "c"], [2, 3], np.random.rand(6)) phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12)) phi4 = DiscreteFactor(["d", "a"], [4, 1], np.random.rand(4)) phi5 = DiscreteFactor(["d", "b"], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1, phi2, phi3, phi4, phi5) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5) def test_factor_graph(self): phi1 = DiscreteFactor(["Alice", "Bob"], [3, 2], np.random.rand(6)) phi2 = DiscreteFactor(["Bob", "Charles"], [2, 2], np.random.rand(4)) self.graph.add_edges_from([("Alice", "Bob"), ("Bob", "Charles")]) self.graph.add_factors(phi1, phi2) factor_graph = self.graph.to_factor_graph() self.assertIsInstance(factor_graph, FactorGraph) self.assertListEqual( sorted(factor_graph.nodes()), ["Alice", "Bob", "Charles", "phi_Alice_Bob", "phi_Bob_Charles"], ) self.assertListEqual( hf.recursive_sorted(factor_graph.edges()), [ ["Alice", "phi_Alice_Bob"], ["Bob", "phi_Alice_Bob"], ["Bob", "phi_Bob_Charles"], ["Charles", "phi_Bob_Charles"], ], ) self.assertListEqual(factor_graph.get_factors(), [phi1, phi2]) def test_factor_graph_raises_error(self): self.graph.add_edges_from([("Alice", "Bob"), ("Bob", "Charles")]) self.assertRaises(ValueError, self.graph.to_factor_graph) def test_junction_tree(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) junction_tree = self.graph.to_junction_tree() self.assertListEqual( hf.recursive_sorted(junction_tree.nodes()), [["a", "b", "d"], ["b", "c", "d"]], ) self.assertEqual(len(junction_tree.edges()), 1) def test_junction_tree_single_clique(self): self.graph.add_edges_from([("x1", "x2"), ("x2", "x3"), ("x1", "x3")]) phi = [ DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges() ] self.graph.add_factors(*phi) junction_tree = self.graph.to_junction_tree() self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()), [["x1", "x2", "x3"]]) factors = junction_tree.get_factors() self.assertEqual(factors[0], factor_product(*phi)) def test_markov_blanket(self): self.graph.add_edges_from([("a", "b"), ("b", "c")]) self.assertListEqual(list(self.graph.markov_blanket("a")), ["b"]) self.assertListEqual(sorted(self.graph.markov_blanket("b")), ["a", "c"]) def test_local_independencies(self): self.graph.add_edges_from([("a", "b"), ("b", "c")]) independencies = self.graph.get_local_independencies() self.assertIsInstance(independencies, Independencies) self.assertEqual(independencies, Independencies(["a", "c", "b"])) def test_bayesian_model(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ["a", "b", "c", "d"]) self.assertTrue(nx.is_chordal(bm.to_undirected())) def tearDown(self): del self.graph
class TestMarkovModelCreation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_class_init_without_data(self): self.assertIsInstance(self.graph, MarkovModel) def test_class_init_with_data_string(self): self.g = MarkovModel([("a", "b"), ("b", "c")]) self.assertListEqual(sorted(self.g.nodes()), ["a", "b", "c"]) self.assertListEqual(hf.recursive_sorted(self.g.edges()), [["a", "b"], ["b", "c"]]) def test_class_init_with_data_nonstring(self): self.g = MarkovModel([(1, 2), (2, 3)]) def test_add_node_string(self): self.graph.add_node("a") self.assertListEqual(list(self.graph.nodes()), ["a"]) def test_add_node_nonstring(self): self.graph.add_node(1) def test_add_nodes_from_string(self): self.graph.add_nodes_from(["a", "b", "c", "d"]) self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "c", "d"]) def test_add_nodes_from_non_string(self): self.graph.add_nodes_from([1, 2, 3, 4]) def test_add_edge_string(self): self.graph.add_edge("d", "e") self.assertListEqual(sorted(self.graph.nodes()), ["d", "e"]) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [["d", "e"]]) self.graph.add_nodes_from(["a", "b", "c"]) self.graph.add_edge("a", "b") self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["d", "e"]]) def test_add_edge_nonstring(self): self.graph.add_edge(1, 2) def test_add_edge_selfloop(self): self.assertRaises(ValueError, self.graph.add_edge, "a", "a") def test_add_edges_from_string(self): self.graph.add_edges_from([("a", "b"), ("b", "c")]) self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "c"]) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["b", "c"]]) self.graph.add_nodes_from(["d", "e", "f"]) self.graph.add_edges_from([("d", "e"), ("e", "f")]) self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "c", "d", "e", "f"]) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), hf.recursive_sorted([("a", "b"), ("b", "c"), ("d", "e"), ("e", "f")]), ) def test_add_edges_from_nonstring(self): self.graph.add_edges_from([(1, 2), (2, 3)]) def test_add_edges_from_self_loop(self): self.assertRaises(ValueError, self.graph.add_edges_from, [("a", "a")]) def test_number_of_neighbors(self): self.graph.add_edges_from([("a", "b"), ("b", "c")]) self.assertEqual(len(list(self.graph.neighbors("b"))), 2) def tearDown(self): del self.graph
class TestVariableEliminationMarkov(unittest.TestCase): def setUp(self): # It is just a moralised version of the above Bayesian network so all the results are same. Only factors # are under consideration for inference so this should be fine. self.markov_model = MarkovModel([('A', 'J'), ('R', 'J'), ('J', 'Q'), ('J', 'L'), ('G', 'L'), ('A', 'R'), ('J', 'G')]) factor_a = TabularCPD('A', 2, values=[[0.2], [0.8]]).to_factor() factor_r = TabularCPD('R', 2, values=[[0.4], [0.6]]).to_factor() factor_j = TabularCPD('J', 2, values=[[0.9, 0.6, 0.7, 0.1], [0.1, 0.4, 0.3, 0.9]], evidence=['A', 'R'], evidence_card=[2, 2]).to_factor() factor_q = TabularCPD('Q', 2, values=[[0.9, 0.2], [0.1, 0.8]], evidence=['J'], evidence_card=[2]).to_factor() factor_l = TabularCPD('L', 2, values=[[0.9, 0.45, 0.8, 0.1], [0.1, 0.55, 0.2, 0.9]], evidence=['J', 'G'], evidence_card=[2, 2]).to_factor() factor_g = TabularCPD('G', 2, [[0.6], [0.4]]).to_factor() self.markov_model.add_factors(factor_a, factor_r, factor_j, factor_q, factor_l, factor_g) self.markov_inference = VariableElimination(self.markov_model) # All the values that are used for comparision in the all the tests are # found using SAMIAM (assuming that it is correct ;)) def test_query_single_variable(self): query_result = self.markov_inference.query(['J']) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.416, 0.584])) def test_query_multiple_variable(self): query_result = self.markov_inference.query(['Q', 'J']) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.416, 0.584])) np_test.assert_array_almost_equal(query_result['Q'].values, np.array([0.4912, 0.5088])) def test_query_single_variable_with_evidence(self): query_result = self.markov_inference.query(variables=['J'], evidence={'A': 0, 'R': 1}) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.60, 0.40])) def test_query_multiple_variable_with_evidence(self): query_result = self.markov_inference.query(variables=['J', 'Q'], evidence={'A': 0, 'R': 0, 'G': 0, 'L': 1}) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.818182, 0.181818])) np_test.assert_array_almost_equal(query_result['Q'].values, np.array([0.772727, 0.227273])) def test_query_multiple_times(self): # This just tests that the models are not getting modified while querying them query_result = self.markov_inference.query(['J']) query_result = self.markov_inference.query(['J']) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.416, 0.584])) query_result = self.markov_inference.query(['Q', 'J']) query_result = self.markov_inference.query(['Q', 'J']) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.416, 0.584])) np_test.assert_array_almost_equal(query_result['Q'].values, np.array([0.4912, 0.5088])) query_result = self.markov_inference.query(variables=['J'], evidence={'A': 0, 'R': 1}) query_result = self.markov_inference.query(variables=['J'], evidence={'A': 0, 'R': 1}) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.60, 0.40])) query_result = self.markov_inference.query(variables=['J', 'Q'], evidence={'A': 0, 'R': 0, 'G': 0, 'L': 1}) query_result = self.markov_inference.query(variables=['J', 'Q'], evidence={'A': 0, 'R': 0, 'G': 0, 'L': 1}) np_test.assert_array_almost_equal(query_result['J'].values, np.array([0.818182, 0.181818])) np_test.assert_array_almost_equal(query_result['Q'].values, np.array([0.772727, 0.227273])) def test_max_marginal(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(), 0.1659, decimal=4) def test_max_marginal_var(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(['G']), 0.5714, decimal=4) def test_max_marginal_var1(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(['G', 'R']), 0.4055, decimal=4) def test_max_marginal_var2(self): np_test.assert_almost_equal(self.markov_inference.max_marginal(['G', 'R', 'A']), 0.3260, decimal=4) def test_map_query(self): map_query = self.markov_inference.map_query() self.assertDictEqual(map_query, {'A': 1, 'R': 1, 'J': 1, 'Q': 1, 'G': 0, 'L': 0}) def test_map_query_with_evidence(self): map_query = self.markov_inference.map_query(['A', 'R', 'L'], {'J': 0, 'Q': 1, 'G': 0}) self.assertDictEqual(map_query, {'A': 1, 'R': 0, 'L': 0}) def test_induced_graph(self): induced_graph = self.markov_inference.induced_graph(['G', 'Q', 'A', 'J', 'L', 'R']) result_edges = sorted([sorted(x) for x in induced_graph.edges()]) self.assertEqual([['A', 'J'], ['A', 'R'], ['G', 'J'], ['G', 'L'], ['J', 'L'], ['J', 'Q'], ['J', 'R'], ['L', 'R']], result_edges) def test_induced_width(self): result_width = self.markov_inference.induced_width(['G', 'Q', 'A', 'J', 'L', 'R']) self.assertEqual(2, result_width) def tearDown(self): del self.markov_inference del self.markov_model
def test_class_init_with_data_nonstring(self): self.g = MarkovModel([(1, 2), (2, 3)])
def ESP_Markov_Model_Joint_Prob(esp_money_market_jointprob_probabilities,week_n_one_time= None, product_name = None,range_of_weeks=24,evidence_=None,single=False): """Returns the probability of having a given ESP product during a certain month. Parameters: esp_money_market_jointprob_probabilities: the dictionary of joint probabilities between each of the products week_n_one_time single , goes along with week_n_one_time . These parameters are used for calculating the probabilities of a given product ONCE. If you want to infer for multiple weeks, leave these parameters along and you can change the range_of_weeks parameters. The range_of_weeks parameter will run a loop for that number of weeks to perform probability inference over. This model works using BeliefPropogation to infer the probability of each product, given evidence from other products. Returns the probabilities associated with each product. """ #Record the probabilities of difference products prob_checking_original = [] start_time = time.time() prob_mmb = [] prob_cmma = [] prob_cm = [] prob_fx = [] prob_loc = [] prob_es = [] prob_checking = [] prob_given_month_no_priors_having_product = {} products =['money_market_bonus','collateral_mma','cash_management', 'fx_products','letters_of_credit','enterprise_sweep','checking_usd'] # Define the factors (joint probabilities) for our markov model model = MarkovModel([('money_market_bonus', 'collateral_mma'), ('money_market_bonus', 'checking_usd'), ('money_market_bonus', 'cash_management'), ('money_market_bonus', 'fx_products'), ('money_market_bonus', 'letters_of_credit'), ('money_market_bonus', 'enterprise_sweep'), ('collateral_mma','cash_management'),('collateral_mma', 'fx_products'),('collateral_mma', 'letters_of_credit'), ('collateral_mma', 'enterprise_sweep'),('collateral_mma', 'checking_usd'),('cash_management', 'fx_products'), ('cash_management', 'fx_products'),('cash_management', 'letters_of_credit'),('cash_management', 'enterprise_sweep'), ('cash_management', 'checking_usd'),('fx_products', 'letters_of_credit'),('fx_products', 'enterprise_sweep'), ('fx_products', 'checking_usd'),('letters_of_credit', 'enterprise_sweep'),('letters_of_credit', 'checking_usd'), ('enterprise_sweep', 'checking_usd')]) def markov_inference(dict_of_esp_jointprob): """Calculate the markov model """ factor_mmb_cmma = Factor(variables=['money_market_bonus', 'collateral_mma'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_cmma0'], dict_of_esp_jointprob['mmb0_cmma1'], dict_of_esp_jointprob['mmb1_cmma0'], dict_of_esp_jointprob['mmb1_cmma1']]) factor_mmb_cm = Factor(variables=['money_market_bonus', 'cash_management'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_cm0'], dict_of_esp_jointprob['mmb0_cm1'], dict_of_esp_jointprob['mmb1_cm0'], dict_of_esp_jointprob['mmb1_cm1']]) factor_mmb_fx = Factor(variables=['money_market_bonus', 'fx_products'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_fx0'], dict_of_esp_jointprob['mmb0_fx1'], dict_of_esp_jointprob['mmb1_fx0'], dict_of_esp_jointprob['mmb1_fx1']]) factor_mmb_loc = Factor(variables=['money_market_bonus', 'letters_of_credit'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_loc0'], dict_of_esp_jointprob['mmb0_loc1'], dict_of_esp_jointprob['mmb1_loc0'], dict_of_esp_jointprob['mmb1_loc1']]) factor_mmb_es = Factor(variables=['money_market_bonus', 'enterprise_sweep'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_es0'], dict_of_esp_jointprob['mmb0_es1'], dict_of_esp_jointprob['mmb1_es0'], dict_of_esp_jointprob['mmb1_es1']]) factor_mmb_checking = Factor(variables=['money_market_bonus', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['mmb0_checking0'], dict_of_esp_jointprob['mmb0_checking1'], dict_of_esp_jointprob['mmb1_checking0'], dict_of_esp_jointprob['mmb1_checking1']]) # collateral mma factor_cmma_cm = Factor(variables=['collateral_mma','cash_management'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cmma0_cm0'], dict_of_esp_jointprob['cmma0_cm1'], dict_of_esp_jointprob['cmma1_cm0'], dict_of_esp_jointprob['cmma1_cm1']]) factor_cmma_fx = Factor(variables=['collateral_mma', 'fx_products'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cmma0_fx0'], dict_of_esp_jointprob['cmma0_fx1'], dict_of_esp_jointprob['cmma1_fx0'], dict_of_esp_jointprob['cmma1_fx1']]) factor_cmma_loc = Factor(variables=['collateral_mma', 'letters_of_credit'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cmma0_loc0'], dict_of_esp_jointprob['cmma0_loc1'], dict_of_esp_jointprob['cmma1_loc0'], dict_of_esp_jointprob['cmma1_loc1']]) factor_cmma_es= Factor(variables=['collateral_mma', 'enterprise_sweep'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cmma0_es0'], dict_of_esp_jointprob['cmma0_es1'], dict_of_esp_jointprob['cmma1_es0'], dict_of_esp_jointprob['cmma1_es1']]) factor_cmma_checking = Factor(variables=['collateral_mma', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cmma0_checking0'], dict_of_esp_jointprob['cmma0_checking1'], dict_of_esp_jointprob['cmma1_checking0'],dict_of_esp_jointprob['cmma1_checking1']]) # cash management factor_cm_fx = Factor(variables=['cash_management', 'fx_products'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cm0_fx0'], dict_of_esp_jointprob['cm0_fx1'], dict_of_esp_jointprob['cm1_fx0'], dict_of_esp_jointprob['cm1_fx1']]) factor_cm_loc = Factor(variables=['cash_management', 'letters_of_credit'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cm0_loc0'], dict_of_esp_jointprob['cm0_loc1'], dict_of_esp_jointprob['cm1_loc0'], dict_of_esp_jointprob['cm1_loc1']]) factor_cm_es= Factor(variables=['cash_management', 'enterprise_sweep'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cm0_es0'], dict_of_esp_jointprob['cm0_es1'], dict_of_esp_jointprob['cm1_es0'], dict_of_esp_jointprob['cm1_es1']]) factor_cm_checking = Factor(variables=['cash_management', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['cm0_checking0'], dict_of_esp_jointprob['cm0_checking1'], dict_of_esp_jointprob['cm1_checking0'], dict_of_esp_jointprob['cm1_checking1']]) # FX products factor_fx_loc = Factor(variables=['fx_products', 'letters_of_credit'], cardinality=[2, 2], values=[dict_of_esp_jointprob['fx0_loc0'], dict_of_esp_jointprob['fx0_loc1'], dict_of_esp_jointprob['fx1_loc0'], dict_of_esp_jointprob['fx1_loc1']]) factor_fx_es= Factor(variables=['fx_products', 'enterprise_sweep'], cardinality=[2, 2], values=[dict_of_esp_jointprob['fx0_es0'], dict_of_esp_jointprob['fx0_es1'], dict_of_esp_jointprob['fx1_es0'], dict_of_esp_jointprob['fx1_es1']]) factor_fx_checking = Factor(variables=['fx_products', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['fx0_checking0'], dict_of_esp_jointprob['fx0_checking1'], dict_of_esp_jointprob['fx1_checking0'], dict_of_esp_jointprob['fx1_checking1']]) # letters of credit factor_loc_es= Factor(variables=['letters_of_credit', 'enterprise_sweep'], cardinality=[2, 2], values=[dict_of_esp_jointprob['loc0_es0'], dict_of_esp_jointprob['loc0_es1'], dict_of_esp_jointprob['loc1_es0'], dict_of_esp_jointprob['loc1_es1']]) factor_loc_checking = Factor(variables=['letters_of_credit', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['loc0_checking0'], dict_of_esp_jointprob['loc0_checking1'], dict_of_esp_jointprob['loc1_checking0'], dict_of_esp_jointprob['loc1_checking1']]) #enterprise sweep factor_es_checking = Factor(variables=['enterprise_sweep', 'checking_usd'], cardinality=[2, 2], values=[dict_of_esp_jointprob['es0_checking0'], dict_of_esp_jointprob['es0_checking1'], dict_of_esp_jointprob['es1_checking0'], dict_of_esp_jointprob['es1_checking1']]) # built the markov model model.add_factors(factor_mmb_cmma , factor_mmb_cm, factor_mmb_fx, factor_mmb_loc,factor_mmb_es, factor_mmb_checking, factor_cmma_cm , factor_cmma_fx, factor_cmma_loc, factor_cmma_es,factor_cmma_checking, factor_cm_fx, factor_cm_loc, factor_cm_es, factor_cm_checking , factor_fx_loc, factor_fx_es , factor_fx_checking, factor_loc_es, factor_loc_checking , factor_es_checking ) belief_propagation = BeliefPropagation(model) all_products = ['money_market_bonus','collateral_mma', 'cash_management','enterprise_sweep', 'fx_products','letters_of_credit','checking_usd'] # perform inference for all product except the one in the for loop for prod in all_products: if evidence_==None: new_evidence=evidence_ else: new_evidence = {key: value for key, value in evidence_.items() if key != prod} # perform belief inference on only one product at a time belief_inference_products = str(prod) # belief propogation on one product at a time given evidence from all other products belief = belief_propagation.query(variables=[belief_inference_products], evidence=new_evidence) try: #mmb = belief_mmb['money_market_bonus'].values[1] mmb = belief['money_market_bonus'].values[1] if mmb <0 : mmb = .0000001 elif mmb >1: mmb =1 prob_mmb.append(mmb)# one is having the product except: # can't perform inference on this product pass try: cmma = belief['collateral_mma'].values[1] if cmma <0: cmma = .0000001 elif cmma >1: cmma =1 prob_cmma.append(cmma) except:## don't have this product pass try: cm = belief['cash_management'].values[1] if cm <0: cm = .0000001 elif cm >1: cm =1 prob_cm.append(cm) except: pass try: checking = belief['checking_usd'].values[1] if checking <0: checking = .0000001 elif checking >1: checking =1 prob_checking.append(checking) except: pass try: fx = belief['fx_products'].values[1] if fx <0: fx = .0000001 elif fx >1: fx =1 prob_fx.append(fx) except: pass try: loc = belief['letters_of_credit'].values[1] if loc <0: loc = .0000001 elif loc > 1: loc = 1 prob_loc.append(loc) except: pass try: es = belief['enterprise_sweep'].values[1] if es<0: es = .0000001 elif es >1: es = 1 prob_es.append(es) except: pass if single==False: for week_n_loop in range(range_of_weeks): dict_of_esp_jointprob = esp_money_market_jointprob_probabilities(week_n_loop) markov_inference(dict_of_esp_jointprob) else: dict_of_esp_jointprob = esp_money_market_jointprob_probabilities(week_n_one_time) markov_inference(dict_of_esp_jointprob) # the order of the factor model is a0_b0, a0_b1, ,a1_b0, a1_b1 #http://conference.scipy.org/proceedings/scipy2015/pdfs/ankur_ankan.pdf # print(prob_checking,'checking', prob_cmma,'cmma', prob_mmb,'mmb', prob_cm,'cm', prob_fx,'fx', prob_loc,'loc', # prob_es,'es') #return prob_checking, prob_cmma, prob_mmb, prob_cm, prob_fx, prob_loc, prob_es, prob_checking_original return prob_checking[0], prob_cmma[0], prob_mmb[0], prob_cm[0], prob_fx[0], prob_loc[0], prob_es[0] end_time = time.time() print('{} weeks took {} seconds'.format(range_of_weeks,end_time-start_time))
class TestUndirectedGraphTriangulation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_check_clique(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "a")]) self.assertTrue(self.graph.is_clique(["a", "b", "c"])) def test_is_triangulated(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "a")]) self.assertTrue(self.graph.is_triangulated()) def test_triangulation_h1_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H1", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]], ) def test_triangulation_h2_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H2", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]], ) def test_triangulation_h3_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H3", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h4_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H4", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h5_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H4", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h6_inplace(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic="H4", inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual( hf.recursive_sorted(self.graph.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_cardinality_mismatch_raises_error(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) factor_list = [ DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges() ] self.graph.add_factors(*factor_list) self.graph.add_factors( DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))) self.assertRaises(ValueError, self.graph.triangulate) def test_triangulation_h1_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H1", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]], ) def test_triangulation_h2_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H2", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]], ) def test_triangulation_h3_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H3", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h4_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H4", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h5_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H5", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_triangulation_h6_create_new(self): self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"), ("d", "a")]) phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic="H6", inplace=True) self.assertListEqual( hf.recursive_sorted(H.edges()), [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]], ) def test_copy(self): # Setup the original graph self.graph.add_nodes_from(["a", "b"]) self.graph.add_edges_from([("a", "b")]) # Generate the copy copy = self.graph.copy() # Ensure the copied model is correct self.assertTrue(copy.check_model()) # Basic sanity checks to ensure the graph was copied correctly self.assertEqual(len(copy.nodes()), 2) self.assertListEqual(list(copy.neighbors("a")), ["b"]) self.assertListEqual(list(copy.neighbors("b")), ["a"]) # Modify the original graph ... self.graph.add_nodes_from(["c"]) self.graph.add_edges_from([("c", "b")]) # ... and ensure none of those changes get propagated self.assertEqual(len(copy.nodes()), 2) self.assertListEqual(list(copy.neighbors("a")), ["b"]) self.assertListEqual(list(copy.neighbors("b")), ["a"]) with self.assertRaises(nx.NetworkXError): list(copy.neighbors("c")) # Ensure the copy has no factors at this point self.assertEqual(len(copy.get_factors()), 0) # Add factors to the original graph phi1 = DiscreteFactor(["a", "b"], [2, 2], [[0.3, 0.7], [0.9, 0.1]]) self.graph.add_factors(phi1) # The factors should not get copied over with self.assertRaises(AssertionError): self.assertListEqual(list(copy.get_factors()), self.graph.get_factors()) # Create a fresh copy del copy copy = self.graph.copy() self.assertListEqual(list(copy.get_factors()), self.graph.get_factors()) # If we change factors in the original, it should not be passed to the clone phi1.values = np.array([[0.5, 0.5], [0.5, 0.5]]) self.assertNotEqual(self.graph.get_factors(), copy.get_factors()) # Start with a fresh copy del copy self.graph.add_nodes_from(["d"]) copy = self.graph.copy() # Ensure an unconnected node gets copied over as well self.assertEqual(len(copy.nodes()), 4) self.assertListEqual(list(self.graph.neighbors("a")), ["b"]) self.assertTrue("a" in self.graph.neighbors("b")) self.assertTrue("c" in self.graph.neighbors("b")) self.assertListEqual(list(self.graph.neighbors("c")), ["b"]) self.assertListEqual(list(self.graph.neighbors("d")), []) # Verify that changing the copied model should not update the original copy.add_nodes_from(["e"]) self.assertListEqual(list(copy.neighbors("e")), []) with self.assertRaises(nx.NetworkXError): self.graph.neighbors("e") # Verify that changing edges in the copy doesn't create edges in the original copy.add_edges_from([("d", "b")]) self.assertTrue("a" in copy.neighbors("b")) self.assertTrue("c" in copy.neighbors("b")) self.assertTrue("d" in copy.neighbors("b")) self.assertTrue("a" in self.graph.neighbors("b")) self.assertTrue("c" in self.graph.neighbors("b")) self.assertFalse("d" in self.graph.neighbors("b")) # If we remove factors from the copied model, it should not reflect in the original copy.remove_factors(phi1) self.assertEqual(len(self.graph.get_factors()), 1) self.assertEqual(len(copy.get_factors()), 0) def tearDown(self): del self.graph
class TestUndirectedGraphTriangulation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_check_clique(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')]) self.assertTrue(self.graph.is_clique(['a', 'b', 'c'])) def test_is_triangulated(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')]) self.assertTrue(self.graph.is_triangulated()) def test_triangulation_h1_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H1', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h2_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H2', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h3_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H3', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h4_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h5_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h6_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_cardinality_mismatch_raises_error(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) factor_list = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges()] self.graph.add_factors(*factor_list) self.graph.add_factors(DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))) self.assertRaises(ValueError, self.graph.triangulate) def test_triangulation_h1_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H1', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h2_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H2', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h3_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H3', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h4_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H4', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h5_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H5', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h6_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H6', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_copy(self): # Setup the original graph self.graph.add_nodes_from(['a', 'b']) self.graph.add_edges_from([('a', 'b')]) # Generate the copy copy = self.graph.copy() # Ensure the copied model is correct self.assertTrue(copy.check_model()) # Basic sanity checks to ensure the graph was copied correctly self.assertEqual(len(copy.nodes()), 2) self.assertListEqual(copy.neighbors('a'), ['b']) self.assertListEqual(copy.neighbors('b'), ['a']) # Modify the original graph ... self.graph.add_nodes_from(['c']) self.graph.add_edges_from([('c', 'b')]) # ... and ensure none of those changes get propagated self.assertEqual(len(copy.nodes()), 2) self.assertListEqual(copy.neighbors('a'), ['b']) self.assertListEqual(copy.neighbors('b'), ['a']) with self.assertRaises(nx.NetworkXError): copy.neighbors('c') # Ensure the copy has no factors at this point self.assertEqual(len(copy.get_factors()), 0) # Add factors to the original graph phi1 = DiscreteFactor(['a', 'b'], [2, 2], [[0.3, 0.7], [0.9, 0.1]]) self.graph.add_factors(phi1) # The factors should not get copied over with self.assertRaises(AssertionError): self.assertListEqual(copy.get_factors(), self.graph.get_factors()) # Create a fresh copy del copy copy = self.graph.copy() self.assertListEqual(copy.get_factors(), self.graph.get_factors()) # If we change factors in the original, it should not be passed to the clone phi1.values = np.array([[0.5, 0.5], [0.5, 0.5]]) self.assertNotEqual(self.graph.get_factors(), copy.get_factors()) # Start with a fresh copy del copy self.graph.add_nodes_from(['d']) copy = self.graph.copy() # Ensure an unconnected node gets copied over as well self.assertEqual(len(copy.nodes()), 4) self.assertListEqual(self.graph.neighbors('a'), ['b']) self.assertTrue('a' in self.graph.neighbors('b')) self.assertTrue('c' in self.graph.neighbors('b')) self.assertListEqual(self.graph.neighbors('c'), ['b']) self.assertListEqual(self.graph.neighbors('d'), []) # Verify that changing the copied model should not update the original copy.add_nodes_from(['e']) self.assertListEqual(copy.neighbors('e'), []) with self.assertRaises(nx.NetworkXError): self.graph.neighbors('e') # Verify that changing edges in the copy doesn't create edges in the original copy.add_edges_from([('d', 'b')]) self.assertTrue('a' in copy.neighbors('b')) self.assertTrue('c' in copy.neighbors('b')) self.assertTrue('d' in copy.neighbors('b')) self.assertTrue('a' in self.graph.neighbors('b')) self.assertTrue('c' in self.graph.neighbors('b')) self.assertFalse('d' in self.graph.neighbors('b')) # If we remove factors from the copied model, it should not reflect in the original copy.remove_factors(phi1) self.assertEqual(len(self.graph.get_factors()), 1) self.assertEqual(len(copy.get_factors()), 0) def tearDown(self): del self.graph
import numpy as np import pandas as pd from pgmpy.models import MarkovModel from pgmpy.estimators import PseudoMomentMatchingEstimator # Generating some random data raw_data = np.random.randint(low=0, high=2, size=(100, 4)) raw_data data = pd.DataFrame(raw_data, columns=['A', 'B', 'C', 'D']) data # Diamond shaped Markov Model as stated in Fig. 6.1 markov_model = MarkovModel([('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A')]) markov_model.fit(data, estimator=PseudoMomentMatchingEstimator) factors = coin_model.get_factors() factors
class TestMarkovModelCreation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_class_init_without_data(self): self.assertIsInstance(self.graph, MarkovModel) def test_class_init_with_data_string(self): self.g = MarkovModel([('a', 'b'), ('b', 'c')]) self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c']) self.assertListEqual(hf.recursive_sorted(self.g.edges()), [['a', 'b'], ['b', 'c']]) def test_class_init_with_data_nonstring(self): self.g = MarkovModel([(1, 2), (2, 3)]) def test_add_node_string(self): self.graph.add_node('a') self.assertListEqual(self.graph.nodes(), ['a']) def test_add_node_nonstring(self): self.graph.add_node(1) def test_add_nodes_from_string(self): self.graph.add_nodes_from(['a', 'b', 'c', 'd']) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd']) def test_add_nodes_from_non_string(self): self.graph.add_nodes_from([1, 2, 3, 4]) def test_add_edge_string(self): self.graph.add_edge('d', 'e') self.assertListEqual(sorted(self.graph.nodes()), ['d', 'e']) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['d', 'e']]) self.graph.add_nodes_from(['a', 'b', 'c']) self.graph.add_edge('a', 'b') self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['d', 'e']]) def test_add_edge_nonstring(self): self.graph.add_edge(1, 2) def test_add_edge_selfloop(self): self.assertRaises(ValueError, self.graph.add_edge, 'a', 'a') def test_add_edges_from_string(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c']) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['b', 'c']]) self.graph.add_nodes_from(['d', 'e', 'f']) self.graph.add_edges_from([('d', 'e'), ('e', 'f')]) self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd', 'e', 'f']) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), hf.recursive_sorted([('a', 'b'), ('b', 'c'), ('d', 'e'), ('e', 'f')])) def test_add_edges_from_nonstring(self): self.graph.add_edges_from([(1, 2), (2, 3)]) def test_add_edges_from_self_loop(self): self.assertRaises(ValueError, self.graph.add_edges_from, [('a', 'a')]) def test_number_of_neighbors(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertEqual(len(self.graph.neighbors('b')), 2) def tearDown(self): del self.graph
from pgmpy.models import MarkovModel from pgmpy.factors import Factor import numpy as np model = MarkovModel() # Fig 2.7(a) represents the MarkovModel model.add_nodes_from(['A', 'B', 'C', 'D']) model.add_edges_from([('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'A')]) # Adding some factors phi_A_B = Factor(['A', 'B'], [2, 2], [1, 100, 100, 1]) phi_B_C = Factor(['B', 'C'], [2, 2], [100, 1, 1, 100]) phi_C_D = Factor(['C', 'D'], [2, 2], [1, 100, 100, 1]) phi_D_A = Factor(['D', 'A'], [2, 2], [100, 1, 1, 100]) model.add_factors(phi_A_B, phi_B_C, phi_C_D, phi_D_A) chordal_graph = model.triangulate() # Fig 2.9 represents the chordal graph created by triangulation chordal_graph.edges()
def setUp(self): self.maxDiff = None edges = [['family-out', 'dog-out'], ['bowel-problem', 'dog-out'], ['family-out', 'light-on'], ['dog-out', 'hear-bark']] cpds = { 'bowel-problem': np.array([[0.01], [0.99]]), 'dog-out': np.array([[0.99, 0.01, 0.97, 0.03], [0.9, 0.1, 0.3, 0.7]]), 'family-out': np.array([[0.15], [0.85]]), 'hear-bark': np.array([[0.7, 0.3], [0.01, 0.99]]), 'light-on': np.array([[0.6, 0.4], [0.05, 0.95]]) } states = { 'bowel-problem': ['true', 'false'], 'dog-out': ['true', 'false'], 'family-out': ['true', 'false'], 'hear-bark': ['true', 'false'], 'light-on': ['true', 'false'] } parents = { 'bowel-problem': [], 'dog-out': ['bowel-problem', 'family-out'], 'family-out': [], 'hear-bark': ['dog-out'], 'light-on': ['family-out'] } self.bayesmodel = BayesianModel(edges) tabular_cpds = [] for var, values in cpds.items(): cpd = TabularCPD(var, len(states[var]), values, evidence=parents[var], evidence_card=[ len(states[evidence_var]) for evidence_var in parents[var] ]) tabular_cpds.append(cpd) self.bayesmodel.add_cpds(*tabular_cpds) self.bayeswriter = UAIWriter(self.bayesmodel) edges = {('var_0', 'var_1'), ('var_0', 'var_2'), ('var_1', 'var_2')} self.markovmodel = MarkovModel(edges) tables = [(['var_0', 'var_1'], ['4.000', '2.400', '1.000', '0.000']), (['var_0', 'var_1', 'var_2'], [ '2.2500', '3.2500', '3.7500', '0.0000', '0.0000', '10.0000', '1.8750', '4.0000', '3.3330', '2.0000', '2.0000', '3.4000' ])] domain = {'var_1': '2', 'var_2': '3', 'var_0': '2'} factors = [] for table in tables: variables = table[0] cardinality = [int(domain[var]) for var in variables] values = list(map(float, table[1])) factor = Factor(variables, cardinality, values) factors.append(factor) self.markovmodel.add_factors(*factors) self.markovwriter = UAIWriter(self.markovmodel)
class TestUndirectedGraphTriangulation(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_check_clique(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')]) self.assertTrue(self.graph.check_clique(['a', 'b', 'c'])) def test_is_triangulated(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')]) self.assertTrue(self.graph.is_triangulated()) def test_triangulation_h1_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H1', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h2_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H2', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h3_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H3', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h4_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h5_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h6_inplace(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.graph.triangulate(heuristic='H4', inplace=True) self.assertTrue(self.graph.is_triangulated()) self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_cardinality_mismatch_raises_error(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) factor_list = [Factor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges()] self.graph.add_factors(*factor_list) self.graph.add_factors(Factor(['a', 'b'], [2, 3], np.random.rand(6))) self.assertRaises(ValueError, self.graph.triangulate) def test_triangulation_h1_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H1', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h2_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H2', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']]) def test_triangulation_h3_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H3', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h4_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H4', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h5_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H5', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def test_triangulation_h6_create_new(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) H = self.graph.triangulate(heuristic='H6', inplace=True) self.assertListEqual(hf.recursive_sorted(H.edges()), [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]) def tearDown(self): del self.graph
import numpy as np import pandas as pd from pgmpy.models import MarkovModel from pgmpy.estimators import MaximumLikelihoodEstimator # Generating some random data raw_data = np.random.randint(low=0, high=2, size=(100, 2)) raw_data data = pd.DataFrame(raw_data, columns=['A', 'B']) data # Markov Model as stated in Fig. 6.5 markov_model = MarkovModel([('A', 'B')]) markov_model.fit(data, estimator=MaximumLikelihoodEstimator) factors = coin_model.get_factors() print(factors[0])
class TestMarkovModelMethods(unittest.TestCase): def setUp(self): self.graph = MarkovModel() def test_get_cardinality(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {'a': 1, 'b': 2}) self.graph.remove_factors(phi1) self.assertDictEqual(self.graph.get_cardinality(), {}) phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4)) phi2 = Factor(['c', 'd'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertDictEqual(self.graph.get_cardinality(), {'d': 2, 'a': 2, 'b': 2, 'c': 1}) phi3 = Factor(['d', 'a'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi3) self.assertDictEqual(self.graph.get_cardinality(), {'d': 1, 'c': 1, 'b': 2, 'a': 2}) self.graph.remove_factors(phi1, phi2, phi3) self.assertDictEqual(self.graph.get_cardinality(), {}) def test_get_cardinality_check_cardinality(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.get_cardinality, check_cardinality=True) phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi2) self.assertRaises(ValueError, self.graph.get_cardinality, check_cardinality=True) phi3 = Factor(['c', 'd'], [2, 2], np.random.rand(4)) self.graph.add_factors(phi3) self.assertDictEqual(self.graph.get_cardinality(check_cardinality=True), {'d': 2, 'c': 2, 'b': 2, 'a': 1}) def test_check_model(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['c', 'b'], [3, 2], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4)) self.graph.add_factors(phi1, phi2, phi3, phi4) self.assertTrue(self.graph.check_model()) self.graph.remove_factors(phi1, phi4) phi1 = Factor(['a', 'b'], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1) self.assertTrue(self.graph.check_model()) def test_check_model1(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['b', 'c'], [3, 3], np.random.rand(9)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) phi3 = Factor(['c', 'a'], [4, 4], np.random.rand(16)) self.graph.add_factors(phi3) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi3) phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 3], np.random.rand(12)) self.graph.add_factors(phi2, phi3, phi4) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2, phi3, phi4) phi2 = Factor(['a', 'b'], [1, 3], np.random.rand(3)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi2) def test_check_model2(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2)) self.graph.add_factors(phi1, phi2) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2) phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2)) phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6)) phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12)) phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4)) phi5 = Factor(['d', 'b'], [4, 2], np.random.rand(8)) self.graph.add_factors(phi1, phi2, phi3, phi4, phi5) self.assertRaises(ValueError, self.graph.check_model) self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5) def test_factor_graph(self): from pgmpy.models import FactorGraph phi1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6)) phi2 = Factor(['Bob', 'Charles'], [2, 2], np.random.rand(4)) self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')]) self.graph.add_factors(phi1, phi2) factor_graph = self.graph.to_factor_graph() self.assertIsInstance(factor_graph, FactorGraph) self.assertListEqual(sorted(factor_graph.nodes()), ['Alice', 'Bob', 'Charles', 'phi_Alice_Bob', 'phi_Bob_Charles']) self.assertListEqual(hf.recursive_sorted(factor_graph.edges()), [['Alice', 'phi_Alice_Bob'], ['Bob', 'phi_Alice_Bob'], ['Bob', 'phi_Bob_Charles'], ['Charles', 'phi_Bob_Charles']]) self.assertListEqual(factor_graph.get_factors(), [phi1, phi2]) def test_factor_graph_raises_error(self): self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')]) self.assertRaises(ValueError, self.graph.to_factor_graph) def test_junction_tree(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) junction_tree = self.graph.to_junction_tree() self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()), [['a', 'b', 'd'], ['b', 'c', 'd']]) self.assertEqual(len(junction_tree.edges()), 1) def test_junction_tree_single_clique(self): from pgmpy.factors import factor_product self.graph.add_edges_from([('x1','x2'), ('x2', 'x3'), ('x1', 'x3')]) phi = [Factor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges()] self.graph.add_factors(*phi) junction_tree = self.graph.to_junction_tree() self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()), [['x1', 'x2', 'x3']]) factors = junction_tree.get_factors() self.assertEqual(factors[0], factor_product(*phi)) def test_markov_blanket(self): self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) self.assertListEqual(self.graph.markov_blanket('a'), ['b']) self.assertListEqual(sorted(self.graph.markov_blanket('b')), ['a', 'c']) def test_local_independencies(self): from pgmpy.independencies import Independencies self.graph.add_edges_from([('a', 'b'), ('b', 'c')]) independencies = self.graph.get_local_independencies() self.assertIsInstance(independencies, Independencies) self.assertEqual(len(independencies.get_assertions()), 2) string = '' for assertion in sorted(independencies.get_assertions(), key=lambda x: list(x.event1)): string += str(assertion) + '\n' self.assertEqual(string, '(a _|_ c | b)\n(c _|_ a | b)\n') def test_bayesian_model(self): from pgmpy.models import BayesianModel import networkx as nx self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a')]) phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6)) phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12)) phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20)) phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10)) self.graph.add_factors(phi1, phi2, phi3, phi4) bm = self.graph.to_bayesian_model() self.assertIsInstance(bm, BayesianModel) self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd']) self.assertTrue(nx.is_chordal(bm.to_undirected())) def tearDown(self): del self.graph