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
F
F
E
E
E->F
B
B
B->F
C
C
B->C
A
A
A->B
D
D
D->E
D->C
structs
Inference in 1.20ms
A
2026-10-09T08:52:23.128023
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:23.150670
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:23.173668
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:23.250997
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:23.204043
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:23.226108
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.55409 , 0.44591] , [0.554051 , 0.445949]]
<A:0> : [[0.805177 , 0.194823] , [0.805175 , 0.194825]]
<A:1> : [[0.228426 , 0.771574] , [0.218254 , 0.781746]]
<B:0|D:0> : [[0.515819 , 0.484181] , [0.515749 , 0.484251]]
<B:1|D:0> : [[0.446477 , 0.553523] , [0.446273 , 0.553727]]
<B:0|D:1> : [[0.764305 , 0.235695] , [0.764303 , 0.235697]]
<B:1|D:1> : [[0.636461 , 0.363539] , [0.636449 , 0.363551]]
<> : [[0.792033 , 0.207967] , [0.792032 , 0.207968]]
<D:0> : [[0.448349 , 0.551651] , [0.448151 , 0.551849]]
<D:1> : [[0.379635 , 0.620365] , [0.379027 , 0.620973]]
<E:0|B:0> : [[0.440777 , 0.559223] , [0.440554 , 0.559446]]
<E:1|B:0> : [[0.577948 , 0.422052] , [0.577921 , 0.422079]]
<E:0|B:1> : [[0.558909 , 0.441091] , [0.558873 , 0.441127]]
<E:1|B:1> : [[0.675147 , 0.324853] , [0.67514 , 0.32486]]
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
F
F
E
E
E->F
B
B
B->F
C
C
B->C
A
A
A->B
D
D
D->E
D->C
structs
Inference in 1.20ms
A
2026-10-09T08:52:23.128023
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:23.150670
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:23.173668
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:23.250997
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:23.204043
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:23.226108
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
structs
Inference in 0.79ms
A
2026-10-09T08:52:24.418625
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:24.452736
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:24.485038
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:24.572393
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:24.513663
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:24.543894
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=1
structs
Inference in 0.18ms
A
2026-10-09T08:52:24.870830
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:24.902527
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:24.922807
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:24.982671
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:24.940132
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:24.957783
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=0.1
structs
Inference in 0.85ms
A
2026-10-09T08:52:25.267521
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:25.307153
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:25.330600
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:25.433310
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:25.358939
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:25.400389
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=0.01
structs
Inference in 1.25ms
A
2026-10-09T08:52:25.713199
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:25.739892
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:25.773165
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:25.884853
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:25.818467
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:25.850468
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=0.001
structs
Inference in 2.42ms
A
2026-10-09T08:52:26.331369
image/svg+xml
Matplotlib v3.11.2,
B
2026-10-09T08:52:26.366177
image/svg+xml
Matplotlib v3.11.2,
A->B
C
2026-10-09T08:52:26.391904
image/svg+xml
Matplotlib v3.11.2,
B->C
F
2026-10-09T08:52:26.510323
image/svg+xml
Matplotlib v3.11.2,
B->F
D
2026-10-09T08:52:26.442320
image/svg+xml
Matplotlib v3.11.2,
D->C
E
2026-10-09T08:52:26.478292
image/svg+xml
Matplotlib v3.11.2,
D->E
E->F
noise=1e-10