# Credal Networks

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 [linux]
Python3.10.10 (main, Mar 5 2023, 22:26:53) [GCC 12.2.1 20230201]
IPython8.13.2
Matplotlib3.7.1
Numpy1.24.3
pyDot1.4.2
pyAgrum1.8.0
Tue May 09 10:01:28 2023 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"])


Bayes Net
B
A
0
1
2
0
0.33320.12640.5403
1
0.09640.55420.3495

CPT

Credal Net
B
A
0
1
2
0
0.29470.08790.5018
1
0.05780.51560.3109

CPTmin
B
A
0
1
2
0
0.37180.16500.5789
1
0.13490.59270.3880

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"])


Credal net

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  27.06ms A 2023-05-09T10:01:29.463664 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B 2023-05-09T10:01:29.528512 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->B D 2023-05-09T10:01:29.659401 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->D E 2023-05-09T10:01:29.714129 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->E C 2023-05-09T10:01:29.602093 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B->C D->C F 2023-05-09T10:01:29.769959 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} E->F structs Inference in  31.58ms A 2023-05-09T10:01:29.979291 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0 2023-05-09T10:01:30.035091 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->B-b0 B-b1 2023-05-09T10:01:30.088782 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->B-b1 D 2023-05-09T10:01:30.215367 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->D E 2023-05-09T10:01:30.270923 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->E B-b0->B-b1 C 2023-05-09T10:01:30.159181 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->C B-v0 2023-05-09T10:01:30.450110 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v0 B-v1 2023-05-09T10:01:30.504054 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v1 B-v2 2023-05-09T10:01:30.559312 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v2 B-b1->C B-b1->B-v0 B-b1->B-v1 B-b1->B-v2 D->C F 2023-05-09T10:01:30.327049 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} E->F structs Inference in   0.41ms A 2023-05-09T10:01:30.786530 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0 2023-05-09T10:01:30.842842 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->B-b0 B-b1 2023-05-09T10:01:30.975700 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->B-b1 D 2023-05-09T10:01:31.085085 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->D E 2023-05-09T10:01:31.142690 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} A->E B-b0->B-b1 C 2023-05-09T10:01:31.031053 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->C B-v0 2023-05-09T10:01:31.256248 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v0 B-v1 2023-05-09T10:01:31.312586 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v1 B-v2 2023-05-09T10:01:31.367824 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} B-b0->B-v2 B-b1->C B-b1->B-v0 B-b1->B-v1 B-b1->B-v2 D->C F 2023-05-09T10:01:31.198432 image/svg+xml Matplotlib v3.7.1, https://matplotlib.org/ *{stroke-linejoin: round; stroke-linecap: butt} 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)

F
0
1
0.26340.5136
F
0
1
0.48640.7366
F
0
1
0.26340.5119
F
0
1
0.48810.7366

A:Range([0,1])
<> : [[0.102429 , 0.897571] , [0.238999 , 0.761001]]

B:Range([0,2])
<A:0> : [[0.294675 , 0.126435 , 0.57889] , [0.294675 , 0.164977 , 0.540348] , [0.333215 , 0.164977 , 0.501808] , [0.371758 , 0.126434 , 0.501808] , [0.333216 , 0.0878939 , 0.57889] , [0.371758 , 0.0878939 , 0.540348]]
<A:1> : [[0.0578125 , 0.554178 , 0.38801] , [0.0578125 , 0.592719 , 0.349469] , [0.096352 , 0.592719 , 0.310929] , [0.134894 , 0.554177 , 0.310929] , [0.0963536 , 0.515636 , 0.38801] , [0.134894 , 0.515636 , 0.34947]]

C:Range([0,1])
<B:0|D:0> : [[0.340507 , 0.659493] , [0.360624 , 0.639376]]
<B:1|D:0> : [[0.505574 , 0.494426] , [0.52569 , 0.47431]]
<B:2|D:0> : [[0.149982 , 0.850018] , [0.170098 , 0.829902]]
<B:0|D:1> : [[0.964798 , 0.0352021] , [0.984914 , 0.0150862]]
<B:1|D:1> : [[0.34812 , 0.65188] , [0.368237 , 0.631763]]
<B:2|D:1> : [[0.664717 , 0.335283] , [0.684834 , 0.315166]]

D:Range([0,1])
<A:0> : [[0.705049 , 0.294951] , [0.873592 , 0.126408]]
<A:1> : [[0.471767 , 0.528233] , [0.64031 , 0.35969]]

E:Range([0,1])
<A:0> : [[0.105756 , 0.894244] , [0.246766 , 0.753234]]
<A:1> : [[0.128255 , 0.871745] , [0.269265 , 0.730735]]

F:Range([0,1])
<E:0> : [[0.745444 , 0.254556] , [0.890904 , 0.109096]]
<E:1> : [[0.195918 , 0.804082] , [0.341377 , 0.658623]]



## 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")

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]:

In [13]:

gnb.showInference(cn,targets={"A","H","L","D"},engine=ie,evs={"L":[0,1],"G":[1,0]})


## 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)


### 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)


## 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.203404647522472, 11.817699847864338, 12.173214728164902, 11.99476087981647, 11.966313382958862, 11.964973878078364, 11.965031829300205, 11.96501512083492, 11.965015808981818)

In [20]:

fig=figure()
ax.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))

Out[20]:

<matplotlib.collections.PolyCollection at 0x7f7a216b8b20>

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.fill_between(range(9),ie.dynamicExpMax("temp"),ie.dynamicExpMin("temp"))

Out[22]:

<matplotlib.collections.PolyCollection at 0x7f7a21549cf0>

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()

In [24]:

fig=figure()

In [ ]: