Tutorial 1: Creating a Bayesian Network

<< Click to Display Table of Contents >>

Navigation:  Tutorials >

Tutorial 1: Creating a Bayesian Network

Consider a slight twist on the problem described in the Hello, SMILE Wrapper! section of this manual.

The twist will include adding an additional variable State of the economy (with the identifier Economy) with three outcomes (Up, Flat, and Down) modeling the developments in the economy. These developments are relevant to the decision, as they are impacting expert predictions. When the economy is heading Up, our expert makes more optimistic predictions, when it is heading Down, the expert makes more pessimistic predictions for the same venture. This is reflected by a directed arc from the node State of the economy to the node Expert forecast. State of the economy also impacts the probability of venture being successful, which we model by adding another arc.

venture_bn

We will show how to create this model and how to save it to disk. In subsequent tutorials, we will show how to enter observations (evidence), how to perform inference, and how to retrieve the calculation results.

We start by declaring our network variable. The three nodes in the network are subsequently created by calling a helper method createCptNode.

Java:

Network net = new Network();

int e = createCptNode(net,

    "Economy", "State of the economy",

    new String[] {"Up","Flat","Down"}, 

    160, 40);

int s = createCptNode(net,

    "Success", "Success of the venture",

    new String[] {"Success","Failure"}, 

    60, 40);

int f = createCptNode(net,

    "Forecast", "Expert forecast",

    new String[] {"Good","Moderate","Poor"}, 

    110, 140);

Python:

net = pysmile.Network()

e = self.create_cpt_node(net,

    "Economy", "State of the economy",

    ["Up","Flat","Down"], 

    160, 40)

s = self.create_cpt_node(net,

    "Success", "Success of the venture",

    ["Success","Failure"], 

    60, 40)

f = self.create_cpt_node(net,

    "Forecast", "Expert forecast",

    ["Good","Moderate","Poor"], 

    110, 140)

C#:

Network net = new Network();

int e = CreateCptNode(net,

    "Economy", "State of the economy",

    new String[] { "Up", "Flat", "Down" },

    160, 40);

int s = CreateCptNode(net,

    "Success", "Success of the venture",

    new String[] { "Success", "Failure" },

    60, 40);

int f = CreateCptNode(net,

    "Forecast", "Expert forecast",

    new String[] { "Good", "Moderate", "Poor" },

    110, 140);

Before connecting the nodes with arcs, let’s have a look at the createCptNode method.

Java:

private static int createCptNode(

        Network net, String id, String name, 

        String[] outcomes, int xPos, int yPos) {

    int handle = net.addNode(Network.NodeType.CPT, id);

    net.setNodeName(handle, name);

    net.setNodePosition(handle, xPos, yPos, 85, 55);

    int initialOutcomeCount = net.getOutcomeCount(handle); 

    for (int i = 0; i < initialOutcomeCount; i ++) {

        net.setOutcomeId(handle, i, outcomes[i]);

    }

    for (int i = initialOutcomeCount; i < outcomes.length; i ++) {

        net.addOutcome(handle, outcomes[i]);

    }

    return handle;

}

Python:

def create_cpt_node(self, net, id, name, outcomes, x_pos, y_pos):

    handle = net.add_node(pysmile.NodeType.CPT, id)

    net.set_node_name(handle, name)

    net.set_node_position(handle, x_pos, y_pos, 85, 55)

    initial_outcome_count = net.get_outcome_count(handle)

    for i in range(0, initial_outcome_count):

        net.set_outcome_id(handle, i, outcomes[i])

    for i in range(initial_outcome_count, len(outcomes)):

        net.add_outcome(handle, outcomes[i])

    return handle

C#:

private static int CreateCptNode(

    Network net, String id, String name,

    String[] outcomes, int xPos, int yPos)

{

    int handle = net.AddNode(Network.NodeType.Cpt, id);

    net.SetNodeName(handle, name);

    net.SetNodePosition(handle, xPos, yPos, 85, 55);

    int initialOutcomeCount = net.GetOutcomeCount(handle);

    for (int i = 0; i < initialOutcomeCount; i++)

    {

        net.SetOutcomeId(handle, i, outcomes[i]);

    }

    for (int i = initialOutcomeCount; i < outcomes.Length; i++)

    {

        net.AddOutcome(handle, outcomes[i]);

    }

    return handle;

}

The function creates a CPT node with specified identifier, name, outcomes and position on the screen. CPT nodes are created with two outcomes named State0 and State1. To change the number of node outcomes and rename them, we will use two loops - the first renames the default outcomes and the second adds new outcomes.

We can now add arcs linking the nodes. Note that we can use either node handles or node identifiers. In this simple program, we use both forms just to showcase this feature.

Java:

net.addArc(e, s);

net.addArc(s, f);

net.addArc("Economy", "Forecast");

Python:

net.add_arc(e, s)

net.add_arc(s, f)

net.add_arc("Economy", "Forecast")

C#:

net.AddArc(e, s);

net.AddArc(s, f);

net.AddArc("Economy", "Forecast");

Next step is to initialize the conditional probability tables of the nodes. See the Multidimensional arrays section in this manual for the description of the CPT memory layout. For each of three nodes we call the Network.setNodeDefinition method. Here's how we set the probabilities of the Success node - note that the comments for each probability show the combination of outcomes it is defined for.

Java:

double[] successDef = new double[] {

    0.3, // P(Success=S|Economy=U)

    0.7, // P(Success=F|Economy=U)

    0.2, // P(Success=S|Economy=F)

    0.8, // P(Success=F|Economy=F)

    0.1, // P(Success=S|Economy=D)

    0.9  // P(Success=F|Economy=D)

};

net.setNodeDefinition(s, successDef);

Python:

successDef = [

    0.3, # P(Success=S|Economy=U)

    0.7, # P(Success=F|Economy=U)

    0.2, # P(Success=S|Economy=F)

    0.8, # P(Success=F|Economy=F)

    0.1, # P(Success=S|Economy=D)

    0.9  # P(Success=F|Economy=D)

]

net.set_node_definition(s, successDef)

C#:

double[] successDef = new double[] 

{

    0.3, // P(Success=S|Economy=U)

    0.7, // P(Success=F|Economy=U)

    0.2, // P(Success=S|Economy=F)

    0.8, // P(Success=F|Economy=F)

    0.1, // P(Success=S|Economy=D)

    0.9  // P(Success=F|Economy=D)

};

net.SetNodeDefinition(s, successDef);

With CPTs initialized our network is complete. We write its contents to the tutorial1.xdsl file. Tutorial 2 will load this file and perform the inference. The split between tutorials is artificial, your program can use networks right after its creation without the need to write/read from the file system.

Java:

net.writeFile("tutorial1.xdsl");

Python:

net.write_file("tutorial1.xdsl");

C#:

net.WriteFile("tutorial1.xdsl");