Click here to hide/show the list of notebooks.
  pyAgrum on notebooks   pyAgrum jupyter
☰  MarkovNetwork 
pyAgrum 0.18.0   
Zipped notebooks   
generation: 2020-06-11 14:09  
In [1]:
%load_ext autoreload
%autoreload 2

import pyAgrum as gum
import pyAgrum.lib.notebook as gnb
import pyAgrum.lib.mn2graph as m2g

Repr et str

In [2]:
gum.config.reset() # back to default
mn=gum.fastMN("A-B-C;C-D;B-E-F;F-D-G;H-J;E-A;J")
mn
Out[2]:
G A A B B C C D D E E F F G G H H J J f0#1#2 f0#1#2--A f0#1#2--B f0#1#2--C f2#3 f2#3--C f2#3--D f7#8 f7#8--H f7#8--J f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f3#5#6 f3#5#6--D f3#5#6--F f3#5#6--G f0#4 f0#4--A f0#4--E f8 f8--J
In [3]:
gum.config.reset() # back to default
gum.config['factorgraph','edge_length']='0.4'
mn
Out[3]:
G A A B B C C D D E E F F G G H H J J f0#1#2 f0#1#2--A f0#1#2--B f0#1#2--C f2#3 f2#3--C f2#3--D f7#8 f7#8--H f7#8--J f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f3#5#6 f3#5#6--D f3#5#6--F f3#5#6--G f0#4 f0#4--A f0#4--E f8 f8--J
In [4]:
gum.config.reset() # back to default
print("Default marko : "+gum.config['notebook','default_markovnetwork_view'])

print("modifiée pour 'graph'")
gum.config['notebook','default_markovnetwork_view']='graph'
mn
Default marko : factorgraph
modifiée pour 'graph'
Out[4]:
G A A B B A--B C C A--C E E A--E B--C B--E F F B--F D D C--D D--F G G D--G E--F F--G H H J J H--J
In [5]:
gnb.sideBySide(gnb.getMN(mn,view="graph",size="5"),
               gnb.getMN(mn,view="factorgraph",size="5"))
G A A B B A--B C C A--C E E A--E B--C B--E F F B--F D D C--D D--F G G D--G E--F F--G H H J J H--J
G A A B B C C D D E E F F G G H H J J f0#1#2 f0#1#2--A f0#1#2--B f0#1#2--C f2#3 f2#3--C f2#3--D f7#8 f7#8--H f7#8--J f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f3#5#6 f3#5#6--D f3#5#6--F f3#5#6--G f0#4 f0#4--A f0#4--E f8 f8--J
In [6]:
gnb.showMN(mn)
print(mn)
G A A B B A--B C C A--C E E A--E B--C B--E F F B--F D D C--D D--F G G D--G E--F F--G H H J J H--J
MN{nodes: 9, edges: 12, domainSize: 512, dim: 38}

accessors

In [7]:
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'})}")
print(f"factor(C,D) : {mn.factor({'D','C'})}")
nodes       : {0, 1, 2, 3, 4, 5, 6, 7, 8}
node names  : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J']
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:0|D:0> :: 0.690306 /<C:1|D:0> :: 0.247997 /<C:0|D:1> :: 0.829866 /<C:1|D:1> :: 0.0611014
factor(C,D) : <C:0|D:0> :: 0.690306 /<C:1|D:0> :: 0.247997 /<C:0|D:1> :: 0.829866 /<C:1|D:1> :: 0.0611014
factor(C,D) : <C:0|D:0> :: 0.690306 /<C:1|D:0> :: 0.247997 /<C:0|D:1> :: 0.829866 /<C:1|D:1> :: 0.0611014
In [8]:
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

In [9]:
mn.factor({'A','B','C'})
Out[9]:
A
C
B
0
1
0
0
0.76620.2810
1
0.43370.8969
1
0
0.09550.6233
1
0.05040.7135
In [10]:
mn.factor({'A','B','C'})[{'B':0}]
Out[10]:
array([[0.76624614, 0.28100406],
       [0.09546067, 0.62333653]])
In [11]:
mn.factor({'A','B','C'})[{'B':0}]=[[1,2],[3,4]]
mn.factor({'A','B','C'})
Out[11]:
A
C
B
0
1
0
0
1.00002.0000
1
0.43370.8969
1
0
3.00004.0000
1
0.05040.7135

detailed graphical representation

In [12]:
gum.config.reset() # back to default
gum.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.sideBySide(gnb.getGraph(m2g.MN2UGdot(mn)),
               gnb.getGraph(m2g.MN2UGdot(mn,nodeColor=nodemap)),
               gnb.getGraph(m2g.MN2FactorGraphdot(mn)),
               gnb.getGraph(m2g.MN2FactorGraphdot(mn,factorColor=fgma,nodeColor=nodemap)),
               captions=['Markov network',
                         'MarkovNet with colored node w.r.t number of neighbours',
                         'Markovnet as factor graph',
                         'MN with colored factor w.r.t to the size of scope'])
G A A B B A--B C C A--C E E A--E B--C B--E F F B--F D D C--D D--F G G D--G E--F F--G H H J J H--J
G A A B B A--B C C A--C E E A--E B--C B--E F F B--F D D C--D D--F G G D--G E--F F--G H H J J H--J
G A A B B C C D D E E F F G G H H J J f0#1#2 f0#1#2--A f0#1#2--B f0#1#2--C f2#3 f2#3--C f2#3--D f7#8 f7#8--H f7#8--J f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f3#5#6 f3#5#6--D f3#5#6--F f3#5#6--G f0#4 f0#4--A f0#4--E f8 f8--J
G A A B B C C D D E E F F G G H H J J f0#1#2 f0#1#2--A f0#1#2--B f0#1#2--C f2#3 f2#3--C f2#3--D f7#8 f7#8--H f7#8--J f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f3#5#6 f3#5#6--D f3#5#6--F f3#5#6--G f0#4 f0#4--A f0#4--E f8 f8--J
Markov network
MarkovNet with colored node w.r.t number of neighbours
Markovnet as factor graph
MN with colored factor w.r.t to the size of scope

from BayesNet to MarkovNet

In [13]:
bn=gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")
mn=gum.MarkovNet.fromBN(bn)
gnb.sideBySide(bn,gnb.getGraph(m2g.MN2UGdot(mn)),gnb.getGraph(m2g.MN2FactorGraphdot(mn)),captions=['a Bayesian network','the corresponding Markov Network'])
G A A B B A->B H H A->H F F B->F C C C->B D D C->D J J C->J E E D->E E->F G G G->B I I H->I K K K->J L L L->K
G A A B B A--B C C A--C G G A--G H H A--H B--C E E B--E F F B--F B--G D D C--D C--G J J C--J K K C--K D--E E--F I I H--I J--K L L K--L
G A A B B C C D D E E F F G G H H I I J J K K L L f0#1#2#6 f0#1#2#6--A f0#1#2#6--B f0#1#2#6--C f0#1#2#6--G f2#3 f2#3--C f2#3--D f3#4 f3#4--D f3#4--E f0#7 f0#7--A f0#7--H f7#8 f7#8--H f7#8--I f2#9#10 f2#9#10--C f2#9#10--J f2#9#10--K f10#11 f10#11--K f10#11--L f11 f11--L f0 f0--A f2 f2--C f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f6 f6--G
a Bayesian network
the corresponding Markov Network

Inference in Markov network

In [14]:
bn=gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")
iebn=gum.LazyPropagation(bn)

mn=gum.MarkovNet.fromBN(bn)
iemn=gum.ShaferShenoyMNInference(mn)
iemn.setEvidence({"A":1,"F":[0.4,0.8]})
iemn.makeInference()
iemn.posterior("B")
Out[14]:
B
0
1
0.46450.5355
In [15]:
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 network mn with evidence "+str(evs)}
                  )
    
print("Inference for both the corresponding models in BayesNet and MarkovNet worlds when the MN 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 MarkovNet worlds when the MN comes from a BN
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.29960.7004
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.29960.7004
Inference in the markov network mn with evidence {}
Inference in the bayesian network bn with evidence {}
C has no impact on A and G
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.00001.0000
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.00001.0000
Inference in the bayesian network bn with evidence {'C': 1}
Inference in the markov network mn with evidence {'C': 1}
But if B is observed
A
0
1
0.27520.7248
G
0
1
0.46100.5390
C
0
1
0.26540.7346
A
0
1
0.27520.7248
G
0
1
0.46100.5390
C
0
1
0.26540.7346
Inference in the markov network mn with evidence {'B': 1}
Inference in the bayesian network bn with evidence {'B': 1}
C has an impact on A and G
A
0
1
0.54120.4588
G
0
1
0.41740.5826
C
0
1
1.00000.0000
A
0
1
0.54120.4588
G
0
1
0.41740.5826
C
0
1
1.00000.0000
Inference in the markov network mn with evidence {'B': 1, 'C': 0}
Inference in the bayesian network bn with evidence {'B': 1, 'C': 0}
In [16]:
mn.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 factors
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.29960.7004
A
0
1
0.26870.7313
G
0
1
0.76580.2342
C
0
1
0.25750.7425
Inference in the markov network mn with evidence {}
Inference in the bayesian network bn with evidence {}
C has impact on A and G even without knowing B
A
0
1
0.25130.7487
G
0
1
0.28710.7129
C
0
1
0.00001.0000
A
0
1
0.32570.6743
G
0
1
0.73280.2672
C
0
1
0.00001.0000
Inference in the bayesian network bn with evidence {'C': 1}
Inference in the markov network mn with evidence {'C': 1}

graphical inference in markov network

In [17]:
bn=gum.fastBN("A->B<-C->D->E->F<-B<-G;A->H->I;C->J<-K<-L")
mn=gum.MarkovNet.fromBN(bn)

gnb.sideBySide(gnb.getJunctionTree(bn),gnb.getJunctionTree(mn))
G (0) 8-7 I H (0) 8-7^(4) 7-0 H (0) 8-7--(0) 8-7^(4) 7-0 (1) 11-10 L K (1) 11-10^(3) 9-2-10 K (1) 11-10--(1) 11-10^(3) 9-2-10 (2) 6-1-0-2 G B A C (2) 6-1-0-2^(8) 1-4-2 B C (2) 6-1-0-2--(2) 6-1-0-2^(8) 1-4-2 (2) 6-1-0-2^(4) 7-0 A (2) 6-1-0-2--(2) 6-1-0-2^(4) 7-0 (3) 9-2-10 J C K (3) 9-2-10^(8) 1-4-2 C (3) 9-2-10--(3) 9-2-10^(8) 1-4-2 (4) 7-0 H A (6) 1-5-4 B F E (6) 1-5-4^(8) 1-4-2 B E (6) 1-5-4--(6) 1-5-4^(8) 1-4-2 (8) 1-4-2 B E C (8) 1-4-2^(9) 3-4-2 E C (8) 1-4-2--(8) 1-4-2^(9) 3-4-2 (9) 3-4-2 D E C (8) 1-4-2^(9) 3-4-2--(9) 3-4-2 (1) 11-10^(3) 9-2-10--(3) 9-2-10 (0) 8-7^(4) 7-0--(4) 7-0 (6) 1-5-4^(8) 1-4-2--(8) 1-4-2 (2) 6-1-0-2^(8) 1-4-2--(8) 1-4-2 (2) 6-1-0-2^(4) 7-0--(4) 7-0 (3) 9-2-10^(8) 1-4-2--(8) 1-4-2
G (0) 8-7 I H (0) 8-7^(4) 7-0 H (0) 8-7--(0) 8-7^(4) 7-0 (1) 11-10 L K (1) 11-10^(3) 9-2-10 K (1) 11-10--(1) 11-10^(3) 9-2-10 (2) 6-1-0-2 G B A C (2) 6-1-0-2^(8) 1-4-2 B C (2) 6-1-0-2--(2) 6-1-0-2^(8) 1-4-2 (2) 6-1-0-2^(4) 7-0 A (2) 6-1-0-2--(2) 6-1-0-2^(4) 7-0 (3) 9-2-10 J C K (3) 9-2-10^(8) 1-4-2 C (3) 9-2-10--(3) 9-2-10^(8) 1-4-2 (4) 7-0 H A (6) 1-5-4 B F E (6) 1-5-4^(8) 1-4-2 B E (6) 1-5-4--(6) 1-5-4^(8) 1-4-2 (8) 1-4-2 B E C (8) 1-4-2^(9) 3-4-2 E C (8) 1-4-2--(8) 1-4-2^(9) 3-4-2 (9) 3-4-2 D E C (8) 1-4-2^(9) 3-4-2--(9) 3-4-2 (1) 11-10^(3) 9-2-10--(3) 9-2-10 (0) 8-7^(4) 7-0--(4) 7-0 (6) 1-5-4^(8) 1-4-2--(8) 1-4-2 (2) 6-1-0-2^(8) 1-4-2--(8) 1-4-2 (2) 6-1-0-2^(4) 7-0--(4) 7-0 (3) 9-2-10^(8) 1-4-2--(8) 1-4-2
In [18]:
gnb.showInference(bn,evs={"D":1,"H":0})
structs Inference in   1.12ms A B A->B H A->H F B->F C C->B D C->D J C->J E D->E E->F G G->B I H->I K K->J L L->K
In [19]:
gum.config.reset()
gnb.showInference(mn,size="8",evs={"D":1,"H":0})
G Inference in   1.29ms A B C D E F G H I J K L f0#1#2#6 f0#1#2#6--A f0#1#2#6--B f0#1#2#6--C f0#1#2#6--G f2#3 f2#3--C f2#3--D f3#4 f3#4--D f3#4--E f0#7 f0#7--A f0#7--H f7#8 f7#8--H f7#8--I f2#9#10 f2#9#10--C f2#9#10--J f2#9#10--K f10#11 f10#11--K f10#11--L f11 f11--L f0 f0--A f2 f2--C f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f6 f6--G
In [20]:
gum.config['factorgraph','edge_length_inference']='1.3'
gnb.showInference(mn,size="8",evs={"D":1,"H":0})
G Inference in   1.32ms A B C D E F G H I J K L f0#1#2#6 f0#1#2#6--A f0#1#2#6--B f0#1#2#6--C f0#1#2#6--G f2#3 f2#3--C f2#3--D f3#4 f3#4--D f3#4--E f0#7 f0#7--A f0#7--H f7#8 f7#8--H f7#8--I f2#9#10 f2#9#10--C f2#9#10--J f2#9#10--K f10#11 f10#11--K f10#11--L f11 f11--L f0 f0--A f2 f2--C f1#4#5 f1#4#5--B f1#4#5--E f1#4#5--F f6 f6--G
In [21]:
gum.config['notebook','default_markovnetwork_view']='graph'
gnb.showInference(mn,size="8",evs={"D":1,"H":0})
structs Inference in   1.46ms A