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.13.0 (main, Oct 7 2024, 05:02:14) [Clang 16.0.0 (clang-1600.0.26.3)]
IPython8.28.0
Matplotlib3.9.2
Numpy2.1.2
pyDot3.0.2
pyAgrum1.16.0
Thu Oct 17 15:40:29 2024 CEST

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

CPT
G E E F F E->F B B C C B->C A A A->E A->B D D A->D D->C
Credal Net
B
A
0
1
2
0
0.25660.32210.2986
1
0.25190.56410.0614

CPTmin
B
A
0
1
2
0
0.33840.40390.3804
1
0.33370.64590.1432

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 E E F F E->F B B C C B->C A A A->E A->B D D A->D D->C
Credal net
G B-v1 B-v1 E E F F E->F B-v0 B-v0 A A A->E B-b0 B-b0 A->B-b0 B-b1 B-b1 A->B-b1 D D A->D B-v2 B-v2 B-b0->B-v1 B-b0->B-v0 B-b0->B-v2 C C B-b0->C B-b0->B-b1 B-b1->B-v1 B-b1->B-v0 B-b1->B-v2 B-b1->C 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 842.82ms A 2024-10-17T15:40:30.521106 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B 2024-10-17T15:40:30.538545 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->B D 2024-10-17T15:40:30.569153 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->D E 2024-10-17T15:40:30.584325 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->E C 2024-10-17T15:40:30.554440 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B->C D->C F 2024-10-17T15:40:30.598976 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ E->F
structs Inference in 1092.36ms A 2024-10-17T15:40:31.900917 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0 2024-10-17T15:40:31.916089 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->B-b0 B-b1 2024-10-17T15:40:31.930776 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->B-b1 D 2024-10-17T15:40:31.962401 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->D E 2024-10-17T15:40:31.976809 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2024-10-17T15:40:31.945584 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->C B-v0 2024-10-17T15:40:32.005677 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2024-10-17T15:40:32.020093 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2024-10-17T15:40:32.034499 image/svg+xml Matplotlib v3.9.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-10-17T15:40:31.991155 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ E->F
structs Inference in   0.35ms A 2024-10-17T15:40:32.193823 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0 2024-10-17T15:40:32.212595 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->B-b0 B-b1 2024-10-17T15:40:32.227280 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->B-b1 D 2024-10-17T15:40:32.256515 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->D E 2024-10-17T15:40:32.272276 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ A->E B-b0->B-b1 C 2024-10-17T15:40:32.241927 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->C B-v0 2024-10-17T15:40:32.303176 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->B-v0 B-v1 2024-10-17T15:40:32.318397 image/svg+xml Matplotlib v3.9.2, https://matplotlib.org/ B-b0->B-v1 B-v2 2024-10-17T15:40:32.333369 image/svg+xml Matplotlib v3.9.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-10-17T15:40:32.287881 image/svg+xml Matplotlib v3.9.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 E E F F E->F B B C C B->C A A A->E A->B D D A->D D->C
F
0
1
0.36100.3352
F
0
1
0.66480.6390
G E E F F E->F B B C C B->C A A A->E A->B D D A->D D->C
F
0
1
0.36100.3352
F
0
1
0.66480.6390

A:Range([0,1])
<> : [[0.464623 , 0.535377] , [0.770552 , 0.229448]]

B:Range([0,2])
<A:0> : [[0.256574 , 0.363016 , 0.38041] , [0.256574 , 0.403918 , 0.339508] , [0.29748 , 0.403918 , 0.298602] , [0.338384 , 0.363014 , 0.298602] , [0.29748 , 0.32211 , 0.38041] , [0.338384 , 0.32211 , 0.339506]]
<A:1> : [[0.25187 , 0.604965 , 0.143165] , [0.25187 , 0.645868 , 0.102261] , [0.292775 , 0.645868 , 0.0613563] , [0.333679 , 0.604965 , 0.0613563] , [0.292774 , 0.564061 , 0.143165] , [0.333679 , 0.564061 , 0.10226]]

C:Range([0,1])
<B:0|D:0> : [[0.371595 , 0.628405] , [0.381014 , 0.618986]]
<B:1|D:0> : [[0.682366 , 0.317634] , [0.691786 , 0.308214]]
<B:2|D:0> : [[0.488501 , 0.511499] , [0.497921 , 0.502079]]
<B:0|D:1> : [[0.00706436 , 0.992936] , [0.0164856 , 0.983514]]
<B:1|D:1> : [[0.515797 , 0.484203] , [0.525215 , 0.474785]]
<B:2|D:1> : [[0.564607 , 0.435393] , [0.574028 , 0.425972]]

D:Range([0,1])
<A:0> : [[0.610309 , 0.389691] , [0.83299 , 0.16701]]
<A:1> : [[0.25433 , 0.74567] , [0.477009 , 0.522991]]

E:Range([0,1])
<A:0> : [[0.502496 , 0.497504] , [0.502747 , 0.497253]]
<A:1> : [[0.999556 , 0.000443853] , [0.999809 , 0.000190767]]

F:Range([0,1])
<E:0> : [[0.31159 , 0.68841] , [0.582919 , 0.417081]]
<E:1> : [[0.525177 , 0.474823] , [0.796504 , 0.203496]]


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 E E H H E->H L L B B B->E A A A->E H->L F F F->H C C C->F G G D D D->F D->G
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)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/var/folders/r1/pj4vdx_n4_d_xpsb04kzf97r0000gp/T/ipykernel_53905/814548779.py in ?()
      1 cn=gum.CredalNet("res/cn/bn_c_8.bif","res/cn/den_c_8.bif")
----> 2 cn.bnToCredal(0.8,False)

~/.virtualenvs/devAgrum/lib/python3.13/site-packages/pyAgrum/pyAgrum.py in ?(self, beta, oneNet, keepZeroes)
  25125         keepZeroes : bool
  25126                 used as a flag as whether or not - respectively True or False - we keep zeroes as zeroes. Default is False, i.e. zeroes are not kept
  25127
  25128         """
> 25129         return _pyAgrum.CredalNet_bnToCredal(self, beta, oneNet, keepZeroes)

TypeError: in method 'CredalNet_bnToCredal', argument 4 of type 'bool'
Additional information:
Wrong number or type of arguments for overloaded function 'CredalNet_bnToCredal'.
  Possible C/C++ prototypes are:
    gum::credal::CredalNet< double >::bnToCredal(double const,bool const,bool const)
    gum::credal::CredalNet< double >::bnToCredal(double const,bool const)

In [ ]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

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

ie.makeInference()
In [ ]:
print(ie.dynamicExpMax("temp"))
In [ ]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))
plt.show()
In [ ]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

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

ie.makeInference()
print(ie.messageApproximationScheme())
In [ ]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))
plt.show()
In [ ]:
ie=gum.CNMonteCarloSampling(cn)
ie.insertModalsFile("res/cn/modalities.modal")

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

gnb.animApproximationScheme(ie)
ie.makeInference()
In [ ]:
fig=figure()
ax=fig.add_subplot(111)
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"));
plt.show()