def __init__(self, variables, cardinality, values): """ Initialize a Joint Probability Distribution class. Defined above, we have the following mapping from variable assignments to the index of the row vector in the value field: +-----+-----+-----+-------------------------+ | x1 | x2 | x3 | P(x1, x2, x2) | +-----+-----+-----+-------------------------+ | x1_0| x2_0| x3_0| P(x1_0, x2_0, x3_0) | +-----+-----+-----+-------------------------+ | x1_1| x2_0| x3_0| P(x1_1, x2_0, x3_0) | +-----+-----+-----+-------------------------+ | x1_0| x2_1| x3_0| P(x1_0, x2_1, x3_0) | +-----+-----+-----+-------------------------+ | x1_1| x2_1| x3_0| P(x1_1, x2_1, x3_0) | +-----+-----+-----+-------------------------+ | x1_0| x2_0| x3_1| P(x1_0, x2_0, x3_1) | +-----+-----+-----+-------------------------+ | x1_1| x2_0| x3_1| P(x1_1, x2_0, x3_1) | +-----+-----+-----+-------------------------+ | x1_0| x2_1| x3_1| P(x1_0, x2_1, x3_1) | +-----+-----+-----+-------------------------+ | x1_1| x2_1| x3_1| P(x1_1, x2_1, x3_1) | +-----+-----+-----+-------------------------+ Parameters ---------- variables: list List of scope of Joint Probability Distribution. cardinality: list, array_like List of cardinality of each variable value: list, array_like List or array of values of factor. A Joint Probability Distribution's values are stored in a row vector in the value using an ordering such that the left-most variables as defined in the variable field cycle through their values the fastest. Examples -------- >>> from pgmpy.factors import JointProbabilityDistribution >>> prob = JointProbabilityDistribution(['x1', 'x2', 'x3'], [2, 2, 2], np.ones(8)/8) >>> print(prob) print(prob) x1 x2 x3 P(x1, x2, x3) x1_0 x2_0 x3_0 0.125 x1_0 x2_0 x3_1 0.125 x1_0 x2_1 x3_0 0.125 x1_0 x2_1 x3_1 0.125 x1_1 x2_0 x3_0 0.125 x1_1 x2_0 x3_1 0.125 x1_1 x2_1 x3_0 0.125 x1_1 x2_1 x3_1 0.125 """ if np.isclose(np.sum(values), 1): Factor.__init__(self, variables, cardinality, values) else: raise ValueError("The probability values doesn't sum to 1.")
def test_factor_product2(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi.product(phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(prod.variables, OrderedDict([ ('x1', [State('x1', 0), State('x1', 1)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)]), ('x4', [State('x4', 0), State('x4', 1)])] )) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = phi.product(phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15])) self.assertEqual(prod.variables, OrderedDict( [('x1', [State('x1', 0), State('x1', 1), State('x1', 2)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)])]))
def __init__(self, variable, variable_card, values, evidence=None, evidence_card=None): self.variable = variable variables = [variable] if not isinstance(variable_card, int): raise TypeError("Event cardinality must be an integer") self.variable_card = variable_card cardinality = [variable_card] if evidence_card: if not isinstance(evidence_card, (list, set, tuple)): evidence_card = [evidence_card] cardinality.extend(evidence_card) if evidence: if not isinstance(evidence, (list, set, tuple)): evidence = [evidence] variables.extend(evidence) if not len(evidence_card) == len(evidence): raise exceptions.CardinalityError("Cardinality of all " "evidences not specified") values = np.array(values) if values.ndim != 2: raise TypeError("Values must be a 2d list/array") Factor.__init__(self, variables, cardinality, values.flatten('C'))
def setUp(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.random.uniform(5, 10, size=8)) self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) self.phi2 = Factor([('x1', 0), ('x2', 0), ('x3', 0)], [2, 3, 2], range(12)) # This larger factor (phi3) caused a bug in reduce card3 = [3, 3, 3, 2, 2, 2, 2, 2, 2] self.phi3 = Factor(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'], card3, np.arange(np.prod(card3), dtype=np.float))
def test_factorset_divide(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(1, 13)) phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(1, 9)) factor_set1 = FactorSet(phi1, phi2) phi3 = Factor(['x5', 'x6', 'x7'], [2, 2, 2], range(1, 9)) phi4 = Factor(['x5', 'x7', 'x8'], [2, 2, 2], range(1, 9)) factor_set2 = FactorSet(phi3, phi4) factor_set3 = factor_set2.divide(factor_set1, inplace=False) self.assertEqual({phi3, phi4, phi1.identity_factor() / phi1, phi2.identity_factor() / phi2}, factor_set3.factors)
class TimeSuite: def setup(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.ones(8)) self.phi_large = Factor(range(10), [2] * 10, [1] * (2**10)) def time_factor_define(self): phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.ones(8)) def time_factor_reduce(self): self.phi.reduce([('x1', 0), ('x2', 1)], inplace=False) def time_factor_reduce_large(self): self.phi_large.reduce([(3, 0), (6, 1)], inplace=False) def time_factor_marginalize(self): self.phi.marginalize(['x1'], inplace=False) def time_factor_marginalize_large(self): self.phi_large.marginalize([4, 5, 8], inplace=False) def time_factor_multiply(self): phi = self.phi * self.phi def time_factor_multiply_large(self): phi = self.phi_large * self.phi_large
def test_max_calibrate_clique_belief(self): belief_propagation = BeliefPropagation(self.junction_tree) belief_propagation.max_calibrate() clique_belief = belief_propagation.get_clique_beliefs() phi1 = Factor(['A', 'B'], [2, 3], range(6)) phi2 = Factor(['B', 'C'], [3, 2], range(6)) phi3 = Factor(['C', 'D'], [2, 2], range(4)) b_A_B = phi1 * (phi3.maximize(['D'], inplace=False) * phi2).maximize(['C'], inplace=False) b_B_C = phi2 * (phi1.maximize(['A'], inplace=False) * phi3.maximize(['D'], inplace=False)) b_C_D = phi3 * (phi1.maximize(['A'], inplace=False) * phi2).maximize(['B'], inplace=False) np_test.assert_array_almost_equal(clique_belief[('A', 'B')].values, b_A_B.values) np_test.assert_array_almost_equal(clique_belief[('B', 'C')].values, b_B_C.values) np_test.assert_array_almost_equal(clique_belief[('C', 'D')].values, b_C_D.values)
def test_factor_product2(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi.product(phi1, inplace=False) expected_factor = Factor(['x1', 'x2', 'x3', 'x4'], [2, 2, 2, 2], [0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9]) self.assertEqual(prod, expected_factor) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3', 'x4']) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = phi.product(phi1, inplace=False) expected_factor = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15]) self.assertEqual(prod, expected_factor) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3'])
def test_max_calibrate_sepset_belief(self): belief_propagation = BeliefPropagation(self.junction_tree) belief_propagation.max_calibrate() sepset_belief = belief_propagation.get_sepset_beliefs() phi1 = Factor(['A', 'B'], [2, 3], range(6)) phi2 = Factor(['B', 'C'], [3, 2], range(6)) phi3 = Factor(['C', 'D'], [2, 2], range(4)) b_B = (phi1 * (phi3.maximize(['D'], inplace=False) * phi2).maximize(['C'], inplace=False)).maximize(['A'], inplace=False) b_C = (phi2 * (phi1.maximize(['A'], inplace=False) * phi3.maximize(['D'], inplace=False))).maximize(['B'], inplace=False) np_test.assert_array_almost_equal(sepset_belief[frozenset((('A', 'B'), ('B', 'C')))].values, b_B.values) np_test.assert_array_almost_equal(sepset_belief[frozenset((('B', 'C'), ('C', 'D')))].values, b_C.values)
def test_factorset_marginalize_not_inplace(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(8)) phi3 = Factor(['x5', 'x6', 'x7'], [2, 2, 2], range(8)) phi4 = Factor(['x5', 'x7', 'x8'], [2, 2, 2], range(8)) factor_set = FactorSet(phi1, phi2, phi3, phi4) new_factor_set = factor_set.marginalize(['x1', 'x5'], inplace=False) phi1_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == set(['x2', 'x3']), new_factor_set.factors))[0] self.assertEqual(phi1.marginalize('x1', inplace=False), phi1_equivalent_in_factor_set) phi2_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == set(['x4', 'x3']), new_factor_set.factors))[0] self.assertEqual(phi2.marginalize('x1', inplace=False), phi2_equivalent_in_factor_set) phi3_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == set(['x6', 'x7']), new_factor_set.factors))[0] self.assertEqual(phi3.marginalize('x5', inplace=False), phi3_equivalent_in_factor_set) phi4_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == set(['x8', 'x7']), new_factor_set.factors))[0] self.assertEqual(phi4.marginalize('x5', inplace=False), phi4_equivalent_in_factor_set)
class TestFactorMethods(unittest.TestCase): def setUp(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.random.uniform(5, 10, size=8)) self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) self.phi2 = Factor([('x1', 0), ('x2', 0), ('x3', 0)], [2, 3, 2], range(12)) # This larger factor (phi3) caused a bug in reduce card3 = [3, 3, 3, 2, 2, 2, 2, 2, 2] self.phi3 = Factor(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'], card3, np.arange(np.prod(card3), dtype=np.float)) def test_scope(self): self.assertListEqual(self.phi.scope(), ['x1', 'x2', 'x3']) self.assertListEqual(self.phi1.scope(), ['x1', 'x2', 'x3']) def test_assignment(self): self.assertListEqual(self.phi.assignment([0]), [[('x1', 0), ('x2', 0), ('x3', 0)]]) self.assertListEqual(self.phi.assignment([4, 5, 6]), [[('x1', 1), ('x2', 0), ('x3', 0)], [('x1', 1), ('x2', 0), ('x3', 1)], [('x1', 1), ('x2', 1), ('x3', 0)]]) self.assertListEqual(self.phi1.assignment(np.array([4, 5, 6])), [[('x1', 0), ('x2', 2), ('x3', 0)], [('x1', 0), ('x2', 2), ('x3', 1)], [('x1', 1), ('x2', 0), ('x3', 0)]]) def test_assignment_indexerror(self): self.assertRaises(IndexError, self.phi.assignment, [10]) self.assertRaises(IndexError, self.phi.assignment, [1, 3, 10, 5]) self.assertRaises(IndexError, self.phi.assignment, np.array([1, 3, 10, 5])) def test_get_cardinality(self): self.assertEqual(self.phi.get_cardinality(['x1']), {'x1': 2}) self.assertEqual(self.phi.get_cardinality(['x2']), {'x2': 2}) self.assertEqual(self.phi.get_cardinality(['x3']), {'x3': 2}) self.assertEqual(self.phi.get_cardinality(['x1', 'x2']), {'x1': 2, 'x2': 2}) self.assertEqual(self.phi.get_cardinality(['x1', 'x3']), {'x1': 2, 'x3': 2}) self.assertEqual(self.phi.get_cardinality(['x1', 'x2', 'x3']), {'x1': 2, 'x2': 2, 'x3': 2}) def test_get_cardinality_scopeerror(self): self.assertRaises(ValueError, self.phi.get_cardinality, ['x4']) def test_get_cardinality_typeerror(self): self.assertRaises(TypeError, self.phi.get_cardinality, 'x1') def test_marginalize(self): self.phi1.marginalize(['x1']) np_test.assert_array_equal(self.phi1.values, np.array([[6, 8], [10, 12], [14, 16]])) self.phi1.marginalize(['x2']) np_test.assert_array_equal(self.phi1.values, np.array([30, 36])) self.phi1.marginalize(['x3']) np_test.assert_array_equal(self.phi1.values, np.array(66)) def test_marginalize_scopeerror(self): self.assertRaises(ValueError, self.phi.marginalize, ['x4']) self.assertRaises(ValueError, self.phi.marginalize, ['x4']) self.phi.marginalize(['x1']) self.assertRaises(ValueError, self.phi.marginalize, ['x1']) def test_marginalize_typeerror(self): self.assertRaises(TypeError, self.phi.marginalize, 'x1') def test_marginalize_shape(self): values = ['A', 'D', 'F', 'H'] phi3_max = self.phi3.marginalize(values, inplace=False) # Previously a sorting error caused these to be different np_test.assert_array_equal(phi3_max.values.shape, phi3_max.cardinality) def test_normalize(self): self.phi1.normalize() np_test.assert_almost_equal(self.phi1.values, np.array([[[0, 0.01515152], [0.03030303, 0.04545455], [0.06060606, 0.07575758]], [[0.09090909, 0.10606061], [0.12121212, 0.13636364], [0.15151515, 0.16666667]]])) def test_reduce(self): self.phi1.reduce([('x1', 0), ('x2', 0)]) np_test.assert_array_equal(self.phi1.values, np.array([0, 1])) def test_reduce1(self): self.phi1.reduce([('x2', 0), ('x1', 0)]) np_test.assert_array_equal(self.phi1.values, np.array([0, 1])) def test_reduce_shape(self): values = [('A', 0), ('D', 0), ('F', 0), ('H', 1)] phi3_reduced = self.phi3.reduce(values, inplace=False) # Previously a sorting error caused these to be different np_test.assert_array_equal(phi3_reduced.values.shape, phi3_reduced.cardinality) @unittest.skip def test_complete_reduce(self): self.phi1.reduce([('x1', 0), ('x2', 0), ('x3', 1)]) np_test.assert_array_equal(self.phi1.values, np.array([1])) np_test.assert_array_equal(self.phi1.cardinality, np.array([])) np_test.assert_array_equal(self.phi1.variables, OrderedDict()) def test_reduce_typeerror(self): self.assertRaises(TypeError, self.phi1.reduce, 'x10') self.assertRaises(TypeError, self.phi1.reduce, ['x10']) self.assertRaises(TypeError, self.phi1.reduce, [('x1', 'x2')]) self.assertRaises(TypeError, self.phi1.reduce, [(0, 'x1')]) self.assertRaises(TypeError, self.phi1.reduce, [(0.1, 'x1')]) self.assertRaises(TypeError, self.phi1.reduce, [(0.1, 0.1)]) self.assertRaises(TypeError, self.phi1.reduce, [('x1', 0.1)]) def test_reduce_scopeerror(self): self.assertRaises(ValueError, self.phi1.reduce, [('x4', 1)]) def test_reduce_sizeerror(self): self.assertRaises(IndexError, self.phi1.reduce, [('x3', 5)]) def test_identity_factor(self): identity_factor = self.phi.identity_factor() self.assertEqual(list(identity_factor.variables), ['x1', 'x2', 'x3']) np_test.assert_array_equal(identity_factor.cardinality, [2, 2, 2]) np_test.assert_array_equal(identity_factor.values, np.ones(8).reshape(2, 2, 2)) def test_factor_product(self): phi = Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = Factor(['x3', 'x4'], [2, 2], range(4)) prod = factor_product(phi, phi1) expected_factor = Factor(['x1', 'x2', 'x3', 'x4'], [2, 2, 2, 2], [0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9]) self.assertEqual(prod, expected_factor) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3', 'x4']) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = factor_product(phi, phi1) expected_factor = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15]) np_test.assert_almost_equal(prod.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15]).reshape(3, 2, 2)) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3']) def test_factor_product2(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi.product(phi1, inplace=False) expected_factor = Factor(['x1', 'x2', 'x3', 'x4'], [2, 2, 2, 2], [0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9]) self.assertEqual(prod, expected_factor) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3', 'x4']) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = phi.product(phi1, inplace=False) expected_factor = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15]) self.assertEqual(prod, expected_factor) self.assertEqual(sorted(prod.variables), ['x1', 'x2', 'x3']) def test_factor_product_non_factor_arg(self): self.assertRaises(TypeError, factor_product, 1, 2) def test_factor_mul(self): phi = Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi * phi1 sorted_vars = ['x1', 'x2', 'x3', 'x4'] for axis in range(prod.values.ndim): exchange_index = prod.variables.index(sorted_vars[axis]) prod.variables[axis], prod.variables[exchange_index] = prod.variables[exchange_index], prod.variables[axis] prod.values = prod.values.swapaxes(axis, exchange_index) np_test.assert_almost_equal(prod.values.ravel(), np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(prod.variables, ['x1', 'x2', 'x3', 'x4']) def test_factor_divide(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = Factor(['x1'], [2], [1, 2]) div = phi1.divide(phi2, inplace=False) phi3 = Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, div) def test_factor_divide_truediv(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = Factor(['x1'], [2], [1, 2]) div = phi1 / phi2 phi3 = Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, div) def test_factor_divide_invalid(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 3, 4]) phi2 = Factor(['x1'], [2], [0, 2]) div = phi1.divide(phi2, inplace=False) np_test.assert_array_equal(div.values.ravel(), np.array([np.inf, np.inf, 1.5, 2])) def test_factor_divide_no_common_scope(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 3, 4]) phi2 = Factor(['x3'], [2], [0, 2]) self.assertRaises(ValueError, factor_divide, phi1, phi2) def test_factor_divide_non_factor_arg(self): self.assertRaises(TypeError, factor_divide, 1, 1) def test_eq(self): self.assertFalse(self.phi == self.phi1) self.assertTrue(self.phi == self.phi) self.assertTrue(self.phi1 == self.phi1) def test_eq1(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 4, 3], range(24)) phi2 = Factor(['x2', 'x1', 'x3'], [4, 2, 3], [0, 1, 2, 12, 13, 14, 3, 4, 5, 15, 16, 17, 6, 7, 8, 18, 19, 20, 9, 10, 11, 21, 22, 23]) self.assertTrue(phi1, phi2) def test_maximize1(self): self.phi1.maximize(['x1']) self.assertEqual(self.phi1, Factor(['x2', 'x3'], [3, 2], [6, 7, 8, 9, 10, 11])) self.phi1.maximize(['x2']) self.assertEqual(self.phi1, Factor(['x3'], [2], [10, 11])) def test_maximize2(self): self.phi1.maximize(['x1', 'x2']) self.assertEqual(self.phi1, Factor(['x3'], [2], [10, 11])) def test_maximize3(self): self.phi2 = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0.25, 0.35, 0.08, 0.16, 0.05, 0.07, 0.00, 0.00, 0.15, 0.21, 0.08, 0.18]) self.phi2.maximize(['x2']) self.assertEqual(self.phi2, Factor(['x1', 'x3'], [3, 2], [0.25, 0.35, 0.05, 0.07, 0.15, 0.21])) def test_maximize_shape(self): values = ['A', 'D', 'F', 'H'] phi3_max = self.phi3.maximize(values, inplace=False) # Previously a sorting error caused these to be different np_test.assert_array_equal(phi3_max.values.shape, phi3_max.cardinality) def test_maximize_scopeerror(self): self.assertRaises(ValueError, self.phi.maximize, ['x10']) def test_maximize_typeerror(self): self.assertRaises(TypeError, self.phi.maximize, 'x1') def tearDown(self): del self.phi del self.phi1
def test_maximize3(self): self.phi2 = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0.25, 0.35, 0.08, 0.16, 0.05, 0.07, 0.00, 0.00, 0.15, 0.21, 0.08, 0.18]) self.phi2.maximize(['x2']) self.assertEqual(self.phi2, Factor(['x1', 'x3'], [3, 2], [0.25, 0.35, 0.05, 0.07, 0.15, 0.21]))
def test_factor_divide_invalid(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 3, 4]) phi2 = Factor(['x1'], [2], [0, 2]) div = phi1.divide(phi2, inplace=False) np_test.assert_array_equal(div.values.ravel(), np.array([np.inf, np.inf, 1.5, 2]))
def test_factor_divide(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = Factor(['x1'], [2], [1, 2]) div = phi1.divide(phi2, inplace=False) phi3 = Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, div)
from pgmpy.factors import Factor factor_a_b = Factor(variables=['A', 'B'], cardinality=[2, 2], value=[90, 100, 1, 10]) factor_b_c = Factor(variables=['B', 'C'], cardinality=[2, 2], value=[10, 80, 70, 30]) factor_c_d = Factor(variables=['C', 'D'], cardinality=[2, 2], value=[10, 1, 100, 90]) factor_d_a = Factor(variables=['D', 'A'], cardinality=[2, 2], value=[80, 60, 20, 10])
class TestFactorSet(unittest.TestCase): def setUp(self): self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) self.phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(8)) self.phi3 = Factor(['x5', 'x6', 'x7'], [2, 2, 2], range(8)) self.phi4 = Factor(['x5', 'x7', 'x8'], [2, 2, 2], range(8)) def test_class_init(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(8)) factor_set1 = FactorSet(phi1, phi2) self.assertEqual({phi1, phi2}, factor_set1.get_factors()) def test_factorset_add_remove_factors(self): self.factor_set1 = FactorSet() self.factor_set1.add_factors(self.phi1, self.phi2) self.assertEqual({self.phi1, self.phi2}, self.factor_set1.get_factors()) self.factor_set1.remove_factors(self.phi2) self.assertEqual({self.phi1}, self.factor_set1.get_factors()) def test_factorset_product(self): factor_set1 = FactorSet(self.phi1, self.phi2) factor_set2 = FactorSet(self.phi3, self.phi4) factor_set3 = factor_set2.product(factor_set1, inplace=False) self.assertEqual({self.phi1, self.phi2, self.phi3, self.phi4}, factor_set3.factors) def test_factorset_divide(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(1, 13)) phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(1, 9)) factor_set1 = FactorSet(phi1, phi2) phi3 = Factor(['x5', 'x6', 'x7'], [2, 2, 2], range(1, 9)) phi4 = Factor(['x5', 'x7', 'x8'], [2, 2, 2], range(1, 9)) factor_set2 = FactorSet(phi3, phi4) factor_set3 = factor_set2.divide(factor_set1, inplace=False) self.assertEqual({phi3, phi4, phi1.identity_factor() / phi1, phi2.identity_factor() / phi2}, factor_set3.factors) def test_factorset_marginalize_inplace(self): factor_set = FactorSet(self.phi1, self.phi2, self.phi3, self.phi4) factor_set.marginalize(['x1', 'x5'], inplace=True) phi1_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x2', 'x3'}, factor_set.factors))[0] self.assertEqual(self.phi1.marginalize(['x1'], inplace=False), phi1_equivalent_in_factor_set) phi2_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x4', 'x3'}, factor_set.factors))[0] self.assertEqual(self.phi2.marginalize(['x1'], inplace=False), phi2_equivalent_in_factor_set) phi3_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x6', 'x7'}, factor_set.factors))[0] self.assertEqual(self.phi3.marginalize(['x5'], inplace=False), phi3_equivalent_in_factor_set) phi4_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x8', 'x7'}, factor_set.factors))[0] self.assertEqual(self.phi4.marginalize(['x5'], inplace=False), phi4_equivalent_in_factor_set) def test_factorset_marginalize_not_inplace(self): factor_set = FactorSet(self.phi1, self.phi2, self.phi3, self.phi4) new_factor_set = factor_set.marginalize(['x1', 'x5'], inplace=False) phi1_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x2', 'x3'}, new_factor_set.factors))[0] self.assertEqual(self.phi1.marginalize(['x1'], inplace=False), phi1_equivalent_in_factor_set) phi2_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x4', 'x3'}, new_factor_set.factors))[0] self.assertEqual(self.phi2.marginalize(['x1'], inplace=False), phi2_equivalent_in_factor_set) phi3_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x6', 'x7'}, new_factor_set.factors))[0] self.assertEqual(self.phi3.marginalize(['x5'], inplace=False), phi3_equivalent_in_factor_set) phi4_equivalent_in_factor_set = list(filter(lambda x: set(x.scope()) == {'x8', 'x7'}, new_factor_set.factors))[0] self.assertEqual(self.phi4.marginalize(['x5'], inplace=False), phi4_equivalent_in_factor_set)
class TestFactorMethods(unittest.TestCase): def setUp(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.random.uniform(5, 10, size=8)) self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) # def test_pos_dist(self): # self.assertTrue(self.phi.is_pos_dist()) # self.assertFalse(self.phi1.is_pos_dist()) def test_scope(self): self.assertListEqual(self.phi.scope(), ['x1', 'x2', 'x3']) self.assertListEqual(self.phi1.scope(), ['x1', 'x2', 'x3']) def test_assignment(self): self.assertListEqual(self.phi.assignment([0]), [['x1_0', 'x2_0', 'x3_0']]) self.assertListEqual(self.phi.assignment([4, 5, 6]), [['x1_1', 'x2_0', 'x3_0'], ['x1_1', 'x2_0', 'x3_1'], ['x1_1', 'x2_1', 'x3_0']]) self.assertListEqual(self.phi1.assignment(np.array([4, 5, 6])), [['x1_0', 'x2_2', 'x3_0'], ['x1_0', 'x2_2', 'x3_1'], ['x1_1', 'x2_0', 'x3_0']]) def test_assignment_indexerror(self): self.assertRaises(IndexError, self.phi.assignment, [10]) self.assertRaises(IndexError, self.phi.assignment, [1, 3, 10, 5]) self.assertRaises(IndexError, self.phi.assignment, np.array([1, 3, 10, 5])) # def test_get_variables(self): # self.assertListEqual(sorted(self.phi.get_variables()), ['x1', 'x2', 'x3']) # self.assertListEqual(sorted(self.phi1.get_variables()), ['x1', 'x2', 'x3']) # def test_get_value(self): # self.assertAlmostEqual(self.phi1.get_value({'x1': 1, 'x2': 2, 'x3': 0, 'x4': 2, 'x5': 1}), 5.0) # self.assertAlmostEqual(self.phi1.get_value([1, 1, 1]), 9.0) def test_get_cardinality(self): self.assertEqual(self.phi.get_cardinality('x1'), 2) self.assertEqual(self.phi.get_cardinality('x2'), 2) self.assertEqual(self.phi.get_cardinality('x3'), 2) def test_get_cardinality_scopeerror(self): self.assertRaises(exceptions.ScopeError, self.phi.get_cardinality, 'x4') def test_marginalize(self): self.phi1.marginalize('x1') np_test.assert_array_equal(self.phi1.values, np.array([6, 8, 10, 12, 14, 16])) self.phi1.marginalize(['x2']) np_test.assert_array_equal(self.phi1.values, np.array([30, 36])) self.phi1.marginalize('x3') np_test.assert_array_equal(self.phi1.values, np.array([66])) def test_marginalize_scopeerror(self): self.assertRaises(exceptions.ScopeError, self.phi.marginalize, 'x4') self.assertRaises(exceptions.ScopeError, self.phi.marginalize, ['x4']) self.phi.marginalize('x1') self.assertRaises(exceptions.ScopeError, self.phi.marginalize, 'x1') def test_normalize(self): self.phi1.normalize() np_test.assert_almost_equal(self.phi1.values, np.array( [0, 0.01515152, 0.03030303, 0.04545455, 0.06060606, 0.07575758, 0.09090909, 0.10606061, 0.12121212, 0.13636364, 0.15151515, 0.16666667])) # def test_maximize(self): # self.phi1.maximize(['x1']) # max_val_indices = {'x1':1} # data = [max_val_indices] * 6 # #print(self.phi1) # np_test.assert_array_equal(self.phi1.values, np.array([6,7,8,9,10,11])) # self.assertEqual(self.phi1.data, sorted(data, key=lambda t: sorted(t.keys()))) def test_reduce(self): self.phi1.reduce(['x1_0', 'x2_0']) np_test.assert_array_equal(self.phi1.values, np.array([0, 1])) def test_reduce_typeerror(self): self.assertRaises(TypeError, self.phi1.reduce, 'x10') self.assertRaises(TypeError, self.phi1.reduce, ['x10']) def test_reduce_scopeerror(self): self.assertRaises(exceptions.ScopeError, self.phi1.reduce, 'x4_1') def test_reduce_sizeerror(self): self.assertRaises(exceptions.SizeError, self.phi1.reduce, 'x3_5') def test_identity_factor(self): identity_factor = self.phi.identity_factor() self.assertEquals(list(identity_factor.variables), ['x1', 'x2', 'x3']) np_test.assert_array_equal(identity_factor.cardinality, [2, 2, 2]) np_test.assert_array_equal(identity_factor.values, np.ones(8)) def test__str(self): from pgmpy import factors phi = factors.Factor(['x1'], [2], np.ones(2)) self.assertEqual(repr(phi.__str__()), "'x1\\t\\tphi(x1)\\n------------------------\\nx1_0\\t\\t1.0\\nx1_1\\t\\t1.0\\n'") def test_factor_product(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) factor_product = factors.factor_product(phi, phi1) np_test.assert_array_equal(factor_product.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(factor_product.variables, OrderedDict([ ('x1', ['x1_0', 'x1_1']), ('x2', ['x2_0', 'x2_1']), ('x3', ['x3_0', 'x3_1']), ('x4', ['x4_0', 'x4_1'])] )) phi = factors.Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = factors.Factor(['x2', 'x3'], [2, 2], range(4)) factor_product = factors.factor_product(phi, phi1) np_test.assert_array_equal(factor_product.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15])) self.assertEqual(factor_product.variables, OrderedDict( [('x1', ['x1_0', 'x1_1', 'x1_2']), ('x2', ['x2_0', 'x2_1']), ('x3', ['x3_0', 'x3_1'])])) def test_factor_product2(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) factor_product = phi.product(phi1) np_test.assert_array_equal(factor_product.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(factor_product.variables, OrderedDict([ ('x1', ['x1_0', 'x1_1']), ('x2', ['x2_0', 'x2_1']), ('x3', ['x3_0', 'x3_1']), ('x4', ['x4_0', 'x4_1'])] )) phi = factors.Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = factors.Factor(['x2', 'x3'], [2, 2], range(4)) factor_product = phi.product(phi1) np_test.assert_array_equal(factor_product.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15])) self.assertEqual(factor_product.variables, OrderedDict( [('x1', ['x1_0', 'x1_1', 'x1_2']), ('x2', ['x2_0', 'x2_1']), ('x3', ['x3_0', 'x3_1'])])) def test_factor_product_non_factor_arg(self): from pgmpy import factors self.assertRaises(TypeError, factors.factor_product, 1, 2) def test_factor_mul(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) factor_product = phi * phi1 np_test.assert_array_equal(factor_product.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(factor_product.variables, OrderedDict([ ('x1', ['x1_0', 'x1_1']), ('x2', ['x2_0', 'x2_1']), ('x3', ['x3_0', 'x3_1']), ('x4', ['x4_0', 'x4_1'])] )) def test_factor_divide(self): from pgmpy import factors phi1 = factors.Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = factors.Factor(['x1'], [2], [1, 2]) factor_divide = phi1.divide(phi2) phi3 = factors.Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, factor_divide) def test_factor_divide_invalid(self): from pgmpy import factors phi1 = factors.Factor(['x1', 'x2', ], [2, 2], [1, 2, 3, 4]) phi2 = factors.Factor(['x1'], [2], [0, 2]) factor_divide = phi1.divide(phi2) np_test.assert_array_equal(factor_divide.values, np.array([0, 0, 1.5, 2])) def test_factor_divide_no_common_scope(self): from pgmpy import factors phi1 = factors.Factor(['x1', 'x2', ], [2, 2], [1, 2, 3, 4]) phi2 = factors.Factor(['x3'], [2], [0, 2]) self.assertRaises(ValueError, factors.factor_divide, phi1, phi2) def test_factor_divide_non_factor_arg(self): from pgmpy import factors self.assertRaises(TypeError, factors.factor_divide, 1, 1) # def test_sum_values(self): # self.assertEqual(self.phi1.sum_values(), 66) def test_eq(self): self.assertFalse(self.phi == self.phi1) self.assertTrue(self.phi == self.phi) self.assertTrue(self.phi1 == self.phi1) def tearDown(self): del self.phi del self.phi1
def setup(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.ones(8)) self.phi_large = Factor(range(10), [2] * 10, [1] * (2**10))
class TestFactorMethods(unittest.TestCase): def setUp(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.random.uniform(5, 10, size=8)) self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) def test_scope(self): self.assertListEqual(self.phi.scope(), ['x1', 'x2', 'x3']) self.assertListEqual(self.phi1.scope(), ['x1', 'x2', 'x3']) def test_assignment(self): self.assertListEqual(self.phi.assignment([0]), [[State('x1', 0), State('x2', 0), State('x3', 0)]]) self.assertListEqual(self.phi.assignment([4, 5, 6]), [[State('x1', 1), State('x2', 0), State('x3', 0)], [State('x1', 1), State('x2', 0), State('x3', 1)], [State('x1', 1), State('x2', 1), State('x3', 0)]]) self.assertListEqual(self.phi1.assignment(np.array([4, 5, 6])), [[State('x1', 0), State('x2', 2), State('x3', 0)], [State('x1', 0), State('x2', 2), State('x3', 1)], [State('x1', 1), State('x2', 0), State('x3', 0)]]) def test_assignment_indexerror(self): self.assertRaises(IndexError, self.phi.assignment, [10]) self.assertRaises(IndexError, self.phi.assignment, [1, 3, 10, 5]) self.assertRaises(IndexError, self.phi.assignment, np.array([1, 3, 10, 5])) def test_get_cardinality(self): self.assertEqual(self.phi.get_cardinality('x1'), 2) self.assertEqual(self.phi.get_cardinality('x2'), 2) self.assertEqual(self.phi.get_cardinality('x3'), 2) def test_get_cardinality_scopeerror(self): self.assertRaises(exceptions.ScopeError, self.phi.get_cardinality, 'x4') def test_marginalize(self): self.phi1.marginalize('x1') np_test.assert_array_equal(self.phi1.values, np.array([6, 8, 10, 12, 14, 16])) self.phi1.marginalize(['x2']) np_test.assert_array_equal(self.phi1.values, np.array([30, 36])) self.phi1.marginalize('x3') np_test.assert_array_equal(self.phi1.values, np.array([66])) def test_marginalize_scopeerror(self): self.assertRaises(exceptions.ScopeError, self.phi.marginalize, 'x4') self.assertRaises(exceptions.ScopeError, self.phi.marginalize, ['x4']) self.phi.marginalize('x1') self.assertRaises(exceptions.ScopeError, self.phi.marginalize, 'x1') def test_normalize(self): self.phi1.normalize() np_test.assert_almost_equal(self.phi1.values, np.array( [0, 0.01515152, 0.03030303, 0.04545455, 0.06060606, 0.07575758, 0.09090909, 0.10606061, 0.12121212, 0.13636364, 0.15151515, 0.16666667])) def test_reduce(self): self.phi1.reduce([('x1', 0), ('x2', 0)]) np_test.assert_array_equal(self.phi1.values, np.array([0, 1])) def test_reduce1(self): self.phi1.reduce([('x2', 0), ('x1', 0)]) np_test.assert_array_equal(self.phi1.values, np.array([0, 1])) @unittest.skip def test_complete_reduce(self): self.phi1.reduce([('x1', 0), ('x2', 0), ('x3', 1)]) np_test.assert_array_equal(self.phi1.values, np.array([0])) np_test.assert_array_equal(self.phi1.cardinality, np.array([])) np_test.assert_array_equal(self.phi1.variables, OrderedDict()) def test_reduce_typeerror(self): self.assertRaises(ValueError, self.phi1.reduce, 'x10') self.assertRaises(ValueError, self.phi1.reduce, ['x10']) def test_reduce_scopeerror(self): self.assertRaises(ValueError, self.phi1.reduce, ('x4', 1)) def test_reduce_sizeerror(self): self.assertRaises(IndexError, self.phi1.reduce, ('x3', 5)) def test_identity_factor(self): identity_factor = self.phi.identity_factor() self.assertEquals(list(identity_factor.variables), ['x1', 'x2', 'x3']) np_test.assert_array_equal(identity_factor.cardinality, [2, 2, 2]) np_test.assert_array_equal(identity_factor.values, np.ones(8)) def test_factor_product(self): phi = Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = Factor(['x3', 'x4'], [2, 2], range(4)) prod = factor_product(phi, phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(prod.variables, OrderedDict([ ('x1', [State('x1', 0), State('x1', 1)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)]), ('x4', [State('x4', 0), State('x4', 1)])] )) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = factor_product(phi, phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15])) self.assertEqual(prod.variables, OrderedDict( [('x1', [State('x1', 0), State('x1', 1), State('x1', 2)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)])])) def test_factor_product2(self): from pgmpy import factors phi = factors.Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = factors.Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi.product(phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(prod.variables, OrderedDict([ ('x1', [State('x1', 0), State('x1', 1)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)]), ('x4', [State('x4', 0), State('x4', 1)])] )) phi = Factor(['x1', 'x2'], [3, 2], range(6)) phi1 = Factor(['x2', 'x3'], [2, 2], range(4)) prod = phi.product(phi1) np_test.assert_array_equal(prod.values, np.array([0, 0, 2, 3, 0, 2, 6, 9, 0, 4, 10, 15])) self.assertEqual(prod.variables, OrderedDict( [('x1', [State('x1', 0), State('x1', 1), State('x1', 2)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)])])) def test_factor_product_non_factor_arg(self): self.assertRaises(TypeError, factor_product, 1, 2) def test_factor_mul(self): phi = Factor(['x1', 'x2'], [2, 2], range(4)) phi1 = Factor(['x3', 'x4'], [2, 2], range(4)) prod = phi * phi1 np_test.assert_array_equal(prod.values, np.array([0, 0, 0, 0, 0, 1, 2, 3, 0, 2, 4, 6, 0, 3, 6, 9])) self.assertEqual(prod.variables, OrderedDict([ ('x1', [State('x1', 0), State('x1', 1)]), ('x2', [State('x2', 0), State('x2', 1)]), ('x3', [State('x3', 0), State('x3', 1)]), ('x4', [State('x4', 0), State('x4', 1)])] )) def test_factor_divide(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = Factor(['x1'], [2], [1, 2]) div = phi1.divide(phi2) phi3 = Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, div) def test_factor_divide_truediv(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 2, 4]) phi2 = Factor(['x1'], [2], [1, 2]) div = phi1 / phi2 phi3 = Factor(['x1', 'x2'], [2, 2], [1, 2, 1, 2]) self.assertEqual(phi3, div) # def test_factor_divide_dividebyzero(self): # phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 3, 4]) # phi2 = Factor(['x1'], [2], [0, 2]) # self.assertRaises(FloatingPointError, factor_divide, phi1, phi2) # def test_factor_divide_invalidvalue(self): phi1 = Factor(['x1', 'x2'], [3, 2], [0.5, 0.2, 0, 0, 0.3, 0.45]) phi2 = Factor(['x1'], [3], [0.8, 0, 0.6]) div = phi1.divide(phi2) np_test.assert_array_equal(div.values, np.array([0.625, 0.25, 0, 0, 0.5, 0.75])) def test_factor_divide_no_common_scope(self): phi1 = Factor(['x1', 'x2'], [2, 2], [1, 2, 3, 4]) phi2 = Factor(['x3'], [2], [0, 2]) self.assertRaises(ValueError, factor_divide, phi1, phi2) def test_factor_divide_non_factor_arg(self): self.assertRaises(TypeError, factor_divide, 1, 1) def test_eq(self): self.assertFalse(self.phi == self.phi1) self.assertTrue(self.phi == self.phi) self.assertTrue(self.phi1 == self.phi1) def test_eq1(self): phi1 = Factor(['x1', 'x2', 'x3'], [2, 4, 3], range(24)) phi2 = Factor(['x2', 'x1', 'x3'], [4, 2, 3], [0, 1, 2, 12, 13, 14, 3, 4, 5, 15, 16, 17, 6, 7, 8, 18, 19, 20, 9, 10, 11, 21, 22, 23]) self.assertTrue(phi1, phi2) def test_index_for_assignment(self): for i, j in enumerate(itertools.product(*[range(2), range(3), range(2)])): self.assertEqual(self.phi1._index_for_assignment(j), i) def test_maximize1(self): self.phi1.maximize('x1') self.assertEqual(self.phi1, Factor(['x2', 'x3'], [3, 2], [6, 7, 8, 9, 10, 11])) self.phi1.maximize('x2') self.assertEqual(self.phi1, Factor(['x3'], [2], [10, 11])) def test_maximize2(self): self.phi1.maximize(['x1', 'x2']) self.assertEqual(self.phi1, Factor(['x3'], [2], [10, 11])) def test_maximize3(self): self.phi2 = Factor(['x1', 'x2', 'x3'], [3, 2, 2], [0.25, 0.35, 0.08, 0.16, 0.05, 0.07, 0.00, 0.00, 0.15, 0.21, 0.08, 0.18]) self.phi2.maximize('x2') self.assertEqual(self.phi2, Factor(['x1', 'x3'], [3, 2], [0.25, 0.35, 0.05, 0.07, 0.15, 0.21])) def tearDown(self): del self.phi del self.phi1
def test_factor_divide_invalidvalue(self): phi1 = Factor(['x1', 'x2'], [3, 2], [0.5, 0.2, 0, 0, 0.3, 0.45]) phi2 = Factor(['x1'], [3], [0.8, 0, 0.6]) div = phi1.divide(phi2) np_test.assert_array_equal(div.values, np.array([0.625, 0.25, 0, 0, 0.5, 0.75]))
def setUp(self): self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12)) self.phi2 = Factor(['x3', 'x4', 'x1'], [2, 2, 2], range(8)) self.phi3 = Factor(['x5', 'x6', 'x7'], [2, 2, 2], range(8)) self.phi4 = Factor(['x5', 'x7', 'x8'], [2, 2, 2], range(8))
def setUp(self): self.phi = Factor(['x1', 'x2', 'x3'], [2, 2, 2], np.random.uniform(5, 10, size=8)) self.phi1 = Factor(['x1', 'x2', 'x3'], [2, 3, 2], range(12))
def backward_inference(self, variables, evidence=None): """ Backward inference method using belief propagation. Parameters: ---------- variables: list list of variables for which you want to compute the probability evidence: dict a dict key, value pair as {var: state_of_var_observed} None if no evidence Examples: -------- >>> from pgmpy.factors import TabularCPD >>> from pgmpy.models import DynamicBayesianNetwork as DBN >>> from pgmpy.inference import DBNInference >>> dbnet = DBN() >>> dbnet.add_edges_from([(('Z', 0), ('X', 0)), (('X', 0), ('Y', 0)), ... (('Z', 0), ('Z', 1))]) >>> z_start_cpd = TabularCPD(('Z', 0), 2, [[0.5, 0.5]]) >>> x_i_cpd = TabularCPD(('X', 0), 2, [[0.6, 0.9], ... [0.4, 0.1]], ... evidence=[('Z', 0)], ... evidence_card=2) >>> y_i_cpd = TabularCPD(('Y', 0), 2, [[0.2, 0.3], ... [0.8, 0.7]], ... evidence=[('X', 0)], ... evidence_card=2) >>> z_trans_cpd = TabularCPD(('Z', 1), 2, [[0.4, 0.7], ... [0.6, 0.3]], ... evidence=[('Z', 0)], ... evidence_card=2) >>> dbnet.add_cpds(z_start_cpd, z_trans_cpd, x_i_cpd, y_i_cpd) >>> dbnet.initialize_initial_state() >>> dbn_inf = DBNInference(dbnet) >>> dbn_inf.backward_inference([('X', 0)], {('Y', 0):0, ('Y', 1):1, ('Y', 2):1})[('X', 0)].values array([ 0.66594382, 0.33405618]) """ variable_dict = defaultdict(list) for var in variables: variable_dict[var[1]].append(var) time_range = max(variable_dict) interface_nodes_dict = {} if evidence: evid_time_range = max( [time_slice for var, time_slice in evidence.keys()]) time_range = max(time_range, evid_time_range) end_bp = BeliefPropagation(self.start_junction_tree) potential_dict = self.forward_inference(variables, evidence, 'potential') update_factor = self._shift_factor(potential_dict[time_range], 1) factor_values = {} for time_slice in range(time_range, 0, -1): evidence_time = self._get_evidence(evidence, time_slice, 1) evidence_prev_time = self._get_evidence(evidence, time_slice - 1, 0) if evidence_prev_time: interface_nodes_dict = { k: v for k, v in evidence_prev_time.items() if k in self.interface_nodes_0 } if evidence_time: evidence_time.update(interface_nodes_dict) mid_bp = BeliefPropagation(self.one_and_half_junction_tree) self._update_belief(mid_bp, self.in_clique, potential_dict[time_slice - 1]) forward_factor = self._shift_factor(potential_dict[time_slice], 1) self._update_belief(mid_bp, self.out_clique, forward_factor, update_factor) if variable_dict[time_slice]: variable_time = self._shift_nodes(variable_dict[time_slice], 1) new_values = mid_bp.query(variable_time, evidence=evidence_time) changed_values = {} for key in new_values.keys(): new_key = (key[0], time_slice) new_factor = Factor([new_key], new_values[key].cardinality, new_values[key].values) changed_values[new_key] = new_factor factor_values.update(changed_values) clique_phi = self._get_factor(mid_bp, evidence_time) in_clique_phi = self._marginalize_factor(self.interface_nodes_0, clique_phi) update_factor = self._shift_factor(in_clique_phi, 1) out_clique_phi = self._shift_factor(update_factor, 0) self._update_belief(end_bp, self.start_interface_clique, potential_dict[0], out_clique_phi) evidence_0 = self._get_evidence(evidence, 0, 0) if variable_dict[0]: factor_values.update(end_bp.query(variable_dict[0], evidence_0)) return factor_values