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 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))
G E E F F E->F D D D->E C C D->C B B B->C B->F A A A->B
structs Inference in   1.44ms A 2024-07-27T17:27:36.954510 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:36.971649 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:36.988952 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:37.039865 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:37.005660 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:37.022682 image/svg+xml Matplotlib v3.9.1, 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_15-Examples_SensitivityAnalysisUsingCredalNetworks_6_0.svg
In [4]:
cr.bnToCredal(beta=1e-10,oneNet=False)
In [5]:
cr.computeBinaryCPTMinMax()
In [6]:
print(cr)

A:Range([0,1])
<> : [[0.776911 , 0.223089] , [0.77691 , 0.22309]]

B:Range([0,1])
<A:0> : [[0.740924 , 0.259076] , [0.740921 , 0.259079]]
<A:1> : [[0.502721 , 0.497279] , [0.502637 , 0.497363]]

C:Range([0,1])
<B:0|D:0> : [[0.43648 , 0.56352] , [0.436241 , 0.563759]]
<B:1|D:0> : [[0.89709 , 0.10291] , [0.000491307 , 0.999509]]
<B:0|D:1> : [[0.465249 , 0.534751] , [0.465098 , 0.534902]]
<B:1|D:1> : [[0.702952 , 0.297048] , [0.702947 , 0.297053]]

D:Range([0,1])
<> : [[0.233498 , 0.766502] , [0.224406 , 0.775594]]

E:Range([0,1])
<D:0> : [[0.343163 , 0.656837] , [0.342027 , 0.657973]]
<D:1> : [[0.847638 , 0.152361]]

F:Range([0,1])
<E:0|B:0> : [[0.23151 , 0.76849] , [0.222013 , 0.777987]]
<E:1|B:0> : [[0.457325 , 0.542675] , [0.457153 , 0.542847]]
<E:0|B:1> : [[0.251951 , 0.748049] , [0.245783 , 0.754217]]
<E:1|B:1> : [[0.750987 , 0.249013] , [0.750985 , 0.249015]]


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=beta,oneNet=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()
structs Inference in   0.24ms A 2024-07-27T17:27:37.635044 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:37.648690 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:37.662124 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:37.702365 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:37.675836 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:37.689124 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->E E->F
noise=1
structs Inference in   0.24ms A 2024-07-27T17:27:37.896795 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:37.911198 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:37.925198 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:37.966359 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:37.938826 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:37.952411 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->E E->F
noise=0.1
structs Inference in   0.24ms A 2024-07-27T17:27:38.189033 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:38.203441 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:38.217466 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:38.258378 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:38.231085 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:38.244583 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->E E->F
noise=0.01
structs Inference in   0.15ms A 2024-07-27T17:27:38.452817 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:38.467052 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:38.507154 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:38.548730 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:38.521056 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:38.535161 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->E E->F
noise=0.001
structs Inference in   0.20ms A 2024-07-27T17:27:38.745500 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B 2024-07-27T17:27:38.759334 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ A->B C 2024-07-27T17:27:38.772820 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->C F 2024-07-27T17:27:38.813777 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ B->F D 2024-07-27T17:27:38.786360 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->C E 2024-07-27T17:27:38.800279 image/svg+xml Matplotlib v3.9.1, https://matplotlib.org/ D->E E->F
noise=1e-10
In [ ]: