MPLP¶
- class pgmpy.inference.mplp.Mplp(model)[source]¶
Class for performing approximate inference using Max-Product Linear Programming method.
We derive message passing updates that result in monotone decrease of the dual of the MAP LP Relaxation.
- Parameters:
model (DiscreteMarkovNetwork for which inference is to be performed.)
Examples
>>> import numpy as np >>> from pgmpy.models import DiscreteMarkovNetwork >>> from pgmpy.inference import Mplp >>> from pgmpy.factors.discrete import DiscreteFactor >>> student = DiscreteMarkovNetwork() >>> student.add_edges_from([("A", "B"), ("B", "C"), ("C", "D"), ("E", "F")]) >>> factor_a = DiscreteFactor( ... ["A"], cardinality=[2], values=np.array([0.54577, 1.8323]) ... ) >>> factor_b = DiscreteFactor( ... ["B"], cardinality=[2], values=np.array([0.93894, 1.065]) ... ) >>> factor_c = DiscreteFactor( ... ["C"], cardinality=[2], values=np.array([0.89205, 1.121]) ... ) >>> factor_d = DiscreteFactor( ... ["D"], cardinality=[2], values=np.array([0.56292, 1.7765]) ... ) >>> factor_e = DiscreteFactor( ... ["E"], cardinality=[2], values=np.array([0.47117, 2.1224]) ... ) >>> factor_f = DiscreteFactor( ... ["F"], cardinality=[2], values=np.array([1.5093, 0.66257]) ... ) >>> factor_a_b = DiscreteFactor( ... ["A", "B"], ... cardinality=[2, 2], ... values=np.array([1.3207, 0.75717, 0.75717, 1.3207]), ... ) >>> factor_b_c = DiscreteFactor( ... ["B", "C"], ... cardinality=[2, 2], ... values=np.array([0.00024189, 4134.2, 4134.2, 0.00024189]), ... ) >>> factor_c_d = DiscreteFactor( ... ["C", "D"], ... cardinality=[2, 2], ... values=np.array([0.0043227, 231.34, 231.34, 0.0043227]), ... ) >>> factor_d_e = DiscreteFactor( ... ["E", "F"], ... cardinality=[2, 2], ... values=np.array([31.228, 0.032023, 0.032023, 31.228]), ... ) >>> student.add_factors( ... factor_a, ... factor_b, ... factor_c, ... factor_d, ... factor_e, ... factor_f, ... factor_a_b, ... factor_b_c, ... factor_c_d, ... factor_d_e, ... ) >>> mplp = Mplp(student)
- class Cluster(intersection_set_variables, cluster_potential)[source]¶
Inner class for representing a cluster. A cluster is a subset of variables.
- Parameters:
set_of_variables (tuple) – This is the set of variables that form the cluster.
intersection_set_variables (set containing frozensets.) –
- collection of intersection of all pairs of cluster variables.
- For eg: {{C_1 cap C_2}, {C_2 cap C_3}, {C_3 cap C_1} }
for clusters C_1, C_2 & C_3.
cluster_potential (DiscreteFactor) – Each cluster has an initial probability distribution provided beforehand.
- find_triangles()[source]¶
Finds all the triangles present in the given model
Examples
>>> from pgmpy.models import DiscreteMarkovNetwork >>> from pgmpy.factors.discrete import DiscreteFactor >>> from pgmpy.inference import Mplp >>> mm = DiscreteMarkovNetwork() >>> 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) >>> mplp = Mplp(mm) >>> mplp.find_triangles()
- get_integrality_gap()[source]¶
- Returns the integrality gap of the current state of the Mplp algorithm. The lesser it is, the closer we are
towards the exact solution.
Examples
>>> from pgmpy.models import DiscreteMarkovNetwork >>> from pgmpy.factors.discrete import DiscreteFactor >>> from pgmpy.inference import Mplp >>> mm = DiscreteMarkovNetwork() >>> 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) >>> mplp = Mplp(mm) >>> mplp.map_query() >>> int_gap = mplp.get_integrality_gap()
- map_query(init_iter=1000, later_iter=20, dual_threshold=0.0002, integrality_gap_threshold=0.0002, tighten_triplet=True, max_triplets=5, max_iterations=100, prolong=False)[source]¶
MAP query method using Max Product LP method. This returns the best assignment of the nodes in the form of a dictionary.
- Parameters:
init_iter (integer) – Number of maximum iterations that we want MPLP to run for the first time.
later_iter (integer) – Number of maximum iterations that we want MPLP to run for later iterations
dual_threshold (double) – This sets the minimum width between the dual objective decrements. If the decrement is lesser than the threshold, then that means we have stuck on a local minima.
integrality_gap_threshold (double) – This sets the threshold for the integrality gap below which we say that the solution is satisfactory.
tighten_triplet (bool) – set whether to use triplets as clusters or not.
max_triplets (integer) – Set the maximum number of triplets that can be added at once.
max_iterations (integer) – Maximum number of times we tighten the relaxation. Used only when tighten_triplet is set True.
prolong (bool) –
If set False: The moment we exhaust of all the triplets the tightening stops. If set True: The tightening will be performed max_iterations
number of times irrespective of the triplets.
References
Section 3.3: The Dual Algorithm; Tightening LP Relaxation for MAP using Message Passing (2008) By Sontag Et al.
Examples
>>> from pgmpy.models import DiscreteMarkovNetwork >>> from pgmpy.factors.discrete import DiscreteFactor >>> from pgmpy.inference import Mplp >>> import numpy as np >>> student = DiscreteMarkovNetwork() >>> student.add_edges_from([("A", "B"), ("B", "C"), ("C", "D"), ("E", "F")]) >>> factor_a = DiscreteFactor( ... ["A"], cardinality=[2], values=np.array([0.54577, 1.8323]) ... ) >>> factor_b = DiscreteFactor( ... ["B"], cardinality=[2], values=np.array([0.93894, 1.065]) ... ) >>> factor_c = DiscreteFactor( ... ["C"], cardinality=[2], values=np.array([0.89205, 1.121]) ... ) >>> factor_d = DiscreteFactor( ... ["D"], cardinality=[2], values=np.array([0.56292, 1.7765]) ... ) >>> factor_e = DiscreteFactor( ... ["E"], cardinality=[2], values=np.array([0.47117, 2.1224]) ... ) >>> factor_f = DiscreteFactor( ... ["F"], cardinality=[2], values=np.array([1.5093, 0.66257]) ... ) >>> factor_a_b = DiscreteFactor( ... ["A", "B"], ... cardinality=[2, 2], ... values=np.array([1.3207, 0.75717, 0.75717, 1.3207]), ... ) >>> factor_b_c = DiscreteFactor( ... ["B", "C"], ... cardinality=[2, 2], ... values=np.array([0.00024189, 4134.2, 4134.2, 0.0002418]), ... ) >>> factor_c_d = DiscreteFactor( ... ["C", "D"], ... cardinality=[2, 2], ... values=np.array([0.0043227, 231.34, 231.34, 0.0043227]), ... ) >>> factor_d_e = DiscreteFactor( ... ["E", "F"], ... cardinality=[2, 2], ... values=np.array([31.228, 0.032023, 0.032023, 31.228]), ... ) >>> student.add_factors( ... factor_a, ... factor_b, ... factor_c, ... factor_d, ... factor_e, ... factor_f, ... factor_a_b, ... factor_b_c, ... factor_c_d, ... factor_d_e, ... ) >>> mplp = Mplp(student) >>> result = mplp.map_query() >>> result {'B': 0.93894, 'C': 1.121, 'A': 1.8323, 'F': 1.5093, 'D': 1.7765, 'E': 2.12239}