Bayesian network inference using the junction-tree algorithm
This demo illustrates Bayesian network inference using the junction-tree algorithm. The example is due to Kevin Murphy (http://bnt.googlecode.com/svn/trunk/docs/usage.html) and uses the sprinkler Bayesian network from Artificial Intelligence: A Modern Approach (1st Edition).
Contents
Creating the network
First we create the sprinkler network.
import org.mensxmachina.pgm.bn.tabular.sprinkler; % create the network BayesNet = org.mensxmachina.pgm.bn.tabular.sprinkler
BayesNet = structure (1,2) 1 (1,3) 1 (2,4) 1 (3,4) 1 Conditional probability distributions cloudy = false cloudy = true 0.5 0.5 sprinkler = false sprinkler = true cloudy = false 0.5 0.5 cloudy = true 0.9 0.1 rain = false rain = true cloudy = false 0.8 0.2 cloudy = true 0.2 0.8 wetGrass = false wetGrass = true sprinkler = false, rain = false 1 0 sprinkler = true, rain = false 0.1 0.9 sprinkler = false, rain = true 0.1 0.9 sprinkler = true, rain = true 0.01 0.99
Viewing the network structure
We view the network structure.
import org.mensxmachina.pgm.bn.viewers.biograph.biographbayesnetviewer; % create Bayesian network Viewer Viewer = biographbayesnetviewer(BayesNet); % view the network structure Viewer.viewbayesnetstructure();
Creating an inference Engine
Probabilistic inference is performed by an "inference Engine". An inference Engine computes the marginal probability distribution of members of a set of variables given evidence.
The junction-tree inference Engine needs to be supplied a Bayesian network, and the evidence and weight for each variable in the network.
The evidence for each variable is a likelihood, which is a special case of a potential. A potential over a set of variables is a function that maps each variable-value combination to a nonnegative number. A likelihood is a potential over a single variable that maps each variable value to a number in range [0, 1]. A likelihood of 1 for a single value x of variable X and 0 for all the other values of X encodes the fact that X = x. A likelihood of 1 for every value of X denotes that the value of X is unknown.
The likelihood of each variable must be compatible with the CPD of that variable in the network. Since all CPDs in our network are tabular CPDs, we create a tabular likelihood for each variable. Our evidence encodes the fact that wetGrass = true and the values of cloudy, sprinkler and rain are unknown.
For finite-domain variables, the weight of a variable is the number of values of that variable.
import org.mensxmachina.stats.cpd.tabular.tabpotential; import org.mensxmachina.pgm.bn.inference.jtree.jtreeinfengine; % create variable values -- same for all variables varValues = nominal([1; 2], {'false', 'true'}, [1 2]); % create evidence for each variable CloudyEvidence = tabpotential({'cloudy'}, {varValues}, [1; 1]) SprinklerEvidence = tabpotential({'sprinkler'}, {varValues}, [1; 1]) RainEvidence = tabpotential({'rain'}, {varValues}, [1; 1]) WetGrassEvidence = tabpotential({'wetGrass'}, {varValues}, [0; 1]) % put the evidence together evidence = {CloudyEvidence, SprinklerEvidence, RainEvidence, WetGrassEvidence}; % create variable weights - same for all variables varWeights = [2 2 2 2]; % create the Engine Engine = jtreeinfengine(BayesNet, evidence, varWeights);
CloudyEvidence = cloudy = false 1 cloudy = true 1 SprinklerEvidence = sprinkler = false 1 sprinkler = true 1 RainEvidence = rain = false 1 rain = true 1 WetGrassEvidence = wetGrass = false 0 wetGrass = true 1
Computing a marginal probability distribution
We compute Pr(sprinkler|wetGrass = true), that is, the probability of the sprinkler being on when the grass is wet.
% get the marginal distribution of variable 2 (sprinkler)
M = marginal(Engine, 2)
M = sprinkler = false sprinkler = true 0.57024 0.42976
Updating the evidence
We update the evidence of the Engine to encode the fact that also rain = true.
% change the evidence for variable 3 (rain) evidence{3} = tabpotential({'rain'}, {varValues}, [0; 1]); % update the evidence Engine.evidence = evidence;
Computing the marginal probability distribution given the new evidence
Finally, we compute Pr(sprinkler|wetGrass = true, rain = true), that is, the probability of the sprinkler being on when the grass is wet and it is raining. We see that the fact that it is raining has reduced the probability that the sprinkler is on.
% get the new marginal distribution of variable 2 (sprinkler)
M = marginal(Engine, 2)
M = sprinkler = false sprinkler = true 0.8055 0.1945