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
OSposix [darwin]
Python3.12.1 (main, Dec 7 2023, 20:45:44) [Clang 15.0.0 (clang-1500.1.0.2.5)]
IPython8.21.0
Matplotlib3.8.2
Numpy1.26.4
pyDot2.0.0
pyAgrum1.12.0
Wed Feb 14 15:37:38 2024 CET

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 E E A->E D D A->D C C B->C F F E->F D->C
Bayes Net
B
A
0
1
2
0
0.36500.23300.4020
1
0.28640.05810.6555

CPT
G A A B B A->B E E A->E D D A->D C C B->C F F E->F D->C
Credal Net
B
A
0
1
2
0
0.34180.20970.3788
1
0.26320.03480.6323

CPTmin
B
A
0
1
2
0
0.38830.25620.4253
1
0.30970.08130.6787

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 E E A->E D D A->D C C B->C F F E->F D->C
Credal net
G B-b1 B-b1 B-v0 B-v0 B-b1->B-v0 B-v2 B-v2 B-b1->B-v2 C C B-b1->C B-v1 B-v1 B-b1->B-v1 A A A->B-b1 B-b0 B-b0 A->B-b0 E E A->E D D A->D B-b0->B-b1 B-b0->B-v0 B-b0->B-v2 B-b0->C B-b0->B-v1 F F E->F D->C
Binarized credal net

Here, \(B\) becomes - \(B\)-b\(i\) : the \(i\)-th bit of B - instrumental \(B\)-v\(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 873.37ms A 2024-02-14T15:37:40.173507 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B 2024-02-14T15:37:40.195069 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->B D 2024-02-14T15:37:40.250716 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->D E 2024-02-14T15:37:40.269034 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->E C 2024-02-14T15:37:40.223493 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B->C D->C F 2024-02-14T15:37:40.306906 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ E->F
structs Inference in 791.12ms A 2024-02-14T15:37:41.423413 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0 2024-02-14T15:37:41.441842 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->B-b0 B-b1 2024-02-14T15:37:41.477592 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->B-b1 D 2024-02-14T15:37:41.535778 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->D E 2024-02-14T15:37:41.556234 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2024-02-14T15:37:41.511842 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->C B-v0 2024-02-14T15:37:41.608958 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2024-02-14T15:37:41.636280 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2024-02-14T15:37:41.655445 image/svg+xml Matplotlib v3.8.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 2024-02-14T15:37:41.583092 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ E->F
structs Inference in   0.26ms A 2024-02-14T15:37:41.933023 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0 2024-02-14T15:37:41.960469 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->B-b0 B-b1 2024-02-14T15:37:41.979270 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->B-b1 D 2024-02-14T15:37:42.024563 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->D E 2024-02-14T15:37:42.053385 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2024-02-14T15:37:42.000857 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->C B-v0 2024-02-14T15:37:42.128362 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2024-02-14T15:37:42.156203 image/svg+xml Matplotlib v3.8.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2024-02-14T15:37:42.174948 image/svg+xml Matplotlib v3.8.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 2024-02-14T15:37:42.086208 image/svg+xml Matplotlib v3.8.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 E E A->E D D A->D C C B->C F F E->F D->C
F
0
1
0.19880.5537
F
0
1
0.44630.8012
G A A B B A->B E E A->E D D A->D C C B->C F F E->F D->C
F
0
1
0.19600.5537
F
0
1
0.44630.8040

A:Range([0,1])
<> : [[0.24898 , 0.75102] , [0.580952 , 0.419048]]

B:Range([0,2])
<A:0> : [[0.341791 , 0.232951 , 0.425258] , [0.341791 , 0.256184 , 0.402025] , [0.365022 , 0.256184 , 0.378794] , [0.388254 , 0.232952 , 0.378794] , [0.365021 , 0.209721 , 0.425258] , [0.388254 , 0.209721 , 0.402025]]
<A:1> : [[0.263198 , 0.058079 , 0.678723] , [0.263198 , 0.0813124 , 0.65549] , [0.28643 , 0.0813124 , 0.632258] , [0.309661 , 0.0580805 , 0.632258] , [0.286428 , 0.0348485 , 0.678723] , [0.309661 , 0.0348485 , 0.65549]]

C:Range([0,1])
<B:0|D:0> : [[0.634417 , 0.365583] , [0.843322 , 0.156678]]
<B:1|D:0> : [[0.189608 , 0.810392] , [0.398513 , 0.601487]]
<B:2|D:0> : [[0.275986 , 0.724014] , [0.48489 , 0.51511]]
<B:0|D:1> : [[0.410443 , 0.589557] , [0.619348 , 0.380652]]
<B:1|D:1> : [[0.621969 , 0.378031] , [0.830872 , 0.169128]]
<B:2|D:1> : [[0.293712 , 0.706288] , [0.502618 , 0.497382]]

D:Range([0,1])
<A:0> : [[0.42238 , 0.57762] , [0.659359 , 0.340641]]
<A:1> : [[0.585288 , 0.414712] , [0.822266 , 0.177734]]

E:Range([0,1])
<A:0> : [[0.197551 , 0.802449] , [0.460952 , 0.539048]]
<A:1> : [[0.255723 , 0.744277] , [0.519126 , 0.480874]]

F:Range([0,1])
<E:0> : [[0.851237 , 0.148763] , [0.86346 , 0.13654]]
<E:1> : [[0.0091659 , 0.990834] , [0.0213876 , 0.978612]]


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 G G H H L L H->L A A E E A->E B B B->E F F F->H C C C->F E->H D D D->G D->F
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.203404648293022, 11.864395265918773, 12.173214728164902, 12.023367090540296, 11.942163246338595, 11.940030233983371, 11.946760975764684, 11.943947159943452, 11.943827275579622)
In [20]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))
plt.show()
../_images/notebooks_24-Models_credalNetworks_29_0.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"))
plt.show()
../_images/notebooks_24-Models_credalNetworks_31_0.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"));
plt.show()
../_images/notebooks_24-Models_credalNetworks_33_0.svg