3. BBN Generation
BBN generation is available. We support singly- and mulit-connected BBNs.
3.1. Singly-connected BBN
Use generate_singly_bbn()
to generate a singly-connected BBN and then use create_reasoning_model()
to create a reasoning model.
[1]:
from pybbn.factory import create_reasoning_model
from pybbn.generator import generate_singly_bbn
import numpy as np
g, p = generate_singly_bbn(
n=10, max_iter=20, max_values=2, max_alpha=10, rng=np.random.default_rng(seed=37)
)
model = create_reasoning_model(g, p)
The singly-connected BBN graph looks like the following.
[2]:
import networkx as nx
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 5))
pos = nx.nx_agraph.graphviz_layout(g, prog="dot")
nx.draw(g, pos=pos, with_labels=True, node_color="#e0e0e0")
fig.tight_layout()

Querying of the posteriors proceeds as usual.
[3]:
import pandas as pd
q1 = model.pquery()
e = {"4": model.create_observation_evidences("4", "s0")}
q2 = model.pquery(evidences=e)
e = {"4": model.create_observation_evidences("4", "s1")}
q3 = model.pquery(evidences=e)
p1 = pd.Series({n: q1[n].iloc[0]["__p__"] for n in model.d.nodes()})
p2 = pd.Series({n: q2[n].iloc[0]["__p__"] for n in model.d.nodes()})
p3 = pd.Series({n: q3[n].iloc[0]["__p__"] for n in model.d.nodes()})
pd.DataFrame([p1, p2, p3]).T.rename(columns={0: "q1", 1: "q2", 2: "q3"})
[3]:
q1 | q2 | q3 | |
---|---|---|---|
0 | 0.500393 | 0.500424 | 0.500380 |
1 | 0.370587 | 0.370672 | 0.370552 |
2 | 0.500547 | 0.500535 | 0.500551 |
3 | 0.221217 | 0.222402 | 0.220730 |
4 | 0.291306 | 1.000000 | 0.000000 |
5 | 0.672492 | 0.630880 | 0.689596 |
6 | 0.246865 | 0.246865 | 0.246865 |
7 | 0.603267 | 0.597744 | 0.605537 |
8 | 0.304271 | 0.304277 | 0.304269 |
9 | 0.887248 | 0.961834 | 0.856590 |
[4]:
from pybbn.serde import model_to_dict
import json
with open("../../_support/bbn/singly-connected.json", "w") as fp:
json.dump(model_to_dict(model), fp, indent=1)
3.2. Multi-connected BBN
Use generate_multi_bbn()
to generate a singly-connected BBN and then use create_reasoning_model()
to create a reasoning model.
[5]:
from pybbn.generator import generate_multi_bbn
g, p = generate_multi_bbn(
n=10, max_iter=5, max_values=2, max_alpha=10, rng=np.random.default_rng(seed=37)
)
model = create_reasoning_model(g, p)
[6]:
fig, ax = plt.subplots(figsize=(5, 5))
pos = nx.nx_agraph.graphviz_layout(g, prog="dot")
nx.draw(g, pos=pos, with_labels=True, node_color="#e0e0e0")
fig.tight_layout()

[7]:
import pandas as pd
q1 = model.pquery()
e = {"0": model.create_observation_evidences("0", "s0")}
q2 = model.pquery(evidences=e)
e = {"0": model.create_observation_evidences("0", "s1")}
q3 = model.pquery(evidences=e)
p1 = pd.Series({n: q1[n].iloc[0]["__p__"] for n in model.d.nodes()})
p2 = pd.Series({n: q2[n].iloc[0]["__p__"] for n in model.d.nodes()})
p3 = pd.Series({n: q3[n].iloc[0]["__p__"] for n in model.d.nodes()})
pd.DataFrame([p1, p2, p3]).T.rename(columns={0: "q1", 1: "q2", 2: "q3"})
[7]:
q1 | q2 | q3 | |
---|---|---|---|
0 | 0.026385 | 1.000000 | 0.000000 |
1 | 0.564311 | 0.210227 | 0.573907 |
2 | 0.486509 | 0.402171 | 0.488795 |
3 | 0.352396 | 0.357359 | 0.352262 |
4 | 0.492260 | 0.477167 | 0.492669 |
5 | 0.446751 | 0.412918 | 0.447668 |
6 | 0.458902 | 0.490701 | 0.458041 |
7 | 0.584410 | 0.767471 | 0.579449 |
8 | 0.634409 | 0.590927 | 0.635587 |
9 | 0.491198 | 0.502911 | 0.490881 |
[8]:
with open("../../_support/bbn/multi-connected.json", "w") as fp:
json.dump(model_to_dict(model), fp, indent=1)