def dict2html(di1,di2=None):
res= "<br/>".join([f"<b>{k:15}</b>:{v}" for k,v in di1.items()])
if di2 is not None:
res+="<br/><br/>"
res+= "<br/>".join([f"<b>{k:15}</b>:{v}" for k,v in di2.items()])
return res
import pyAgrum as gum
import pyAgrum.lib.notebook as gnb
import pyAgrum.lib.bn_vs_bn as gcm
PyAgrum allows you to compare BNs in several ways. This notebook show you some of them:
26-klForBNs
for more)The graphical diff propose to show the different possible structural differences from two structures with the same nodes in the layout of the first BN (the reference of the comparison).
bn1=gum.fastBN("A->B->C->D->E<-A->F")
bn2=gum.fastBN("A->B<-C->D->E<-A;F->E")
gnb.showBNDiff(bn1,bn2)
The meaning of the diffent style for the arcs are :
import pyAgrum.lib.bn_vs_bn as bnvsbn
bnvsbn.graphDiffLegend()
cmp=gcm.GraphicalBNComparator(bn1,bn2)
kl=gum.ExactBNdistance(bn1,bn2) # bruteForce is possible car the BNs are small
gnb.sideBySide(bn1,bn2,gnb.getBNDiff(bn1,bn2),dict2html(cmp.scores(),cmp.hamming()),cmp.equivalentBNs(),dict2html(kl.compute()),
captions=['bn1','bn2','graphical diff','Scores','equivalent ?','distances'],valign="bottom")
The logic for the arcs of the graphical diff is the following. When comparaing bn1 with bn2 (in that order) :
For the scores :
EquivalentBN
return "OK" if equivalent or a reason for non equivalence
Finally, BruteForceKL
compute in the same time several distances : I-projection, M-projection, Hellinger and Bhattacharya. For more complex BNs, there exists a GibbsKL
to approximate those distances. Of course, the computation are much slower.
bn1=gum.fastBN("A->B->C->D->E<-A->F")
bn2=gum.fastBN("A->B->C->D->E<-A->F")
cmp=gcm.GraphicalBNComparator(bn1,bn2)
kl=gum.ExactBNdistance(bn1,bn2) # bruteForce is possible car the BNs are small
gnb.sideBySide(bn1,bn2,gnb.getBNDiff(bn1,bn2),dict2html(cmp.scores(),cmp.hamming()),cmp.equivalentBNs(),dict2html(kl.compute()),
captions=['bn1','bn2','graphical diff','Scores','equivalent ?','distances'],valign="bottom")
bn1=gum.fastBN("A->B->C->D->E<-A->F")
bn2=bn1
cmp=gcm.GraphicalBNComparator(bn1,bn2)
kl=gum.ExactBNdistance(bn1,bn2) # bruteForce is possible car the BNs are small
gnb.sideBySide(bn1,bn2,gnb.getBNDiff(bn1,bn2),dict2html(cmp.scores(),cmp.hamming()),cmp.equivalentBNs(),dict2html(kl.compute()),
captions=['bn1','bn2','graphical diff','Scores','equivalent ?','distances'],valign="bottom")
In the notebook Learning_DirichletPriorAndWeightedDatabase
, you can find an interresting discussion on how can change those scores and distance.