dotnet / infer

Infer.NET is a framework for running Bayesian inference in graphical models
https://dotnet.github.io/infer/
MIT License
1.56k stars 229 forks source link

How to implement a dynamic bayes network with Infer.net? #99

Closed SebastianKapunkt closed 5 years ago

SebastianKapunkt commented 5 years ago

I want to build a Dynamic Bayes Network.

I am completly new to probalistic progamming, factor graphs and simulation. I came up with a small scenario with cats and mice. The cats and mice have a certain birthrate and deathrate, but also cats eat the mice. I came up with something close to a factor graph that I implemented with the Infer.Net modeling API. You can see an Image of it here https://github.com/SebastianKapunkt/urban-garden-mouse-cats/blob/master/KatzenM%C3%A4useFactorGraph.png (Its in german :D).

Now I want to know how many cats I need so that the mice population is stable. For that I to continously see the populaiton change of both. Currently I just have a uggly version of this and I am also not quite sure if the model that I build is build the infer.net way.

You can find all my code in this repository: https://github.com/SebastianKapunkt/urban-garden-mouse-cats

In the file RunCarAndMouseModel.cs is all the code that will run the Model and the value I came up by researching the internet (my expoert knowgled of this case :D). In the other files is the code to create the model with its rules.

Some more question I have:

tminka commented 5 years ago

The method ContiniousView has a loop that creates 15 distinct models and runs inference in them. But the only difference in those models is two numbers. A better approach is to create a single model and use ObservedValues for those two changing numbers, as explained in the Truncated Gaussian tutorial.

Another problem with your approach is that it only does a crude form of forward filtering. If you want to correctly infer the evolution of the populations as a time series, then you need to create a Markov chain model, as explained in the user guide.

tminka commented 5 years ago

Another problem that I see in your code is that you are repeatedly creating a model, calling Infer, then passing that value into another model. That is inefficient and inaccurate. It is better to create one big model and then call Infer once.

SebastianKapunkt commented 5 years ago

Thanks for your advice! I could rewrite my model so it just compiles once. So the "big" model question is done :) SebastianKapunkt/urban-garden-mouse-cats@d4f5a9a

In the second commit I changed the code so I use JaggedArrays to kinda make a Markov chain. https://github.com/SebastianKapunkt/urban-garden-mouse-cats/commit/a11a86b5368e154222909f60f0e74f06db41ed95

@tminka would you be so kind and take a look at the code if I did it the right way?

So for now I can run the model. It builds just once and I linked the model iterations, but the values feel wrong, the variance is kinda big. (I also get the warning: This model will consume a lot of memory due to the following mix of indexing expressions inside of a conditional: vdouble0[0, 0], vdouble0[0, 1] --- could this be because I designed the model wrong?)

tminka commented 5 years ago

The revised code looks fine to me. If you want to avoid the warning, then use two 1D arrays instead of two columns of a 2D array. Also, instead of Variable.Random<double, Gaussian> you can use Variable<double>.Random.