def to_factor_graph(self):
        """
        Converts the markov model into factor graph.

        A factor graph contains two types of nodes. One type corresponds to
        random variables whereas the second type corresponds to factors over
        these variables. The graph only contains edges between variables and
        factor nodes. Each factor node is associated with one factor whose
        scope is the set of variables that are its neighbors.

        Examples
        --------
        >>> from pgmpy.models import MarkovModel
        >>> from pgmpy.factors.discrete import DiscreteFactor
        >>> student = MarkovModel([('Alice', 'Bob'), ('Bob', 'Charles')])
        >>> factor1 = DiscreteFactor(['Alice', 'Bob'], [3, 2], np.random.rand(6))
        >>> factor2 = DiscreteFactor(['Bob', 'Charles'], [2, 2], np.random.rand(4))
        >>> student.add_factors(factor1, factor2)
        >>> factor_graph = student.to_factor_graph()
        """
        from pgmpy.models import FactorGraph
        factor_graph = FactorGraph()

        if not self.factors:
            raise ValueError('Factors not associated with the random variables.')

        factor_graph.add_nodes_from(self.nodes())
        for factor in self.factors:
            scope = factor.scope()
            factor_node = 'phi_' + '_'.join(scope)
            factor_graph.add_edges_from(itertools.product(scope, [factor_node]))
            factor_graph.add_factors(factor)

        return factor_graph
Beispiel #2
0
    def to_factor_graph(self):
        """
        Converts the markov model into factor graph.

        A factor graph contains two types of nodes. One type corresponds to
        random variables whereas the second type corresponds to factors over
        these variables. The graph only contains edges between variables and
        factor nodes. Each factor node is associated with one factor whose
        scope is the set of variables that are its neighbors.

        Examples
        --------
        >>> from pgmpy.models import MarkovModel
        >>> from pgmpy.factors import Factor
        >>> student = MarkovModel([('Alice', 'Bob'), ('Bob', 'Charles')])
        >>> factor1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6))
        >>> factor2 = Factor(['Bob', 'Charles'], [2, 2], np.random.rand(4))
        >>> student.add_factors(factor1, factor2)
        >>> factor_graph = student.to_factor_graph()
        """
        from pgmpy.models import FactorGraph
        factor_graph = FactorGraph()

        if not self.factors:
            raise ValueError('Factors not associated with the random variables.')

        factor_graph.add_nodes_from(self.nodes())
        for factor in self.factors:
            scope = factor.scope()
            factor_node = 'phi_' + '_'.join(scope)
            factor_graph.add_edges_from(itertools.product(scope, [factor_node]))
            factor_graph.add_factors(factor)

        return factor_graph
Beispiel #3
0
def create_model():
    # Init graph.
    G = FactorGraph()

    # Add variable nodes to model.
    G.add_nodes_from(v)

    # Add factor nodes to model.
    G.add_nodes_from(f)

    # Add edges to the model.
    edges = [('X1', f1), ('X2', f2),    \
             ('X3', f31), ('X1', f31),  \
             ('X5', f52), ('X2', f52),  \
             ('X4', f42), ('X2', f42),  \
             ('X6', f68), ('X8', f68),
             ('X8', f843), ('X4', f843), ('X3', f843),
             ('X7', f758), ('X5', f758), ('X8', f758)]
    G.add_edges_from(edges)

    # Finally add all factors.
    G.add_factors(f1, f2, f31, f52, f42, f68, f843, f758)

    assert (G.check_model())
    return G
Beispiel #4
0
class TestFactorGraphMethods(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_get_factor_nodes(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.assertListEqual(sorted(self.graph.get_factor_nodes()),
                             ['phi1', 'phi2'])

    def test_get_variable_nodes(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.assertListEqual(sorted(self.graph.get_variable_nodes()),
                             ['a', 'b', 'c'])

    def test_get_variable_nodes_raises_error(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        self.assertRaises(ValueError, self.graph.get_variable_nodes)

    def test_to_markov_model(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        mm = self.graph.to_markov_model()
        self.assertIsInstance(mm, MarkovModel)
        self.assertListEqual(sorted(mm.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(mm.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.assertListEqual(sorted(mm.get_factors(),
                             key=lambda x: x.scope()), [phi1, phi2])

    def test_to_junction_tree(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        jt = self.graph.to_junction_tree()
        self.assertIsInstance(jt, JunctionTree)
        self.assertListEqual(hf.recursive_sorted(jt.nodes()),
                             [['a', 'b'], ['b', 'c']])
        self.assertEqual(len(jt.edges()), 1)

    def tearDown(self):
        del self.graph
Beispiel #5
0
class TestFactorGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_add_single_factor(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1)
        six.assertCountEqual(self, self.graph.factors, [phi1])

    def test_add_multiple_factors(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.factors, [phi1, phi2])
    
    def test_get_factors(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])

        six.assertCountEqual(self, self.graph.get_factors(), [])

        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_factors(node=phi1), phi1)
        self.assertEqual(self.graph.get_factors(node=phi2), phi2)
        six.assertCountEqual(self, self.graph.get_factors(), [phi1, phi2])

        self.graph.remove_factors(phi1)
        self.assertRaises(ValueError, self.graph.get_factors, node=phi1)


    def test_remove_factors(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        six.assertCountEqual(self, self.graph.factors, [phi2])

    def test_get_partition_function(self):
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_partition_function(), 22.0)

    def tearDown(self):
        del self.graph
Beispiel #6
0
class TestFactorGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_add_single_factor(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1)
        six.assertCountEqual(self, self.graph.factors, [phi1])

    def test_add_multiple_factors(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.factors, [phi1, phi2])

    def test_get_factors(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])

        six.assertCountEqual(self, self.graph.get_factors(), [])

        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_factors(node=phi1), phi1)
        self.assertEqual(self.graph.get_factors(node=phi2), phi2)
        six.assertCountEqual(self, self.graph.get_factors(), [phi1, phi2])

        self.graph.remove_factors(phi1)
        self.assertRaises(ValueError, self.graph.get_factors, node=phi1)

    def test_remove_factors(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'), ('b', 'phi2'),
                                   ('c', 'phi2')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        six.assertCountEqual(self, self.graph.factors, [phi2])

    def test_get_partition_function(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], range(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], range(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_partition_function(), 22.0)

    def tearDown(self):
        del self.graph
Beispiel #7
0
class TestFactorGraphCreation(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_class_init_without_data(self):
        self.assertIsInstance(self.graph, FactorGraph)

    def test_class_init_data_string(self):
        self.graph = FactorGraph([('a', 'phi1'), ('b', 'phi1')])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'phi1'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'phi1'], ['b', 'phi1']])

    def test_add_single_node(self):
        self.graph.add_node('phi1')
        self.assertEqual(self.graph.nodes(), ['phi1'])

    def test_add_multiple_nodes(self):
        self.graph.add_nodes_from(['a', 'b', 'phi1'])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'phi1'])

    def test_add_single_edge(self):
        self.graph.add_edge('a', 'phi1')
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'phi1'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'phi1']])

    def test_add_multiple_edges(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1')])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'phi1'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'phi1'], ['b', 'phi1']])

    def test_add_self_loop_raises_error(self):
        self.assertRaises(ValueError, self.graph.add_edge, 'a', 'a')

    def test_add_edge_between_variable_nodes_raises_error(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1')])
        self.assertRaises(ValueError, self.graph.add_edge, 'a', 'b')

    def tearDown(self):
        del self.graph
Beispiel #8
0
class TestFactorGraphCreation(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_class_init_without_data(self):
        self.assertIsInstance(self.graph, FactorGraph)

    def test_class_init_data_string(self):
        self.graph = FactorGraph([("a", "phi1"), ("b", "phi1")])
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "phi1"])
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()), [["a", "phi1"], ["b", "phi1"]]
        )

    def test_add_single_node(self):
        self.graph.add_node("phi1")
        self.assertEqual(list(self.graph.nodes()), ["phi1"])

    def test_add_multiple_nodes(self):
        self.graph.add_nodes_from(["a", "b", "phi1"])
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "phi1"])

    def test_add_single_edge(self):
        self.graph.add_edge("a", "phi1")
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "phi1"])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()), [["a", "phi1"]])

    def test_add_multiple_edges(self):
        self.graph.add_edges_from([("a", "phi1"), ("b", "phi1")])
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "phi1"])
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()), [["a", "phi1"], ["b", "phi1"]]
        )

    def test_add_self_loop_raises_error(self):
        self.assertRaises(ValueError, self.graph.add_edge, "a", "a")

    def tearDown(self):
        del self.graph
Beispiel #9
0
class TestFactorGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_add_single_factor(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1)
        self.assertListEqual(self.graph.get_factors(), [phi1])

    def test_add_multiple_factors(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_factors(node='phi1'), phi1)
        self.assertEqual(self.graph.get_factors(node='phi2'), phi2)

    def test_remove_factors(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        self.assertListEqual(self.graph.get_factors(), [phi2])

    def test_get_partition_function(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_partition_function(), 22.0)

    def tearDown(self):
        del self.graph
Beispiel #10
0
class TestFactorGraphMethods(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_get_cardinality(self):

        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('c', 'phi2'), ('d', 'phi2'),
                                   ('a', 'phi3'), ('d', 'phi3')])

        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_nodes_from(['a', 'b', 'c', 'd'])
        
        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.graph.add_edges_from([('a', phi1), ('b', 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.graph.add_edges_from([('a', phi2), ('c', phi2)])
        self.assertRaises(ValueError, self.graph.get_cardinality, check_cardinality=True)

        phi3 = Factor(['d', 'a'], [1, 1], np.random.rand(1))
        self.graph.add_factors(phi3)
        self.graph.add_edges_from([('d', phi3), ('a', phi3)])
        self.assertDictEqual(self.graph.get_cardinality(check_cardinality=True), {'d': 1, 'c': 2, 'b': 2, 'a': 1})

    def test_get_factor_nodes(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))

        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_factor_nodes(), [phi1, phi2])

    def test_get_variable_nodes(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_variable_nodes(), ['a', 'b', 'c'])

    def test_get_variable_nodes_raises_error(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'),
                                   ('b', 'phi2'), ('c', 'phi2')])
        self.assertRaises(ValueError, self.graph.get_variable_nodes)

    def test_to_markov_model(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        mm = self.graph.to_markov_model()
        self.assertIsInstance(mm, MarkovModel)
        self.assertListEqual(sorted(mm.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(mm.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.assertListEqual(sorted(mm.get_factors(),
                             key=lambda x: x.scope()), [phi1, phi2])

    def test_to_junction_tree(self):
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1),
                                   ('b', phi2), ('c', phi2)])
        
        self.graph.add_factors(phi1, phi2)
        jt = self.graph.to_junction_tree()
        self.assertIsInstance(jt, JunctionTree)
        self.assertListEqual(hf.recursive_sorted(jt.nodes()),
                             [['a', 'b'], ['b', 'c']])
        self.assertEqual(len(jt.edges()), 1)

    def test_check_model(self):
        self.graph.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))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertTrue(self.graph.check_model())

        self.graph.remove_factors(phi1)
        self.graph.remove_node(phi1)
        phi1 = Factor(['a', 'b'], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1)
        self.graph.add_edges_from([('a', phi1)])
        self.assertTrue(self.graph.check_model())

    def test_check_model1(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_node('d')
        self.assertTrue(self.graph.check_model())

    def test_check_model2(self):
        self.graph.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))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)

        self.graph.add_edges_from([('a', 'b')])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.add_edges_from([(phi1, phi2)])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_edges_from([('a', 'b'), (phi1, phi2)])
        self.assertTrue(self.graph.check_model())

    def test_check_model3(self):
        
        
        self.graph.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))
        phi3 = Factor(['a', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2, phi3)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi3)
        self.assertTrue(self.graph.check_model())

    def test_check_model4(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['b', 'c'], [3, 2], np.random.rand(6))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), 
                                   ('b', phi2), ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_factors(phi2)
        self.graph.remove_node(phi2)
        phi3 = Factor(['c', 'a'], [4, 4], np.random.rand(16))
        self.graph.add_factors(phi3)
        self.graph.add_edges_from([('a', phi3), ('c', phi3)])
        self.assertRaises(ValueError, self.graph.check_model)

    def tearDown(self):
        del self.graph
Beispiel #11
0
class TestFactorGraphMethods(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_get_cardinality(self):

        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'), ('c', 'phi2'),
                                   ('d', 'phi2'), ('a', 'phi3'),
                                   ('d', 'phi3')])

        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_check_cardinality(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])

        phi1 = DiscreteFactor(['a', 'b'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.graph.add_edges_from([('a', phi1), ('b', phi1)])
        self.assertRaises(ValueError,
                          self.graph.get_cardinality,
                          check_cardinality=True)

        phi2 = DiscreteFactor(['a', 'c'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi2)
        self.graph.add_edges_from([('a', phi2), ('c', phi2)])
        self.assertRaises(ValueError,
                          self.graph.get_cardinality,
                          check_cardinality=True)

        phi3 = DiscreteFactor(['d', 'a'], [1, 1], np.random.rand(1))
        self.graph.add_factors(phi3)
        self.graph.add_edges_from([('d', phi3), ('a', phi3)])
        self.assertDictEqual(
            self.graph.get_cardinality(check_cardinality=True), {
                'd': 1,
                'c': 2,
                'b': 2,
                'a': 1
            })

    def test_get_factor_nodes(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))

        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_factor_nodes(), [phi1, phi2])

    def test_get_variable_nodes(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_variable_nodes(),
                             ['a', 'b', 'c'])

    def test_get_variable_nodes_raises_error(self):
        self.graph.add_edges_from([('a', 'phi1'), ('b', 'phi1'), ('b', 'phi2'),
                                   ('c', 'phi2')])
        self.assertRaises(ValueError, self.graph.get_variable_nodes)

    def test_to_markov_model(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        mm = self.graph.to_markov_model()
        self.assertIsInstance(mm, MarkovModel)
        self.assertListEqual(sorted(mm.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(mm.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.assertListEqual(sorted(mm.get_factors(), key=lambda x: x.scope()),
                             [phi1, phi2])

    def test_to_junction_tree(self):
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])

        self.graph.add_factors(phi1, phi2)
        jt = self.graph.to_junction_tree()
        self.assertIsInstance(jt, JunctionTree)
        self.assertListEqual(hf.recursive_sorted(jt.nodes()),
                             [['a', 'b'], ['b', 'c']])
        self.assertEqual(len(jt.edges()), 1)

    def test_check_model(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertTrue(self.graph.check_model())

        self.graph.remove_factors(phi1)
        self.graph.remove_node(phi1)
        phi1 = DiscreteFactor(['a', 'b'], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1)
        self.graph.add_edges_from([('a', phi1)])
        self.assertTrue(self.graph.check_model())

    def test_check_model1(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_node('d')
        self.assertTrue(self.graph.check_model())

    def test_check_model2(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)

        self.graph.add_edges_from([('a', 'b')])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.add_edges_from([(phi1, phi2)])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_edges_from([('a', 'b'), (phi1, phi2)])
        self.assertTrue(self.graph.check_model())

    def test_check_model3(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [2, 2], np.random.rand(4))
        phi3 = DiscreteFactor(['a', 'c'], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2, phi3)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi3)
        self.assertTrue(self.graph.check_model())

    def test_check_model4(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(['b', 'c'], [3, 2], np.random.rand(6))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([('a', phi1), ('b', phi1), ('b', phi2),
                                   ('c', phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_factors(phi2)
        self.graph.remove_node(phi2)
        phi3 = DiscreteFactor(['c', 'a'], [4, 4], np.random.rand(16))
        self.graph.add_factors(phi3)
        self.graph.add_edges_from([('a', phi3), ('c', phi3)])
        self.assertRaises(ValueError, self.graph.check_model)

    def tearDown(self):
        del self.graph
Beispiel #12
0
#                  |                    |
#               ___|___   ________   ___|___
#               |__B__|---|__f2__|---|__C__|
#             
#               
########################################################
# First import factor graph class from pgmpy.models
from pgmpy.models import FactorGraph
factor_graph = FactorGraph()

# Add variable nodes and factor nodes to model
factor_graph.add_nodes_from(['A','B','C','D','phi1','phi2','phi3'])

# Add edges between all nodes
factor_graph.add_edges_from([('A','phi1'), ('B','phi1'),
	                         ('B','phi2'), ('C','phi2'),
	                         ('C','phi3'), ('A','phi3')])


# Add factors into phi1, phi2, phi3
from pgmpy.factors import Factor
import numpy as np
phi1 = Factor(['A','B'], [2,2], np.random.rand(4))
phi2 = Factor(['A','B'], [2,2], np.random.rand(4))
phi3 = Factor(['A','B'], [2,2], np.random.rand(4))
factor_graph.add_factors(phi1, phi2, phi3)




import numpy as np
from pgmpy.models import FactorGraph
from pgmpy.factors.discrete import DiscreteFactor
from pgmpy.inference import BeliefPropagation

G = FactorGraph()
G.add_node(0)
G.add_node(1)
G.add_node(2)

f01 = DiscreteFactor([0, 1], [2, 2], np.random.rand(4))
f02 = DiscreteFactor([0, 2], [2, 2], np.random.rand(4))
f12 = DiscreteFactor([1, 2], [2, 2], np.random.rand(4))
G.add_factors(f01)
G.add_factors(f02)
G.add_factors(f12)

G.add_edges_from([(0, f01), (1, f01), (0, f02), (2, f02), (1, f12), (2, f12)])
bp = BeliefPropagation(G)
bp.calibrate()
# First import FactorGraph class from pgmpy.models
from pgmpy.models import FactorGraph
factor_graph = FactorGraph()
# Add nodes (both variable nodes and factor nodes) to the model
# as we did in previous other models
factor_graph.add_nodes_from(['A', 'B', 'C', 'D', 'phi1', 'phi2', 'phi3'])
# Add edges between all variable nodes and factor nodes
factor_graph.add_edges_from([('A', 'phi1'), ('B', 'phi1'),
                             ('B', 'phi2'), ('C', 'phi2'),
                             ('C', 'phi3'), ('A', 'phi3')])
Beispiel #15
0
class TestFactorGraphMethods(unittest.TestCase):
    def setUp(self):
        self.graph = FactorGraph()

    def test_get_cardinality(self):
        self.graph.add_edges_from(
            [
                ("a", "phi1"),
                ("b", "phi1"),
                ("c", "phi2"),
                ("d", "phi2"),
                ("a", "phi3"),
                ("d", "phi3"),
            ]
        )

        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_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        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"), 2)

    def test_get_factor_nodes(self):
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))

        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_factor_nodes(), [phi1, phi2])

    def test_get_variable_nodes(self):
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_variable_nodes(), ["a", "b", "c"])

    def test_get_variable_nodes_raises_error(self):
        self.graph.add_edges_from(
            [("a", "phi1"), ("b", "phi1"), ("b", "phi2"), ("c", "phi2")]
        )
        self.assertRaises(ValueError, self.graph.get_variable_nodes)

    def test_to_markov_model(self):
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        mm = self.graph.to_markov_model()
        self.assertIsInstance(mm, MarkovModel)
        self.assertListEqual(sorted(mm.nodes()), ["a", "b", "c"])
        self.assertListEqual(hf.recursive_sorted(mm.edges()), [["a", "b"], ["b", "c"]])
        self.assertListEqual(
            sorted(mm.get_factors(), key=lambda x: x.scope()), [phi1, phi2]
        )

    def test_to_junction_tree(self):
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])

        self.graph.add_factors(phi1, phi2)
        jt = self.graph.to_junction_tree()
        self.assertIsInstance(jt, JunctionTree)
        self.assertListEqual(hf.recursive_sorted(jt.nodes()), [["a", "b"], ["b", "c"]])
        self.assertEqual(len(jt.edges()), 1)

    def test_check_model(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertTrue(self.graph.check_model())

        self.graph.remove_factors(phi1)
        self.graph.remove_node(phi1)
        phi1 = DiscreteFactor(["a", "b"], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1)
        self.graph.add_edges_from([("a", phi1)])
        self.assertTrue(self.graph.check_model())

    def test_check_model1(self):
        self.graph.add_nodes_from(["a", "b", "c", "d"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_node("d")
        self.assertTrue(self.graph.check_model())

    def test_check_model2(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)

        self.graph.add_edges_from([("a", "b")])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.add_edges_from([(phi1, phi2)])
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_edges_from([("a", "b"), (phi1, phi2)])
        self.assertTrue(self.graph.check_model())

    def test_check_model3(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        phi3 = DiscreteFactor(["a", "c"], [2, 2], np.random.rand(4))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2, phi3)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi3)
        self.assertTrue(self.graph.check_model())

    def test_check_model4(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [3, 2], np.random.rand(6))
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)

        self.graph.remove_factors(phi2)
        self.graph.remove_node(phi2)
        phi3 = DiscreteFactor(["c", "a"], [4, 4], np.random.rand(16))
        self.graph.add_factors(phi3)
        self.graph.add_edges_from([("a", phi3), ("c", phi3)])
        self.assertRaises(ValueError, self.graph.check_model)

    def test_copy(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], np.random.rand(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.add_nodes_from([phi1, phi2])
        self.graph.add_edges_from([("a", phi1), ("b", phi1), ("b", phi2), ("c", phi2)])
        graph_copy = self.graph.copy()
        self.assertIsInstance(graph_copy, FactorGraph)
        self.assertTrue(graph_copy.check_model())
        self.assertEqual(self.graph.get_factors(), graph_copy.get_factors())
        self.graph.remove_factors(phi1, phi2)
        self.assertTrue(
            phi1 not in self.graph.factors and phi2 not in self.graph.factors
        )
        self.assertTrue(phi1 in graph_copy.factors and phi2 in graph_copy.factors)
        self.graph.add_factors(phi1, phi2)
        self.graph.factors[0] = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        self.assertNotEqual(self.graph.get_factors()[0], graph_copy.get_factors()[0])
        self.assertNotEqual(self.graph.factors, graph_copy.factors)

    def tearDown(self):
        del self.graph