Make-Believe (R22): Command and Control

umbrella_textThis version mostly focuses on giving access to Make-Believe outside of the browser. There are two components to this: an API and a standalone desktop app. I describe those in a bit more detail below.

The only other significant change in this version is support for text boxes from .xdsl files (see image at right). They are view-only, but you can move them around.

API

The API is available via node.js. The initial version just exposes the main classes in the core Make-Believe JavaScript files in a node.js module. Using the makeBelieve.js module, it’s now possible to create a Bayesian network, add some nodes and then do an inference. Here’s an example (adapted from the apiTest.js file):

var mb = require("./makeBelieve.js");

var bn = new mb.BN();
var pollutionNode = bn.addNode("Pollution", ["High", "Medium", "Low"],
   {cpt: [.1,.4,.5]});
var cancerNode = bn.addNode("Cancer", ["Absent", "Present"],
   {parents: [pollutionNode], cpt: [.3,.7, .2,.8, .05,.95]});
bn.updateBeliefs();
console.log(cancerNode.beliefs);

Note the last line actually requires a custom/temporary console.apilog function for now, as I’m suppressing lots of junky ordinary console.log output. That obviously needs to change.

It also currently requires ‘cheerio’ (essentially, jQuery optimised for node.js). Since I’m not using very much of it, I may try to remove that dependency, which would make the API significantly smaller and more convenient.

Current steps for using the API with the apiTest.js:

  • Install node.js (if don’t have)
  • Grab Make-Believe source files (choose ‘Download ZIP’) and extract somewhere
  • Go to the Make-Believe folder with ‘apiTest.js’
  • (If first time) Run ‘npm install cheerio’
  • Run node apiTest.js

Standalone Desktop App

I also fortuitously came across Electron this week. Actually, I’d encountered it before, but I read something that inspired me to believe porting a HTML5 app to it would be easy. And indeed it is. So here is a first version for Windows:

Extract it, run make-believe.exe and voilà.

It should be easy to get it working on other platforms too. Grab a pre-built Electron build from here, extract it, and then copy the core Make-Believe files into resources/app (you need to create the ‘app’ folder in resources). You then need to run ‘electron’ with no arguments.

To be honest, the use cases for the desktop version are pretty limited. Make-Believe is a web app first and foremost, and the web app will always be the most capable version. What’s more, you can put Make-Believe anywhere you want (on your own webserver, for example) and it will just work. If you’ve got Firefox, just running ‘index.html’ from the source files will run just fine. (Chrome has (always had) very crappy support for file: based apps. IE might work, but I still haven’t gotten things working in that generally yet. I’m hoping Edge will catch up by itself.)

As such, I may not update the desktop version very much. Still, getting things going was very easy, so well done to the Electron team. (Of course, since Chromium and node.js are both bundled, the size is quite hefty.)

Changes

  • Small improvement to CPTs (state name overflow, fixed width columns)
  • Add support for textboxes
  • Allow textboxes to be moved (initial)
  • API: Fair bit of work to get something working in node.js. Requires ‘npm install cheerio’.
  • API: Created apiTest.js for API examples/testing. Run as ‘node apiTest.js’.

Make-Believe (R21): Coming of Age

nodecptNot a whole lot new in this release in comparison to some of the previous releases, with most of the work going into the backend. I’m starting to think about the API for Make-Believe and cleaning things up here and there in preparation for a more friendly and useful API. Two user-facing changes are the ability to rename states (from the CPT context menu — just click the state label to start editing) and bar graphs for the probabilities in the CPT (which are currently always visible). CPT formatting needs a lot of work, of course, and there are more useful things to be done there first, but the bars were cheap and fun to implement! (In case it’s of interest, I’m actually using CSS gradients for this.)

Also, I’m trying to switch to a numerical representation everywhere I’m calling ‘chances’. (The latest change is in the CPTs.) It’s nothing dramatic, and I was already using it in the interface. Essentially, non-certain probabilities are represented by a decimal point followed by decimals (importantly, with no leading zero) and the certain probabilities are (as you’d expect) 0 and 1. This is because I’m sick of saying things like “a probability of 0.345” (14 syllables) or “a 34.5% chance” (9 syllables, and somewhat misleading) and would prefer to say “a .345 chance” (6 syllables). I like my languages Huffman-coded…

Changes:

  • Added bars (bar graphs) to CPT cell background
  • Changed CPTs to display ‘chances’
  • Check for valid CPT on change
  • API: Allow adding states
  • API: Allow deleting states
  • API: Allow renaming states
  • API: Centralise new Node/addNode code
  • Can rename states from CPT context menu (click column header for state to start editing)

Make-Believe (R20): Submodel Cleanup

Tnodecontexthe focus in this version was cleaning up some of the rougher edges (and outright breakages) from the introduction of submodels. So, it’s now possible to move nodes between submodels from the node context menu. It’s possible to remove all the submodel information from a network using the Network -> Flatten Network command. And it’s possible to view arc strengths with BNs containing submodels (using a perhaps questionable approach to summarising the influence flowing into and out of a submodel).

DNE support has also been fixed, along with a bug from the past that prevented evidence being entered into certain types of DNE file. (There is almost certainly a very large number of other issues with DNE support still — it’s not a main focus.)

Changes:

  • Can (properly) flatten a network with submodels (but this is a non-reversible change, rather than a different view)
  • Can move nodes from one submodel to another, by changing it’s ‘path’
  • Made ‘type’ visible on context menu (need to make changeable … somehow)
  • Added ‘label’ to the context menu
  • Made context menus available on submodels
  • Possible to change ID and label on submodel nodes
  • Code: .submodelPath vs .path (the latter includes id of the submodel itself). Eliminated .path
  • Can view submodel path, and move submodels to different submodels from context menu
  • Show arc strengths fixed, and can be used with BNs containing submodels (I’m not clear that the approach I’ve chosen is sensible, though, which is sum(mi)/sum(child-entropies) for all applicable paths)
  • FIXED: Significant contextmenu dialog duplication. PART FIXED: Now fix node context menu
  • FIXED: Continuous nodes/networks seem to have broken.
  • FIXED: .dne support broken

Make-Believe (R19): ((Sub)Sub)Submodels

Submodels in Bunce's FarmSubmodels are now supported. Submodel nodes are rendered with thick borders to distinguish them from variable nodes. You need to double-click them (as per GeNIe) to open them up, and when you’re in a submodel, the parent model can be accessed by double-clicking the ‘..’ node (obviously inspired by command line navigation) in the top left corner. This is clearly not the final interface, but perfectly workable for the time-being. Also for the time-being, submodel nodes are very much view only — it’s not possible to do anything with them other than to move them about. And saving networks with submodels will simply ignore the submodel information, which I guess counts as one (temporary) way to flatten a network.

Submodels are the last major XDSL feature I was aiming to have some support for in Make-Believe. (Note that .dne support has been broken since R18, but will be revived soon.) I’ll be taking the opportunity over the next few months to focus on polish: trying to improve robustness, code legibility and ensuring that everything is properly CRUD-capable.

Changes:

  • Initial group support
    • Show only nodes from currently focused group
    • Show node for submodel, with arcs
    • Allow submodel navigation
    • Allow moving with submodel
    • |display()| function clean up
      • Fixed up pathsIn/pathsOut to store information as objects rather than arrays
    • Delete of variable nodes now working again
  • Context menus supported (minimally) on utility and decision nodes

Make-Believe (R18): Now in Colour

asia-colorsNode colours and formats are now fully supported (create/read/update/delete), however the behaviour deviates from GeNIe a little to allow for “default” (or unspecified) colours. This relies on assuming default colours are the intent if the formatting of a node has been left at GeNIe’s defaults. I’m not happy with this approach, but I can’t think of a better way to allow unspecified colours.

Other notable changes in this version include an expansion of some of the functions supported for compatibility with GeNIe’s functions, and the implementation of a simple probability of evidence function (Network -> Calculate Probability of Evidence). Worker-based inference is also back in this version. This involved cleaning up the compile step, which is a bit more robust (all of which is in the background only).

Changes:

  • Fixed worker-based inference, when changes have been made to network
  • Support for .dne comments
  • Fixed menu markers
  • Added support for node colours and formats
    • Read in from .xdsl files
    • Fix editing of formatting controls
    • Save format changes to .xdsl file
    • Added a simple regression test (requires visual verification)
  • Probability of Evidence (simple, slow version)
  • Added support for the same function-form logical operators as GeNIe (And, Or, etc.). No “Not”, because there’s none in GeNIe.
  • Support for further functions (arithmetic)

Make-Believe (R17): Resumption

After a small (unexpected) break, I’m getting back to fortnightly updates of Make-Believe. While it’s been a while since the last post, I have been making changes to the code, so there’s a few extra things in this update. Firstly, there are some bug fixes to really silly regressions that had snuck in. As a consequence, there are also a first set of regression tests now to help make future versions a touch more reliable.

It’s possible to switch between belief bar and labelled box view. This is experimental, but should work fine. The main issue is I need to rework arrow drawing to handle different node shapes. (But it works pretty well nonetheless.)

It’s now possible to view and change node equations and comments. Changes are saved to .xdsl files.

Farcinfluenceinally, a very experimental and rough visualisation under View -> Show Arc Strengths. This shows the proportion of a child’s entropy that each parent would reduce if evidence in that parent were set. This is also conditional on the current evidence in the network, which is kind of neat, because you can see (for example) the effect of evidence on d-separation/d-connection. As mentioned, it’s still experimental, so things can get a little comical with oversized arrowheads and the like. (SVG markers are not as flexible as I’d like.)

One current issue is that I’ve had to disable worker-based inference, until I’ve cleaned up a few things.

Changes:

  • Fixed entering evidence in first state (should have been ‘if undefined’ not ‘if 0’)
  • TESTING: Created testing file (makeBelieveTests.js), and added an initial test
  • TESTING: Added click-to-update test. Accuracy may be an issue for reproducibility
  • TESTING: Added running tests to debug menu
  • For very small iterations, worker threads > iterations. Fixed to handle this properly
  • Auto-layout is now animated. (Using a slow method –can be much faster.)
  • Auto-layout animation with faster method. 🙂
  • Added a label-only view
  • Fixed: [bug] auto-layout, switching between distro/label view sometimes causes arrows to disappear
  • Prompt for node delete (in future, undo/redo makes this redundant/undesirable)
  • Allowed viewing of equation node definitions
  • Allowed setting the equation node definitions (with no validation)
  • Added comment reading/viewing from .xdsl file
  • Allow changing text in comments
  • Save comment to .xdsl file
  • Fixed decision network evaluation bustage (broken since had switched to worker threads as default)
  • TESTING: Added a simple regression test for decision networks
  • Very preliminary add node capability (backend only)
  • Arc weights based on % mutual info for children

 

Make-Believe (R16): Changes

cpt

Node context menu

Most of the changes in this version have to do with the ability to make changes to the network. So it’s now possible to rename nodes and delete nodes. This functionality can be found when right-clicking a node. Another change is that right-clicking brings up a menu relating to the node. I’m taking a slightly experimental approach with this. We’ll see how it works out. It’s certainly not settled.

One more thing added in this version is the ability to learn (CPT) parameters from data via counting. This works pretty straightforwardly, although only with tab delimited text files (.txt) at the moment. If it encounters a row with missing data, it can still learn a node’s CPT parameters, so long as there is complete data for the node and its parents in that row.

All of the above changes can be saved to file, though it’s all experimental as well, so I certainly wouldn’t rely on it!

Changes:

  • Initial right-click menu
  • Allow renaming nodes
  • Allow deleting nodes
  • Allow learning parameters from data via counting
  • Background changes to file organisation and small amount of cleanup

Make-Believe (R15): CPT Editing

A very small update this time, although in a way it’s one of the more substantial changes to the direction of the software.

In the past, when you double clicked an ordinary discrete node, a dialog would pop up with the probabilities in the CPT. This still happens, but the numbers are now actually labelled and you can edit them. There’s no validation there at the moment, so if you enter nonsense, it will still try to run the network with whatever you’ve entered. What you edit will also get saved to file — and again, if you enter nonsense, who knows what can happen! (Actually, it will probably just result in a file you can’t open.)

One thing I’ve implemented here is that as soon as you click ‘Save’, the network will try to run the inference again. This will no doubt be annoying for large networks, but for small networks it tightens the ‘try it and see’ loop. I’ll put in a setting at some later stage to control this.

Changes:

  • Added headers, parent state combination names to CPT view (double-click to view)
  • Allow editing of CPT

Make-Believe (R14): Initial Netica .dne support

For a little while, I’ve been wanting to add support for Netica .dne files, and I’ve managed to finally land something. The support is very crude (even cruder than for GeNIe .xdsl files) and probably very flaky. There’s only support for basic networks with discrete chance nodes — no support at all for deterministic nodes, equations, decision nodes, utility nodes or dynamic nodes (as there is for GeNIe files).

I included another one of my side-projects in order to get this support, namely a parser. I ought to write a separate post about the parser at some point, but in short, it’s meant to be a very quick way to use a grammar (with embedded regular expression support) to transform an input source into not just a syntax tree, but something that more closely represents the final desired object model. It’s not quite there yet, but it’s certainly good enough to do the parsing work needed here.

Anyway, here’s the 14th release of Make-Believe:

Changes:

  • Initial Netica .dne support for basic networks (discrete chance nodes only!)
  • Update beliefs immediately on BN loaded from query string

Make-Believe (R13): Working Workers

I finally have workers performing inference as quickly as on the main thread. This means workers now actually speed up the inference, with some substantial speed improvements as you move up to 4-8 cores. In fact, updating speed is no longer simply comparable to GeNIe, but can run quite a bit faster — OK, you should take that with a large grain of salt, because it’s BN-dependent, I’m not testing if the output variance is the same, and I’m just testing with the same number of sample iterations.

One nice side-effect of this is that I can finally unify the main-thread and worker-thread implementations. This may encourage me to clean the code organisation up a little bit. I hope.

2 workers are enabled by default for now. To change this number, go to the ‘Debug’ menu. It’s best to set the number equal to or slightly lower than the number of CPUs/cores that you have.

Changes:

  • Made worker-based belief update run as quickly as main thread update
    • (The solution was to recreate BNs on the worker side, rather than pass in via structured clone. I’m unaware as to why this is needed, since the structures (TypedArrays, etc.) were identical as far as I could tell. This was the case on both Firefox and Chrome, so it’s obviously something I missed.)
  • Enabled worker-based belief updating by default
  • Added a ‘Debug’ menu
    • (Mostly just performance-testing options.)
  • Performance tweaks to continuous variables