示例#1
0
    def add_separator(self, separator):
        """
        Add a valid separator made up of variables to the list of separators
        Variables can be both list/dict of references or a list of variable names

        :type separator: list[str] or dict[Variable,None] or list[Variable]
        :return: None
        """
        if all(isinstance(x, str) for x in separator):
            separator = [self.get_variable_by_name(name) for name in separator]

        separator = dict.fromkeys(separator)
        if not separator.keys() <= self._variables.keys():
            raise AttributeError(
                "The given separator is not valid for the junction tree")
        new_node = Node(BeliefTable(separator))
        self._separators.append(new_node)
示例#2
0
    def add_clique(self, clique):
        """
        Add a valid clique made up of variables to the list of cliques
        Variables can be both list/dict of references or a list of variable names

        :type clique: list[str] or dict[Variable,None] or list[Variable]
        :return: None
        """
        if all(isinstance(x, str) for x in clique):
            clique = [self.get_variable_by_name(name) for name in clique]

        clique = dict.fromkeys(clique)
        if not clique.keys() <= self._variables.keys():
            raise AttributeError(
                "The given clique is not valid for the junction tree")
        new_node = Node(BeliefTable(clique))
        self._cliques.append(new_node)
示例#3
0
    def test_marginalization(self):
        # Check that it doesn't allow marginalization on sets greater than the variables of the table
        dict1 = dict.fromkeys([self.A])
        dict2 = dict.fromkeys([self.A, self.B])
        arr1 = np.arange(2).reshape(2)

        t1 = BeliefTable(dict1, arr1)
        self.assertRaises(AttributeError, t1.marginalize, dict2)

        # Test marginalization on single variable
        dict1 = dict.fromkeys([self.A, self.B])
        dict2 = dict.fromkeys([self.A])

        arr1 = np.arange(4).reshape((2, 2))

        t1 = BeliefTable(dict1, arr1)
        t2 = t1.marginalize(dict2)

        self.assertEqual(t2.get_prob(0), 1)
        self.assertEqual(t2.get_prob(1), 5)

        # Test marginalization on one variable from 3
        dict1 = dict.fromkeys([self.A, self.B, self.C])
        dict2 = dict.fromkeys([self.C])

        arr1 = np.arange(8).reshape((2, 2,2))

        t1 = BeliefTable(dict1, arr1)
        t2 = t1.marginalize(dict2)

        self.assertEqual(t2.get_prob(0), 12)
        self.assertEqual(t2.get_prob(1), 16)

        # Test marginalization on two variables
        dict1 = dict.fromkeys([self.A, self.B, self.C])
        dict2 = dict.fromkeys([self.A, self.C])

        arr1 = np.arange(8).reshape((2, 2,2))

        t1 = BeliefTable(dict1, arr1)
        t2 = t1.marginalize(dict2)

        self.assertEqual(t2.get_prob((0, 0)), 2)
        self.assertEqual(t2.get_prob((0, 1)), 4)
        self.assertEqual(t2.get_prob((1, 0)), 10)
        self.assertEqual(t2.get_prob((1, 1)), 12)
示例#4
0
    def test_collect_and_distribute(self):
        # Apple tree example, 2 clusters
        tS = BeliefTable(dict.fromkeys([self.S]), np.zeros(2))
        tD = BeliefTable(dict.fromkeys([self.D]), np.zeros(2))
        tL = BeliefTable(dict.fromkeys([self.S, self.D, self.L]), np.zeros((2, 2, 2)))
        tH = BeliefTable(dict.fromkeys([self.H, self.S]))

        tS.set_probability_dict({'S': 0}, 0.9)
        tS.set_probability_dict({'S': 1}, 0.1)

        tD.set_probability_dict({'D': 0}, 0.9)
        tD.set_probability_dict({'D': 1}, 0.1)

        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 0}, 0.98)
        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 1}, 0.02)
        tL.set_probability_dict({'S': 0, 'D': 1, 'L': 0}, 0.15)
        tL.set_probability_dict({'D': 1, 'L': 1, 'S': 0}, 0.85)
        tL.set_probability_dict({'L': 0, 'S': 1, 'D': 0}, 0.1)
        tL.set_probability_dict({'S': 1, 'D': 0, 'L': 1}, 0.9)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 0}, 0.05)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 1}, 0.95)

        tH.set_probability_dict({'H': 0, 'S': 0}, 0.8)
        tH.set_probability_dict({'H': 0, 'S': 1}, 0.3)
        tH.set_probability_dict({'H': 1, 'S': 0}, 0.2)
        tH.set_probability_dict({'H': 1, 'S': 1}, 0.7)

        net = BayesianNet()
        net.add_variable(self.L)
        net.add_variable(self.S)
        net.add_variable(self.D)
        net.add_variable(self.H)

        net.add_dependence('L', 'S')
        net.add_dependence('L', 'D')
        net.add_dependence('H', 'S')

        net.add_prob_table('L', tL)
        net.add_prob_table('S', tS)
        net.add_prob_table('D', tD)
        net.add_prob_table('H', tH)

        jtree = JunctionTree(dict.fromkeys([self.S, self.D, self.L, self.H]))
        jtree.add_clique(['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('S', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('D', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('L', ['S', 'D', 'L'])

        jtree.add_clique(['S', 'H'])
        jtree.set_variable_chosen_clique('H', ['H', 'S'])

        jtree.add_separator(['S'])
        jtree.add_link(['S', 'H'], ['S'])
        jtree.add_link(['S', 'D', 'L'], ['S'])

        jtree.initialize_tables(net)

        jtree.add_evidence('L', 0)
        jtree.add_evidence('H', 1)
        jtree.sum_propagate()

        STable = jtree.calculate_variable_probability('S')
        DTable = jtree.calculate_variable_probability('D')
        LTable = jtree.calculate_variable_probability('L')
        HTable = jtree.calculate_variable_probability('H')

        self.assertAlmostEqual(round(STable.get_prob(0), 4), 0.9604)
        self.assertAlmostEqual(round(STable.get_prob(1), 4), 0.0396)

        self.assertAlmostEqual(round(DTable.get_prob(0), 4), 0.9819)
        self.assertAlmostEqual(round(DTable.get_prob(1), 4), 0.0181)

        self.assertAlmostEqual(round(LTable.get_prob(0), 4), 1)
        self.assertAlmostEqual(round(LTable.get_prob(1), 4), 0)

        self.assertAlmostEqual(round(HTable.get_prob(0), 4), 0)
        self.assertAlmostEqual(round(HTable.get_prob(1), 4), 1)
示例#5
0
    def test_inserting_evidence(self):
        # Cluster tree with only one node
        tS = BeliefTable([self.S], np.zeros(2))
        tD = BeliefTable([self.D], np.zeros(2))
        tL = BeliefTable(dict.fromkeys([self.S, self.D, self.L]), np.zeros((2, 2, 2)))

        tS.set_probability_dict({'S': 0}, 0.9)
        tS.set_probability_dict({'S': 1}, 0.1)

        tD.set_probability_dict({'D': 0}, 0.9)
        tD.set_probability_dict({'D': 1}, 0.1)

        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 0}, 0.98)
        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 1}, 0.02)
        tL.set_probability_dict({'S': 0, 'D': 1, 'L': 0}, 0.15)
        tL.set_probability_dict({'D': 1, 'L': 1, 'S': 0}, 0.85)
        tL.set_probability_dict({'L': 0, 'S': 1, 'D': 0}, 0.1)
        tL.set_probability_dict({'S': 1, 'D': 0, 'L': 1}, 0.9)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 0}, 0.05)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 1}, 0.95)

        net = BayesianNet()
        net.add_variable(self.L)
        net.add_variable(self.S)
        net.add_variable(self.D)

        net.add_dependence('L', 'S')
        net.add_dependence('L', 'D')

        net.add_prob_table('L', tL)
        net.add_prob_table('S', tS)
        net.add_prob_table('D', tD)

        jtree = JunctionTree(dict.fromkeys([self.S, self.D, self.L]))
        jtree.add_clique(['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('S', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('D', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('L', ['S', 'D', 'L'])

        jtree.initialize_tables(net)

        # Add evidence to one node
        jtree.add_evidence('L', 0)
        Stable = jtree.calculate_variable_probability('S')
        Dtable = jtree.calculate_variable_probability('D')

        self.assertAlmostEqual(Stable.get_prob(0), 0.9884, 4)
        self.assertAlmostEqual(Stable.get_prob(1), 0.0116, 4)

        self.assertAlmostEqual(Dtable.get_prob(0), 0.9829, 4)
        self.assertAlmostEqual(Dtable.get_prob(1), 0.0171, 4)

        # Add evidence to another one
        jtree.add_evidence('S', 0)

        Stable = jtree.calculate_variable_probability('S')
        Dtable = jtree.calculate_variable_probability('D')

        self.assertAlmostEqual(Stable.get_prob(0), 1, 4)
        self.assertAlmostEqual(Stable.get_prob(1), 0, 4)

        self.assertAlmostEqual(Dtable.get_prob(0), 0.9833, 4)
        self.assertAlmostEqual(Dtable.get_prob(1), 0.0167, 4)
示例#6
0
    def test_bnet_linking(self):
        # Test if it's possible to calculate the probability of a variable given the bayesian net
        # No message passing, single cluster

        tS = BeliefTable([self.S], np.zeros(2))
        tD = BeliefTable([self.D], np.zeros(2))
        tL = BeliefTable(dict.fromkeys([self.S, self.D, self.L]), np.zeros((2, 2, 2)))

        tS.set_probability_dict({'S': 0}, 0.9)
        tS.set_probability_dict({'S': 1}, 0.1)

        tD.set_probability_dict({'D': 0}, 0.9)
        tD.set_probability_dict({'D': 1}, 0.1)

        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 0}, 0.98)
        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 1}, 0.02)
        tL.set_probability_dict({'S': 0, 'D': 1, 'L': 0}, 0.15)
        tL.set_probability_dict({'D': 1, 'L': 1, 'S': 0}, 0.85)
        tL.set_probability_dict({'L': 0, 'S': 1, 'D': 0}, 0.1)
        tL.set_probability_dict({'S': 1, 'D': 0, 'L': 1}, 0.9)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 0}, 0.05)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 1}, 0.95)

        net = BayesianNet()
        net.add_variable(self.L)
        net.add_variable(self.S)
        net.add_variable(self.D)

        net.add_dependence('L', 'S')
        net.add_dependence('L', 'D')

        net.add_prob_table('L', tL)
        net.add_prob_table('S', tS)
        net.add_prob_table('D', tD)

        jtree = JunctionTree(dict.fromkeys([self.S, self.D, self.L]))
        jtree.add_clique(['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('S', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('D', ['S', 'D', 'L'])
        jtree.set_variable_chosen_clique('L', ['S', 'D', 'L'])

        jtree.initialize_tables(net)

        Ltable = jtree.calculate_variable_probability('L')
        self.assertAlmostEqual(Ltable.get_prob(0), 0.8168)
        self.assertAlmostEqual(Ltable.get_prob(1), 0.1832)
示例#7
0
    def test_table_assignment(self):
        # Check if assigning tables via identifiers works correctly even when the order of variables is wrong
        S = Variable('S', 'S', [0, 1])
        D = Variable('D', 'D', [0, 1])
        L = Variable('L', 'L', [0, 1])

        tS = BeliefTable(dict.fromkeys([S]), np.zeros(2))
        tD = BeliefTable(dict.fromkeys([D]), np.zeros(2))
        tL = BeliefTable(dict.fromkeys([S, D, L]), np.zeros((2, 2, 2)))

        tS.set_probability_dict({'S': 0}, 0.9)
        tS.set_probability_dict({'S': 1}, 0.1)

        tD.set_probability_dict({'D': 0}, 0.9)
        tD.set_probability_dict({'D': 1}, 0.1)

        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 0}, 0.98)
        tL.set_probability_dict({'S': 0, 'D': 0, 'L': 1}, 0.02)
        tL.set_probability_dict({'S': 0, 'D': 1, 'L': 0}, 0.15)
        tL.set_probability_dict({'D': 1, 'L': 1, 'S': 0}, 0.85)
        tL.set_probability_dict({'L': 0, 'S': 1, 'D': 0}, 0.1)
        tL.set_probability_dict({'S': 1, 'D': 0, 'L': 1}, 0.9)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 0}, 0.05)
        tL.set_probability_dict({'S': 1, 'D': 1, 'L': 1}, 0.95)

        net = BayesianNet()
        net.add_variable(L)
        net.add_variable(S)
        net.add_variable(D)

        net.add_dependence('L', 'S')
        net.add_dependence('L', 'D')

        net.add_prob_table('L', tL)
        net.add_prob_table('S', tS)
        net.add_prob_table('D', tD)

        self.assertEqual(str(tS), str(net.get_table(S)))
        self.assertEqual(str(tD), str(net.get_table(D)))
        self.assertEqual(str(tL), str(net.get_table(L)))