Showing some additional features

Serialization-deserialization (serde) a BBN

Let's serialize (save) a BBN and deserialize it for later use. The BBN is a simple two node network $a \rightarrow b$.

Serializing


In [1]:
import json

from pybbn.graph.variable import Variable
from pybbn.graph.node import BbnNode
from pybbn.graph.edge import Edge, EdgeType
from pybbn.graph.dag import Bbn

a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
bbn = Bbn().add_node(a).add_node(b) \
    .add_edge(Edge(a, b, EdgeType.DIRECTED))

# serialize to JSON file
s = json.dumps(Bbn.to_dict(bbn))
with open('simple-bbn.json', 'w') as f:
    f.write(s)
    
print(bbn)


0|a|t,f
1|b|t,f
0->1

Deserializing


In [2]:
# deserialize from JSON file
with open('simple-bbn.json', 'r') as f:
    d = json.loads(f.read())
    bbn = Bbn.from_dict(d)
    
print(bbn)


0|a|t,f
1|b|t,f
0->1

Serde a join tree

Serializing


In [3]:
from pybbn.pptc.inferencecontroller import InferenceController
from pybbn.graph.jointree import JoinTree

a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
bbn = Bbn().add_node(a).add_node(b) \
    .add_edge(Edge(a, b, EdgeType.DIRECTED))
jt = InferenceController.apply(bbn)

with open('simple-join-tree.json', 'w') as f:
    d = JoinTree.to_dict(jt)
    j = json.dumps(d, sort_keys=True, indent=2)
    f.write(j)
    
print(jt)


(a,b)

Deserializing


In [4]:
with open('simple-join-tree.json', 'r') as f:
    j = f.read()
    d = json.loads(j)
    jt = JoinTree.from_dict(d)
    jt = InferenceController.apply_from_serde(jt)
    
print(jt)


(a,b)

Updating the conditional probability tables (CPTs) of a BBN nodes in a junction tree

Sometimes, you may want to update the CPTs of BBN nodes in a junction tree; the junction tree may be expensive to build for large graph, and you want to avoid building it since it is a computationally expensive procedure. Below, we show how to reuse a junction tree with updated CPTs.


In [5]:
# you have built a BBN 
a = BbnNode(Variable(0, 'a', ['t', 'f']), [0.2, 0.8])
b = BbnNode(Variable(1, 'b', ['t', 'f']), [0.1, 0.9, 0.9, 0.1])
bbn = Bbn().add_node(a).add_node(b) \
    .add_edge(Edge(a, b, EdgeType.DIRECTED))

# you have built a junction tree from the BBN
# let's call this "original" junction tree the left-hand side (lhs) junction tree
lhs_jt = InferenceController.apply(bbn)

# you may just update the CPTs with the original junction tree structure
# the algorithm to find/build the junction tree is avoided
# the CPTs are updated
rhs_jt = InferenceController.reapply(lhs_jt, {0: [0.3, 0.7], 1: [0.2, 0.8, 0.8, 0.2]})

# let's print out the marginal probabilities and see how things changed
# print the marginal probabilities for the lhs junction tree
print('lhs probabilities')
for node in lhs_jt.get_bbn_nodes():
    potential = lhs_jt.get_bbn_potential(node)
    print(node)
    print(potential)
    print('>')
    

# print the marginal probabilities for the rhs junction tree
print('rhs probabilities')
for node in rhs_jt.get_bbn_nodes():
    potential = rhs_jt.get_bbn_potential(node)
    print(node)
    print(potential)
    print('>')


lhs probabilities
1|b|t,f
1=t|0.74000
1=f|0.26000
>
0|a|t,f
0=t|0.20000
0=f|0.80000
>
rhs probabilities
1|b|t,f
1=t|0.62000
1=f|0.38000
>
0|a|t,f
0=t|0.30000
0=f|0.70000
>

In [ ]: