There are several sensitivity analysis frameworks for Bayesian networks. A fairly efficient method is certainly to use credal networks to do this analysis.
import pyagrum.credal_net as gum
import pyagrum.lib.notebook as gnb
bn = gum.fastBN( "A->B->C<-D->E->F<-B" )
gnb.flow.row(bn, gnb.getInference(bn))
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,
B
2026-09-28T17:47:26.508252
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:26.536774
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:26.625869
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:26.560118
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:26.592490
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
It is easy to build a credal network from a Bayesian network by indicating the ‘noise’ on each parameter.
cr = gum.CredalNet(bn, bn)
cr.bnToCredal( 1e-10 , False , False )
cr.computeBinaryCPTMinMax()
<> : [[0.712502 , 0.287498] , [0.712498 , 0.287502]]
<A:0> : [[0.462944 , 0.537056] , [0.462787 , 0.537213]]
<A:1> : [[0.675036 , 0.324964] , [0.675029 , 0.324971]]
<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]]
<> : [[0.915245 , 0.0847542]]
<D:0> : [[0.376233 , 0.623767] , [0.375588 , 0.624412]]
<D:1> : [[0.315478 , 0.684522] , [0.313626 , 0.686374]]
<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]]
We can therefore easily conduct a sensitivity analysis based on an assumption of error on all the parameters of the network.
cr = gum.CredalNet(bn, bn)
cr.bnToCredal(beta, False , False )
cr.computeBinaryCPTMinMax()
ielbp = gum.CNLoopyPropagation(cr)
return gnb.getInference(cr, engine = ielbp)
for eps in [ 1 , 1e-1 , 1e-2 , 1e-3 , 1e-10 ]:
gnb.flow.add(showNoisy(bn, eps), caption = f "noise= { eps } " )
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,
B
2026-09-28T17:47:26.508252
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:26.536774
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:26.625869
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:26.560118
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:26.592490
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
structs
Inference in 0.42ms
A
2026-09-28T17:47:27.510370
image/svg+xml
Matplotlib v3.11.2,
B
2026-09-28T17:47:27.541553
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:27.577277
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:27.671836
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:27.607892
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:27.641611
image/svg+xml
Matplotlib v3.11.2,
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,
B
2026-09-28T17:47:28.042344
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:28.081818
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:28.184640
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:28.109178
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:28.151043
image/svg+xml
Matplotlib v3.11.2,
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,
B
2026-09-28T17:47:28.472003
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:28.507546
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:28.598910
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:28.539037
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:28.570115
image/svg+xml
Matplotlib v3.11.2,
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,
B
2026-09-28T17:47:28.918750
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:28.949737
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:29.059138
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:28.989321
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:29.027925
image/svg+xml
Matplotlib v3.11.2,
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,
B
2026-09-28T17:47:29.477954
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-09-28T17:47:29.505800
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-09-28T17:47:29.589865
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-09-28T17:47:29.533220
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-09-28T17:47:29.564588
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=1e-10