Markov random fields (a.k.a. Markov Networks)
![]() | ![]() |
import pyagrum as gumimport pyagrum.lib.notebook as gnbimport pyagrum.lib.mrf2graph as m2gbuilding a Markov random field
Section titled “building a Markov random field”gum.config.reset() # back to defaultgum.config["notebook", "default_markovrandomfield_view"] = "graph"mn = gum.fastMRF("A--B--C;C--D;B--E--F;F--D--G;H--J;E--A;J")mnUsing pyagrum.config, it is possible to adapt the graphical representations for Markov random field (see the notebook 99-Tools_configForPyAgrum.ipynb).
gum.config.reset() # back to defaultgum.config["factorgraph", "edge_length"] = "0.4"gnb.showMRF(mn)gum.config.reset() # back to defaultprint("Default view for Markov random field: " + gum.config["notebook", "default_markovrandomfield_view"])gum.config["notebook", "default_markovrandomfield_view"] = "graph"print("modified to: " + gum.config["notebook", "default_markovrandomfield_view"])mnDefault view for Markov random field: factorgraphmodified to: graphgnb.sideBySide(gnb.getMRF(mn, view="graph", size="5"), gnb.getMRF(mn, view="factorgraph", size="5"))gnb.showMRF(mn)print(mn)MRF{nodes: 9, edges: 12, domainSize: 512, dim: 38}Accessors for Markov random fields
Section titled “Accessors for Markov random fields”print(f"nodes : {mn.nodes()}")print(f"node names : {mn.names()}")print(f"edges : {mn.edges()}")print(f"components : {mn.connectedComponents()}")print(f"factors : {mn.factors()}")print(f"factor(C,D) : {mn.factor({2, 3})}")print(f"factor(C,D) : {mn.factor({'C', 'D'})}")nodes : {0, 1, 2, 3, 4, 5, 6, 7, 8}node names : {'F', 'C', 'D', 'E', 'G', 'B', 'H', 'J', 'A'}edges : {(0, 1), (1, 2), (0, 4), (1, 5), (1, 4), (2, 3), (4, 5), (0, 2), (5, 6), (7, 8), (3, 6), (3, 5)}components : {0: {0, 1, 2, 3, 4, 5, 6}, 7: {8, 7}}factors : [{0, 1, 2}, {2, 3}, {8, 7}, {1, 4, 5}, {3, 5, 6}, {0, 4}, {8}]factor(C,D) : || C |D ||0 |1 |------||---------|---------|0 || 0.9436 | 0.7297 |1 || 0.8764 | 0.1343 |
factor(C,D) : || C |D ||0 |1 |------||---------|---------|0 || 0.9436 | 0.7297 |1 || 0.8764 | 0.1343 |try: mn.factor({0, 1})except gum.GumException as e: print(e)try: mn.factor({"A", "B"})except gum.GumException as e: print(e)[pyAgrum] Object not found: No element with the key <{1,0}>[pyAgrum] Object not found: No element with the key <{1,0}>Manipulating factors
Section titled “Manipulating factors”mn.factor({"A", "B", "C"})|
|
| ||
|---|---|---|---|
|
| 0.3069 | 0.2860 | |
| 0.5429 | 0.6637 | ||
|
| 0.1542 | 0.1874 | |
| 0.2178 | 0.9992 | ||
mn.factor({"A", "B", "C"})[{"B": 0}]array([[0.30685555, 0.28598548], [0.15420833, 0.18741267]])mn.factor({"A", "B", "C"})[{"B": 0}] = [[1, 2], [3, 4]]mn.factor({"A", "B", "C"})|
|
| ||
|---|---|---|---|
|
| 1.0000 | 2.0000 | |
| 0.5429 | 0.6637 | ||
|
| 3.0000 | 4.0000 | |
| 0.2178 | 0.9992 | ||
Customizing graphical representation
Section titled “Customizing graphical representation”gum.config.reset() # back to defaultgum.config["factorgraph", "edge_length"] = "0.5"
maxnei = max([len(mn.neighbours(n)) for n in mn.nodes()])nodemap = {n: len(mn.neighbours(mn.idFromName(n))) / maxnei for n in mn.names()}
facmax = max([len(f) for f in mn.factors()])fgma = lambda factor: (1 + len(factor) ** 2) / (1 + facmax * facmax)
gnb.flow.row( gnb.getGraph(m2g.MRF2UGdot(mn)), gnb.getGraph(m2g.MRF2UGdot(mn, nodeColor=nodemap)), gnb.getGraph(m2g.MRF2FactorGraphdot(mn)), gnb.getGraph(m2g.MRF2FactorGraphdot(mn, factorColor=fgma, nodeColor=nodemap)), captions=[ "Markov random field", "MarkovRandomField with colored node w.r.t number of neighbours", "MarkovRandomField as factor graph", "MRF with colored factor w.r.t to the size of scope", ],)from BayesNet to MarkovRandomField
Section titled “from BayesNet to MarkovRandomField”bn = gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")mn = gum.MarkovRandomField.fromBN(bn)gnb.flow.row( bn, gnb.getGraph(m2g.MRF2UGdot(mn)), captions=["a Bayesian network", "the corresponding Markov random field"])## The corresponding factor graphm2g.MRF2FactorGraphdot(mn)Inference in Markov random field
Section titled “Inference in Markov random field”bn = gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")iebn = gum.LazyPropagation(bn)
mn = gum.MarkovRandomField.fromBN(bn)iemn = gum.ShaferShenoyMRFInference(mn)iemn.setEvidence({"A": 1, "F": [0.4, 0.8]})iemn.makeInference()iemn.posterior("B")|
|
|
|---|---|
| 0.5664 | 0.4336 |
def affAGC(evs): gnb.sideBySide( gnb.getSideBySide( gum.getPosterior(bn, target="A", evs=evs), gum.getPosterior(bn, target="G", evs=evs), gum.getPosterior(bn, target="C", evs=evs), ), gnb.getSideBySide( gum.getPosterior(mn, target="A", evs=evs), gum.getPosterior(mn, target="G", evs=evs), gum.getPosterior(mn, target="C", evs=evs), ), captions=[ "Inference in the Bayesian network bn with evidence " + str(evs), "Inference in the Markov random field mn with evidence " + str(evs), ], )
print( "Inference for both the corresponding models in BayesNet and Markov Random Field worlds when the MRF comes from a BN")affAGC({})print("C has no impact on A and G")affAGC({"C": 1})
print("But if B is observed")affAGC({"B": 1})print("C has an impact on A and G")affAGC({"B": 1, "C": 0})Inference for both the corresponding models in BayesNet and Markov Random Field worlds when the MRF comes from a BNC has no impact on A and GBut if B is observedC has an impact on A and Gmn.generateFactors()print("But with more general factors")affAGC({})print("C has impact on A and G even without knowing B")affAGC({"C": 1})But with more general factorsC has impact on A and G even without knowing BGraphical inference in Markov random field
Section titled “Graphical inference in Markov random field”bn = gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")mn = gum.MarkovRandomField.fromBN(bn)
gnb.sideBySide( gnb.getJunctionTree(bn), gnb.getJunctionTree(mn), captions=["Junction tree for the BN", "Junction tree for the induced MN"],)gnb.sideBySide( gnb.getJunctionTreeMap(bn, size="3!"), gnb.getJunctionTreeMap(mn, size="3!"), captions=["Map of the junction tree for the BN", "Map of the junction tree for the induced MN"],)gnb.showInference(bn, evs={"D": 1, "H": 0})gum.config.reset()gnb.showInference(mn, size="8", evs={"D": 1, "H": 0})gum.config["factorgraph", "edge_length_inference"] = "1.1"gnb.showInference(mn, size="11", evs={"D": 1, "H": 0})gum.config["notebook", "default_markovrandomfield_view"] = "graph"gnb.showInference(mn, size="8", evs={"D": 1, "H": 0})
