package aima.test.core.unit.probability; import org.junit.Assert; import aima.core.probability.ProbabilityModel; import aima.core.probability.domain.FiniteIntegerDomain; import aima.core.probability.example.ExampleRV; import aima.core.probability.proposition.AssignmentProposition; import aima.core.probability.proposition.ConjunctiveProposition; import aima.core.probability.proposition.DisjunctiveProposition; import aima.core.probability.proposition.EquivalentProposition; import aima.core.probability.proposition.IntegerSumProposition; import aima.core.probability.proposition.SubsetProposition; /** * @author Ciaran O'Reilly * */ public abstract class CommonProbabilityModelTests { public static final double DELTA_THRESHOLD = ProbabilityModel.DEFAULT_ROUNDING_THRESHOLD; // // PROTECTED METHODS // protected void test_RollingPairFairDiceModel(ProbabilityModel model) { Assert.assertTrue(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.assertEquals(1.0 / 6.0, model.prior(ad1), DELTA_THRESHOLD); Assert.assertEquals(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.assertEquals(1.0 / 6.0, model.prior(ad1), DELTA_THRESHOLD); Assert.assertEquals(1.0 / 6.0, model.prior(ad2), DELTA_THRESHOLD); // pg. 485 AIMA3e Assert.assertEquals(1.0 / 36.0, model.prior(ad1, ad2), DELTA_THRESHOLD); Assert.assertEquals(1.0 / 36.0, model.prior(d1AndD2), DELTA_THRESHOLD); Assert.assertEquals(1.0 / 6.0, model.posterior(ad1, ad2), DELTA_THRESHOLD); Assert.assertEquals(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.assertEquals(2.0 / 36.0, model.prior(total11), DELTA_THRESHOLD); EquivalentProposition doubles = new EquivalentProposition("Doubles", ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV); Assert.assertEquals(1.0 / 6.0, model.prior(doubles), DELTA_THRESHOLD); SubsetProposition evenDice1 = new SubsetProposition("EvenDice1", new FiniteIntegerDomain(2, 4, 6), ExampleRV.DICE_1_RV); Assert.assertEquals(0.5, model.prior(evenDice1), DELTA_THRESHOLD); SubsetProposition oddDice2 = new SubsetProposition("OddDice2", new FiniteIntegerDomain(1, 3, 5), ExampleRV.DICE_2_RV); Assert.assertEquals(0.5, model.prior(oddDice2), DELTA_THRESHOLD); // pg. 485 AIMA3e AssignmentProposition dice1Is5 = new AssignmentProposition( ExampleRV.DICE_1_RV, 5); Assert.assertEquals(1.0 / 6.0, model.posterior(doubles, dice1Is5), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.prior(ExampleRV.DICE_1_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.prior(ExampleRV.DICE_2_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV), DELTA_THRESHOLD); Assert.assertEquals(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.assertEquals(1.0 / 6.0 + 1.0 / 6.0 - 1.0 / 36.0, model.prior(dice1Is5OrDice2Is5), DELTA_THRESHOLD); } protected void test_ToothacheCavityCatchModel(ProbabilityModel model) { Assert.assertTrue(model.isValid()); AssignmentProposition atoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, Boolean.TRUE); AssignmentProposition anottoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, Boolean.FALSE); AssignmentProposition acavity = new AssignmentProposition( ExampleRV.CAVITY_RV, Boolean.TRUE); AssignmentProposition anotcavity = new AssignmentProposition( ExampleRV.CAVITY_RV, Boolean.FALSE); AssignmentProposition acatch = new AssignmentProposition( ExampleRV.CATCH_RV, Boolean.TRUE); AssignmentProposition anotcatch = new AssignmentProposition( ExampleRV.CATCH_RV, Boolean.FALSE); // AIMA3e pg. 485 Assert.assertEquals(0.2, model.prior(acavity), DELTA_THRESHOLD); Assert.assertEquals(0.6, model.posterior(acavity, atoothache), DELTA_THRESHOLD); ConjunctiveProposition toothacheAndNotCavity = new ConjunctiveProposition( atoothache, anotcavity); Assert.assertEquals(0.0, model.posterior(acavity, toothacheAndNotCavity), DELTA_THRESHOLD); Assert.assertEquals(0.0, model.posterior(acavity, atoothache, anotcavity), DELTA_THRESHOLD); // AIMA3e pg. 492 DisjunctiveProposition cavityOrToothache = new DisjunctiveProposition( acavity, atoothache); Assert.assertEquals(0.28, model.prior(cavityOrToothache), DELTA_THRESHOLD); // AIMA3e pg. 493 Assert.assertEquals(0.4, model.posterior(anotcavity, atoothache), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.prior(ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.prior(ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.prior(ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV), DELTA_THRESHOLD); Assert.assertEquals(1.0, model.posterior(ExampleRV.CATCH_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD); Assert.assertEquals(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.assertEquals(model.posterior(acavity, atoothache), (model.posterior(atoothache, acavity) * model.prior(acavity)) / model.prior(atoothache), DELTA_THRESHOLD); Assert.assertEquals( model.posterior(acavity, anottoothache), (model.posterior(anottoothache, acavity) * model.prior(acavity)) / model.prior(anottoothache), DELTA_THRESHOLD); Assert.assertEquals( model.posterior(anotcavity, atoothache), (model.posterior(atoothache, anotcavity) * model .prior(anotcavity)) / model.prior(atoothache), DELTA_THRESHOLD); Assert.assertEquals( model.posterior(anotcavity, anottoothache), (model.posterior(anottoothache, anotcavity) * model .prior(anotcavity)) / model.prior(anottoothache), DELTA_THRESHOLD); // Assert.assertEquals(model.posterior(acavity, acatch), (model.posterior(acatch, acavity) * model.prior(acavity)) / model.prior(acatch), DELTA_THRESHOLD); Assert.assertEquals(model.posterior(acavity, anotcatch), (model.posterior(anotcatch, acavity) * model.prior(acavity)) / model.prior(anotcatch), DELTA_THRESHOLD); Assert.assertEquals(model.posterior(anotcavity, acatch), (model.posterior(acatch, anotcavity) * model.prior(anotcavity)) / model.prior(acatch), DELTA_THRESHOLD); Assert.assertEquals( model.posterior(anotcavity, anotcatch), (model.posterior(anotcatch, anotcavity) * model .prior(anotcavity)) / model.prior(anotcatch), DELTA_THRESHOLD); } // AIMA3e pg. 488, 494 protected void test_ToothacheCavityCatchWeatherModel(ProbabilityModel 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.assertEquals(0.6, model.prior(asunny), DELTA_THRESHOLD); Assert.assertEquals(0.1, model.prior(arain), DELTA_THRESHOLD); Assert.assertEquals(0.29, model.prior(acloudy), DELTA_THRESHOLD); Assert.assertEquals(0.01, model.prior(asnow), DELTA_THRESHOLD); // AIMA3e pg. 488 // P(sunny, cavity) // P(sunny AND cavity) AssignmentProposition atoothache = new AssignmentProposition( ExampleRV.TOOTHACHE_RV, Boolean.TRUE); AssignmentProposition acatch = new AssignmentProposition( ExampleRV.CATCH_RV, Boolean.TRUE); AssignmentProposition acavity = new AssignmentProposition( ExampleRV.CAVITY_RV, Boolean.TRUE); ConjunctiveProposition sunnyAndCavity = new ConjunctiveProposition( asunny, acavity); // 0.6 (sunny) * 0.2 (cavity) = 0.12 Assert.assertEquals(0.12, model.prior(asunny, acavity), DELTA_THRESHOLD); Assert.assertEquals(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.assertEquals( 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.assertEquals( model.prior(toothacheAndCatchAndCavityAndCloudy), model.posterior(acloudy, atoothache, acatch, acavity) * model.prior(toothacheAndCatchAndCavity), DELTA_THRESHOLD); // P(cloudy | toothache, catch, cavity) = P(cloudy) // (13.10) Assert.assertEquals( model.posterior(acloudy, atoothache, acatch, acavity), model.prior(acloudy), DELTA_THRESHOLD); // P(toothache, catch, cavity, cloudy) = // P(cloudy)P(tootache, catch, cavity) Assert.assertEquals( model.prior(atoothache, acatch, acavity, acloudy), model.prior(acloudy) * model.prior(atoothache, acatch, acavity), DELTA_THRESHOLD); // P(a | b) = P(a) Assert.assertEquals(model.posterior(acavity, acloudy), model.prior(acavity), DELTA_THRESHOLD); // P(b | a) = P(b) Assert.assertEquals(model.posterior(acloudy, acavity), model.prior(acloudy), DELTA_THRESHOLD); // P(a AND b) = P(a)P(b) Assert.assertEquals(model.prior(acavity, acloudy), model.prior(acavity) * model.prior(acloudy), DELTA_THRESHOLD); ConjunctiveProposition acavityAndacloudy = new ConjunctiveProposition( acavity, acloudy); Assert.assertEquals(model.prior(acavityAndacloudy), model.prior(acavity) * model.prior(acloudy), DELTA_THRESHOLD); } // AIMA3e pg. 496 protected void test_MeningitisStiffNeckModel(ProbabilityModel model) { Assert.assertTrue(model.isValid()); AssignmentProposition ameningitis = new AssignmentProposition( ExampleRV.MENINGITIS_RV, true); AssignmentProposition anotmeningitis = new AssignmentProposition( ExampleRV.MENINGITIS_RV, false); AssignmentProposition astiffNeck = new AssignmentProposition( ExampleRV.STIFF_NECK_RV, true); AssignmentProposition anotstiffNeck = new AssignmentProposition( ExampleRV.STIFF_NECK_RV, false); // P(stiffNeck | meningitis) = 0.7 Assert.assertEquals(0.7, model.posterior(astiffNeck, ameningitis), DELTA_THRESHOLD); // P(meningitis) = 1/50000 Assert.assertEquals(0.00002, model.prior(ameningitis), DELTA_THRESHOLD); // P(~meningitis) = 1-1/50000 Assert.assertEquals(0.99998, model.prior(anotmeningitis), DELTA_THRESHOLD); // P(stiffNeck) = 0.01 Assert.assertEquals(0.01, model.prior(astiffNeck), DELTA_THRESHOLD); // P(~stiffNeck) = 0.99 Assert.assertEquals(0.99, model.prior(anotstiffNeck), DELTA_THRESHOLD); // P(meningitis | stiffneck) // = P(stiffneck | meningitis)P(meningitis)/P(stiffneck) // = (0.7 * 0.00002)/0.01 // = 0.0014 (13.4) Assert.assertEquals(0.0014, model.posterior(ameningitis, astiffNeck), DELTA_THRESHOLD); // Assuming P(~stiffneck | meningitis) = 0.3 (pg. 497), i.e. CPT (row // must = 1) // // P(meningitis | ~stiffneck) // = P(~stiffneck | meningitis)P(meningitis)/P(~stiffneck) // = (0.3 * 0.00002)/0.99 // = 0.000006060606 Assert.assertEquals(0.000006060606, model.posterior(ameningitis, anotstiffNeck), DELTA_THRESHOLD); } // AIMA3e pg. 512 protected void test_BurglaryAlarmModel(ProbabilityModel model) { Assert.assertTrue(model.isValid()); AssignmentProposition aburglary = new AssignmentProposition( ExampleRV.BURGLARY_RV, Boolean.TRUE); AssignmentProposition anotburglary = new AssignmentProposition( ExampleRV.BURGLARY_RV, Boolean.FALSE); AssignmentProposition anotearthquake = new AssignmentProposition( ExampleRV.EARTHQUAKE_RV, Boolean.FALSE); AssignmentProposition aalarm = new AssignmentProposition( ExampleRV.ALARM_RV, Boolean.TRUE); AssignmentProposition anotalarm = new AssignmentProposition( ExampleRV.ALARM_RV, Boolean.FALSE); AssignmentProposition ajohnCalls = new AssignmentProposition( ExampleRV.JOHN_CALLS_RV, Boolean.TRUE); AssignmentProposition amaryCalls = new AssignmentProposition( ExampleRV.MARY_CALLS_RV, Boolean.TRUE); // AIMA3e pg. 514 Assert.assertEquals(0.00062811126, model.prior(ajohnCalls, amaryCalls, aalarm, anotburglary, anotearthquake), DELTA_THRESHOLD); Assert.assertEquals(0.00049800249, model.prior(ajohnCalls, amaryCalls, anotalarm, anotburglary, anotearthquake), DELTA_THRESHOLD); // AIMA3e pg. 524 // P(Burglary = true | JohnCalls = true, MaryCalls = true) = 0.00059224 Assert.assertEquals(0.00059224, model.prior(aburglary, ajohnCalls, amaryCalls), DELTA_THRESHOLD); // P(Burglary = false | JohnCalls = true, MaryCalls = true) = 0.0014919 Assert.assertEquals(0.00149185764899, model.prior(anotburglary, ajohnCalls, amaryCalls), DELTA_THRESHOLD); } }