(*
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().Named("bag1")
let mutable bag2 = Variable.New().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(``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)``