Skip to content

Getting Started ​

Installation ​

EnhancedBayesianNetworks.jl is not yet registered in Julia's General registry, so install it directly from its GitHub repository. From the Julia REPL, enter the package manager with ] and add it by URL:

julia
pkg> add https://github.com/JuliaUQ/EnhancedBayesianNetworks.jl

or, equivalently, from code:

julia
using Pkg
Pkg.add(url = "https://github.com/JuliaUQ/EnhancedBayesianNetworks.jl")

Then load it, this also brings in the re-exported UncertaintyQuantification.jl types (UQModel, Parameter, Interval, ProbabilityBox and the simulation methods)

julia
using EnhancedBayesianNetworks

Your first Bayesian Network ​

Building a Bayesian, Credal or Enhanced Bayesian network always follows the same three steps: construct the nodes, wire the edges with add_child!, and finalize with order!. Here is a two-node weather/sprinkler model, a root node W and a child node S whose Conditional Probability Table (CPT) is conditioned on it:

julia
W = DiscreteNode(:W)
W[:W => :sunny]  = 0.5
W[:W => :cloudy] = 0.5

S = DiscreteNode(:S, [:W])
S[:W => :sunny,  :S => :on] = 0.9
S[:W => :sunny,  :S => :off] = 0.1
S[:W => :cloudy, :S => :on] = 0.2
S[:W => :cloudy, :S => :off] = 0.8

bn = BayesianNetwork([W, S])
add_child!(bn, :W, :S)
order!(bn)
bn
BayesianNetwork

Nodes: 2
Edges: 1

Topology:

#   Node            States              Parents
--------------------------------------------------------------------------------
1   W               sunny, cloudy       -
2   S               on, off             W

Now query it. infer returns the posterior over a query variable given some evidence:

julia
infer(bn, :S, Evidence(:W => :sunny))       # P(S | W = sunny)
Posterior P(S | W=sunny)

S	Probability
------------------------
on	0.9
off	0.1

With no evidence you get the posterior is just the prior marginal:

julia
infer(bn, :S, Evidence())                   # P(S)
Posterior P(S)

S	Probability
------------------------
on	0.55
off	0.45

A first enhanced Bayesian Network ​

The real power of the package is mixing in DiscreteNodes, ContinuousNodes and functional nodes, a node whose CPT comes from a reliability analysis rather than being tabulated and can be either a DiscreteFunctionalNode or a ContinuousFunctionalNode. The EnhancedBayesianNetwork (eBN) is reduced to a standard BayesianNetwork (BN) with reduce function, then queried exactly as above:

julia
Load = DiscreteNode(:Load, [:low => [Parameter(1.0, :Load)], :high => [Parameter(3.0, :Load)]])
Load[:Load => :low] = 0.7; Load[:Load => :high] = 0.3
R = ContinuousNode(:R, Normal(3.0, 0.5))                 # a continuous resistance
model = Model(df -> df.R .- df.Load, :g)                 # limit state g = R - Load
F = DiscreteFunctionalNode(:F, [model], df -> df.g, MonteCarlo(2000))

ebn = EnhancedBayesianNetwork([Load, R, F])
add_child!(ebn, :Load, :F)
add_child!(ebn, :R, :F)
order!(ebn)
ebn
EnhancedBayesianNetwork

Nodes: 3
Edges: 2
Discrete nodes: 2
Continuous nodes: 1
Functional nodes: 1

Topology:

Node                Type                    Precision   Parents
--------------------------------------------------------------------------------
Load                Discrete                Precise     -
R                   Continuous              Precise     -
F                   DiscreteFunctional                  Load, R
julia
reduced = reduce(ebn)                                    # -> BayesianNetwork
infer(reduced, :F, Evidence(:Load => :high))            # failure probability given a high load
Posterior P(F | Load=high)

F	Probability
------------------------
F_failed	0.48249999999999993
F_safe	0.5175000000000001

The package allows for an imprecise description of both discrete and continuous nodes. See Reduction & Structural Reliability Problem for the full story.

Where to next ​