Markov Network

class pgmpy.models.MarkovNetwork.MarkovNetwork(ebunch=None, latents=[])[source]

Base class for Markov Model.

A MarkovNetwork stores nodes and edges with potentials

MarkovNetwork holds undirected edges.

Parameters:

data (input graph) – Data to initialize graph. If data=None (default) an empty graph is created. The data can be an edge list, or any NetworkX graph object.

Examples

Create an empty Markov Model with no nodes and no edges.

>>> from pgmpy.models import MarkovNetwork
>>> G = MarkovNetwork()

G can be grown in several ways.

Nodes:

Add one node at a time:

>>> G.add_node('a')

Add the nodes from any container (a list, set or tuple or the nodes from another graph).

>>> G.add_nodes_from(['a', 'b'])

Edges:

G can also be grown by adding edges.

Add one edge,

>>> G.add_edge('a', 'b')

a list of edges,

>>> G.add_edges_from([('a', 'b'), ('b', 'c')])

If some edges connect nodes not yet in the model, the nodes are added automatically. There are no errors when adding nodes or edges that already exist.

Shortcuts:

Many common graph features allow python syntax for speed reporting.

>>> 'a' in G     # check if node in graph
True
>>> len(G)  # number of nodes in graph
3
add_edge(u, v, **kwargs)[source]

Add an edge between u and v.

The nodes u and v will be automatically added if they are not already in the graph

Parameters:
  • u (nodes) – Nodes can be any hashable Python object.

  • v (nodes) – Nodes can be any hashable Python object.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> G = MarkovNetwork()
>>> G.add_nodes_from(['Alice', 'Bob', 'Charles'])
>>> G.add_edge('Alice', 'Bob')
add_factors(*factors)[source]

Associate a factor to the graph. See factors class for the order of potential values

Parameters:

*factor (pgmpy.factors.factors object) – A factor object on any subset of the variables of the model which is to be associated with the model.

Return type:

None

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> student = MarkovNetwork([('Alice', 'Bob'), ('Bob', 'Charles'),
...                        ('Charles', 'Debbie'), ('Debbie', 'Alice')])
>>> factor = DiscreteFactor(['Alice', 'Bob'], cardinality=[3, 2],
...                 values=np.random.rand(6))
>>> student.add_factors(factor)
check_model()[source]

Check the model for various errors. This method checks for the following errors -

  • Checks if the cardinalities of all the variables are consistent across all the factors.

  • Factors are defined for all the random variables.

Returns:

check – True if all the checks are passed

Return type:

boolean

copy()[source]

Returns a copy of this Markov Model.

Returns:

MarkovNetwork

Return type:

Copy of this Markov model.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> from pgmpy.models import MarkovNetwork
>>> G = MarkovNetwork()
>>> G.add_nodes_from([('a', 'b'), ('b', 'c')])
>>> G.add_edge(('a', 'b'), ('b', 'c'))
>>> G_copy = G.copy()
>>> G_copy.edges()
EdgeView([(('a', 'b'), ('b', 'c'))])
>>> G_copy.nodes()
[('a', 'b'), ('b', 'c')]
>>> factor = DiscreteFactor([('a', 'b')], cardinality=[3],
...                 values=np.random.rand(3))
>>> G.add_factors(factor)
>>> G.get_factors()
[<DiscreteFactor representing phi(('a', 'b'):3) at 0x...>]
>>> G_copy.get_factors()
[]
get_cardinality(node=None)[source]

Returns the cardinality of the node. If node is not specified returns a dictionary with the given variable as keys and their respective cardinality as values.

Parameters:

node (any hashable python object (optional)) – The node whose cardinality we want. If node is not specified returns a dictionary with the given variable as keys and their respective cardinality as values.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> student = MarkovNetwork([('Alice', 'Bob'), ('Bob', 'Charles')])
>>> factor = DiscreteFactor(['Alice', 'Bob'], cardinality=[2, 2],
...                 values=np.random.rand(4))
>>> student.add_factors(factor)
>>> student.get_cardinality(node='Alice')
2
>>> student.get_cardinality()
defaultdict(<class 'int'>, {'Bob': 2, 'Alice': 2})
get_factors(node=None)[source]

Returns all the factors containing the node. If node is not specified returns all the factors that have been added till now to the graph.

Parameters:

node (any hashable python object (optional)) – The node whose factor we want. If node is not specified

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> student = MarkovNetwork([('Alice', 'Bob'), ('Bob', 'Charles')])
>>> factor1 = DiscreteFactor(['Alice', 'Bob'], cardinality=[2, 2],
...                          values=np.random.rand(4))
>>> factor2 = DiscreteFactor(['Bob', 'Charles'], cardinality=[2, 3],
...                          values=np.ones(6))
>>> student.add_factors(factor1,factor2)
>>> student.get_factors()
[<DiscreteFactor representing phi(Alice:2, Bob:2) at 0x7f8a0e9bf630>,
<DiscreteFactor representing phi(Bob:2, Charles:3) at 0x7f8a0e9bf5f8>]
>>> student.get_factors('Alice')
[<DiscreteFactor representing phi(Alice:2, Bob:2) at 0x7f8a0e9bf630>]
get_local_independencies(latex=False)[source]

Returns all the local independencies present in the markov model.

Local independencies are the independence assertion in the form of .. math:: {X perp W - {X} - MB(X) | MB(X)} where MB is the markov blanket of all the random variables in X

Parameters:

latex (boolean) – If latex=True then latex string of the indepedence assertion would be created

Examples

>>> from pgmpy.models import MarkovNetwork
>>> mm = MarkovNetwork()
>>> 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()
get_partition_function()[source]

Returns the partition function for a given undirected graph.

A partition function is defined as

\sum_{X}(\prod_{i=1}^{m} \phi_i)

where m is the number of factors present in the graph and X are all the random variables present.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> G = MarkovNetwork()
>>> G.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7'])
>>> G.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'),
...                   ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'),
...                   ('x4', 'x7'), ('x5', 'x7')])
>>> phi = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in G.edges()]
>>> G.add_factors(*phi)
>>> G.get_partition_function()
markov_blanket(node)[source]

Returns a markov blanket for a random variable.

Markov blanket is the neighboring nodes of the given node.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> mm = MarkovNetwork()
>>> 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.markov_blanket('x1')
remove_factors(*factors)[source]

Removes the given factors from the added factors.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> student = MarkovNetwork([('Alice', 'Bob'), ('Bob', 'Charles')])
>>> factor = DiscreteFactor(['Alice', 'Bob'], cardinality=[2, 2],
...                 values=np.random.rand(4))
>>> student.add_factors(factor)
>>> student.remove_factors(factor)
property states

Returns a dictionary mapping each node to its list of possible states.

Returns:

state_dict – Dictionary of nodes to possible states

Return type:

dict

to_bayesian_model()[source]

Creates a Bayesian Model which is a minimum I-Map for this Markov Model.

The ordering of parents may not remain constant. It would depend on the ordering of variable in the junction tree (which is not constant) all the time. Also, if the model is not connected, the connected components are treated as separate models, converted, and then joined together.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> mm = MarkovNetwork()
>>> 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')])
>>> phi = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in mm.edges()]
>>> mm.add_factors(*phi)
>>> bm = mm.to_bayesian_model()
to_factor_graph()[source]

Converts the Markov Model into Factor Graph.

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

Examples

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

Creates a junction tree (or clique tree) for a given markov model.

For a given markov model (H) a junction tree (G) is a graph 1. where each node in G corresponds to a maximal clique in H 2. each sepset in G separates the variables strictly on one side of the edge to other.

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> mm = MarkovNetwork()
>>> 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')])
>>> phi = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in mm.edges()]
>>> mm.add_factors(*phi)
>>> junction_tree = mm.to_junction_tree()
triangulate(heuristic='H6', order=None, inplace=False)[source]

Triangulate the graph.

If order of deletion is given heuristic algorithm will not be used.

Parameters:
  • heuristic (H1 | H2 | H3 | H4 | H5 | H6) –

    The heuristic algorithm to use to decide the deletion order of the variables to compute the triangulated graph. Let X be the set of variables and X(i) denotes the i-th variable.

    • S(i) - The size of the clique created by deleting the variable.

    • E(i) - Cardinality of variable X(i).

    • M(i) - Maximum size of cliques given by X(i) and its adjacent nodes.

    • C(i) - Sum of size of cliques given by X(i) and its adjacent nodes.

    The heuristic algorithm decide the deletion order if this way:

    • H1 - Delete the variable with minimal S(i).

    • H2 - Delete the variable with minimal S(i)/E(i).

    • H3 - Delete the variable with minimal S(i) - M(i).

    • H4 - Delete the variable with minimal S(i) - C(i).

    • H5 - Delete the variable with minimal S(i)/M(i).

    • H6 - Delete the variable with minimal S(i)/C(i).

  • order (list, tuple (array-like)) – The order of deletion of the variables to compute the triagulated graph. If order is given heuristic algorithm will not be used.

  • inplace (True | False) – if inplace is true then adds the edges to the object from which it is called else returns a new object.

References

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.56.3607

Examples

>>> from pgmpy.models import MarkovNetwork
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> G = MarkovNetwork()
>>> G.add_nodes_from(['x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7'])
>>> G.add_edges_from([('x1', 'x3'), ('x1', 'x4'), ('x2', 'x4'),
...                   ('x2', 'x5'), ('x3', 'x6'), ('x4', 'x6'),
...                   ('x4', 'x7'), ('x5', 'x7')])
>>> phi = [DiscreteFactor(edge, [2, 2], np.random.rand(4)) for edge in G.edges()]
>>> G.add_factors(*phi)
>>> G_chordal = G.triangulate()