4 people like it.
Like the snippet!
Bayesian Inference with Infer.Net: M&M problem
Solve a sample problem from the book "Think Bayes" by Allen B. Downey. Shows how the problem can be modeled with Infer.Net and also provide the manual solution as presented in the book. The code relies on the Infer.Net "FSharpWrapper" project which is not included in the nuget package (as of now).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
|
(*
In 1995, they introduced blue M&M’s. Before then, the color mix in a bag of plain M&M’s was
30% Brown, 20% Yellow, 20% Red, 10% Green, 10% Orange, 10% Tan.
Afterward it was 24% Blue, 20% Green, 16% Orange, 14% Yellow, 13% Red, 13% Brown.
Suppose a friend of mine has two bags of M&M’s, and he tells me that one is from 1994 and one from 1996.
He won’t tell me which is which, but he gives me one M&M from each bag.
One is yellow and one is green. What is the probability that the yellow one came from the 1994 bag?
Downey, Allen B.. Think Bayes . O'Reilly Media. Kindle Edition.
*)
#r "nuget: Microsoft.ML.Probabilistic.Compiler.Visualizers.Windows"
#r @"../FsharpWrapper/bin/Debug/net48/Microsoft.ML.Probabilistic.FSharp.dll" //need to compile this from infer.net source
open Microsoft.ML.Probabilistic.Models
open Microsoft.ML.Probabilistic.FSharp
open Microsoft.ML.Probabilistic.Distributions
type Cls = Br | Bl | Y | R | G | T | O
let check ls = (ls |> List.sumBy snd) - 1.0 |> abs < 0.000000001
let ``1994 mix`` = [Br, 0.3; Y, 0.2; R, 0.2; G, 0.1; O, 0.1; T, 0.1; Bl, 0.0]
let ``1996 mix`` = [Br,0.13; Y,0.14; R,0.13; G,0.20; O,0.16; T, 0.0; Bl,0.24]
check ``1994 mix``
check ``1996 mix``
let bag94Mix() = ``1994 mix`` |> Seq.map snd |> Seq.toArray |> Variable.Discrete
let bag96Mix() = ``1996 mix`` |> Seq.map snd |> Seq.toArray |> Variable.Discrete
let mutable bag1 = Variable.New<int>().Named("bag1")
let mutable bag2 = Variable.New<int>().Named("bag2")
let ``p(bag1=94)`` = Variable.Bernoulli(0.5).Named("p(bag1=94)")
Variable.IfBlock ``p(bag1=94)``
(fun _ -> bag94Mix() |> bag1.SetTo; bag96Mix() |> bag2.SetTo)
(fun _ -> bag96Mix() |> bag1.SetTo; bag94Mix() |> bag2.SetTo)
bag1.ObservedValue <- 1 //Y
bag2.ObservedValue <- 3 //G
let ie = InferenceEngine()
ie.ShowFactorGraph <- true //need to install graphviz s.t. 'dot' command is available
let ``p(bag1=94)_posterior`` = ie.Infer<Bernoulli>(``p(bag1=94)``) //, Microsoft.ML.Probabilistic.QueryTypes.Samples)
module ManualMethod =
//manual approach using the 'table' method (see book ref above)
let ``p(bag1=94)`` = 0.5
let ``p(H|D,bag1=94)`` = 0.2 * 0.2 //likelihoods
let ``p(H|D,bag1=96)`` = 0.14 * 0.1
let caseA_unormailzied = ``p(bag1=94)`` * ``p(H|D,bag1=94)``
let caseB_unormalized = (1.0 - ``p(bag1=94)``) * ``p(H|D,bag1=96)``
let ``p(D)`` = caseA_unormailzied + caseB_unormalized
let ``p(D|H,bag1=94)`` = caseA_unormailzied / ``p(D)``
|
namespace Microsoft
type Cls =
| Br
| Bl
| Y
| R
| G
| T
| O
union case Cls.Br: Cls
union case Cls.Bl: Cls
union case Cls.Y: Cls
union case Cls.R: Cls
union case Cls.G: Cls
union case Cls.T: Cls
union case Cls.O: Cls
val check : ls:('a * float) list -> bool
val ls : ('a * float) list
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex : rank:int * offset:int -> int
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
...
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)
val snd : tuple:('T1 * 'T2) -> 'T2
val abs : value:'T -> 'T (requires member Abs)
val ( 1994 mix ) : (Cls * float) list
val ( 1996 mix ) : (Cls * float) list
val bag94Mix : unit -> 'a
module Seq
from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
val toArray : source:seq<'T> -> 'T []
val bag96Mix : unit -> 'a
val mutable bag1 : obj
Multiple items
val int : value:'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val mutable bag2 : obj
val ( p(bag1=94) ) : obj
val ie : obj
val ( p(bag1=94)_posterior ) : obj
module ManualMethod
from Script
Multiple items
val ( p(bag1=94) ) : float
--------------------
val ( p(bag1=94) ) : obj
val ( p(H|D,bag1=94) ) : float
val ( p(H|D,bag1=96) ) : float
val caseA_unormailzied : float
val ( p(bag1=94) ) : float
val caseB_unormalized : float
val ( p(D) ) : float
val ( p(D|H,bag1=94) ) : float
More information