Basic Tutorial
In this tutorial we will run through the basics of creating a model and conditioning it.
First load Omega:
using Omega, Distributions
If you tossed a coin and observed the sequqnce HHHHH
, you would be a little suspicious, HHHHHHHH
would make you very suspicious. Elementary probability theory tells us that for a fair coin, HHHHHHHH
is just a likely outcome as HHTTHHTH
. What gives? We will use Omega to model this behaviour, and see how that belief about a coin changes after observing a number of tosses.
Model the coin as a bernoulli distribution. The weight of a bernoulli determines the probability it comes up true (which represents heads). Use a beta distribution to represent our prior belief weight of the coin.
weight = @~ Beta(2.0, 2.0)
A beta distribution is appropriate here because it is bounded between 0 and 1.
Draw a 10000 samples from weight
using rand
:
beta_samples = randsample(weight, 10000)
Let's see what this distribution looks like using UnicodePlots. If you don't have it installed already install with:
] add UnicodePlots
To visualize the distribution, plot a histogram of the samples:
using UnicodePlots
UnicodePlots.histogram(beta_samples)
┌────────────────────────────────────────┐
(0.0,0.1] │▇▇▇▇▇▇ 279 │
(0.1,0.2] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 727 │
(0.2,0.3] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1218 │
(0.3,0.4] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1354 │
(0.4,0.5] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1482 │
(0.5,0.6] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1426 │
(0.6,0.7] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1406 │
(0.7,0.8] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 1124 │
(0.8,0.9] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 702 │
(0.9,1.0] │▇▇▇▇▇▇ 282 │
└────────────────────────────────────────┘
The distribution is symmetric around 0.5 and has support over the the interval [0, 1].
So far we have not done anything we couldn't do with Distributions.jl
. A primary distinction between a package like Distribution.jl
, is that Omega.jl
allows you to condition probability distributions.
Create a model representing four flips of the coin. Since a coin can be heads or tales, the appropriate distribution is the bernouli distribution:
nflips = 4
coinflips_ = [Bernoulli.(weight, Bool) for i = 1:nflips]
Take note that weight
is the random variable defined previously. bernoulli
takes a type as its secoond argument; Bool
indicates the result will be a Bool
rather than an Int
.
coinflips
is a normal Julia array of Random Variables (RandVar
s). For reasons we will elaborate in later sections, it will be useful to have an Array
-valued RandVar
(instead of an Array
of RandVar
).
One way to do this (there are several ways discuseed later), is to use the function randarray
coinflips = randarray(coinflips_)
coinflips
is a RandVar
and hence we can sample from it with rand
julia> rand(coinflips)
4-element Array{Bool,1}:
true
false
false
false
Now we can condition the model. We want to find the conditional distribution over the weight of the coin given some observations.
First create some fake data
observations = [true, true, true, false]
Create a predicate that tests whether simulating from the model matches the observed data:
condition = coinflips ==ᵣ observations
condition
is a random variable; we can sample from it. The function ==ᵣ
(and more generally functions subscripted with ᵣ) should be read as "a realization of coinflips == observations"
We can use rand
to sample from the model conditioned on condition
being true:
weight_samples = rand(weight, condition, 1000; alg = RejectionSample)
weight_samples
is a set of 1000
samples from the conditional (sometimes called posterior) distribution of weight
condition on the fact that coinflips == observations.
In this case, rand
takes
- A random variable we want to sample from
- A predicate (type
RandVar
which evaluates to aBool
) that we want to condition on, i.e. assert that it is true - An inference algorithm. Here we use rejection sampling.
Plot a histogram of the weights like before:
julia> UnicodePlots.histogram(weight_samples)
┌────────────────────────────────────────┐
(0.1,0.2] │▇ 4 │
(0.2,0.3] │▇▇▇ 22 │
(0.3,0.4] │▇▇▇▇▇▇▇▇▇▇▇ 69 │
(0.4,0.5] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 147 │
(0.5,0.6] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 185 │
(0.6,0.7] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 226 │
(0.7,0.8] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 203 │
(0.8,0.9] │▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 120 │
(0.9,1.0] │▇▇▇▇ 23 │
└────────────────────────────────────────┘
Observe that our belief about the weight has now changed. We are more convinced the coin is biased towards heads (true
).