Credal Networks

Creative Commons License

aGrUM

interactive online version

In [1]:
import os

%matplotlib inline
from pylab import *
import matplotlib.pyplot as plt

In [2]:
import pyAgrum as gum
import pyAgrum.lib.notebook as gnb
gnb.configuration()
LibraryVersion
OSnt [win32]
Python3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]
IPython8.6.0
Matplotlib3.6.2
Numpy1.23.4
pyDot1.4.2
pyAgrum1.4.1.9
Fri Nov 11 20:07:53 2022 Paris, Madrid

Credal Net from BN

In [3]:
bn=gum.fastBN("A->B[3]->C<-D<-A->E->F")
bn_min=gum.BayesNet(bn)
bn_max=gum.BayesNet(bn)
for n in bn.nodes():
  x=0.4*min(bn.cpt(n).min(),1-bn.cpt(n).max())
  bn_min.cpt(n).translate(-x)
  bn_max.cpt(n).translate(x)

cn=gum.CredalNet(bn_min,bn_max)
cn.intervalToCredal()

gnb.flow.row(bn,bn.cpt("B"),cn,bn_min.cpt("B"),bn_max.cpt("B"),captions=["Bayes Net","CPT","Credal Net","CPTmin","CPTmax"])

G A A B B A->B D D A->D E E A->E C C B->C D->C F F E->F
Bayes Net
B
A
0
1
2
0
0.64670.14750.2057
1
0.31660.10900.5744

CPT
G A A B B A->B D D A->D E E A->E C C B->C D->C F F E->F
Credal Net
B
A
0
1
2
0
0.60310.10400.1621
1
0.27300.06540.5308

CPTmin
B
A
0
1
2
0
0.69030.19110.2493
1
0.36020.15260.6180

CPTmax

We can use LBP on CN (L2U) only for binary credal networks (here B is not binary). We then propose the classical binarization (but warn the user that this leads to approximation in the inference)

In [4]:
cn2=gum.CredalNet(bn_min,bn_max)
cn2.intervalToCredal()
cn2.approximatedBinarization()
cn2.computeBinaryCPTMinMax()

gnb.flow.row(cn,cn2,captions=["Credal net","Binarized credal net"])
G A A B B A->B D D A->D E E A->E C C B->C D->C F F E->F
Credal net
G B-b1 B-b1 B-v0 B-v0 B-b1->B-v0 B-v1 B-v1 B-b1->B-v1 B-v2 B-v2 B-b1->B-v2 C C B-b1->C A A A->B-b1 B-b0 B-b0 A->B-b0 D D A->D E E A->E B-b0->B-b1 B-b0->B-v0 B-b0->B-v1 B-b0->B-v2 B-b0->C D->C F F E->F
Binarized credal net

Here, \(B\) becomes - \(B\)-b:math:i : the \(i\)-th bit of B - instrumental \(B\)-v:math:k : the indicator variable for each modality \(k\) of \(B\)

In [5]:
ie_mc=gum.CNMonteCarloSampling(cn)
ie2_lbp=gum.CNLoopyPropagation(cn2)
ie2_mc=gum.CNMonteCarloSampling(cn2)
In [6]:
gnb.sideBySide(gnb.getInference(cn,engine=ie_mc),
               gnb.getInference(cn2,engine=ie2_mc),
               gnb.getInference(cn2,engine=ie2_lbp))
structs Inference in  65.04ms A 2022-11-11T20:07:53.579028 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B 2022-11-11T20:07:53.641970 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->B D 2022-11-11T20:07:53.835781 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->D E 2022-11-11T20:07:53.914058 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->E C 2022-11-11T20:07:53.761053 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B->C D->C F 2022-11-11T20:07:53.989232 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ E->F
structs Inference in  78.37ms A 2022-11-11T20:07:54.349653 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0 2022-11-11T20:07:54.413812 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->B-b0 B-b1 2022-11-11T20:07:54.459759 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->B-b1 D 2022-11-11T20:07:54.553611 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->D E 2022-11-11T20:07:54.595927 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2022-11-11T20:07:54.505155 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->C B-v0 2022-11-11T20:07:54.722740 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2022-11-11T20:07:54.791958 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2022-11-11T20:07:54.840446 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v2 B-b1->C B-b1->B-v0 B-b1->B-v1 B-b1->B-v2 D->C F 2022-11-11T20:07:54.672844 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ E->F
structs Inference in   0.00ms A 2022-11-11T20:07:55.257581 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0 2022-11-11T20:07:55.320717 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->B-b0 B-b1 2022-11-11T20:07:55.367199 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->B-b1 D 2022-11-11T20:07:55.463608 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->D E 2022-11-11T20:07:55.507671 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2022-11-11T20:07:55.413443 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->C B-v0 2022-11-11T20:07:55.596063 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2022-11-11T20:07:55.639718 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2022-11-11T20:07:55.762323 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ B-b0->B-v2 B-b1->C B-b1->B-v0 B-b1->B-v1 B-b1->B-v2 D->C F 2022-11-11T20:07:55.553635 image/svg+xml Matplotlib v3.6.2, https://matplotlib.org/ E->F
In [7]:
gnb.sideBySide(ie_mc.CN(),ie_mc.marginalMin("F"),ie_mc.marginalMax("F"),
               ie_mc.CN(),ie2_lbp.marginalMin("F"),ie2_lbp.marginalMax("F"),
              ncols=3)
print(cn)
G A A B B A->B D D A->D E E A->E C C B->C D->C F F E->F
F
0
1
0.46270.2947
F
0
1
0.70530.5373
G A A B B A->B D D A->D E E A->E C C B->C D->C F F E->F
F
0
1
0.37290.2947
F
0
1
0.70530.6271

A:Range([0,1])
<> : [[0.0837589 , 0.916241] , [0.195435 , 0.804565]]

B:Range([0,2])
<A:0> : [[0.60315 , 0.147547 , 0.249304] , [0.60315 , 0.19114 , 0.20571] , [0.646745 , 0.19114 , 0.162115] , [0.690339 , 0.147547 , 0.162115] , [0.646744 , 0.103952 , 0.249304] , [0.690339 , 0.103952 , 0.20571]]
<A:1> : [[0.272995 , 0.108987 , 0.618018] , [0.272995 , 0.152582 , 0.574423] , [0.316589 , 0.152582 , 0.530829] , [0.360184 , 0.108987 , 0.530829] , [0.31659 , 0.0653924 , 0.618018] , [0.360184 , 0.0653924 , 0.574424]]

C:Range([0,1])
<B:0|D:0> : [[0.500982 , 0.499018] , [0.513663 , 0.486337]]
<B:1|D:0> : [[0.418886 , 0.581114] , [0.431566 , 0.568434]]
<B:2|D:0> : [[0.114657 , 0.885343] , [0.127336 , 0.872664]]
<B:0|D:1> : [[0.977811 , 0.0221893] , [0.990491 , 0.00950872]]
<B:1|D:1> : [[0.143169 , 0.856831] , [0.155849 , 0.844151]]
<B:2|D:1> : [[0.62924 , 0.37076] , [0.641919 , 0.358081]]

D:Range([0,1])
<A:0> : [[0.593434 , 0.406566] , [0.783228 , 0.216772]]
<A:1> : [[0.142344 , 0.857656] , [0.332139 , 0.667861]]

E:Range([0,1])
<A:0> : [[0.209976 , 0.790024] , [0.489943 , 0.510057]]
<A:1> : [[0.389381 , 0.610619] , [0.669348 , 0.330652]]

F:Range([0,1])
<E:0> : [[0.251754 , 0.748246] , [0.479112 , 0.520888]]
<E:1> : [[0.602119 , 0.397881] , [0.82948 , 0.17052]]


Credal Net from bif files

In [8]:
cn=gum.CredalNet("res/cn/2Umin.bif","res/cn/2Umax.bif")
cn.intervalToCredal()
In [9]:
gnb.showCN(cn,"2")
../_images/notebooks_24-Models_credalNetworks_14_0.svg
In [10]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertEvidenceFile("res/cn/L2U.evi")
In [11]:
ie.setRepetitiveInd(False)
ie.setMaxTime(1)
ie.setMaxIter(1000)

ie.makeInference()
In [12]:
cn
Out[12]:
G H H L L H->L G G A A E E A->E B B B->E C C F F C->F D D D->G D->F E->H F->H
In [13]:
gnb.showInference(cn,targets={"A","H","L","D"},engine=ie,evs={"L":[0,1],"G":[1,0]})
../_images/notebooks_24-Models_credalNetworks_18_0.svg

Comparing inference in credal networks

In [14]:
import pyAgrum as gum

def showDiffInference(model,mc,lbp):
    for i in model.current_bn().nodes():
        a,b=mc.marginalMin(i)[:]
        c,d=mc.marginalMax(i)[:]

        e,f=lbp.marginalMin(i)[:]
        g,h=lbp.marginalMax(i)[:]

        plt.scatter([a,b,c,d],[e,f,g,h])


cn=gum.CredalNet("res/cn/2Umin.bif","res/cn/2Umax.bif")
cn.intervalToCredal()

The two inference give quite the same result

In [15]:
ie_mc=gum.CNMonteCarloSampling(cn)
ie_mc.makeInference()

cn.computeBinaryCPTMinMax()
ie_lbp=gum.CNLoopyPropagation(cn)
ie_lbp.makeInference()

showDiffInference(cn,ie_mc,ie_lbp)
../_images/notebooks_24-Models_credalNetworks_22_0.svg

but not when evidence are inserted

In [16]:
ie_mc=gum.CNMonteCarloSampling(cn)
ie_mc.insertEvidenceFile("res/cn/L2U.evi")
ie_mc.makeInference()

ie_lbp=gum.CNLoopyPropagation(cn)
ie_lbp.insertEvidenceFile("res/cn/L2U.evi")
ie_lbp.makeInference()

showDiffInference(cn,ie_mc,ie_lbp)

../_images/notebooks_24-Models_credalNetworks_24_0.svg

Dynamical Credal Net

In [17]:
cn=gum.CredalNet("res/cn/bn_c_8.bif","res/cn/den_c_8.bif")
cn.bnToCredal(0.8,False)
In [18]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

ie.setRepetitiveInd(True)
ie.setMaxTime(5)
ie.setMaxIter(1000)

ie.makeInference()
In [19]:
print(ie.dynamicExpMax("temp"))
(14.20340464862347, 11.769513762315974, 12.190483075680442, 12.017742181033096, 12.004198572496797, 12.008328195599265, 12.007694250617146, 12.007688078235907, 12.00772208700393)
In [20]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))
Out[20]:
<matplotlib.collections.PolyCollection at 0x215d5715110>
../_images/notebooks_24-Models_credalNetworks_29_1.svg
In [21]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

ie.setRepetitiveInd(False)
ie.setMaxTime(5)
ie.setMaxIter(1000)

ie.makeInference()
print(ie.messageApproximationScheme())
stopped with epsilon=0
In [22]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))
Out[22]:
<matplotlib.collections.PolyCollection at 0x215d54bfbd0>
../_images/notebooks_24-Models_credalNetworks_31_1.svg
In [23]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

ie.setRepetitiveInd(False)
ie.setMaxTime(5)
ie.setMaxIter(5000)

gnb.animApproximationScheme(ie)
ie.makeInference()
../_images/notebooks_24-Models_credalNetworks_32_0.svg
In [24]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"));
../_images/notebooks_24-Models_credalNetworks_33_0.svg
In [ ]: