Exemplo n.º 1
0
def test_find_MAP():
    print '-' * 80
    G = MarkovModel()
    G.add_nodes_from(['x1', 'x2', 'x3'])
    G.add_edges_from([('x1', 'x2'), ('x1', 'x3')])
    phi = [
        DiscreteFactor(['x2', 'x1'],
                       cardinality=[2, 2],
                       values=np.array([[1.0 / 1, 1.0 / 2], [1.0 / 3,
                                                             1.0 / 4]])),
        DiscreteFactor(['x3', 'x1'],
                       cardinality=[2, 2],
                       values=np.array([[1.0 / 1, 1.0 / 2], [1.0 / 3,
                                                             1.0 / 4]]))
    ]
    #		   DiscreteFactor(['x1'], cardinality=[2],
    #		   values=np.array([2,2]))]
    G.add_factors(*phi)
    print "nodes:", G.nodes()

    bp = BeliefPropagation(G)
    bp.max_calibrate()
    #	bp.calibrate()
    clique_beliefs = bp.get_clique_beliefs()
    print clique_beliefs
    print clique_beliefs[('x1', 'x2')]
    print clique_beliefs[('x1', 'x3')]
    #	print 'partition function should be', np.sum(clique_beliefs[('x1', 'x3')].values)
    phi_query = bp._query(['x1', 'x2', 'x3'], operation='maximize')
    #	phi_query = bp._query(['x1', 'x2', 'x3'], operation='marginalize')
    print phi_query

    sleep(52)
def generate_random_fully_connected_MRF(N):
    '''
    Create an MRF with N binary nodes that are all part of the same clique, which
    has 2^N random values

    '''

    G = MarkovModel()

    #create an N nodes
    node_names = ['x%d' % i for i in range(N)]

    G.add_nodes_from(node_names)

    #add an edge between each node and its 4 neighbors, except when the
    #node is on the grid border and has fewer than 4 neighbors
    edges = []

    for i in range(N):
        for j in range(i + 1, N):
            edges.append(('x%d' % i, 'x%d' % j))

    assert (len(edges) == .5 * N**2)

    G.add_edges_from(edges)

    single_factor = DiscreteFactor(
        edges,
        cardinality=[2 for i in range(N)],
        values=np.random.rand(*[2 for i in range(N)]))
    G.add_factors(single_factor)

    return G
Exemplo n.º 3
0
 def build_graph(self):
     mm = MarkovModel()
     mm.add_nodes_from(self.dataset.dataframe.columns)
     graph_structure_name = list(
         map(lambda tuple: (self.columns[tuple[0]], self.columns[tuple[1]]),
             self.graph_structure_index))
     mm.add_edges_from(graph_structure_name)
     self.model = mm.to_bayesian_model()
Exemplo n.º 4
0
class TestUndirectedGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_add_factor_raises_error(self):
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles'),
                                   ('Charles', 'Debbie'), ('Debbie', 'Alice')])
        factor = Factor(['Alice', 'Bob', 'John'], [2, 2, 2], np.random.rand(8))
        self.assertRaises(ValueError, self.graph.add_factors, factor)

    def test_add_single_factor(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi = Factor(['a', 'b'], [2, 2], range(4))
        self.graph.add_factors(phi)
        self.assertListEqual(self.graph.get_factors(), [phi])

    def test_add_multiple_factors(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertListEqual(self.graph.get_factors(), [phi1, phi2])

    def test_remove_single_factor(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        self.assertListEqual(self.graph.get_factors(), [phi2])

    def test_remove_multiple_factors(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1, phi2)
        self.assertListEqual(self.graph.get_factors(), [])

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

    def test_partition_function_raises_error(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError,
                          self.graph.get_partition_function)

    def tearDown(self):
        del self.graph
Exemplo n.º 5
0
class TestUndirectedGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_add_factor_raises_error(self):
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles'),
                                   ('Charles', 'Debbie'), ('Debbie', 'Alice')])
        factor = Factor(['Alice', 'Bob', 'John'], [2, 2, 2], np.random.rand(8))
        self.assertRaises(ValueError, self.graph.add_factors, factor)

    def test_add_single_factor(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi = Factor(['a', 'b'], [2, 2], range(4))
        self.graph.add_factors(phi)
        self.assertListEqual(self.graph.get_factors(), [phi])

    def test_add_multiple_factors(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertListEqual(self.graph.get_factors(), [phi1, phi2])

    def test_remove_single_factor(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        self.assertListEqual(self.graph.get_factors(), [phi2])

    def test_remove_multiple_factors(self):
        self.graph.add_nodes_from(['a', 'b', 'c'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1, phi2)
        self.assertListEqual(self.graph.get_factors(), [])

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

    def test_partition_function_raises_error(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        phi1 = Factor(['a', 'b'], [2, 2], range(4))
        phi2 = Factor(['b', 'c'], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.get_partition_function)

    def tearDown(self):
        del self.graph
Exemplo n.º 6
0
    def to_bn(self, use_mst=False):
        """ Given the undirected graph, return the directed model corresponding to the minimal I-map. The directed model is
        placed in the directed attribute.
        Remarks: This method supports models which are not connected.
        :param use_mst (boolean): To direct a prelearned model in the directed attribute, direct_mst=False. To obtain
            the directed model from the maximum spanning tree learned by self.mst, use direct_mst=True.
        """

        # Generate connected components
        if use_mst:
            edges = list(self.maxtree.edges())
            vertices = list(self.maxtree.nodes)
            mm = MarkovModel()
            mm.add_nodes_from(vertices)
            mm.add_edges_from(edges)
            bm = mm.to_bayesian_model()

            self.directed = bm

        else:
            connected = list(nx.algorithms.components.connected_components(self.undirected))
            # Hold the edges of each connected component as a list(list())
            connected_comps = list()
            # If the graph is not completely connected
            if len(connected) > 1:
                self.directed = BayesianModel()
                for comp in connected:
                    # If the connected component is not a single vertex
                    if len(comp) > 1:
                        edges_to_add = list()
                        temp = MarkovModel()
                        for vert1 in comp:
                            neighbours = list(self.undirected.neighbors(vert1))
                            for vert2 in neighbours:
                                if not ((vert1, vert2) in edges_to_add) and not ((vert2, vert1) in edges_to_add):
                                    edges_to_add.append((vert1, vert2))

                        temp.add_nodes_from(comp)
                        temp.add_edges_from(edges_to_add)
                        temp_bn = temp.to_bayesian_model()
                        connected_comps.append(temp_bn)
                    else:
                        self.directed.add_nodes_from(comp)

                for bn in connected_comps:
                    self.directed.add_nodes_from(list(bn.nodes))
                    self.directed.add_edges_from(list(bn.edges))

            else:
                # If the graph is completely connected, just add all edges to markov model
                edges = list(self.undirected.edges())
                vertices = list(self.undirected.nodes)
                mm = MarkovModel()
                mm.add_nodes_from(vertices)
                mm.add_edges_from(edges)
                bm = mm.to_bayesian_model()

                self.directed = bm
Exemplo n.º 7
0
    def to_markov_model(self):
        """
        Converts the factor graph into markov model.

        A markov model contains nodes as random variables and edge between
        two nodes imply interaction between them.

        Examples
        --------
        >>> from pgmpy.models import FactorGraph
        >>> from pgmpy.factors import Factor
        >>> G = FactorGraph()
        >>> G.add_nodes_from(['a', 'b', 'c'])
        >>> G.add_nodes_from(['phi1', 'phi2'])
        >>> G.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))
        >>> G.add_factors(phi1, phi2)
        >>> mm = G.to_markov_model()
        """
        from pgmpy.models import MarkovModel
        mm = MarkovModel()

        variable_nodes = self.get_variable_nodes()

        if len(set(self.nodes()) - set(variable_nodes)) != len(self.factors):
            raise ValueError(
                'Factors not associated with all the factor nodes.')

        mm.add_nodes_from(variable_nodes)
        for factor in self.factors:
            scope = factor.scope()
            mm.add_edges_from(itertools.combinations(scope, 2))
            mm.add_factors(factor)

        return mm
Exemplo n.º 8
0
    def to_markov_model(self):
        """
        Converts the factor graph into markov model.

        A markov model contains nodes as random variables and edge between
        two nodes imply interaction between them.

        Examples
        --------
        >>> from pgmpy.models import FactorGraph
        >>> from pgmpy.factors import Factor
        >>> G = FactorGraph()
        >>> G.add_nodes_from(['a', 'b', 'c'])
        >>> phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        >>> phi2 = Factor(['b', 'c'], [2, 2], np.random.rand(4))
        >>> G.add_factors(phi1, phi2)
        >>> G.add_nodes_from([phi1, phi2])
        >>> G.add_edges_from([('a', phi1), ('b', phi1),
        ...                   ('b', phi2), ('c', phi2)])
        >>> mm = G.to_markov_model()
        """
        from pgmpy.models import MarkovModel
        mm = MarkovModel()

        variable_nodes = self.get_variable_nodes()

        if len(set(self.nodes()) - set(variable_nodes)) != len(self.factors):
            raise ValueError('Factors not associated with all the factor nodes.')

        mm.add_nodes_from(variable_nodes)
        for factor in self.factors:
            scope = factor.scope()
            mm.add_edges_from(itertools.combinations(scope, 2))
            mm.add_factors(factor)

        return mm
Exemplo n.º 9
0
class TestMarkovModelCreation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

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

    def test_class_init_with_data_string(self):
        self.g = MarkovModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [['a', 'b'], ['b', 'c']])

    def test_class_init_with_data_nonstring(self):
        self.g = MarkovModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.graph.add_node('a')
        self.assertListEqual(self.graph.nodes(), ['a'])

    def test_add_node_nonstring(self):
        self.graph.add_node(1)

    def test_add_nodes_from_string(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd'])

    def test_add_nodes_from_non_string(self):
        self.graph.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.graph.add_edge('d', 'e')
        self.assertListEqual(sorted(self.graph.nodes()), ['d', 'e'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['d', 'e']])
        self.graph.add_nodes_from(['a', 'b', 'c'])
        self.graph.add_edge('a', 'b')
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['d', 'e']])

    def test_add_edge_nonstring(self):
        self.graph.add_edge(1, 2)

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

    def test_add_edges_from_string(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.graph.add_nodes_from(['d', 'e', 'f'])
        self.graph.add_edges_from([('d', 'e'), ('e', 'f')])
        self.assertListEqual(sorted(self.graph.nodes()),
                             ['a', 'b', 'c', 'd', 'e', 'f'])
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            hf.recursive_sorted([('a', 'b'), ('b', 'c'), ('d', 'e'),
                                 ('e', 'f')]))

    def test_add_edges_from_nonstring(self):
        self.graph.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.graph.add_edges_from, [('a', 'a')])

    def test_number_of_neighbors(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertEqual(len(self.graph.neighbors('b')), 2)

    def tearDown(self):
        del self.graph
Exemplo n.º 10
0
class TestMarkovModelMethods(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_get_cardinality(self):

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

        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {'a': 1, 'b': 2})
        self.graph.remove_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['c', 'd'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertDictEqual(self.graph.get_cardinality(), {'d': 2, 'a': 2, 'b': 2, 'c': 1})

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

        self.graph.remove_factors(phi1, phi2, phi3)
        self.assertDictEqual(self.graph.get_cardinality(), {})


    def test_get_cardinality_check_cardinality(self):

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

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

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

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


    def test_check_model(self):

        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['c', 'b'], [3, 2], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4))

        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.assertTrue(self.graph.check_model())

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

    def test_check_model1(self):
    
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))

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

        phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 3], np.random.rand(12))
        self.graph.add_factors(phi2, phi3, phi4)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2, phi3, phi4)

        phi2 = Factor(['a', 'b'], [1, 3], np.random.rand(3))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2)

    def test_check_model2(self):
    
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])

        phi1 = Factor(['a', 'c'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1)

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2)


        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4))
        phi5 = Factor(['d', 'b'], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1, phi2, phi3, phi4, phi5)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5)


    def test_factor_graph(self):
        from pgmpy.models import FactorGraph

        phi1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6))
        phi2 = Factor(['Bob', 'Charles'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.graph.add_factors(phi1, phi2)

        factor_graph = self.graph.to_factor_graph()
        self.assertIsInstance(factor_graph, FactorGraph)
        self.assertListEqual(sorted(factor_graph.nodes()),
                             ['Alice', 'Bob', 'Charles', 'phi_Alice_Bob',
                              'phi_Bob_Charles'])
        self.assertListEqual(hf.recursive_sorted(factor_graph.edges()),
                             [['Alice', 'phi_Alice_Bob'], ['Bob', 'phi_Alice_Bob'],
                              ['Bob', 'phi_Bob_Charles'], ['Charles', 'phi_Bob_Charles']])
        self.assertListEqual(factor_graph.get_factors(), [phi1, phi2])

    def test_factor_graph_raises_error(self):
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.assertRaises(ValueError, self.graph.to_factor_graph)

    def test_junction_tree(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['a', 'b', 'd'], ['b', 'c', 'd']])
        self.assertEqual(len(junction_tree.edges()), 1)

    def test_junction_tree_single_clique(self):
        from pgmpy.factors import factor_product

        self.graph.add_edges_from([('x1','x2'), ('x2', 'x3'), ('x1', 'x3')])
        phi = [Factor(edge, [2, 2], np.random.rand(4)) for edge in self.graph.edges()]
        self.graph.add_factors(*phi)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['x1', 'x2', 'x3']])
        factors = junction_tree.get_factors()
        self.assertEqual(factors[0], factor_product(*phi))

    def test_markov_blanket(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.graph.markov_blanket('a'), ['b'])
        self.assertListEqual(sorted(self.graph.markov_blanket('b')),
                             ['a', 'c'])

    def test_local_independencies(self):
        from pgmpy.independencies import Independencies

        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        independencies = self.graph.get_local_independencies()

        self.assertIsInstance(independencies, Independencies)
        self.assertEqual(len(independencies.get_assertions()), 2)

        string = ''
        for assertion in sorted(independencies.get_assertions(),
                                key=lambda x: list(x.event1)):
            string += str(assertion) + '\n'

        self.assertEqual(string, '(a _|_ c | b)\n(c _|_ a | b)\n')

    def test_bayesian_model(self):
        from pgmpy.models import BayesianModel
        import networkx as nx

        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        bm = self.graph.to_bayesian_model()
        self.assertIsInstance(bm, BayesianModel)
        self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd'])
        self.assertTrue(nx.is_chordal(bm.to_undirected()))

    def tearDown(self):
        del self.graph
Exemplo n.º 11
0
class TestUndirectedGraphTriangulation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_check_clique(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.check_clique(['a', 'b', 'c']))

    def test_is_triangulated(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.is_triangulated())

    def test_triangulation_h1_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_cardinality_mismatch_raises_error(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        factor_list = [Factor(edge, [2, 2], np.random.rand(4)) for edge in
                       self.graph.edges()]
        self.graph.add_factors(*factor_list)
        self.graph.add_factors(Factor(['a', 'b'], [2, 3], np.random.rand(6)))
        self.assertRaises(ValueError, self.graph.triangulate)

    def test_triangulation_h1_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H5', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H6', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def tearDown(self):
        del self.graph
Exemplo n.º 12
0
from pgmpy.models import MarkovModel
mm = MarkovModel()
mm.add_nodes_from(['A', 'B', 'C'])
mm.add_edges_from([('A', 'B'), ('B', 'C'), ('C', 'A')])
mm.add_factors(phi1, phi2, phi3)
factor_graph_from_mm = mm.to_factor_graph()
# While converting a markov model into factor graph, factor nodes
# would be automatically added the factor nodes would be in the
# form of phi_node1_node2_...
factor_graph_from_mm.nodes()
factor_graph.edges()
# FactorGraph to MarkovModel
phi = Factor(['A', 'B', 'C'], [2, 2, 2],
np.random.rand(8))
factor_graph = FactorGraph()
factor_graph.add_nodes_from(['A', 'B', 'C', 'phi'])
factor_graph.add_edges_from([('A', 'phi'), ('B', 'phi'), ('C', 'phi')])
Exemplo n.º 13
0
import numpy as np
from pgmpy.models import MarkovModel
from pgmpy.factors.discrete import DiscreteFactor

from pgmpy.inference import BeliefPropagation
from pgmpy.models import BayesianModel
import pandas as pd

#when undirected edges are added, the stored node order seems to be flipped at random.
#When factors are defined, the node order matters, so explicitly specify the order to
#avoid problems, also maybe double check this.

G = MarkovModel()
G.add_nodes_from(['x1', 'x2', 'x3'])
G.add_edges_from([('x1', 'x2'), ('x1', 'x3')])

#G.add_edges_from([('z1', 'z2'), ('z1', 'z3')])
#G.add_edges_from([('x2', 'x1'), ('x3', 'x2')])
#G.add_edges_from([('x1', 'x3'), ('x1', 'x2')])
#G.add_edges_from([('a', 'c'), ('a', 'b')])
#G.add_edge('z1', 'z2')
#G.add_edge('z1', 'z3')
for edge in G.edges():
    print edge
#phi = [DiscreteFactor(edge, cardinality=[2, 2], values=np.random.rand(4)) for edge in G.edges()]

#####phi = [DiscreteFactor(edge, cardinality=[2, 2],
#####	   values=np.array([[1,2],
#####	   					[3,4]])) for edge in G.edges()]
#G.add_nodes_from(['z1', 'z2'])
#G.add_edges_from([('z1', 'z2')])
Exemplo n.º 14
0
class TestUndirectedGraphFactorOperations(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_add_factor_raises_error(self):
        self.graph.add_edges_from([
            ("Alice", "Bob"),
            ("Bob", "Charles"),
            ("Charles", "Debbie"),
            ("Debbie", "Alice"),
        ])
        factor = DiscreteFactor(["Alice", "Bob", "John"], [2, 2, 2],
                                np.random.rand(8))
        self.assertRaises(ValueError, self.graph.add_factors, factor)

    def test_add_single_factor(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi = DiscreteFactor(["a", "b"], [2, 2], range(4))
        self.graph.add_factors(phi)
        six.assertCountEqual(self, self.graph.factors, [phi])

    def test_add_multiple_factors(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.factors, [phi1, phi2])

    def test_get_factors(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4))
        six.assertCountEqual(self, self.graph.get_factors(), [])
        self.graph.add_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.get_factors(), [phi1, phi2])
        six.assertCountEqual(self, self.graph.get_factors("a"), [phi1])

    def test_remove_single_factor(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1)
        six.assertCountEqual(self, self.graph.factors, [phi2])

    def test_remove_multiple_factors(self):
        self.graph.add_nodes_from(["a", "b", "c"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.graph.remove_factors(phi1, phi2)
        six.assertCountEqual(self, self.graph.factors, [])

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

    def test_partition_function_raises_error(self):
        self.graph.add_nodes_from(["a", "b", "c", "d"])
        phi1 = DiscreteFactor(["a", "b"], [2, 2], range(4))
        phi2 = DiscreteFactor(["b", "c"], [2, 2], range(4))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.get_partition_function)

    def tearDown(self):
        del self.graph
Exemplo n.º 15
0
class TestMarkovModelMethods(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_factor_graph(self):
        from pgmpy.models import FactorGraph

        phi1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6))
        phi2 = Factor(['Bob', 'Charles'], [3, 2], np.random.rand(6))
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.graph.add_factors(phi1, phi2)

        factor_graph = self.graph.to_factor_graph()
        self.assertIsInstance(factor_graph, FactorGraph)
        self.assertListEqual(
            sorted(factor_graph.nodes()),
            ['Alice', 'Bob', 'Charles', 'phi_Alice_Bob', 'phi_Bob_Charles'])
        self.assertListEqual(
            hf.recursive_sorted(factor_graph.edges()),
            [['Alice', 'phi_Alice_Bob'], ['Bob', 'phi_Alice_Bob'],
             ['Bob', 'phi_Bob_Charles'], ['Charles', 'phi_Bob_Charles']])
        self.assertListEqual(factor_graph.get_factors(), [phi1, phi2])

    def test_factor_graph_raises_error(self):
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.assertRaises(ValueError, self.graph.to_factor_graph)

    def test_junction_tree(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['a', 'b', 'd'], ['b', 'c', 'd']])
        self.assertEqual(len(junction_tree.edges()), 1)

    def test_junction_tree_single_clique(self):
        from pgmpy.factors import factor_product

        self.graph.add_edges_from([('x1', 'x2'), ('x2', 'x3'), ('x1', 'x3')])
        phi = [
            Factor(edge, [2, 2], np.random.rand(4))
            for edge in self.graph.edges()
        ]
        self.graph.add_factors(*phi)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['x1', 'x2', 'x3']])
        factors = junction_tree.get_factors()
        self.assertEqual(factors[0], factor_product(*phi))

    def test_markov_blanket(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.graph.markov_blanket('a'), ['b'])
        self.assertListEqual(sorted(self.graph.markov_blanket('b')),
                             ['a', 'c'])

    def test_local_independencies(self):
        from pgmpy.independencies import Independencies

        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        independencies = self.graph.get_local_independencies()

        self.assertIsInstance(independencies, Independencies)
        self.assertEqual(len(independencies.get_assertions()), 2)

        string = ''
        for assertion in sorted(independencies.get_assertions(),
                                key=lambda x: list(x.event1)):
            string += str(assertion) + '\n'

        self.assertEqual(string, '(a _|_ c | b)\n(c _|_ a | b)\n')

    def test_bayesian_model(self):
        from pgmpy.models import BayesianModel
        import networkx as nx

        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        bm = self.graph.to_bayesian_model()
        self.assertIsInstance(bm, BayesianModel)
        self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd'])
        self.assertTrue(nx.is_chordal(bm.to_undirected()))

    def tearDown(self):
        del self.graph
Exemplo n.º 16
0
class TestUndirectedGraphTriangulation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_check_clique(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.check_clique(['a', 'b', 'c']))

    def test_is_triangulated(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.is_triangulated())

    def test_triangulation_h1_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_cardinality_mismatch_raises_error(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        factor_list = [
            Factor(edge, [2, 2], np.random.rand(4))
            for edge in self.graph.edges()
        ]
        self.graph.add_factors(*factor_list)
        self.graph.add_factors(Factor(['a', 'b'], [2, 3], np.random.rand(6)))
        self.assertRaises(CardinalityError, self.graph.triangulate)

    def test_triangulation_h1_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H5', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H6', inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [['a', 'b'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']])

    def tearDown(self):
        del self.graph
Exemplo n.º 17
0
def eval_partition_func_random_glass_spin(N):
    '''
	
	Inputs:
		-N: int, generate a random NxN glass spin model

	Outputs:

	'''
    G = MarkovModel()

    #create an NxN grid of nodes
    node_names = ['x%d%d' % (r, c) for r in range(N) for c in range(N)]
    print node_names
    G.add_nodes_from(node_names)

    #add an edge between each node and its 4 neighbors, except when the
    #node is on the grid border and has fewer than 4 neighbors
    edges = []
    for r in range(N):
        for c in range(N):
            if r < N - 1:
                edges.append(('x%d%d' % (r, c), 'x%d%d' % (r + 1, c)))
            if c < N - 1:
                edges.append(('x%d%d' % (r, c), 'x%d%d' % (r, c + 1)))
    assert (len(edges) == 2 * N * (N - 1))
    print edges
    print "number edges =", len(edges)
    G.add_edges_from(edges)

    all_factors = []
    #sample single variable potentials
    STRONG_LOCAL_FIELD = True
    if STRONG_LOCAL_FIELD:
        f = 1  #strong local field
    else:
        f = .1  #weak local field
    for node in node_names:
        #sample in the half open interval [-f, f), gumbel paper actually uses closed interval, shouldn't matter
        theta_i = np.random.uniform(low=-f, high=f)
        factor_vals = np.array([np.exp(-theta_i), np.exp(theta_i)])
        all_factors.append(
            DiscreteFactor([node], cardinality=[2], values=factor_vals))

    #sample two variable potentials
    theta_ij_max = 1.5
    for edge in edges:
        #sample in the half open interval [0, theta_ij_max)
        theta_ij = np.random.uniform(low=0.0, high=theta_ij_max)
        factor_vals = np.array([[np.exp(theta_ij),
                                 np.exp(-theta_ij)],
                                [np.exp(-theta_ij),
                                 np.exp(theta_ij)]])
        all_factors.append(
            DiscreteFactor(edge, cardinality=[2, 2], values=factor_vals))

    G.add_factors(*all_factors)
    #print "factors:", G.get_factors
    #	partition_function_enumeration = G.get_partition_function()
    partition_function_bp = get_partition_function_BP(G)
    #	print "partition function enumeration =", partition_function_enumeration
    print "partition function bp =", partition_function_bp
Exemplo n.º 18
0
from pgmpy.models import MarkovModel
mm = MarkovModel()
mm.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7'])
mm.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'),
                   ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'),
                   ('x4', 'x7'), ('x5', 'x7')])
mm.get_local_independencies()
Exemplo n.º 19
0
class TestMarkovModelMethods(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_get_cardinality(self):

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

        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {'a': 1, 'b': 2})
        self.graph.remove_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = Factor(['a', 'b'], [2, 2], np.random.rand(4))
        phi2 = Factor(['c', 'd'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertDictEqual(self.graph.get_cardinality(), {
            'd': 2,
            'a': 2,
            'b': 2,
            'c': 1
        })

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

        self.graph.remove_factors(phi1, phi2, phi3)
        self.assertDictEqual(self.graph.get_cardinality(), {})

    def test_get_cardinality_check_cardinality(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])

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

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

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

    def test_check_model(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['c', 'b'], [3, 2], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4))

        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.assertTrue(self.graph.check_model())

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

    def test_check_model1(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))

        phi2 = Factor(['b', 'c'], [3, 3], np.random.rand(9))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2)

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

        phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 3], np.random.rand(12))
        self.graph.add_factors(phi2, phi3, phi4)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2, phi3, phi4)

        phi2 = Factor(['a', 'b'], [1, 3], np.random.rand(3))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2)

    def test_check_model2(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])

        phi1 = Factor(['a', 'c'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1)

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['a', 'c'], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2)

        phi1 = Factor(['a', 'b'], [1, 2], np.random.rand(2))
        phi2 = Factor(['b', 'c'], [2, 3], np.random.rand(6))
        phi3 = Factor(['c', 'd'], [3, 4], np.random.rand(12))
        phi4 = Factor(['d', 'a'], [4, 1], np.random.rand(4))
        phi5 = Factor(['d', 'b'], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1, phi2, phi3, phi4, phi5)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5)

    def test_factor_graph(self):
        phi1 = Factor(['Alice', 'Bob'], [3, 2], np.random.rand(6))
        phi2 = Factor(['Bob', 'Charles'], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.graph.add_factors(phi1, phi2)

        factor_graph = self.graph.to_factor_graph()
        self.assertIsInstance(factor_graph, FactorGraph)
        self.assertListEqual(
            sorted(factor_graph.nodes()),
            ['Alice', 'Bob', 'Charles', 'phi_Alice_Bob', 'phi_Bob_Charles'])
        self.assertListEqual(
            hf.recursive_sorted(factor_graph.edges()),
            [['Alice', 'phi_Alice_Bob'], ['Bob', 'phi_Alice_Bob'],
             ['Bob', 'phi_Bob_Charles'], ['Charles', 'phi_Bob_Charles']])
        self.assertListEqual(factor_graph.get_factors(), [phi1, phi2])

    def test_factor_graph_raises_error(self):
        self.graph.add_edges_from([('Alice', 'Bob'), ('Bob', 'Charles')])
        self.assertRaises(ValueError, self.graph.to_factor_graph)

    def test_junction_tree(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['a', 'b', 'd'], ['b', 'c', 'd']])
        self.assertEqual(len(junction_tree.edges()), 1)

    def test_junction_tree_single_clique(self):

        self.graph.add_edges_from([('x1', 'x2'), ('x2', 'x3'), ('x1', 'x3')])
        phi = [
            Factor(edge, [2, 2], np.random.rand(4))
            for edge in self.graph.edges()
        ]
        self.graph.add_factors(*phi)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [['x1', 'x2', 'x3']])
        factors = junction_tree.get_factors()
        self.assertEqual(factors[0], factor_product(*phi))

    def test_markov_blanket(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(self.graph.markov_blanket('a'), ['b'])
        self.assertListEqual(sorted(self.graph.markov_blanket('b')),
                             ['a', 'c'])

    def test_local_independencies(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        independencies = self.graph.get_local_independencies()
        self.assertIsInstance(independencies, Independencies)
        self.assertEqual(independencies, Independencies(['a', 'c', 'b']))

    def test_bayesian_model(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = Factor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = Factor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = Factor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = Factor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        bm = self.graph.to_bayesian_model()
        self.assertIsInstance(bm, BayesianModel)
        self.assertListEqual(sorted(bm.nodes()), ['a', 'b', 'c', 'd'])
        self.assertTrue(nx.is_chordal(bm.to_undirected()))

    def tearDown(self):
        del self.graph
Exemplo n.º 20
0
class TestMarkovModelMethods(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_get_cardinality(self):

        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])

        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {"a": 1, "b": 2})
        self.graph.remove_factors(phi1)
        self.assertDictEqual(self.graph.get_cardinality(), {})

        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["c", "d"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertDictEqual(self.graph.get_cardinality(), {
            "d": 2,
            "a": 2,
            "b": 2,
            "c": 1
        })

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

        self.graph.remove_factors(phi1, phi2, phi3)
        self.assertDictEqual(self.graph.get_cardinality(), {})

    def test_get_cardinality_with_node(self):

        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])

        phi1 = DiscreteFactor(["a", "b"], [2, 2], np.random.rand(4))
        phi2 = DiscreteFactor(["c", "d"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertEqual(self.graph.get_cardinality("a"), 2)
        self.assertEqual(self.graph.get_cardinality("b"), 2)
        self.assertEqual(self.graph.get_cardinality("c"), 1)
        self.assertEqual(self.graph.get_cardinality("d"), 2)

    def test_check_model(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])

        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertRaises(ValueError, self.graph.check_model)

        phi2 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi2)
        self.assertRaises(ValueError, self.graph.check_model)

    def test_check_model1(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))
        phi2 = DiscreteFactor(["c", "b"], [3, 2], np.random.rand(6))
        phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12))
        phi4 = DiscreteFactor(["d", "a"], [4, 1], np.random.rand(4))

        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.assertTrue(self.graph.check_model())

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

    def test_check_model2(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])

        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))

        phi2 = DiscreteFactor(["b", "c"], [3, 3], np.random.rand(9))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2)

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

        phi2 = DiscreteFactor(["b", "c"], [2, 3], np.random.rand(6))
        phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12))
        phi4 = DiscreteFactor(["d", "a"], [4, 3], np.random.rand(12))
        self.graph.add_factors(phi2, phi3, phi4)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2, phi3, phi4)

        phi2 = DiscreteFactor(["a", "b"], [1, 3], np.random.rand(3))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi2)

    def test_check_model3(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])

        phi1 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1)

        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))
        phi2 = DiscreteFactor(["a", "c"], [1, 2], np.random.rand(2))
        self.graph.add_factors(phi1, phi2)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2)

        phi1 = DiscreteFactor(["a", "b"], [1, 2], np.random.rand(2))
        phi2 = DiscreteFactor(["b", "c"], [2, 3], np.random.rand(6))
        phi3 = DiscreteFactor(["c", "d"], [3, 4], np.random.rand(12))
        phi4 = DiscreteFactor(["d", "a"], [4, 1], np.random.rand(4))
        phi5 = DiscreteFactor(["d", "b"], [4, 2], np.random.rand(8))
        self.graph.add_factors(phi1, phi2, phi3, phi4, phi5)
        self.assertRaises(ValueError, self.graph.check_model)
        self.graph.remove_factors(phi1, phi2, phi3, phi4, phi5)

    def test_factor_graph(self):
        phi1 = DiscreteFactor(["Alice", "Bob"], [3, 2], np.random.rand(6))
        phi2 = DiscreteFactor(["Bob", "Charles"], [2, 2], np.random.rand(4))
        self.graph.add_edges_from([("Alice", "Bob"), ("Bob", "Charles")])
        self.graph.add_factors(phi1, phi2)

        factor_graph = self.graph.to_factor_graph()
        self.assertIsInstance(factor_graph, FactorGraph)
        self.assertListEqual(
            sorted(factor_graph.nodes()),
            ["Alice", "Bob", "Charles", "phi_Alice_Bob", "phi_Bob_Charles"],
        )
        self.assertListEqual(
            hf.recursive_sorted(factor_graph.edges()),
            [
                ["Alice", "phi_Alice_Bob"],
                ["Bob", "phi_Alice_Bob"],
                ["Bob", "phi_Bob_Charles"],
                ["Charles", "phi_Bob_Charles"],
            ],
        )
        self.assertListEqual(factor_graph.get_factors(), [phi1, phi2])

    def test_factor_graph_raises_error(self):
        self.graph.add_edges_from([("Alice", "Bob"), ("Bob", "Charles")])
        self.assertRaises(ValueError, self.graph.to_factor_graph)

    def test_junction_tree(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(
            hf.recursive_sorted(junction_tree.nodes()),
            [["a", "b", "d"], ["b", "c", "d"]],
        )
        self.assertEqual(len(junction_tree.edges()), 1)

    def test_junction_tree_single_clique(self):

        self.graph.add_edges_from([("x1", "x2"), ("x2", "x3"), ("x1", "x3")])
        phi = [
            DiscreteFactor(edge, [2, 2], np.random.rand(4))
            for edge in self.graph.edges()
        ]
        self.graph.add_factors(*phi)

        junction_tree = self.graph.to_junction_tree()
        self.assertListEqual(hf.recursive_sorted(junction_tree.nodes()),
                             [["x1", "x2", "x3"]])
        factors = junction_tree.get_factors()
        self.assertEqual(factors[0], factor_product(*phi))

    def test_markov_blanket(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c")])
        self.assertListEqual(list(self.graph.markov_blanket("a")), ["b"])
        self.assertListEqual(sorted(self.graph.markov_blanket("b")),
                             ["a", "c"])

    def test_local_independencies(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c")])
        independencies = self.graph.get_local_independencies()
        self.assertIsInstance(independencies, Independencies)
        self.assertEqual(independencies, Independencies(["a", "c", "b"]))

    def test_bayesian_model(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)

        bm = self.graph.to_bayesian_model()
        self.assertIsInstance(bm, BayesianModel)
        self.assertListEqual(sorted(bm.nodes()), ["a", "b", "c", "d"])
        self.assertTrue(nx.is_chordal(bm.to_undirected()))

    def tearDown(self):
        del self.graph
Exemplo n.º 21
0
def main():
    # maximum size of segments grid cell
    map_size = 50
    # minimum number of pixels to consider segment
    pixels_thresh = 500
    # number of image in the database
    num_images = 70

    # counter for incorrectly classified segments
    num_incorrect = 0
    for idx in range(num_images):
        print('\n\nImage ', idx)

        # read image from disk
        image = cv2.imread('export/image_%04d.jpg' % idx)
        # read ground truth classes
        labels_gt_im = cv2.imread('export/labels_%04d.png' % idx,
                                  cv2.IMREAD_ANYDEPTH).astype(np.int)
        labels_gt_im[labels_gt_im == 65535] = -1
        # read a priori probabilities from classifier
        prob_im = cv2.imread('export/prob_%04d.png' % idx,
                             cv2.IMREAD_ANYDEPTH) / 65535.0
        # read image division into segments
        segments_im = cv2.imread('export/segments_%04d.png' % idx,
                                 cv2.IMREAD_ANYDEPTH)

        # display image
        cv2.imshow('original image', image)
        cv2.waitKey(1)

        # mean R, G, B values for each segment
        mean_rgb = np.zeros([map_size, map_size, 3], dtype=np.float)
        # number of pixels for each segment
        num_pixels = np.zeros([map_size, map_size], dtype=np.uint)
        # a priori probabilities for each segment
        prob = np.zeros([map_size, map_size, 2], dtype=np.float)
        # ground truth classes for each segment
        labels_gt = -1 * np.ones([map_size, map_size], dtype=np.int)
        for y in range(map_size):
            for x in range(map_size):
                # segment identifier
                cur_seg = y * map_size + x
                # indices of pixels belonging to the segment
                cur_pixels = np.nonzero(segments_im == cur_seg)

                if len(cur_pixels[0]) > 0:
                    num_pixels[y, x] = len(cur_pixels[0])
                    # flip because opencv stores images as BGR by default
                    mean_rgb[y,
                             x, :] = np.flip(np.mean(image[cur_pixels],
                                                     axis=0))
                    # average results from the classifier - should not be necessary
                    prob[y, x, 0] = np.mean(prob_im[cur_pixels])
                    prob[y, x, 1] = 1.0 - prob[y, x, 0]
                    # labeling boundaries don't have to be aligned with segments boundaties
                    # count which label is the most common in this segment
                    labels_unique, count = np.unique(labels_gt_im[cur_pixels],
                                                     return_counts=True)
                    labels_gt[y, x] = labels_unique[np.argmax(count)]
                    pass

        # build model
        # PUT YOUR CODE HERE

        nodes = []
        # if segment size is bigger than pixels_thresh, add current segment to node list
        for y in range(map_size):
            for x in range(map_size):
                if num_pixels[y, x] > pixels_thresh:
                    nodes.append("s_" + str(y) + "_" + str(x))

        factors_unary = []
        # if segment size is bigger than pixels_thresh, add unary factor of segment to list
        for y in range(map_size):
            for x in range(map_size):
                if num_pixels[y, x] > pixels_thresh:
                    # print(prob[y, x] * 0.9/1 + 0.05)
                    cur_f = create_factor(["s_" + str(y) + "_" + str(x)],
                                          [[0, 1]], [0.945212], [unary_feat],
                                          [prob[y, x]])
                    factors_unary.append(cur_f)

        factors_pairway = []
        edges_pairway = []
        # if segment size is bigger than pixels_thresh and his neighbour too, add pairway factor to list
        for y in range(map_size - 1):
            for x in range(map_size - 1):
                if num_pixels[y, x] > pixels_thresh:

                    # check neighnour to the right
                    if num_pixels[y, x + 1] > pixels_thresh:
                        cur_f = create_factor([
                            "s_" + str(y) + "_" + str(x),
                            "s_" + str(y) + "_" + str(x + 1)
                        ], [[0, 1], [0, 1]], [1.86891, 1.07741, 1.89271], [
                            pairway_feat_red, pairway_feat_green,
                            pairway_feat_blue
                        ], [mean_rgb[y, x], mean_rgb[y, x + 1]])
                        factors_pairway.append(cur_f)
                        edges_pairway.append(
                            ("s_" + str(y) + "_" + str(x),
                             "s_" + str(y) + "_" + str(x + 1)))
                    # check neighbour under
                    if num_pixels[y + 1, x] > pixels_thresh:
                        cur_f = create_factor([
                            "s_" + str(y) + "_" + str(x),
                            "s_" + str(y + 1) + "_" + str(x)
                        ], [[0, 1], [0, 1]], [1.86891, 1.07741, 1.89271], [
                            pairway_feat_red, pairway_feat_green,
                            pairway_feat_blue
                        ], [mean_rgb[y, x], mean_rgb[y + 1, x]])
                        factors_pairway.append(cur_f)
                        edges_pairway.append(
                            ("s_" + str(y) + "_" + str(x),
                             "s_" + str(y + 1) + "_" + str(x)))

        # use Markov model, because MPLP doesn't support factor graphs
        G = MarkovModel()
        G.add_nodes_from(nodes)  # add nodes
        G.add_factors(*factors_unary)  # add unary factors
        G.add_factors(*factors_pairway)  # add pairway factors
        G.add_edges_from(edges_pairway)  # add edges

        # check if everything is ok
        print("Check model: ", G.check_model())

        # ------------------

        # inferred image pixels
        labels_infer = -1 * np.ones([map_size, map_size], dtype=np.int)

        # read results of the inference
        # PUT YOUR CODE HERE
        mplp_infer = Mplp(G)
        q = mplp_infer.map_query()

        segment_cnt = 0
        for y in range(map_size):
            for x in range(map_size):

                if num_pixels[y, x] > pixels_thresh:
                    val = q["s_" + str(y) + "_" + str(x)]
                    rv = None
                    if val == factors_unary[segment_cnt].values[0]:
                        rv = 0
                    else:
                        rv = 1
                    labels_infer[y, x] = rv

                    segment_cnt += 1

        # ------------------

        labels_class = -1 * np.ones([map_size, map_size], dtype=np.int)

        for y in range(map_size - 1):
            for x in range(map_size - 1):
                if num_pixels[y, x] > pixels_thresh:
                    # label as the class with the highest probability
                    if prob[y, x, 0] >= 0.5:
                        labels_class[y, x] = 0
                    else:
                        labels_class[y, x] = 1

        # count correct pixels
        cnt_corr = np.sum(
            np.logical_and(labels_gt == labels_infer, labels_gt != -1))

        print('Accuracy = ', cnt_corr / np.sum(labels_gt != -1))
        num_incorrect += np.sum(labels_gt != -1) - cnt_corr

        # transfer results for segments onto image
        labels_infer_im = -1 * np.ones_like(labels_gt_im)
        labels_class_im = -1 * np.ones_like(labels_gt_im)
        for y in range(map_size - 1):
            for x in range(map_size - 1):
                if labels_infer[y, x] >= 0:
                    cur_seg = y * map_size + x
                    cur_pixels = np.nonzero(segments_im == cur_seg)

                    labels_infer_im[cur_pixels] = labels_infer[y, x]
                    labels_class_im[cur_pixels] = labels_class[y, x]

        # class 0 - green, class 1 - red in BGR
        colors = np.array([[0, 255, 0], [0, 0, 255]], dtype=np.uint8)

        image_infer = image.copy()
        image_class = image.copy()
        image_gt = image.copy()

        # color pixels according to label
        for l in range(2):
            image_infer[labels_infer_im == l] = colors[l]
            image_class[labels_class_im == l] = colors[l]
            image_gt[labels_gt_im == l] = colors[l]

        # show inferred, classified, and gt image by blending the original image with the colored one
        image_infer_vis = (0.75 * image + 0.25 * image_infer).astype(np.uint8)
        cv2.imshow('inferred', image_infer_vis)

        image_class_vis = (0.75 * image + 0.25 * image_class).astype(np.uint8)
        cv2.imshow('classified', image_class_vis)

        image_gt_vis = (0.75 * image + 0.25 * image_gt).astype(np.uint8)
        cv2.imshow('ground truth', image_gt_vis)

        # uncomment to stop after each image
        # cv2.waitKey()
        cv2.waitKey(10)

    print('Incorrectly inferred ', num_incorrect, ' segments')
Exemplo n.º 22
0
class TestMarkovModelCreation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

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

    def test_class_init_with_data_string(self):
        self.g = MarkovModel([("a", "b"), ("b", "c")])
        self.assertListEqual(sorted(self.g.nodes()), ["a", "b", "c"])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [["a", "b"], ["b", "c"]])

    def test_class_init_with_data_nonstring(self):
        self.g = MarkovModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.graph.add_node("a")
        self.assertListEqual(list(self.graph.nodes()), ["a"])

    def test_add_node_nonstring(self):
        self.graph.add_node(1)

    def test_add_nodes_from_string(self):
        self.graph.add_nodes_from(["a", "b", "c", "d"])
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "c", "d"])

    def test_add_nodes_from_non_string(self):
        self.graph.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.graph.add_edge("d", "e")
        self.assertListEqual(sorted(self.graph.nodes()), ["d", "e"])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [["d", "e"]])
        self.graph.add_nodes_from(["a", "b", "c"])
        self.graph.add_edge("a", "b")
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [["a", "b"], ["d", "e"]])

    def test_add_edge_nonstring(self):
        self.graph.add_edge(1, 2)

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

    def test_add_edges_from_string(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c")])
        self.assertListEqual(sorted(self.graph.nodes()), ["a", "b", "c"])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [["a", "b"], ["b", "c"]])
        self.graph.add_nodes_from(["d", "e", "f"])
        self.graph.add_edges_from([("d", "e"), ("e", "f")])
        self.assertListEqual(sorted(self.graph.nodes()),
                             ["a", "b", "c", "d", "e", "f"])
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            hf.recursive_sorted([("a", "b"), ("b", "c"), ("d", "e"),
                                 ("e", "f")]),
        )

    def test_add_edges_from_nonstring(self):
        self.graph.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.graph.add_edges_from, [("a", "a")])

    def test_number_of_neighbors(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c")])
        self.assertEqual(len(list(self.graph.neighbors("b"))), 2)

    def tearDown(self):
        del self.graph
Exemplo n.º 23
0
from pgmpy.models import MarkovModel
mm = MarkovModel()
mm.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7'])
mm.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'), ('x2', 'x5'),
                   ('x3', 'x6'), ('x4', 'x6'), ('x4', 'x7'), ('x5', 'x7')])
mm.get_local_independencies()
Exemplo n.º 24
0
class TestUndirectedGraphTriangulation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_check_clique(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "a")])
        self.assertTrue(self.graph.is_clique(["a", "b", "c"]))

    def test_is_triangulated(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "a")])
        self.assertTrue(self.graph.is_triangulated())

    def test_triangulation_h1_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H1", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]],
        )

    def test_triangulation_h2_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H2", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]],
        )

    def test_triangulation_h3_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H3", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h4_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H4", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h5_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H4", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h6_inplace(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic="H4", inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(
            hf.recursive_sorted(self.graph.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_cardinality_mismatch_raises_error(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        factor_list = [
            DiscreteFactor(edge, [2, 2], np.random.rand(4))
            for edge in self.graph.edges()
        ]
        self.graph.add_factors(*factor_list)
        self.graph.add_factors(
            DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6)))
        self.assertRaises(ValueError, self.graph.triangulate)

    def test_triangulation_h1_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H1", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]],
        )

    def test_triangulation_h2_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H2", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "c"], ["a", "d"], ["b", "c"], ["c", "d"]],
        )

    def test_triangulation_h3_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H3", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h4_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H4", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h5_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H5", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_triangulation_h6_create_new(self):
        self.graph.add_edges_from([("a", "b"), ("b", "c"), ("c", "d"),
                                   ("d", "a")])
        phi1 = DiscreteFactor(["a", "b"], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(["b", "c"], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(["c", "d"], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(["d", "a"], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic="H6", inplace=True)
        self.assertListEqual(
            hf.recursive_sorted(H.edges()),
            [["a", "b"], ["a", "d"], ["b", "c"], ["b", "d"], ["c", "d"]],
        )

    def test_copy(self):
        # Setup the original graph
        self.graph.add_nodes_from(["a", "b"])
        self.graph.add_edges_from([("a", "b")])

        # Generate the copy
        copy = self.graph.copy()

        # Ensure the copied model is correct
        self.assertTrue(copy.check_model())

        # Basic sanity checks to ensure the graph was copied correctly
        self.assertEqual(len(copy.nodes()), 2)
        self.assertListEqual(list(copy.neighbors("a")), ["b"])
        self.assertListEqual(list(copy.neighbors("b")), ["a"])

        # Modify the original graph ...
        self.graph.add_nodes_from(["c"])
        self.graph.add_edges_from([("c", "b")])

        # ... and ensure none of those changes get propagated
        self.assertEqual(len(copy.nodes()), 2)
        self.assertListEqual(list(copy.neighbors("a")), ["b"])
        self.assertListEqual(list(copy.neighbors("b")), ["a"])
        with self.assertRaises(nx.NetworkXError):
            list(copy.neighbors("c"))

        # Ensure the copy has no factors at this point
        self.assertEqual(len(copy.get_factors()), 0)

        # Add factors to the original graph
        phi1 = DiscreteFactor(["a", "b"], [2, 2], [[0.3, 0.7], [0.9, 0.1]])
        self.graph.add_factors(phi1)

        # The factors should not get copied over
        with self.assertRaises(AssertionError):
            self.assertListEqual(list(copy.get_factors()),
                                 self.graph.get_factors())

        # Create a fresh copy
        del copy
        copy = self.graph.copy()
        self.assertListEqual(list(copy.get_factors()),
                             self.graph.get_factors())

        # If we change factors in the original, it should not be passed to the clone
        phi1.values = np.array([[0.5, 0.5], [0.5, 0.5]])
        self.assertNotEqual(self.graph.get_factors(), copy.get_factors())

        # Start with a fresh copy
        del copy
        self.graph.add_nodes_from(["d"])
        copy = self.graph.copy()

        # Ensure an unconnected node gets copied over as well
        self.assertEqual(len(copy.nodes()), 4)
        self.assertListEqual(list(self.graph.neighbors("a")), ["b"])
        self.assertTrue("a" in self.graph.neighbors("b"))
        self.assertTrue("c" in self.graph.neighbors("b"))
        self.assertListEqual(list(self.graph.neighbors("c")), ["b"])
        self.assertListEqual(list(self.graph.neighbors("d")), [])

        # Verify that changing the copied model should not update the original
        copy.add_nodes_from(["e"])
        self.assertListEqual(list(copy.neighbors("e")), [])
        with self.assertRaises(nx.NetworkXError):
            self.graph.neighbors("e")

        # Verify that changing edges in the copy doesn't create edges in the original
        copy.add_edges_from([("d", "b")])

        self.assertTrue("a" in copy.neighbors("b"))
        self.assertTrue("c" in copy.neighbors("b"))
        self.assertTrue("d" in copy.neighbors("b"))

        self.assertTrue("a" in self.graph.neighbors("b"))
        self.assertTrue("c" in self.graph.neighbors("b"))
        self.assertFalse("d" in self.graph.neighbors("b"))

        # If we remove factors from the copied model, it should not reflect in the original
        copy.remove_factors(phi1)
        self.assertEqual(len(self.graph.get_factors()), 1)
        self.assertEqual(len(copy.get_factors()), 0)

    def tearDown(self):
        del self.graph
Exemplo n.º 25
0
    def __init__(self,
                 m,
                 v=1,
                 y_edges=[],
                 lambda_y_edges=[],
                 lambda_edges=[],
                 allow_abstentions=True,
                 triplets=None,
                 triplet_seed=0):
        '''Initialize the LabelModel with a graph G.
        
        m: number of LF's
        v: number of Y tasks
        y_edges: edges between the tasks. (i, j) in y_edges means that
            there is an edge between y_i and y_j.
        lambda_y_edges: edges between LF's and tasks. (i, j) in lambda_y_edges
            means that there is an edge between lambda_i and y_j. If this list
            is empty, assume that all labeling functions are connected to Y_0.
        lambda_edges: edges between LF's. (i, j) in lambda_edges means that
            there is an edge between lambda_i and lambda_j.
        allow_abstentions: if True, allow abstentions in L_train.
        triplets: if specified, use these triplets
        triplet_seed: if triplets not specified, randomly shuffle the nodes
            with this seed when generating triplets
        '''
        if lambda_y_edges == []:
            lambda_y_edges = [(i, 0) for i in range(m)]

        G = MarkovModel()
        # Add LF nodes
        G.add_nodes_from(['lambda_{}'.format(i) for i in range(m)])
        G.add_nodes_from(['Y_{}'.format(i) for i in range(v)])

        # Add edges
        G.add_edges_from([('Y_{}'.format(start), 'Y_{}'.format(end))
                          for start, end in y_edges])
        G.add_edges_from([('lambda_{}'.format(start), 'Y_{}'.format(end))
                          for start, end in lambda_y_edges])
        G.add_edges_from([('lambda_{}'.format(start), 'lambda_{}'.format(end))
                          for start, end in lambda_edges])

        self.fully_independent_case = lambda_edges == []

        self.m = m
        if m < 3:
            raise NotImplementedError(
                "Triplet method needs at least three LF's to run.")
        self.v = v
        self.G = G
        self.junction_tree = self.G.to_junction_tree()

        self.nodes = sorted(list(self.G.nodes))
        self.triplet_seed = triplet_seed
        if triplet_seed is not None:
            random.seed(triplet_seed)
            random.shuffle(self.nodes)

        self.separator_sets = set([
            tuple(sorted(list((set(clique1).intersection(set(clique2))))))
            for clique1, clique2 in self.junction_tree.edges
        ])

        self.allow_abstentions = allow_abstentions
        self.triplets = triplets

        if not self._check():
            raise NotImplementedError(
                'Cannot run triplet method for specified graph.')
Exemplo n.º 26
0
# THIS CODE HAS TO BE RUN ON PYTHON 2
# Otherwise, you will get wrong results

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

# Construct a graph
PGM = MarkovModel()
PGM.add_nodes_from(['w1', 'w2', 'w3'])
PGM.add_edges_from([('w1', 'w2'), ('w2', 'w3')])
tr_matrix = np.array([1, 10, 3, 2, 1, 5, 3, 3, 2])
tr_matrix = np.array([1, 2, 3, 10, 1, 3, 3, 5, 2]).reshape(3, 3).T.reshape(-1)
phi = [DiscreteFactor(edge, [3, 3], tr_matrix) for edge in PGM.edges()]
print(phi[0])
print(phi[1])
PGM.add_factors(*phi)

# Calculate partition funtion
Z = PGM.get_partition_function()
print('The partition function is:', Z)

# Calibrate the click
belief_propagation = BeliefPropagation(PGM)
belief_propagation.calibrate()

# Output calibration result, which you should get
query = belief_propagation.query(variables=['w2'])
print('After calibration you should get the following mu(S):\n', query * Z)
Exemplo n.º 27
0
from pgmpy.models import MarkovModel
mm = MarkovModel()
mm.add_nodes_from(['A', 'B', 'C'])
mm.add_edges_from([('A', 'B'), ('B', 'C'), ('C', 'A')])
mm.add_factors(phi1, phi2, phi3)
factor_graph_from_mm = mm.to_factor_graph()
# While converting a markov model into factor graph, factor nodes
# would be automatically added the factor nodes would be in the
# form of phi_node1_node2_...
factor_graph_from_mm.nodes()
factor_graph.edges()
# FactorGraph to MarkovModel
phi = Factor(['A', 'B', 'C'], [2, 2, 2], np.random.rand(8))
factor_graph = FactorGraph()
factor_graph.add_nodes_from(['A', 'B', 'C', 'phi'])
factor_graph.add_edges_from([('A', 'phi'), ('B', 'phi'), ('C', 'phi')])
Exemplo n.º 28
0
from pgmpy.models import MarkovModel
from pgmpy.factors import Factor
model = MarkovModel()
# Fig 2.7(a) represents the Markov model
model.add_nodes_from(['A', 'B', 'C', 'D'])
model.add_edges_from([('A', 'B'), ('B', 'C'),
                      ('C', 'D'), ('D', 'A')])
# Adding some factors.
phi_A_B = Factor(['A', 'B'], [2, 2], [1, 100,
phi_B_C = Factor(['B', 'C'], [2, 2], [100, 1,
phi_C_D = Factor(['C', 'D'], [2, 2], [1, 100,
phi_D_A = Factor(['D', 'A'], [2, 2], [100, 1,
model.add_factors(phi_A_B, phi_B_C, phi_C_D,
bayesian_model = model.to_bayesian_model()
bayesian_model.edges()
class TestUndirectedGraphTriangulation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

    def test_check_clique(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.is_clique(['a', 'b', 'c']))

    def test_is_triangulated(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'a')])
        self.assertTrue(self.graph.is_triangulated())

    def test_triangulation_h1_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_inplace(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertTrue(self.graph.is_triangulated())
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_cardinality_mismatch_raises_error(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        factor_list = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in
                       self.graph.edges()]
        self.graph.add_factors(*factor_list)
        self.graph.add_factors(DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6)))
        self.assertRaises(ValueError, self.graph.triangulate)

    def test_triangulation_h1_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H1', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h2_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H2', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'c'], ['a', 'd'],
                              ['b', 'c'], ['c', 'd']])

    def test_triangulation_h3_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H3', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h4_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H4', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h5_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H5', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_triangulation_h6_create_new(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c'), ('c', 'd'),
                                   ('d', 'a')])
        phi1 = DiscreteFactor(['a', 'b'], [2, 3], np.random.rand(6))
        phi2 = DiscreteFactor(['b', 'c'], [3, 4], np.random.rand(12))
        phi3 = DiscreteFactor(['c', 'd'], [4, 5], np.random.rand(20))
        phi4 = DiscreteFactor(['d', 'a'], [5, 2], np.random.random(10))
        self.graph.add_factors(phi1, phi2, phi3, phi4)
        H = self.graph.triangulate(heuristic='H6', inplace=True)
        self.assertListEqual(hf.recursive_sorted(H.edges()),
                             [['a', 'b'], ['a', 'd'], ['b', 'c'],
                              ['b', 'd'], ['c', 'd']])

    def test_copy(self):
        # Setup the original graph
        self.graph.add_nodes_from(['a', 'b'])
        self.graph.add_edges_from([('a', 'b')])

        # Generate the copy
        copy = self.graph.copy()

        # Ensure the copied model is correct
        self.assertTrue(copy.check_model())

        # Basic sanity checks to ensure the graph was copied correctly
        self.assertEqual(len(copy.nodes()), 2)
        self.assertListEqual(copy.neighbors('a'), ['b'])
        self.assertListEqual(copy.neighbors('b'), ['a'])

        # Modify the original graph ...
        self.graph.add_nodes_from(['c'])
        self.graph.add_edges_from([('c', 'b')])

        # ... and ensure none of those changes get propagated
        self.assertEqual(len(copy.nodes()), 2)
        self.assertListEqual(copy.neighbors('a'), ['b'])
        self.assertListEqual(copy.neighbors('b'), ['a'])
        with self.assertRaises(nx.NetworkXError):
            copy.neighbors('c')

        # Ensure the copy has no factors at this point
        self.assertEqual(len(copy.get_factors()), 0)

        # Add factors to the original graph
        phi1 = DiscreteFactor(['a', 'b'], [2, 2], [[0.3, 0.7], [0.9, 0.1]])
        self.graph.add_factors(phi1)

        # The factors should not get copied over
        with self.assertRaises(AssertionError):
            self.assertListEqual(copy.get_factors(), self.graph.get_factors())

        # Create a fresh copy
        del copy
        copy = self.graph.copy()
        self.assertListEqual(copy.get_factors(), self.graph.get_factors())

        # If we change factors in the original, it should not be passed to the clone
        phi1.values = np.array([[0.5, 0.5], [0.5, 0.5]])
        self.assertNotEqual(self.graph.get_factors(), copy.get_factors())

        # Start with a fresh copy
        del copy
        self.graph.add_nodes_from(['d'])
        copy = self.graph.copy()

        # Ensure an unconnected node gets copied over as well
        self.assertEqual(len(copy.nodes()), 4)
        self.assertListEqual(self.graph.neighbors('a'), ['b'])
        self.assertTrue('a' in self.graph.neighbors('b'))
        self.assertTrue('c' in self.graph.neighbors('b'))
        self.assertListEqual(self.graph.neighbors('c'), ['b'])
        self.assertListEqual(self.graph.neighbors('d'), [])

        # Verify that changing the copied model should not update the original
        copy.add_nodes_from(['e'])
        self.assertListEqual(copy.neighbors('e'), [])
        with self.assertRaises(nx.NetworkXError):
            self.graph.neighbors('e')

        # Verify that changing edges in the copy doesn't create edges in the original
        copy.add_edges_from([('d', 'b')])

        self.assertTrue('a' in copy.neighbors('b'))
        self.assertTrue('c' in copy.neighbors('b'))
        self.assertTrue('d' in copy.neighbors('b'))

        self.assertTrue('a' in self.graph.neighbors('b'))
        self.assertTrue('c' in self.graph.neighbors('b'))
        self.assertFalse('d' in self.graph.neighbors('b'))

        # If we remove factors from the copied model, it should not reflect in the original
        copy.remove_factors(phi1)
        self.assertEqual(len(self.graph.get_factors()), 1)
        self.assertEqual(len(copy.get_factors()), 0)

    def tearDown(self):
        del self.graph
Exemplo n.º 30
0
class generate(object):
    def __init__(self, adj_mat=None, struct=None):
        DEBUG = False
        self.G = MarkovModel()
        self.n_nodes = adj_mat.shape[0]
        if DEBUG: print 'struct', struct
        if struct == 'complete':
            self._complete_graph(adj_mat)
        if struct == 'nodes':
            self._nodes_only(adj_mat)
        if struct is None:
            self._import_adj(adj_mat)
        self._ising_factors(Wf=5, Wi=5, f_type='mixed')
        if DEBUG: print 'generate_init', self.G, self.G.nodes()

    def get_model(self):
        return self.G

    def _complete_graph(self, adj_mat):
        """
        generate the complete graph over len(adj_mat)
        """

        self._nodes_only(adj_mat)
        for i in range(self.n_nodes):
            self.G.add_edges_from([(i, j)
                                   for j in range(self.n_nodes)])

    def _import_adj(self, adj_mat):
        """
        add nodes and edges to graph
        adj_mat - square matrix, numpy array like
        """
        DEBUG = False
        assert (adj_mat is not None), "can't import empty adj mat"
        # add nodes
        self._nodes_only(adj_mat)
        # add edges
        for i in range(self.n_nodes):
            edges_list = ([(i, j)
                           for j in range(self.n_nodes)
                           if adj_mat[i][j]])
            if DEBUG: print edges_list
            self.G.add_edges_from(edges_list)
            if DEBUG: print len(self.G)

    def _nodes_only(self, adj_mat):
        """
        add nodes to graph
        adj_mat - aquare matrix, numpy array like
        """
        global DEBUG
        assert (adj_mat is not None), "can't import empty adj mat"
        assert (self.n_nodes == adj_mat.shape[1]), "adj_mat is not sqaure"
        self.G.add_nodes_from([i for i in range(self.n_nodes)])
        if DEBUG: print '_nodes_only', [i for i in range(self.n_nodes)]
        if DEBUG: print '_nodes_only print G', self.G.nodes()
        assert (self.n_nodes == len(self.G)), "graph size is incosistent with adj_mat"

    def _ising_factors(self, Wf=1, Wi=1, f_type='mixed'):
        """
        Add ising-like factors to model graph
        cardinality is the number of possible values
        in our case we have boolean nodes, thus cardinality = 2
        Wf   =  \theta_i     = ~U[-Wf, Wf] 
        type =  'mixed'      = ~U[-Wi,Wi]
                'attractive' = ~U[0,Wi]
        """
        self._field_factors(Wf)
        self._interact_factors(Wi, f_type)

    def _field_factors(self, w, states=2):
        """
            this function assigns factor for single node
            currently states=2 for ising model generation
        """

        for i in self.G.nodes():
            phi_i = Factor([i], [states], self._wf(w, states))
            self.G.add_factors(phi_i)

    def _interact_factors(self, w, f_type, states=2):
        """
            this function assigns factor for two interacting nodes
            currently states=2 for ising model generation
        """

        for e in self.G.edges():
            # if DEBUG: print 'interact_factors edges,states, values',e,[e[0],
            #  e[1]],len(e)*[states], self._wi(w, f_type, states)
            phi_ij = Factor([e[0], e[1]], [states] * len(e), self._wi(w, f_type, states))
            self.G.add_factors(phi_ij)

    def _wf(self, w, k):
        """
            generate field factor
        """
        # if DEBUG: print 'w',type(w),w
        return np.random.uniform(low=-1 * w, high=w, size=k)

    def _wi(self, w, f_type, k):
        """
            generate interaction factor
            current support only for k=2
        """
        # if DEBUG: print 'w',type(w),w
        a_ij = np.random.uniform(low=-1 * w, high=w)
        if f_type == 'mixed':
            dis_aij = -a_ij
        else:  # f_type == 'attractive':
            dis_aij = 0
        # else:
        #     print 'f_type error'
        return [a_ij, dis_aij, dis_aij, a_ij]
Exemplo n.º 31
0
class TestMarkovModelCreation(unittest.TestCase):
    def setUp(self):
        self.graph = MarkovModel()

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

    def test_class_init_with_data_string(self):
        self.g = MarkovModel([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.g.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.g.edges()),
                             [['a', 'b'], ['b', 'c']])

    def test_class_init_with_data_nonstring(self):
        self.g = MarkovModel([(1, 2), (2, 3)])

    def test_add_node_string(self):
        self.graph.add_node('a')
        self.assertListEqual(self.graph.nodes(), ['a'])

    def test_add_node_nonstring(self):
        self.graph.add_node(1)

    def test_add_nodes_from_string(self):
        self.graph.add_nodes_from(['a', 'b', 'c', 'd'])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c', 'd'])

    def test_add_nodes_from_non_string(self):
        self.graph.add_nodes_from([1, 2, 3, 4])

    def test_add_edge_string(self):
        self.graph.add_edge('d', 'e')
        self.assertListEqual(sorted(self.graph.nodes()), ['d', 'e'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['d', 'e']])
        self.graph.add_nodes_from(['a', 'b', 'c'])
        self.graph.add_edge('a', 'b')
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['d', 'e']])

    def test_add_edge_nonstring(self):
        self.graph.add_edge(1, 2)

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

    def test_add_edges_from_string(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertListEqual(sorted(self.graph.nodes()), ['a', 'b', 'c'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             [['a', 'b'], ['b', 'c']])
        self.graph.add_nodes_from(['d', 'e', 'f'])
        self.graph.add_edges_from([('d', 'e'), ('e', 'f')])
        self.assertListEqual(sorted(self.graph.nodes()),
                             ['a', 'b', 'c', 'd', 'e', 'f'])
        self.assertListEqual(hf.recursive_sorted(self.graph.edges()),
                             hf.recursive_sorted([('a', 'b'), ('b', 'c'),
                                                  ('d', 'e'), ('e', 'f')]))

    def test_add_edges_from_nonstring(self):
        self.graph.add_edges_from([(1, 2), (2, 3)])

    def test_add_edges_from_self_loop(self):
        self.assertRaises(ValueError, self.graph.add_edges_from,
                          [('a', 'a')])

    def test_number_of_neighbors(self):
        self.graph.add_edges_from([('a', 'b'), ('b', 'c')])
        self.assertEqual(len(self.graph.neighbors('b')), 2)

    def tearDown(self):
        del self.graph