Credal Networks
In [1]:
import matplotlib.pyplot as plt
import pyagrum as gum
import pyagrum.lib.notebook as gnb
gnb.configuration()
| Library | Version |
|---|---|
| OS | posix [darwin] |
| Python | 3.14.6 (main, Jun 10 2026, 10:03:53) [Clang 21.0.0 (clang-2100.0.123.102)] |
| IPython | 9.15.0 |
| Matplotlib | 3.11.0 |
| Numpy | 2.5.1 |
| pyDot | 4.0.1 |
| pyAgrum | 3.0.0 |
Thu Jul 16 18:15:08 2026 CEST
Credal Net from BN
In [2]:
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()
cn
Out[2]:
inference on Credal Net
In [3]:
gnb.flow.row(
bn, bn.cpt("B"), cn, bn_min.cpt("B"), bn_max.cpt("B"), captions=["Bayes Net", "CPT", "Credal Net", "CPTmin", "CPTmax"]
)
Out[3]:
|
|
|
| |
|---|---|---|---|
| 0.4917 | 0.2835 | 0.2248 | |
| 0.1314 | 0.4469 | 0.4217 | |
|
|
|
| |
|---|---|---|---|
| 0.4391 | 0.2310 | 0.1722 | |
| 0.0788 | 0.3944 | 0.3691 | |
|
|
|
| |
|---|---|---|---|
| 0.5443 | 0.3361 | 0.2773 | |
| 0.1840 | 0.4995 | 0.4742 | |
Binarization
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"])
Out[4]:
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)
)
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)
A:Range([0,1])
<> : [[0.238616 , 0.761384] , [0.556772 , 0.443228]]
B:Range([0,2])
<A:0> : [[0.439142 , 0.283518 , 0.277339] , [0.439142 , 0.336079 , 0.224778] , [0.491702 , 0.336079 , 0.172219] , [0.544262 , 0.283519 , 0.172219] , [0.491702 , 0.230958 , 0.277339] , [0.544262 , 0.230958 , 0.224779]]
<A:1> : [[0.078841 , 0.446938 , 0.474221] , [0.078841 , 0.499497 , 0.421662] , [0.131401 , 0.499497 , 0.369102] , [0.18396 , 0.446938 , 0.369102] , [0.1314 , 0.394379 , 0.474221] , [0.18396 , 0.394379 , 0.421661]]
C:Range([0,1])
<B:0|D:0> : [[0.334328 , 0.665672] , [0.518771 , 0.481229]]
<B:1|D:0> : [[0.332627 , 0.667373] , [0.517068 , 0.482932]]
<B:2|D:0> : [[0.677225 , 0.322775] , [0.861668 , 0.138332]]
<B:0|D:1> : [[0.249843 , 0.750157] , [0.434288 , 0.565712]]
<B:1|D:1> : [[0.311744 , 0.688256] , [0.496187 , 0.503813]]
<B:2|D:1> : [[0.560863 , 0.439137] , [0.745305 , 0.254695]]
D:Range([0,1])
<A:0> : [[0.305218 , 0.694782] , [0.461071 , 0.538929]]
<A:1> : [[0.727259 , 0.272741] , [0.883111 , 0.116889]]
E:Range([0,1])
<A:0> : [[0.17662 , 0.82338] , [0.412114 , 0.587886]]
<A:1> : [[0.415819 , 0.584181] , [0.651313 , 0.348687]]
F:Range([0,1])
<E:0> : [[0.555642 , 0.444358] , [0.678365 , 0.321635]]
<E:1> : [[0.0920422 , 0.907958] , [0.214765 , 0.785235]]
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
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()
Inference with no evidence
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)
The problem of evidence
When evidence are inserted, there are some divergence.
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.203404648293022, 11.864395265918773, 12.173214728164902, 12.017742181033096, 12.004198572496797, 12.008328195599265, 12.007694250617146, 12.007688078235908, 12.00772208700393)
In [20]:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.fill_between(range(9), ie.dynamicExpMax("temp"), ie.dynamicExpMin("temp"))
plt.show()
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 = plt.figure()
ax = fig.add_subplot(111)
ax.fill_between(range(9), ie.dynamicExpMax("temp"), ie.dynamicExpMin("temp"))
plt.show()
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 = plt.figure()
ax = fig.add_subplot(111)
ax.fill_between(range(9), ie.dynamicExpMax("temp"), ie.dynamicExpMin("temp"))
plt.show()
In [ ]:

