Author Topic: Generate multiple simulations in the API  (Read 19350 times)

Offline DS

  • Newbie
  • *
  • Posts: 3
    • View Profile
Generate multiple simulations in the API
« on: September 15, 2015, 14:43:21 »
Hi
I have been trying to write a program that generates multiple simulations given some evidence. I.e. I want to sample a Bayesian network a number of times given some observations. I know this is possible to do using the GUI (with the "generate cases" button) and generally I think that the API is quite straightforward to use, but this time I have got stuck. It might be the case that I will have to write the entire sampling method myself, in which case I can probably do it, but it feels like it should be possible to do with the "saveCases(...)" method for the domain object straight away. I can however not get it to work and only get "NA" values in my output (like if the values are missing) so I guess I somehow need to set up the "cases" before-hand, but can't figure out how. Does anyone have an idea of what I do wrong or what I am missing?
I have attached my code below and I think it is quite straightforward to understand with the comments.
 
 
Code: [Select]
import java.awt.geom.Point2D;

import COM.hugin.HAPI.ContinuousChanceNode;
import COM.hugin.HAPI.Domain;
import COM.hugin.HAPI.ExceptionHugin;


public class exampleCase {

public static void main(String[] args) {
try {
Domain d;
d = new Domain ();
d.setNodeSize (new Point2D.Double (50, 30));

//set up the basic stucture with a collider over node3
ContinuousChanceNode node1 = new ContinuousChanceNode(d);
node1.setLabel ("node1");
node1.setName ("node1");
node1.setPosition(new Point2D.Double (50, 50));
ContinuousChanceNode node2 = new ContinuousChanceNode(d);
node2.setLabel ("node2");
node2.setName ("node2");
node2.setPosition(new Point2D.Double (150, 50));
ContinuousChanceNode node3 = new ContinuousChanceNode(d);
node3.setLabel ("node3");
node3.setName ("node3");
node3.setPosition(new Point2D.Double (100, 100));
node3.addParent(node1);
node3.addParent(node2);
d.compile ();

//set the parameters
node1.setAlpha(0.1, 0); //alpha = intercept
                node1.setGamma(10, 0); //variance
                node2.setAlpha(0.2, 0); //alpha = intercept
                node2.setGamma(10, 0); //variance
                node3.setBeta(0.3, node1, 0); //beta = weights
                node3.setBeta(0.4, node2, 0);
                node3.setGamma(0.5,0); //variance
d.saveAsNet ("example.net");

//So what I want to do is to sample this BN 10 times with the evidence set below.
node1.enterValue(1.1);
node2.enterValue(1.2);
d.propagate(Domain.H_EQUILIBRIUM_SUM, Domain.H_EVIDENCE_MODE_NORMAL);
//Here I can also check that the network is updated correctly (which it is)
System.out.println("Name: "+node1.getName()+" val: "+node1.getMean());
System.out.println("Name: "+node2.getName()+" val: "+node2.getMean());
System.out.println("Name: "+node3.getName()+" val: "+node3.getMean());

//However, for the simulation (sampling)-part I am unsure how to do it .
//If I want to save the evidence of a single case I know I can simply write:
d.saveCase("Single_sample.dat"); //saves the set evidence
//but what if I want to save multiple (10) simulations given the evidence?
//Intuitively I would think that this code would do the trick:
d.setNumberOfCases(10); 
d.saveCases("Multiple_samples.dat", d.getNodes(), null, false, ",", "NA");
//but unfortunately only NA-values are given in the output file
//like if all values are missing. So what do I need more?
//And what do the following methods do? Are they related to the simulation part?
d.newCase(); //is this if I want different evidence in the different cases?
d.enterCase(0); //does this select case 0 for altering the evidence in that case?
d.setCaseCount(0,3); //repeats the case 0 3 times or?
d.adapt(); //Is this related to the simulations?

} catch (ExceptionHugin e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(99);
}
}
}

Offline Frank Jensen

  • HUGIN Expert
  • Hero Member
  • *****
  • Posts: 576
    • View Profile
Re: Generate multiple simulations in the API
« Reply #1 on: September 23, 2015, 17:45:24 »
Hello,

First: The Java API documentation basically only explains the Java interface.  For the full explanation, you also need to read the Hugin API Reference Manual.  This is the "api-manual.pdf" file in the Hugin software package.

Second: There are two different file formats for cases -- the "case file" format and the "data file" format.  The first type only contains a single case, but the second type can contain multiple cases (this is basically a restricted CSV file format).  "saveCase" saves the currently entered evidence as a "case file", and "saveCases" saves the currently stored cases within the Domain object as a "data file".  In the latter case, you must create (sample) the cases and store them in the Domain object, before they can be saved.  In the "test" subdirectory of the Hugin distribution, there is a program called "generate_cases.c", which does exactly what you want, but it is written in C.

I hope this helps.  If not, then please ask for more help.

Frank

Offline DS

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Generate multiple simulations in the API
« Reply #2 on: September 30, 2015, 16:09:31 »
Thank you! From the c-program it was easy to follow. Here is the example-code updated if anyone else has the same problem:
Code: [Select]
import java.awt.geom.Point2D;
import COM.hugin.HAPI.ContinuousChanceNode;
import COM.hugin.HAPI.Domain;
import COM.hugin.HAPI.ExceptionHugin;


public class exampleCase {

public static void main(String[] args) {
try {
Domain d;
d = new Domain ();
d.setNodeSize (new Point2D.Double (50, 30));
//set up the basic stucture with a collider over node3
ContinuousChanceNode node1 = new ContinuousChanceNode(d);
node1.setLabel ("node1");
node1.setName ("node1");
node1.setPosition(new Point2D.Double (50, 50));
ContinuousChanceNode node2 = new ContinuousChanceNode(d);
node2.setLabel ("node2");
node2.setName ("node2");
node2.setPosition(new Point2D.Double (150, 50));
ContinuousChanceNode node3 = new ContinuousChanceNode(d);
node3.setLabel ("node3");
node3.setName ("node3");
node3.setPosition(new Point2D.Double (100, 100));
node3.addParent(node1);
node3.addParent(node2);
d.compile ();

//set the parameters
node1.setAlpha(0.1, 0); //alpha = intercept
                node1.setGamma(10, 0); //variance
                node2.setAlpha(0.2, 0); //alpha = intercept
                node2.setGamma(10, 0); //variance
                node3.setBeta(0.3, node1, 0); //beta = weights
                node3.setBeta(0.4, node2, 0);
                node3.setGamma(0.1,0); //variance
d.saveAsNet ("example.net");

//Set the evidence that should be present in all samples
node1.enterValue(1.1);
node2.enterValue(1.2);
d.propagate(Domain.H_EQUILIBRIUM_SUM, Domain.H_EVIDENCE_MODE_NORMAL);

int nrOfCases = 100;
d.setNumberOfCases(nrOfCases);
for (int k =0;k<nrOfCases;k++){
d.simulate();//simulate a single case (i.e. values for all variables) given the evidence
//set the case to the simulated values (node 1 and 2 will have the evidence as the simulated value)
node1.setCaseValue(k, node1.getSampledValue());
node2.setCaseValue(k, node2.getSampledValue());
node3.setCaseValue(k, node3.getSampledValue());
}
//and save the cases
d.saveCases("Multiple_samples.dat", d.getNodes(), null, false, ",", "NA");

} catch (ExceptionHugin e) {
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(99);
}
}
}