def test_multiplication_different_values(self): f1 = Factor( ['A'], { 'A': ['a1', 'a2'] }, { ('a1',): 0.8, ('a2',): 0.2 } ) f2 = Factor( ['B'], { 'B': ['b1', 'b2'] }, { ('b1',): 0.8, ('b2',): 0.2 } ) f3 = f1 * f2 self.assertEqual(f3.variables, ['A', 'B']) self.assertAlmostEqual(f3[('a1', 'b1')], 0.64)
def test_get_assignment_from_index(self): factor = Factor( ['A', 'B', 'C'], { "A": [0, 1], "B": [0, 1, 2], "C": [0, 1], }, { # (A, B, C): P(A, B, C) (0, 0, 0): 0.01, (0, 0, 1): 0.02, (0, 1, 0): 0.03, (0, 1, 1): 0.04, (0, 2, 0): 0.05, (0, 2, 1): 0.05, (1, 0, 0): 0.06, (1, 0, 1): 0.07, (1, 1, 0): 0.08, (1, 1, 1): 0.09, (1, 2, 0): 0.1, (1, 2, 1): 0.4, }) self.assertEquals( factor._get_assignment_from_index(3), (0, 1, 1)) self.assertEquals( factor._get_assignment_from_index(10), (1, 2, 0))
def test_marginalize(self): factor = Factor( ['A', 'B', 'C'], { "A": [0, 1], "B": [0, 1, 2], "C": [0, 1], }, { # (A, B, C): P(A, B, C) (0, 0, 0): 0.01, (0, 0, 1): 0.02, (0, 1, 0): 0.03, (0, 1, 1): 0.04, (0, 2, 0): 0.05, (0, 2, 1): 0.05, (1, 0, 0): 0.06, (1, 0, 1): 0.07, (1, 1, 0): 0.08, (1, 1, 1): 0.09, (1, 2, 0): 0.1, (1, 2, 1): 0.4, }) factor_a = factor.marginalize(["A"]) self.assertAlmostEqual(factor_a[(0,)], 0.2) self.assertAlmostEqual(factor_a[(1,)], 0.8) factor_ac = factor.marginalize(["A", "C"]) self.assertAlmostEqual(factor_ac[(0, 0)], 0.09)
def test_multiplication(self): f1 = Factor( ['A', 'B'], { 'A': ['a', 'b'], 'B': [0, 1, 2] }, { ('a', 0): 0.1, ('a', 1): 0.15, ('a', 2): 0.2, ('b', 0): 0.25, ('b', 1): 0.25, ('b', 2): 0.05, }) f2 = Factor( ['B', 'C'], { 'B': [0, 1, 2], 'C': [0, 1] }, { (0, 0): 0.1, (0, 1): 0.15, (1, 0): 0.2, (1, 1): 0.25, (2, 0): 0.25, (2, 1): 0.05, }) f3 = f1 * f2 self.assertEqual(f3.variables, ['A', 'B', 'C']) self.assertAlmostEqual(f3[('a', 0, 0)], f1[('a', 0)] * f2[(0, 0)]) self.assertAlmostEqual(f3[('b', 1, 0)], f1[('b', 1)] * f2[(1, 0)]) self.assertAlmostEqual(f3[('b', 2, 1)], f1[('b', 2)] * f2[(2, 1)])
def test_rename(self): f = Factor( ['A', 'B'], { 'A': ['a1', 'a2'], 'B': ['b1', 'b2'] }, { ('a1', 'b1'): 0.3, ('a1', 'b2'): 0.2, ('a2', 'b1'): 0.7, ('a2', 'b2'): 0.8, }) f.rename_variables({'A': 'Z'}) self.assertAlmostEqual(f[('a1', 'b1')], 0.3) f1 = Factor( ['Z'], { 'Z': ['a1', 'a2'], }, { ('a1',): 0.5, ('a2',): 0.5, }) f2 = f * f1 self.assertAlmostEqual(f2[('b1', 'a1')], 0.15) self.assertAlmostEqual(f2[('b1', 'a2')], 0.35)
def constant_factor(variables, variables_dict, length, logarithmetic=True): if logarithmetic: factor = Factor(variables, variables_dict, to_log(np.ones(length)), logarithmetic) else: factor = Factor(variables, variables_dict, np.ones(length), logarithmetic) return factor
def test_parents_normalize(self): f = Factor(['A', 'B'], { 'A': ['a1', 'a2'], 'B': ['b1', 'b2'] }, { ('a1', 'b1'): 1, ('a2', 'b1'): 1, ('a1', 'b2'): 1, ('a2', 'b2'): 1 }) f.normalize(parents=['B']) self.assertAlmostEqual(f[('a1', 'b1')], 0.5)
def test_fast_mul_correct(self): f1 = Factor(['B'], {'B': [0, 1, 2]}, { (0, ): 0.2, (1, ): 0.25, (2, ): 0.55, }) f2 = Factor(['B'], {'B': [0, 1]}, { (0, ): 0.7, (1, ): 0.3, }) self.assertRaises(ValueError, lambda: f2 * f1)
def test_apply_op_same(self): f = Factor(['A'], {'A': ['a1', 'a2']}, {('a1',): 0.8, ('a2',): 0.2}, logarithmetic=False) g = Factor(['A'], {'A': ['a1', 'a2']}, { ('a1',): 0.5, ('a2',): 0.5, }, logarithmetic=False) h = f._apply_op_same(g, np.multiply) self.assertAlmostEqual(h[('a1',)], 0.4) self.assertAlmostEqual(h[('a2',)], 0.1) h = f._apply_op_same(g, np.add) self.assertAlmostEqual(h[('a1',)], 1.3) self.assertAlmostEqual(h[('a2',)], 0.7) h = f._apply_op_same(g, np.divide) self.assertAlmostEqual(h[('a1',)], 1.6) self.assertAlmostEqual(h[('a2',)], 0.4) h = f._apply_op_same(g, np.subtract) self.assertAlmostEqual(h[('a1',)], 0.3) self.assertAlmostEqual(h[('a2',)], -0.3) h = f._apply_op_same(g, np.power) self.assertAlmostEqual(h[('a1',)], 0.894427191) self.assertAlmostEqual(h[('a2',)], 0.447213595)
def test_dir_tight(self): theta = DirichletParameterNode( 'theta', Factor(['X', 'ZDummy'], { 'X': ['same', 'diff'], 'ZDummy': ['dummy'] }, { ('same', 'dummy'): 1, ('diff', 'dummy'): 1, }, logarithmetic=False)) X = DiscreteVariableNode('X', ['same', 'diff'], logarithmetic=False) D = DiscreteVariableNode('ZDummy', ['dummy'], logarithmetic=False) f = DirichletFactorNode('f') X.observed({('same', ): 0.8, ('diff', ): 0.2}) f.connect(theta) f.connect(X, parent=False) f.connect(D) X.message_to(f) D.message_to(f) f.update() f.message_to(theta) theta.message_to(f) X.observed({('same', ): 0.5, ('diff', ): 0.7}) X.message_to(f) f.update() f.message_to(theta)
def test_observed_complex(self): s1 = DiscreteVariableNode('s1', ['a', 'b']) s2 = DiscreteVariableNode('s2', ['a', 'b']) f = DiscreteFactorNode( 'f', Factor(['s1', 's2'], { 's1': ['a', 'b'], 's2': ['a', 'b'], }, { ('a', 'a'): 1, ('a', 'b'): 0.5, ('b', 'a'): 0, ('b', 'b'): 0.5 })) s1.connect(f) s2.connect(f) s2.observed({('a', ): 0.7, ('b', ): 0.3}) s1.send_messages() s2.send_messages() f.update() f.normalize() f.send_messages() s1.update() s1.normalize() self.assertClose(s1.belief[('a', )], 0.85) self.assertClose(s1.belief[('b', )], 0.15) self.assertClose(s2.belief[('a', )], 0.7)
def test_ep_tight(self): theta = DirichletParameterNode( 'theta', Factor(['X', 'ZDummy'], { 'X': ['same', 'diff'], 'ZDummy': ['dummy'] }, { ('same', 'dummy'): 1, ('diff', 'dummy'): 1, }, logarithmetic=False)) X = DiscreteVariableNode('X', ['same', 'diff'], logarithmetic=False) D = DiscreteVariableNode('ZDummy', ['dummy'], logarithmetic=False) f = DirichletFactorNode('f') X.observed({('same', ): 0.50001, ('diff', ): 0.49999}) f.connect(theta) f.connect(X, parent=False) f.connect(D) # Add nodes to lbp. lbp = LBP(strategy='tree') lbp.add_nodes([f, X, D, theta]) for i in range(50): lbp.run() #print theta.alpha.pretty_print(precision=5) lbp.init_messages() print theta.alpha.pretty_print(precision=5)
def test_sum_other(self): alpha = Factor(['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1'], }, { ('x0_0', 'x1_0'): 8, ('x0_0', 'x1_1'): 1, ('x0_1', 'x1_0'): 2, ('x0_1', 'x1_1'): 1, }) f = alpha.sum_other() self.assertAlmostEqual(f[('x0_0', 'x1_0')], 4) self.assertAlmostEqual(f[('x0_0', 'x1_1')], 11, places=5) self.assertAlmostEqual(f[('x0_1', 'x1_0')], 10) self.assertAlmostEqual(f[('x0_1', 'x1_1')], 11, places=5)
def test_parents_normalize(self): f = Factor( ['A', 'B'], { 'A': ['a1', 'a2'], 'B': ['b1', 'b2'] }, { ('a1', 'b1'): 1, ('a2', 'b1'): 1, ('a1', 'b2'): 1, ('a2', 'b2'): 1 }) f.normalize(parents=['B']) self.assertAlmostEqual(f[('a1', 'b1')], 0.5)
def test_parameter_simple(self): alpha = DirichletParameterNode( 'theta', Factor(['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0'], }, { ('x0_0', 'x1_0'): 3, ('x0_1', 'x1_0'): 1, })) factor = DirichletFactorNode('factor') x0 = DiscreteVariableNode('X0', ['x0_0', 'x0_1']) x1 = DiscreteVariableNode('X1', ['x1_0']) x1.observed({('x1_0', ): 1}) factor.connect(alpha) factor.connect(x0, parent=False) factor.connect(x1, parent=True) x0.message_to(factor) x1.message_to(factor) factor.update() self.assertAlmostEqual(factor.belief[('x0_0', 'x1_0')], 0.5) factor.message_to(x0) factor.message_to(x1) x0.update() self.assertAlmostEqual(x0.belief[('x0_0', )], 3.0 / 4) factor.message_to(alpha)
def test_two_factors_one_theta2(self): alpha = DirichletParameterNode( 'theta', Factor(['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1', 'x1_2'], }, { ('x0_0', 'x1_0'): 1, ('x0_0', 'x1_1'): 8, ('x0_0', 'x1_2'): 1, ('x0_1', 'x1_0'): 1, ('x0_1', 'x1_1'): 2, ('x0_1', 'x1_2'): 1, })) f1 = DirichletFactorNode('f1', aliases={'X0': 'X0_a', 'X1': 'X1_a'}) x0 = DiscreteVariableNode('X0_a', ['x0_0', 'x0_1']) x1 = DiscreteVariableNode('X1_a', ['x1_0', 'x1_1', 'x1_2']) f2 = DirichletFactorNode('f2', aliases={'X0': 'X0_b', 'X1': 'X1_b'}) x2 = DiscreteVariableNode('X0_b', ['x0_0', 'x0_1']) x3 = DiscreteVariableNode('X1_b', ['x1_0', 'x1_1', 'x1_2']) f1.connect(x0, parent=False) f1.connect(x1) f2.connect(x2, parent=False) f2.connect(x3) f1.connect(alpha) f2.connect(alpha) alpha.aliases = { 'X0_a': 'X0', 'X0_b': 'X0', 'X1_a': 'X1', 'X1_b': 'X1' } x0.observed({('x0_0', ): 1}) x1.observed({('x1_0', ): 1}) x2.observed({('x0_1', ): 1}) x3.observed({('x1_0', ): 1}) x0.message_to(f1) x1.message_to(f1) x2.message_to(f2) x3.message_to(f2) f1.update() f2.update() f1.message_to(alpha) f2.message_to(alpha) self.assertAlmostEqual(alpha.alpha[('x0_0', 'x1_0')], 2, places=5) self.assertAlmostEqual(alpha.alpha[('x0_1', 'x1_0')], 2, places=5)
def test_mul_div(self): factor = Factor( ['A', 'B', 'C'], { "A": [0, 1], "B": [0, 1, 2], "C": [0, 1], }, { # (A, B, C): P(A, B, C) (0, 0, 0): 0.01, (0, 0, 1): 0.02, (0, 1, 0): 0.03, (0, 1, 1): 0.04, (0, 2, 0): 0.05, (0, 2, 1): 0.05, (1, 0, 0): 0.06, (1, 0, 1): 0.07, (1, 1, 0): 0.08, (1, 1, 1): 0.09, (1, 2, 0): 0.1, (1, 2, 1): 0.4, }) f2 = Factor( ['B', 'C'], { 'B': [0, 1, 2], 'C': [0, 1] }, { (0, 0): 0.1, (0, 1): 0.15, (1, 0): 0.2, (1, 1): 0.25, (2, 0): 0.25, (2, 1): 0.05, }) f3 = factor * f2 f4 = f3 / f2 for i in range(f4.factor_length): assignment = f4._get_assignment_from_index(i) self.assertAlmostEqual(f4[assignment], factor[assignment])
def test_division(self): factor = Factor( ['A', 'B', 'C'], { "A": [0, 1], "B": [0, 1, 2], "C": [0, 1], }, { # (A, B, C): P(A, B, C) (0, 0, 0): 0.01, (0, 0, 1): 0.02, (0, 1, 0): 0.03, (0, 1, 1): 0.04, (0, 2, 0): 0.05, (0, 2, 1): 0.05, (1, 0, 0): 0.06, (1, 0, 1): 0.07, (1, 1, 0): 0.08, (1, 1, 1): 0.09, (1, 2, 0): 0.1, (1, 2, 1): 0.4, }) f2 = Factor( ['B', 'C'], { 'B': [0, 1, 2], 'C': [0, 1] }, { (0, 0): 0.1, (0, 1): 0.15, (1, 0): 0.2, (1, 1): 0.25, (2, 0): 0.25, (2, 1): 0.05, }) f3 = factor / f2 self.assertAlmostEqual(f3[(0, 0, 0)], 0.1) self.assertAlmostEqual(f3[(1, 0, 1)], 7 / 15.0) self.assertAlmostEqual(f3[(1, 2, 0)], 0.4)
def test_observations(self): f = Factor( ['X'], { 'X': [0, 1], }, { (0,): 0.8, (1,): 0.2, } ) self.assertAlmostEqual(f[(0,)], 0.8) f.observed({(1,): 0.2}) self.assertAlmostEqual(f[(0,)], 0) self.assertAlmostEqual(f[(1,)], 0.2) f.observed(None) self.assertAlmostEqual(f[(0,)], 0.8) self.assertAlmostEqual(f[(1,)], 0.2)
def test_sum_other(self): alpha = Factor( ['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1'], }, { ('x0_0', 'x1_0'): 8, ('x0_0', 'x1_1'): 1, ('x0_1', 'x1_0'): 2, ('x0_1', 'x1_1'): 1, } ) f = alpha.sum_other() self.assertAlmostEqual(f[('x0_0', 'x1_0')], 4) self.assertAlmostEqual(f[('x0_0', 'x1_1')], 11, places=5) self.assertAlmostEqual(f[('x0_1', 'x1_0')], 10) self.assertAlmostEqual(f[('x0_1', 'x1_1')], 11, places=5)
def test_expected_value_squared(self): alpha = Factor( ['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1'], }, { ('x0_0', 'x1_0'): 8, ('x0_0', 'x1_1'): 1, ('x0_1', 'x1_0'): 2, ('x0_1', 'x1_1'): 1, } ) sum_of_alphas = alpha.marginalize(['X1']) expected_value_squared = alpha * (alpha + 1) / (sum_of_alphas * (sum_of_alphas + 1)) self.assertAlmostEqual(expected_value_squared[('x0_0', 'x1_0')], 72.0/110) self.assertAlmostEqual(expected_value_squared[('x0_0', 'x1_1')], 1.0/3) self.assertAlmostEqual(expected_value_squared[('x0_1', 'x1_0')], 6.0/110) self.assertAlmostEqual(expected_value_squared[('x0_1', 'x1_1')], 1.0/3)
def test_setitem(self): f = Factor(['X'], { 'X': [0, 1], }, { (0, ): 0.8, (1, ): 0.2, }) self.assertAlmostEqual(f[(0, )], 0.8) f[(0, )] = 0.6 self.assertAlmostEqual(f[(0, )], 0.6)
def test_add(self): X0 = Factor(['X0'], {'X0': ['x0_0', 'x0_1']}, { ('x0_0', ): 1, ('x0_1', ): 0, }) f = X0 + 1 self.assertAlmostEqual(f[('x0_0', )], 2) self.assertAlmostEqual(f[('x0_1', )], 1) f = X0 + X0 self.assertAlmostEqual(f[('x0_0', )], 2) self.assertAlmostEqual(f[('x0_1', )], 0)
def test_power(self): f = Factor(['A', 'B'], { 'A': ['a1', 'a2'], 'B': ['b1', 'b2'] }, { ('a1', 'b1'): 0.3, ('a1', 'b2'): 0.2, ('a2', 'b1'): 0.7, ('a2', 'b2'): 0.8, }) f1 = f**2 self.assertAlmostEqual(f[('a1', 'b1')], 0.3) self.assertAlmostEqual(f1[('a1', 'b1')], 0.09)
def test_fast_mul(self): f1 = Factor(['A', 'B'], { 'A': ['a', 'b'], 'B': [0, 1, 2] }, { ('a', 0): 0.1, ('a', 1): 0.15, ('a', 2): 0.2, ('b', 0): 0.25, ('b', 1): 0.25, ('b', 2): 0.05, }) f2 = f1 * f1 self.assertAlmostEqual(f2[('a', 2)], 0.04) self.assertAlmostEqual(f2[('b', 1)], 0.0625)
def test_fast_div(self): f2 = Factor(['B', 'C'], { 'B': [0, 1, 2], 'C': [0, 1] }, { (0, 0): 0.1, (0, 1): 0.15, (1, 0): 0.2, (1, 1): 0.25, (2, 0): 0.25, (2, 1): 0.05, }) f3 = f2 / f2 self.assertAlmostEqual(f3[0, 0], 1) self.assertAlmostEqual(f3[1, 1], 1)
def test_network(self): # Create network. hid = DiscreteVariableNode("hid", ["save", "del"]) obs = DiscreteVariableNode("obs", ["osave", "odel"]) fact_h1_o1 = DiscreteFactorNode("fact_h1_o1", Factor( ['hid', 'obs'], { "hid": ["save", "del"], "obs": ["osave", "odel"] }, { ("save", "osave"): 0.3, ("save", "odel"): 0.6, ("del", "osave"): 0.7, ("del", "odel"): 0.4 })) # Add edges. obs.connect(fact_h1_o1) fact_h1_o1.connect(hid) # 1. Without observations, send_messages used. obs.send_messages() fact_h1_o1.send_messages() hid.update() hid.normalize() self.assertClose(hid.belief[("save",)], 0.45) # 2. Observed value, message_to and update_belief used. obs.observed({("osave",): 1}) obs.message_to(fact_h1_o1) fact_h1_o1.update() fact_h1_o1.message_to(hid) hid.update() hid.normalize() self.assertClose(hid.belief[("save",)], 0.3) # 3. Without observations, send_messages used. obs.observed(None) obs.send_messages() fact_h1_o1.send_messages() hid.update() hid.normalize() self.assertClose(hid.belief[("save",)], 0.45)
def test_parameter(self): alpha = DirichletParameterNode('theta', Factor( ['X0', 'X1'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1', 'x1_2'], }, { ('x0_0', 'x1_0'): 1, ('x0_0', 'x1_1'): 8, ('x0_0', 'x1_2'): 1, ('x0_1', 'x1_0'): 1, ('x0_1', 'x1_1'): 2, ('x0_1', 'x1_2'): 1, } )) factor = DirichletFactorNode('factor') x0 = DiscreteVariableNode('X0', ['x0_0', 'x0_1']) x1 = DiscreteVariableNode('X1', ['x1_0', 'x1_1', 'x1_2']) x0.observed({('x0_0',): 1}) x1.observed({('x1_0',): 0.7, ('x1_1',): 0.2, ('x1_2',): 0.1}) factor.connect(alpha) factor.connect(x0, parent=False) factor.connect(x1, parent=True) x0.message_to(factor) x1.message_to(factor) factor.update() factor.message_to(x0) factor.message_to(x1) x0.update() factor.message_to(alpha) print alpha.alpha alpha.message_to(factor) factor.update() factor.message_to(alpha) print alpha.alpha
def test_observations(self): f = Factor(['X'], { 'X': [0, 1], }, { (0, ): 0.8, (1, ): 0.2, }) self.assertAlmostEqual(f[(0, )], 0.8) f.observed({(1, ): 0.2}) self.assertAlmostEqual(f[(0, )], 0) self.assertAlmostEqual(f[(1, )], 0.2) f.observed(None) self.assertAlmostEqual(f[(0, )], 0.8) self.assertAlmostEqual(f[(1, )], 0.2)
def test_strides(self): factor = Factor( ['A', 'B', 'C'], { "A": [0, 1], "B": [0, 1, 2], "C": [0, 1], }, { # (A, B, C): P(A, B, C) (0, 0, 0): 0.01, (0, 0, 1): 0.02, (0, 1, 0): 0.03, (0, 1, 1): 0.04, (0, 2, 0): 0.05, (0, 2, 1): 0.05, (1, 0, 0): 0.06, (1, 0, 1): 0.07, (1, 1, 0): 0.08, (1, 1, 1): 0.09, (1, 2, 0): 0.1, (1, 2, 1): 0.4, }) self.assertEquals(factor.strides, {"A": 6, "B": 2, "C": 1})
def test_alphas(self): alpha = Factor( ['X0', 'X1', 'X2', 'X3'], { 'X0': ['x0_0', 'x0_1'], 'X1': ['x1_0', 'x1_1'], 'X2': ['x2_0', 'x2_1'], 'X3': ['x3_0', 'x3_1'], }, { ('x0_0', 'x1_0', 'x2_0', 'x3_0'): 1, ('x0_0', 'x1_0', 'x2_0', 'x3_1'): 1, ('x0_0', 'x1_0', 'x2_1', 'x3_0'): 1, ('x0_0', 'x1_0', 'x2_1', 'x3_1'): 2, ('x0_0', 'x1_1', 'x2_0', 'x3_0'): 5, ('x0_0', 'x1_1', 'x2_0', 'x3_1'): 1, ('x0_0', 'x1_1', 'x2_1', 'x3_0'): 3, ('x0_0', 'x1_1', 'x2_1', 'x3_1'): 1, ('x0_1', 'x1_0', 'x2_0', 'x3_0'): 1, ('x0_1', 'x1_0', 'x2_0', 'x3_1'): 1, ('x0_1', 'x1_0', 'x2_1', 'x3_0'): 1, ('x0_1', 'x1_0', 'x2_1', 'x3_1'): 1, ('x0_1', 'x1_1', 'x2_0', 'x3_0'): 1, ('x0_1', 'x1_1', 'x2_0', 'x3_1'): 1, ('x0_1', 'x1_1', 'x2_1', 'x3_0'): 1, ('x0_1', 'x1_1', 'x2_1', 'x3_1'): 1, }) X0 = Factor( ['X0'], { 'X0': ['x0_0', 'x0_1'] }, { ('x0_0',): 1, ('x0_1',): 0, }) X1 = Factor( ['X1'], { 'X1': ['x1_0', 'x1_1'] }, { ('x1_0',): 0, ('x1_1',): 1, }) X2 = Factor( ['X2'], { 'X2': ['x2_0', 'x2_1'] }, { ('x2_0',): 1, ('x2_1',): 0, }) X3 = Factor( ['X3'], { 'X3': ['x3_0', 'x3_1'] }, { ('x3_0',): 1, ('x3_1',): 0, }) # Compute message to X1. cavity = X0 * X2 * X3 self.assertAlmostEqual(cavity[('x0_0', 'x2_0', 'x3_0')], 1.0) sum_of_alphas = alpha.marginalize(['X1', 'X2', 'X3']) self.assertAlmostEqual(sum_of_alphas[('x1_1', 'x2_0', 'x3_0')], 6) expected_value = alpha / sum_of_alphas self.assertAlmostEqual(expected_value[('x0_0', 'x1_1', 'x2_1', 'x3_0')], 0.75) factor = cavity * expected_value self.assertAlmostEqual(factor[('x0_0', 'x1_1', 'x2_0', 'x3_0')], 5.0/6) msg = factor.marginalize(['X1']) self.assertAlmostEqual(msg[('x1_0',)], 0.5) # Compute message to X0. cavity = X1 * X2 * X3 self.assertAlmostEqual(cavity[('x1_1', 'x2_0', 'x3_0')], 1.0) self.assertAlmostEqual(cavity[('x1_0', 'x2_0', 'x3_0')], 0.0) sum_of_alphas = alpha.marginalize(['X1', 'X2', 'X3']) expected_value = alpha / sum_of_alphas self.assertAlmostEqual(expected_value[('x0_0', 'x1_1', 'x2_0', 'x3_1')], 0.5) factor = cavity * expected_value msg = factor.marginalize(['X0']) self.assertAlmostEqual(msg[('x0_0',)], 5.0/6) # Compute w_0. sum_of_alphas = alpha.marginalize(['X1', 'X2', 'X3']) expected_value = alpha / sum_of_alphas belief = X0 * X1 * X2 * X3 factor = belief * expected_value msg = factor.marginalize(['X1', 'X2', 'X3']) w0 = msg.sum_other() self.assertAlmostEqual(w0[('x1_0', 'x2_0', 'x3_0')], 5.0/6) # Compute w_k. # When we want to compute w_k for each j, we can just compute the belief. # Each j is denoted by an assignment of parents, which in this case is # the assignment of X1, X2, X3, and each k is a value of a child, in # this case it's the value of X0. # For given j and k, we can get the value of w_jk, by getting one row # from w_k. w_k = X0 * X1 * X2 * X3 self.assertAlmostEqual(w_k[('x0_0', 'x1_0', 'x2_0', 'x3_0')], 0) self.assertAlmostEqual(w_k[('x0_0', 'x1_1', 'x2_0', 'x3_0')], 1) # Compute expected value of p(theta) sum_of_alphas = alpha.marginalize(['X1', 'X2', 'X3']) expected_value_0 = alpha / sum_of_alphas sum_of_alphas_plus_1 = alpha.marginalize(['X1', 'X2', 'X3']) sum_of_alphas_plus_1 += 1 expected_values = [w0 * expected_value_0] self.assertAlmostEqual(expected_values[0][('x0_0', 'x1_0', 'x2_0', 'x3_0')], 5.0/12) self.assertAlmostEqual(expected_values[0][('x0_1', 'x1_0', 'x2_0', 'x3_0')], 5.0/12) for k in X0.variable_values['X0']: new_alpha = copy.deepcopy(alpha) for i, item in enumerate(new_alpha): (assignment, value) = item if assignment[0] == k: new_alpha[assignment] += 1 expected_value_k = new_alpha / sum_of_alphas_plus_1 expected_values.append(w_k * expected_value * expected_value_k) expected_value_sum = reduce(operator.add, expected_values)
def test_single_linked(self): f_h_o = { ("save", "osave"): 0.8, ("del", "osave"): 0.2, ("save", "odel"): 0.2, ("del", "odel"): 0.8, } f_h_h = { ("save", "save"): 0.9, ("del", "save"): 0.1, ("save", "del"): 0.1, ("del", "del"): 0.9 } # Create nodes. hid1 = DiscreteVariableNode("hid1", ["save", "del"]) obs1 = DiscreteVariableNode("obs1", ["osave", "odel"]) fact_h1_o1 = DiscreteFactorNode( "fact_h1_o1", Factor(['hid1', 'obs1'], { "hid1": ["save", "del"], "obs1": ["osave", "odel"] }, f_h_o)) hid2 = DiscreteVariableNode("hid2", ["save", "del"]) obs2 = DiscreteVariableNode("obs2", ["osave", "odel"]) fact_h2_o2 = DiscreteFactorNode( "fact_h2_o2", Factor(['hid2', 'obs2'], { "hid2": ["save", "del"], "obs2": ["osave", "odel"] }, f_h_o)) fact_h1_h2 = DiscreteFactorNode( "fact_h1_h2", Factor(['hid1', 'hid2'], { "hid1": ["save", "del"], "hid2": ["save", "del"], }, f_h_h)) hid3 = DiscreteVariableNode("hid3", ["save", "del"]) obs3 = DiscreteVariableNode("obs3", ["osave", "odel"]) fact_h3_o3 = DiscreteFactorNode( "fact_h3_o3", Factor(['hid3', 'obs3'], { "hid3": ["save", "del"], "obs3": ["osave", "odel"] }, f_h_o)) fact_h2_h3 = DiscreteFactorNode( "fact_h2_h3", Factor(['hid2', 'hid3'], { "hid2": ["save", "del"], "hid3": ["save", "del"], }, f_h_h)) # Connect nodes. obs1.connect(fact_h1_o1) obs2.connect(fact_h2_o2) obs3.connect(fact_h3_o3) fact_h1_o1.connect(hid1) fact_h2_o2.connect(hid2) fact_h3_o3.connect(hid3) hid1.connect(fact_h1_h2) hid2.connect(fact_h1_h2) hid2.connect(fact_h2_h3) hid3.connect(fact_h2_h3) # Add nodes to lbp. lbp = LBP(strategy='tree') lbp.add_nodes([ obs1, obs2, obs3, fact_h1_o1, fact_h2_o2, fact_h3_o3, hid1, hid2, hid3, fact_h1_h2, fact_h2_h3 ]) obs1.observed({('osave', ): 1}) lbp.run() self.assertAlmostEqual(hid1.belief[('save', )], 0.8) self.assertAlmostEqual(hid2.belief[('save', )], 0.8 * 0.9 + 0.2 * 0.1, places=6) self.assertAlmostEqual(hid3.belief[('save', )], hid2.belief[('save', )] * 0.9 + hid2.belief[('del', )] * 0.1, places=6)
def test_ep(self): # Create nodes. hid1 = DiscreteVariableNode("hid1", ["save", "del"]) obs1 = DiscreteVariableNode("obs1", ["osave", "odel"]) fact_h1_o1 = DirichletFactorNode("fact_h1_o1") theta_h1_o1 = DirichletParameterNode( 'theta_h1_o1', Factor(['hid1', 'obs1'], { "hid1": ["save", "del"], "obs1": ["osave", "odel"] }, { ("save", "osave"): 1, ("save", "odel"): 1, ("del", "osave"): 1, ("del", "odel"): 1, })) hid2 = DiscreteVariableNode("hid2", ["save", "del"]) obs2 = DiscreteVariableNode("obs2", ["osave", "odel"]) fact_h2_o2 = DirichletFactorNode("fact_h2_o2") theta_h2_o2 = DirichletParameterNode( 'theta_h2_o2', Factor(['hid2', 'obs2'], { "hid2": ["save", "del"], "obs2": ["osave", "odel"] }, { ("save", "osave"): 1, ("save", "odel"): 1, ("del", "osave"): 1, ("del", "odel"): 1, })) fact_h1_h2 = DiscreteFactorNode( "fact_h1_h2", Factor(['hid1', 'hid2'], { "hid1": ["save", "del"], "hid2": ["save", "del"], }, { ("save", "save"): 0.9, ("save", "del"): 0.1, ("del", "save"): 0, ("del", "del"): 1 })) # Connect nodes. obs1.connect(fact_h1_o1, parent=False) fact_h1_o1.connect(hid1) fact_h1_o1.connect(theta_h1_o1) obs2.connect(fact_h2_o2, parent=False) fact_h2_o2.connect(hid2) fact_h2_o2.connect(theta_h2_o2) hid1.connect(fact_h1_h2) hid2.connect(fact_h1_h2) # Add nodes to lbp. lbp = LBP(strategy='tree') lbp.add_nodes([ obs1, obs2, fact_h1_o1, fact_h2_o2, theta_h1_o1, theta_h2_o2, hid1, hid2, fact_h1_h2 ]) obs1.observed({('osave', ): 1}) obs2.observed({('osave', ): 1}) hid1.observed({('save', ): 1}) hid2.observed({('save', ): 1}) for i in range(100): lbp.run() print theta_h1_o1.alpha.pretty_print(precision=5) lbp.init_messages()