public Proposition GetProposition(object owner, IContextLookup globalVars, IDictionary <string, RandomVariable> randomVariables) { switch (PropositionType) { case PropositionType.RandomVariable: case PropositionType.Assignment: RandomVariable randomVar; if (!randomVariables.TryGetValue(RandomVariable, out randomVar)) { throw new ApplicationException("Missing variable " + RandomVariable); } switch (PropositionType) { case PropositionType.RandomVariable: return((Proposition)randomVar); case PropositionType.Assignment: var objValue = Value.EvaluateTyped(owner, globalVars); return(new AssignmentProposition(randomVar, objValue)); default: throw new ArgumentOutOfRangeException(); } case PropositionType.Dysjunctive: case PropositionType.Conjunctive: if (Children.Count > 0) { Proposition newPropositionInfo = null; foreach (PropositionInfo assignmentPropositionInfo in Children) { var objAssignment = assignmentPropositionInfo.GetProposition(owner, globalVars, randomVariables); if (newPropositionInfo == null) { newPropositionInfo = objAssignment; } else { if (PropositionType == PropositionType.Conjunctive) { newPropositionInfo = new ConjunctiveProposition(newPropositionInfo, objAssignment); } else { newPropositionInfo = new DisjunctiveProposition(newPropositionInfo, objAssignment); } } } return(newPropositionInfo); } else { throw new ArgumentOutOfRangeException(); } default: throw new ArgumentOutOfRangeException(); } }
public virtual double posterior(IProposition phi, params IProposition[] evidence) { IProposition conjEvidence = ProbUtil.constructConjunction(evidence); // P(A | B) = P(A AND B)/P(B) - (13.3 AIMA3e) IProposition aAndB = new ConjunctiveProposition(phi, conjEvidence); double probabilityOfEvidence = prior(conjEvidence); if (0 != probabilityOfEvidence) { return(prior(aAndB) / probabilityOfEvidence); } return(0); }
// // PROTECTED METHODS // protected void test_RollingPairFairDiceModel(IProbabilityModel model) { Assert.IsTrue(model.isValid()); // Ensure each dice has 1/6 probability for (int d = 1; d <= 6; d++) { AssignmentProposition ad1 = new AssignmentProposition( ExampleRV.DICE_1_RV, d); AssignmentProposition ad2 = new AssignmentProposition( ExampleRV.DICE_2_RV, d); Assert.AreEqual(1.0 / 6.0, model.prior(ad1), DELTA_THRESHOLD); Assert.AreEqual(1.0 / 6.0, model.prior(ad2), DELTA_THRESHOLD); } // Ensure each combination is 1/36 for (int d1 = 1; d1 <= 6; d1++) { for (int d2 = 1; d2 <= 6; d2++) { AssignmentProposition ad1 = new AssignmentProposition( ExampleRV.DICE_1_RV, d1); AssignmentProposition ad2 = new AssignmentProposition( ExampleRV.DICE_2_RV, d2); ConjunctiveProposition d1AndD2 = new ConjunctiveProposition( ad1, ad2); Assert.AreEqual(1.0 / 6.0, model.prior(ad1), DELTA_THRESHOLD); Assert.AreEqual(1.0 / 6.0, model.prior(ad2), DELTA_THRESHOLD); // pg. 485 AIMA3e Assert.AreEqual(1.0 / 36.0, model.prior(ad1, ad2), DELTA_THRESHOLD); Assert.AreEqual(1.0 / 36.0, model.prior(d1AndD2), DELTA_THRESHOLD); Assert.AreEqual(1.0 / 6.0, model.posterior(ad1, ad2), DELTA_THRESHOLD); Assert.AreEqual(1.0 / 6.0, model.posterior(ad2, ad1), DELTA_THRESHOLD); } } // Test Sets of events defined via constraint propositions IntegerSumProposition total11 = new IntegerSumProposition("Total11", new FiniteIntegerDomain(11), ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV); Assert.AreEqual(2.0 / 36.0, model.prior(total11), DELTA_THRESHOLD); EquivalentProposition doubles = new EquivalentProposition("Doubles", ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV); Assert.AreEqual(1.0 / 6.0, model.prior(doubles), DELTA_THRESHOLD); SubsetProposition evenDice1 = new SubsetProposition("EvenDice1", new FiniteIntegerDomain(2, 4, 6), ExampleRV.DICE_1_RV); Assert.AreEqual(0.5, model.prior(evenDice1), DELTA_THRESHOLD); SubsetProposition oddDice2 = new SubsetProposition("OddDice2", new FiniteIntegerDomain(1, 3, 5), ExampleRV.DICE_2_RV); Assert.AreEqual(0.5, model.prior(oddDice2), DELTA_THRESHOLD); // pg. 485 AIMA3e AssignmentProposition dice1Is5 = new AssignmentProposition( ExampleRV.DICE_1_RV, 5); Assert.AreEqual(1.0 / 6.0, model.posterior(doubles, dice1Is5), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.prior(ExampleRV.DICE_1_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.prior(ExampleRV.DICE_2_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.DICE_2_RV, ExampleRV.DICE_1_RV), DELTA_THRESHOLD); // Test a disjunctive proposition pg.489 // P(a OR b) = P(a) + P(b) - P(a AND b) // = 1/6 + 1/6 - 1/36 AssignmentProposition dice2Is5 = new AssignmentProposition( ExampleRV.DICE_2_RV, 5); DisjunctiveProposition dice1Is5OrDice2Is5 = new DisjunctiveProposition( dice1Is5, dice2Is5); Assert.AreEqual(1.0 / 6.0 + 1.0 / 6.0 - 1.0 / 36.0, model.prior(dice1Is5OrDice2Is5), DELTA_THRESHOLD); }
// AIMA3e pg. 488, 494 protected void test_ToothacheCavityCatchWeatherModel(IProbabilityModel model) { // Should be able to run all the same queries for this independent // sub model. test_ToothacheCavityCatchModel(model); // AIMA3e pg. 486 AssignmentProposition asunny = new AssignmentProposition( ExampleRV.WEATHER_RV, "sunny"); AssignmentProposition arain = new AssignmentProposition( ExampleRV.WEATHER_RV, "rain"); AssignmentProposition acloudy = new AssignmentProposition( ExampleRV.WEATHER_RV, "cloudy"); AssignmentProposition asnow = new AssignmentProposition( ExampleRV.WEATHER_RV, "snow"); Assert.AreEqual(0.6, model.prior(asunny), DELTA_THRESHOLD); Assert.AreEqual(0.1, model.prior(arain), DELTA_THRESHOLD); Assert.AreEqual(0.29, model.prior(acloudy), DELTA_THRESHOLD); Assert.AreEqual(0.01, model.prior(asnow), DELTA_THRESHOLD); // AIMA3e pg. 488 // P(sunny, cavity) // P(sunny AND cavity) AssignmentProposition atoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, true); AssignmentProposition acatch = new AssignmentProposition( ExampleRV.CATCH_RV, true); AssignmentProposition acavity = new AssignmentProposition( ExampleRV.CAVITY_RV, true); ConjunctiveProposition sunnyAndCavity = new ConjunctiveProposition( asunny, acavity); // 0.6 (sunny) * 0.2 (cavity) = 0.12 Assert.AreEqual(0.12, model.prior(asunny, acavity), DELTA_THRESHOLD); Assert.AreEqual(0.12, model.prior(sunnyAndCavity), DELTA_THRESHOLD); // AIMA3e pg. 494 // P(toothache, catch, cavity, cloudy) = // P(cloudy | toothache, catch, cavity)P(toothache, catch, cavity) Assert.AreEqual( model.prior(atoothache, acatch, acavity, acloudy), model.posterior(acloudy, atoothache, acatch, acavity) * model.prior(atoothache, acatch, acavity), DELTA_THRESHOLD); ConjunctiveProposition toothacheAndCatchAndCavityAndCloudy = new ConjunctiveProposition( new ConjunctiveProposition(atoothache, acatch), new ConjunctiveProposition(acavity, acloudy)); ConjunctiveProposition toothacheAndCatchAndCavity = new ConjunctiveProposition( new ConjunctiveProposition(atoothache, acatch), acavity); Assert.AreEqual( model.prior(toothacheAndCatchAndCavityAndCloudy), model.posterior(acloudy, atoothache, acatch, acavity) * model.prior(toothacheAndCatchAndCavity), DELTA_THRESHOLD); // P(cloudy | toothache, catch, cavity) = P(cloudy) // (13.10) Assert.AreEqual( model.posterior(acloudy, atoothache, acatch, acavity), model.prior(acloudy), DELTA_THRESHOLD); // P(toothache, catch, cavity, cloudy) = // P(cloudy)P(tootache, catch, cavity) Assert.AreEqual( model.prior(atoothache, acatch, acavity, acloudy), model.prior(acloudy) * model.prior(atoothache, acatch, acavity), DELTA_THRESHOLD); // P(a | b) = P(a) Assert.AreEqual(model.posterior(acavity, acloudy), model.prior(acavity), DELTA_THRESHOLD); // P(b | a) = P(b) Assert.AreEqual(model.posterior(acloudy, acavity), model.prior(acloudy), DELTA_THRESHOLD); // P(a AND b) = P(a)P(b) Assert.AreEqual(model.prior(acavity, acloudy), model.prior(acavity) * model.prior(acloudy), DELTA_THRESHOLD); ConjunctiveProposition acavityAndacloudy = new ConjunctiveProposition( acavity, acloudy); Assert.AreEqual(model.prior(acavityAndacloudy), model.prior(acavity) * model.prior(acloudy), DELTA_THRESHOLD); }
protected void test_ToothacheCavityCatchModel(IProbabilityModel model) { Assert.IsTrue(model.isValid()); AssignmentProposition atoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, true); AssignmentProposition anottoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, false); AssignmentProposition acavity = new AssignmentProposition( ExampleRV.CAVITY_RV, true); AssignmentProposition anotcavity = new AssignmentProposition( ExampleRV.CAVITY_RV, false); AssignmentProposition acatch = new AssignmentProposition( ExampleRV.CATCH_RV, true); AssignmentProposition anotcatch = new AssignmentProposition( ExampleRV.CATCH_RV, false); // AIMA3e pg. 485 Assert.AreEqual(0.2, model.prior(acavity), DELTA_THRESHOLD); Assert.AreEqual(0.6, model.posterior(acavity, atoothache), DELTA_THRESHOLD); ConjunctiveProposition toothacheAndNotCavity = new ConjunctiveProposition( atoothache, anotcavity); Assert.AreEqual(0.0, model.posterior(acavity, toothacheAndNotCavity), DELTA_THRESHOLD); Assert.AreEqual(0.0, model.posterior(acavity, atoothache, anotcavity), DELTA_THRESHOLD); // AIMA3e pg. 492 DisjunctiveProposition cavityOrToothache = new DisjunctiveProposition( acavity, atoothache); Assert.AreEqual(0.28, model.prior(cavityOrToothache), DELTA_THRESHOLD); // AIMA3e pg. 493 Assert.AreEqual(0.4, model.posterior(anotcavity, atoothache), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.prior(ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.prior(ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.prior(ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CATCH_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.AreEqual(1.0, model.posterior(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); // AIMA3e pg. 495 - Bayes' Rule // P(b|a) = P(a|b)P(b)/P(a) Assert.AreEqual(model.posterior(acavity, atoothache), (model.posterior(atoothache, acavity) * model.prior(acavity)) / model.prior(atoothache), DELTA_THRESHOLD); Assert.AreEqual( model.posterior(acavity, anottoothache), (model.posterior(anottoothache, acavity) * model.prior(acavity)) / model.prior(anottoothache), DELTA_THRESHOLD); Assert.AreEqual( model.posterior(anotcavity, atoothache), (model.posterior(atoothache, anotcavity) * model .prior(anotcavity)) / model.prior(atoothache), DELTA_THRESHOLD); Assert.AreEqual( model.posterior(anotcavity, anottoothache), (model.posterior(anottoothache, anotcavity) * model .prior(anotcavity)) / model.prior(anottoothache), DELTA_THRESHOLD); // Assert.AreEqual(model.posterior(acavity, acatch), (model.posterior(acatch, acavity) * model.prior(acavity)) / model.prior(acatch), DELTA_THRESHOLD); Assert.AreEqual(model.posterior(acavity, anotcatch), (model.posterior(anotcatch, acavity) * model.prior(acavity)) / model.prior(anotcatch), DELTA_THRESHOLD); Assert.AreEqual(model.posterior(anotcavity, acatch), (model.posterior(acatch, anotcavity) * model.prior(anotcavity)) / model.prior(acatch), DELTA_THRESHOLD); Assert.AreEqual( model.posterior(anotcavity, anotcatch), (model.posterior(anotcatch, anotcavity) * model .prior(anotcavity)) / model.prior(anotcatch), DELTA_THRESHOLD); }
protected void test_ToothacheCavityCatchModel_Distributions(IFiniteProbabilityModel model) { AssignmentProposition atoothache = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, true); AssignmentProposition anottoothache = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, false); AssignmentProposition acatch = new AssignmentProposition(ExampleRV.CATCH_RV, true); AssignmentProposition anotcatch = new AssignmentProposition(ExampleRV.CATCH_RV, false); // AIMA3e pg. 493 // P<>(Cavity | toothache) = <0.6, 0.4> assertArrayEquals(new double[] { 0.6, 0.4 }, model .posteriorDistribution(ExampleRV.CAVITY_RV, atoothache) .getValues(), DELTA_THRESHOLD); // AIMA3e pg. 497 // P<>(Cavity | toothache AND catch) = <0.871, 0.129> assertArrayEquals(new double[] { 0.8709677419354839, 0.12903225806451615 }, model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache, acatch).getValues(), DELTA_THRESHOLD); // AIMA3e pg. 498 // (13.17) // P<>(toothache AND catch | Cavity) // = P<>(toothache | Cavity)P<>(catch | Cavity) ConjunctiveProposition toothacheAndCatch = new ConjunctiveProposition(atoothache, acatch); assertArrayEquals(model.posteriorDistribution(toothacheAndCatch, ExampleRV.CAVITY_RV).getValues(), model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV) .multiplyBy( model.posteriorDistribution(acatch, ExampleRV.CAVITY_RV)).getValues(), DELTA_THRESHOLD); // (13.18) // P<>(Cavity | toothache AND catch) // = αP<>(toothache | Cavity)P<>(catch | Cavity)P(Cavity) assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV, toothacheAndCatch).getValues(), model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV) .multiplyBy( model.posteriorDistribution(acatch, ExampleRV.CAVITY_RV)) .multiplyBy( model.priorDistribution(ExampleRV.CAVITY_RV)) .normalize().getValues(), DELTA_THRESHOLD); // (13.19) // P<>(Toothache, Catch | Cavity) // = P<>(Toothache | Cavity)P<>(Catch | Cavity) ConjunctiveProposition toothacheAndCatchRV = new ConjunctiveProposition(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV); assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV, ExampleRV.CAVITY_RV).getValues(), model.posteriorDistribution(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV) .multiplyByPOS( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV), ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(), DELTA_THRESHOLD); // (product rule) // P<>(Toothache, Catch, Cavity) // = P<>(Toothache, Catch | Cavity)P<>(Cavity) assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(), model.posteriorDistribution(toothacheAndCatchRV, ExampleRV.CAVITY_RV) .multiplyBy( model.priorDistribution(ExampleRV.CAVITY_RV)) .getValues(), DELTA_THRESHOLD); // (using 13.19) // P<>(Toothache, Catch | Cavity)P<>(Cavity) // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity) assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV, ExampleRV.CAVITY_RV) .multiplyBy( model.priorDistribution(ExampleRV.CAVITY_RV)) .getValues(), model.posteriorDistribution(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV) .multiplyByPOS( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV) .multiplyBy( model.priorDistribution(ExampleRV.CAVITY_RV)), ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(), DELTA_THRESHOLD); // // P<>(Toothache, Catch, Cavity) // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity) assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(), model.posteriorDistribution(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV) .multiplyByPOS( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV), ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV) .multiplyBy( model.priorDistribution(ExampleRV.CAVITY_RV)) .getValues(), DELTA_THRESHOLD); // AIMA3e pg. 496 // General case of Bayes' Rule // P<>(Y | X) = P<>(X | Y)P<>(Y)/P<>(X) // Note: Performing in this order - // P<>(Y | X) = (P<>(Y)P<>(X | Y))/P<>(X) // as default multiplication of distributions are not commutative (could // also use pointwiseProductPOS() to specify the order). assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV).getValues(), model.priorDistribution(ExampleRV.CAVITY_RV) .multiplyBy( model.posteriorDistribution( ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV)) .divideBy( model.priorDistribution(ExampleRV.TOOTHACHE_RV)) .getValues(), DELTA_THRESHOLD); assertArrayEquals( model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV).getValues(), model.priorDistribution(ExampleRV.CAVITY_RV) .multiplyBy( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV)) .divideBy(model.priorDistribution(ExampleRV.CATCH_RV)) .getValues(), DELTA_THRESHOLD); // General Bayes' Rule conditionalized on background evidence e (13.3) // P<>(Y | X, e) = P<>(X | Y, e)P<>(Y|e)/P<>(X | e) // Note: Performing in this order - // P<>(Y | X, e) = (P<>(Y|e)P<>(X | Y, e)))/P<>(X | e) // as default multiplication of distributions are not commutative (could // also use pointwiseProductPOS() to specify the order). assertArrayEquals( model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV, acatch).getValues(), model.posteriorDistribution(ExampleRV.CAVITY_RV, acatch) .multiplyBy( model.posteriorDistribution( ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV, acatch)) .divideBy( model.posteriorDistribution( ExampleRV.TOOTHACHE_RV, acatch)) .getValues(), DELTA_THRESHOLD); // assertArrayEquals( model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV, anotcatch).getValues(), model.posteriorDistribution(ExampleRV.CAVITY_RV, anotcatch) .multiplyBy( model.posteriorDistribution( ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV, anotcatch)) .divideBy( model.posteriorDistribution( ExampleRV.TOOTHACHE_RV, anotcatch)) .getValues(), DELTA_THRESHOLD); // assertArrayEquals( model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV, atoothache).getValues(), model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache) .multiplyBy( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV, atoothache)) .divideBy( model.posteriorDistribution(ExampleRV.CATCH_RV, atoothache)).getValues(), DELTA_THRESHOLD); assertArrayEquals( model.posteriorDistribution(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV, anottoothache).getValues(), model.posteriorDistribution(ExampleRV.CAVITY_RV, anottoothache) .multiplyBy( model.posteriorDistribution(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV, anottoothache)) .divideBy( model.posteriorDistribution(ExampleRV.CATCH_RV, anottoothache)).getValues(), DELTA_THRESHOLD); }