Sensitivity analysis for Bayesian networks using credal networks

Creative Commons License

aGrUM

interactive online version

There are several sensitivity analysis frameworks for Bayesian networks. A fairly efficient method is certainly to use credal networks to do this analysis.

Creating a Bayesian network

In [1]:
import pyagrum.credal_net as gum
import pyagrum.lib.notebook as gnb
In [2]:
bn = gum.fastBN("A->B->C<-D->E->F<-B")
gnb.flow.row(bn, gnb.getInference(bn))
Out[2]:
G C C A A B B A->B F F B->C B->F D D D->C E E D->E E->F
structs Inference in   0.67ms A 2026-09-28T17:47:26.477235 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:26.508252 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:26.536774 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:26.625869 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:26.560118 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:26.592490 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F

Building a credal network from a BN

It is easy to build a credal network from a Bayesian network by indicating the ‘noise’ on each parameter.

In [3]:
cr = gum.CredalNet(bn, bn)
gnb.show(cr)
../_images/notebooks_14-Examples_SensitivityAnalysisUsingCredalNetworks_6_0.svg
In [4]:
cr.bnToCredal(1e-10, False, False)
In [5]:
cr.computeBinaryCPTMinMax()
In [6]:
print(cr)

A:Range([0,1])
<> : [[0.712502 , 0.287498] , [0.712498 , 0.287502]]

B:Range([0,1])
<A:0> : [[0.462944 , 0.537056] , [0.462787 , 0.537213]]
<A:1> : [[0.675036 , 0.324964] , [0.675029 , 0.324971]]

C:Range([0,1])
<B:0|D:0> : [[0.296845 , 0.703155] , [0.294246 , 0.705754]]
<B:1|D:0> : [[0.403277 , 0.596723] , [0.402866 , 0.597134]]
<B:0|D:1> : [[0.320386 , 0.679614] , [0.31869 , 0.68131]]
<B:1|D:1> : [[0.208129 , 0.791871] , [0.0823787 , 0.917621]]

D:Range([0,1])
<> : [[0.915245 , 0.0847542]]

E:Range([0,1])
<D:0> : [[0.376233 , 0.623767] , [0.375588 , 0.624412]]
<D:1> : [[0.315478 , 0.684522] , [0.313626 , 0.686374]]

F:Range([0,1])
<E:0|B:0> : [[0.513989 , 0.486011] , [0.513918 , 0.486082]]
<E:1|B:0> : [[0.909494 , 0.0905053]]
<E:0|B:1> : [[0.349387 , 0.650613] , [0.348368 , 0.651632]]
<E:1|B:1> : [[0.484391 , 0.515609] , [0.484279 , 0.515721]]


Testing difference hypothesis about the global precision on the parameters

We can therefore easily conduct a sensitivity analysis based on an assumption of error on all the parameters of the network.

In [7]:
def showNoisy(bn, beta):
  cr = gum.CredalNet(bn, bn)
  cr.bnToCredal(beta, False, False)
  cr.computeBinaryCPTMinMax()
  ielbp = gum.CNLoopyPropagation(cr)
  return gnb.getInference(cr, engine=ielbp)
In [8]:
for eps in [1, 1e-1, 1e-2, 1e-3, 1e-10]:
  gnb.flow.add(showNoisy(bn, eps), caption=f"noise={eps}")
gnb.flow.display()
G C C A A B B A->B F F B->C B->F D D D->C E E D->E E->F
structs Inference in   0.67ms A 2026-09-28T17:47:26.477235 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:26.508252 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:26.536774 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:26.625869 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:26.560118 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:26.592490 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
structs Inference in   0.42ms A 2026-09-28T17:47:27.510370 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:27.541553 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:27.577277 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:27.671836 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:27.607892 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:27.641611 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
noise=1
structs Inference in   0.56ms A 2026-09-28T17:47:27.985036 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:28.042344 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:28.081818 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:28.184640 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:28.109178 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:28.151043 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
noise=0.1
structs Inference in   0.20ms A 2026-09-28T17:47:28.444992 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:28.472003 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:28.507546 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:28.598910 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:28.539037 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:28.570115 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
noise=0.01
structs Inference in   0.32ms A 2026-09-28T17:47:28.865299 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:28.918750 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:28.949737 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:29.059138 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:28.989321 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:29.027925 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
noise=0.001
structs Inference in   0.34ms A 2026-09-28T17:47:29.449471 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B 2026-09-28T17:47:29.477954 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ A->B C 2026-09-28T17:47:29.505800 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->C F 2026-09-28T17:47:29.589865 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ B->F D 2026-09-28T17:47:29.533220 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->C E 2026-09-28T17:47:29.564588 image/svg+xml Matplotlib v3.11.2, https://matplotlib.org/ D->E E->F
noise=1e-10
In [ ]: