If you have ever needed to work with Bayesian networks and conditional probabilities, you may have searched around for some libraries you can use. This article describes how to use two libraries with Java API support – Netica and JavaBayes – to set up a simple Bayesian network and calculate inferences.

Netica is a commercial product with support for multiple programming languages and has demo versions available for download. Its API seems very straightforward to use but its Java implementation relies on native libraries which can cause issues depending on which platform you are on. Some platforms (e.g. Linux) seem to be more regularly updated than others.

JavaBayes is an open source application/library written in pure Java but has not been updated for a long time (source code was written for Java 1.0.2 – yikes!). ItsAPI is also not as straightforward to use. For this exercise, the JavaBayes source was modified to live in its own package and to compile with Java 6. The modified source can be found here.

Both have applications/user interfaces that you can use to manually create/view a network and run queries on it but this article will focus on just the API capabilities for generating a network and calculating inference. The sample network that we will be creating is the DogProblem network described here. All source code/supporting libraries can be found here.

To create a simple network, the basic steps are to:

  • Create the nodes in the network with their links
  • Assign probabilities
  • Provide the evidence/observations for the nodes with known values
  • Run the inference calculations in order to obtain the probability of the node that you are interested in.

The Netica implementation is very straightforward but the JavaBayes implementation is more complicated since its API is used more by its user interface than as a standalone API. To compensate for this, some helper methods were created (shown at the very end).

To create nodes, there is some small setup to create the network itself and then for each node we give the name of the node, a string value for when the node is in its ‘true’ state, and a string value for when it is in its ‘false’ state. After the nodes are created, the nodes that affect the probabilities of other nodes are linked to form a directed graph.

Creating nodes with Netica:

Creating nodes with JavaBayes:

Once we have the nodes, we set up the various probabilities. Most probabilities are conditional based on the values of connected nodes but some ‘leaf’ nodes are given unconditional probabilities. A node that is conditional on one other node is pretty straightforward. For example, the probability that you will hear a bark given that the dog is out is .70. Since the hearBark node only has two values, this means that the probability that you will not hear a bark given that the dog is out is .30. In the same way, the probability that you will hear a bark given that the dog is not out is .01 (perhaps some frogs make noises that sound like dog barks) and the probability you will not hear a bark is 0.99. A node that is conditional on multiple nodes is a little more complicated since one has to account for each combination of probabilities (so two nodes would mean four different combinations).

Assigning probabilities with Netica:

Assigning probabilities with JavaBayes:

Now that we have the network set up, we can ask it to provide us with the probability of a node having a certain value just based on the ‘leaf’ node probabilities we provided and the conditional probabilities we gave to the other nodes. So, we ask it to calculate the probability that the light is on. Once we obtain this value, we provide some evidence to the network based on our observations. In this case we say that we heard a bark and that the dog does not have a bowel problem. We then ask the network again to calculate the probability that the light is on.

Providing evidence and calculating belief with Netica:

Providing evidence and calculating belief with JavaBayes:

The output of the Netica program when it is run gives:

The probability of the light being on is 0.13249997794628143
The probability of the light being on given a bark was heard and no bowel problem is 0.23651915788650513

and the output of the JavaBayes program gives:

The probability of the light being on is 0.1325
The probability of the light being on given a bark was heard and no bowel problem is 0.23651916875671802

Both come within the same answer for a fair number of significant digits.

There are the helper methods used with JavaBayes to make its API more similar to Netica’s:

As you can see, with a few helpers added for the JavaBayes implementation, a simple Bayesian network can be created to calculate inference with both libraries. If you are just interested in using the APIs and not the user interfaces, the Netica library is easier to use out of the box and supports multiple languages but has a commercial license and also uses native libraries for its Java implementation. To play around with both of these libraries, feel free to run the examples yourself using the source. Note only the Windows native library is included for Netica but others are available on the Netica site.