locked
Expanding on the coin flip example (Migrated from community.research.microsoft.com) RRS feed

  • Question

  • David White posted on 07-03-2010 11:21 AM

    The coin flip example is a great hello world example for this framework. In looking at the other examples they just past a critical spot in learning for me and that is handling the next step is understanding how to best set up the framework for problems like returning probabilities of runs. Using loops and other structures.

    Maybe I missed an example or a post in the forums but does someone have an example of looking for getting the odds of n repeated (runs) heads/tails over n repeated series attempts? I think a simple example like this could be a great second step in learning how to handle programming issues with the framework.

    I would love to have any hints tips or pointers on best practices on this kind of problem, and yes I have read the documentation. Maybe I'm stuck on stupid, usually great examples get me past it.

    Regards,

     

     

     

    Friday, June 3, 2011 5:54 PM

Answers

  • DavidKnowles replied on 07-05-2010 10:36 AM

    The problem you describe: calculating the probability of getting a run of R heads when flipping N coins can be solved analytically using recursive formula, see for example:

    http://mathdl.maa.org/mathDL/22/?pa=content&sa=viewDocument&nodeId=2681

    As a result, trying to solve this problem using approximate inference methods such as those provided by Infer.NET should be seen only as an exercise. The following code will do it for you, although it is quite memory expensive since you need a factor for each possible location of a run. For this example (R=6, N=200) Infer.NET gives .95, whereas the exact answer is .80. 

     int numCoins = 200;
    var n = new Range(numCoins);
    var coins = Variable.Array<bool>(n);
    coins[n] = Variable.Bernoulli(.5).ForEach(n);
    int runLength = 6;
    var indices0 = new int[runLength];
    for (int j = 0; j < runLength; j++)
        indices0[j] = 0 + j;
    var indicesVar0 = Variable.Constant(indices0);
    var allHeadsTotal = Variable.AllTrue(Variable.Subarray(coins, indicesVar0));~

    for (int i = 1; i <= numCoins - runLength; i++)
    {
        var indices = new int[runLength];
        for (int j = 0; j < runLength; j++)
            indices[j] = i + j;
        var indicesVar = Variable.Constant(indices);
        var allHeads = Variable.AllTrue(Variable.Subarray(coins, indicesVar));
        allHeadsTotal |= allHeads; 
    }
    var engine = new InferenceEngine();
    Bernoulli result = engine.Infer<Bernoulli>(allHeadsTotal);
    Console.WriteLine("P(run of length {0} in {1} flips) = {2}", runLength, numCoins, result.GetProbTrue());

     

     

    Friday, June 3, 2011 5:54 PM

All replies

  • jwinn replied on 07-05-2010 4:58 AM

    We don't have this example in the tutorials, but it is covered in this talk:
    http://microsoftpdc.com/Sessions/VTL03

    We're looking to improve the documentation in this area so we may put in an example like this to help with the learning curve.

    Thanks for the feedback,

    Best,
    John W.

    Friday, June 3, 2011 5:54 PM
  • David White replied on 07-05-2010 8:37 AM

    Thanks for your pointer to your talk. Since you don't have an example yet, can you give a snippit that would show the logic around using returning the probability of lets say n1-n20 head run/clump in a 10,000 unit test instead of hard coding coin1 coin2 coin 3 coin4 coin5 coin6 etc.) That is the base concept I am missing.

    I didn't see your code from your talk anywhere so I typed it in below.

    private void Form1_Load(object sender, EventArgs e)

    {

     

     

     

    // *********** Probabilistic Program ***********

     

     

     

    var firstcoin = Variable

    .Bernoulli(0.5);

     

     

     

    var secondcoin = Variable

    .Bernoulli(0.5);

     

     

     

    var

    bothHeads = firstcoin & secondcoin;

     

     

     

    // *********************************************

     

     

     

    var engine = new InferenceEngine {ShowProgress = false

    };

     

     

     

    Bernoulli result = engine.Infer<Bernoulli

    >(bothHeads);

     

     

     

    Double

    probTrue = result.GetProbTrue();

     

     

     

    Console.WriteLine("P(bothHeads=true) = {0}%"

    , 100 * probTrue);

     

     

     

    //Adding and observation = false

    bothHeads.ObservedValue =

     

     

    false

    ;

     

     

     

    Console.WriteLine("P (firstCoin=true | bothHeads = false) = {0}%"

    ,

    100 * engine.Infer<

     

     

    Bernoulli

    >(firstcoin).GetProbTrue());

     

     

     

    Console.WriteLine("Program completed run"

    );

    Friday, June 3, 2011 5:54 PM
  • DavidKnowles replied on 07-05-2010 10:36 AM

    The problem you describe: calculating the probability of getting a run of R heads when flipping N coins can be solved analytically using recursive formula, see for example:

    http://mathdl.maa.org/mathDL/22/?pa=content&sa=viewDocument&nodeId=2681

    As a result, trying to solve this problem using approximate inference methods such as those provided by Infer.NET should be seen only as an exercise. The following code will do it for you, although it is quite memory expensive since you need a factor for each possible location of a run. For this example (R=6, N=200) Infer.NET gives .95, whereas the exact answer is .80. 

     int numCoins = 200;
    var n = new Range(numCoins);
    var coins = Variable.Array<bool>(n);
    coins[n] = Variable.Bernoulli(.5).ForEach(n);
    int runLength = 6;
    var indices0 = new int[runLength];
    for (int j = 0; j < runLength; j++)
        indices0[j] = 0 + j;
    var indicesVar0 = Variable.Constant(indices0);
    var allHeadsTotal = Variable.AllTrue(Variable.Subarray(coins, indicesVar0));~

    for (int i = 1; i <= numCoins - runLength; i++)
    {
        var indices = new int[runLength];
        for (int j = 0; j < runLength; j++)
            indices[j] = i + j;
        var indicesVar = Variable.Constant(indices);
        var allHeads = Variable.AllTrue(Variable.Subarray(coins, indicesVar));
        allHeadsTotal |= allHeads; 
    }
    var engine = new InferenceEngine();
    Bernoulli result = engine.Infer<Bernoulli>(allHeadsTotal);
    Console.WriteLine("P(run of length {0} in {1} flips) = {2}", runLength, numCoins, result.GetProbTrue());

     

     

    Friday, June 3, 2011 5:54 PM