diff --git a/data/short_recipebook.xml b/data/short_recipebook.xml new file mode 100644 index 0000000..317b3d6 --- /dev/null +++ b/data/short_recipebook.xml @@ -0,0 +1,521 @@ + + + + + Catalan Rice + + + Fish + Casserole + Main dish + Pork + Clams + + 6servings + + + + + + + + + 2.5 + cups + + Fish stock + + + + + 0.25 + teaspoon + + Saffron Threads + + + + + 0.25 + cup + + Dry white wine + + + + + 6 + tablespoons + + Lard + + + + + 0.5 + pound + + Chorizo + Sliced 1/4" + + + + 1.5 + pounds + + Pork Loin + 1" Cubes + + + + 1 + + + onion + thinly sliced + + + + 2 + + + Bell peppers + julienned + + + + 2 + + + tomatoes + peeled,seeded + + + + 3 + + + Large Squid + + + + + 2 + cups + + Long-Grained Rice + + + + + 0.75 + cup + + Blanched almonds + + + + + 0.333333 + cup + + Pine Nuts + + + + + 3 + + + garlic cloves + minced + + + + 1 + cup + + Artichoke hearts + drained + + + + 18 + + + Clams Or Mussels + scrubbed + + + + 0.5 + cup + + Peas + + + + + 0.25 + cup + + Pimientos + julienned + + + + 2 + tablespoons + + Fresh parsley + minced + + + + Clean squid and cut body sacs into rings. Cut tentacles in half. In +a small saucepan, bring stock to a bare simmer. Crush saffron and +combine it with wine in a small bowl. In a flameproof casserole or +paella pan, heat the lard over moderately high heat. Saute the +chorizo and pork, turning them until they are browned. Add the +onion, bell peppers, tomatoes, and squid and cook the mixture over +moderate heat, stirring, for 15 minutes. Stir in the rice and cook +for 1 minute, stirring. Stir in almonds, pine nuts, garlic, saffron +mixture, and artichoke hearts. Ladle in enough stock to just cover +the rice mixture. Bring to a boil and simmer it, covered, for 20 +minutes. Arrange the clams in the rice, add the peas, and simmer for +10-15 minutes, or until the rice is just tender and the clams open. +Discard any clams that do not open. Garnish with pimientos and +parsley. This is a recipe by Elizabeth David, appearing in an article +in 1972 by James Beard. It originated on Spain's Costa Brava. "not a +true paella, but it is quite good." A 1972 Gourmet Magazine Favorite. + + + + + Hamburger Steak + + + Beef + Penndutch + + 1servings + + + + + + + + + 1 + pound + + Beef + ground + + + + 0.5 + teaspoon + + salt + + + + + 1 + + + onion + minced + + + + 1 + + + egg + well beaten + + + + 1 + dash + + pepper + + + + + 0.25 + cup + + bread crumbs + + + + + Mix in order given and shape into round cakes. Fry in butter until +nicely browned. Source: Pennsylvania Dutch Cook Book - Fine Old +Recipes, Culinary Arts Press, 1936. + + + + + Potatoes in a Thick Sauce + + + Main dish + Potatoes + Indian + Vegetarian + + 6servings + + + + + + + + + 5 + medium + + potatoes + cubed & cooked + + + + 1 + slice + + ginger + + + + + 1 + tablespoon + + Coriander + + + + + 1 + teaspoon + + cumin + + + + + 6 + tablespoons + + tomato sauce + + + + + 6 + tablespoons + + vegetable oil + + + + + 1 + teaspoon + + Fennel + + + + + 1 + teaspoon + + Fenugreek + + + + + 0.5 + teaspoon + + Black mustard seeds + + + + + 3 + + + Whole dried red chilies + + + + + 1 + teaspoon + + salt + + + + + 1.5 + teaspoons + + lemon juice + + + + + 1 + teaspoon + + Garam masala + + + + + Place ginger, coriander, cumin, tomato sauce & 3 tb water in a +blender & blend till smooth. + +Break potatoes into bite sized pieces. + +Heat oil (I use ghee) in a large pot. When hot, throw in fennel, +fenugreek & mustard seeds. After 20 seconds, add red chilies. As +they darken, put in paste from blender. Fry for 5 minutes, stirring +frequently. Put in the potato pieces & fry for 3 to 5 minutes. Add 1 +1/2 c warm water. Bring to a boil. Add salt & lemon juice. Simmer +for 20 minutes. + +Before serving, sprinkle with garam masala. + +Madhur Jaffrey, "An Invitation to Indian Cooking. + + + + + Tomato-Zucchini Casserole + + + Vegetarian + Casseroles + + 4servings + + + + + + + + + 1.5 + teaspoons + + chili powder + + + + + 1 + tablespoon + + parsley flakes + + + + + 0.5 + teaspoon + + garlic powder + + + + + 0.5 + teaspoon + + onion powder + + + + + 0.125 + teaspoon + + salt + + + + + 0.125 + teaspoon + + black pepper + ground + + + + 3 + cups + + zucchini + thinly sliced,fresh + + + + 1 + pound + + tomatoes + fresh,sliced + + + + 0.25 + cup + + bread crumbs + white,fresh + + + + 1 + tablespoon + + vegetable oil + + + + + 1. Combine chili powder, 1 1/2 teaspooons parsley flakes, garlic and +onion powders, salt and pepper in a small bowl.~ 2. Place half the +zucchini in a lightly greased 6-cup casserole, or layer with half the +tomatoes.~ 3. Sprinkle with half the seasoning mixture.~ 4. Repeat +the layers.~ 5. Combine bread crumbs, oil and remaining parsley +flakes; sprinkle over vegetables.~ 6. Bake, uncovered, in preheated +375'F. oven, until vegetables are tender, about 40 minutes.~ + + + \ No newline at end of file diff --git a/data/short_survey.xml b/data/short_survey.xml new file mode 100644 index 0000000..33805ec --- /dev/null +++ b/data/short_survey.xml @@ -0,0 +1,109 @@ + + + + + 0 + Catalan Rice + + + 1 + Hamburger Steak + + + 2 + Potatoes in a Thick Sauce + + + 3 + Tomato-Zucchini Casserole + + + + + 0 + + chocolate + + + + 1 + + nuts + + + + 2 + shellfish + + + + 0 + + + 0 + 10 + + + 1 + 2 + + + 2 + 5 + + + 3 + 5 + + + + + 0 + false + + + 1 + false + + + 2 + false + + + + + 1 + + + 0 + 10 + + + 1 + 2 + + + 2 + 5 + + + 3 + 5 + + + + + 0 + false + + + 1 + false + + + 2 + false + + + + \ No newline at end of file diff --git a/src/dkohl/bayes/builders/FoodNetBuilder.java b/src/dkohl/bayes/builders/FoodNetBuilder.java new file mode 100644 index 0000000..677ea76 --- /dev/null +++ b/src/dkohl/bayes/builders/FoodNetBuilder.java @@ -0,0 +1,218 @@ +package dkohl.bayes.builders; + +import java.util.HashSet; + +import net.woodyfolsom.cs6601.p2.Diner; +import net.woodyfolsom.cs6601.p2.Ingredient.TYPE; +import net.woodyfolsom.cs6601.p2.Ingredients; +import net.woodyfolsom.cs6601.p2.Recipe; +import net.woodyfolsom.cs6601.p2.RecipeBook; +import net.woodyfolsom.cs6601.p2.Survey; +import dkohl.bayes.bayesnet.BayesNet; +import dkohl.bayes.estimation.MaximumLikelihoodEstimation; +import dkohl.bayes.example.builders.FoodExampleBuilder; +import dkohl.bayes.probability.Assignment; +import dkohl.bayes.probability.Probability; +import dkohl.bayes.probability.Variable; +import dkohl.bayes.probability.distribution.ContinousDistribution; +import dkohl.bayes.probability.distribution.ProbabilityDistribution; +import dkohl.bayes.probability.distribution.ProbabilityTable; +import dkohl.bayes.statistic.DataPoint; +import dkohl.bayes.statistic.DataSet; +import dkohl.onthology.Ontology; + +public class FoodNetBuilder { + public static final String TASTE = "Taste"; + public static final String SOMEONE_VEGETARIAN = "Vegetarian"; + public static final String CONTAINS_MEAT = "Meat"; + public static final String CONTAINS_VEGETABLE = "Vegetable"; + public static final String CONTAINS_BEEF = TYPE.BEEF.toString(); + public static final String CONTAINS_PORK = TYPE.PORK.toString(); + public static final String CONTAINS_TOMATOS = TYPE.TOMATO.toString(); + public static final String CONTAINS_POTATOS = TYPE.POTATO.toString(); + + public static final String TRUE_VALUE = "true"; + public static final String FALSE_VALUE = "false"; + + public static final String DOMAIN[] = { TRUE_VALUE, FALSE_VALUE }; + + public static final String RATING_DOMAIN[] = { "1", "2", "3", "4", "5", + "6", "7", "8", "9", "10" }; + + private static final String[] VARIABLES = { SOMEONE_VEGETARIAN, + CONTAINS_BEEF, CONTAINS_MEAT, CONTAINS_PORK, CONTAINS_POTATOS, + CONTAINS_TOMATOS, CONTAINS_VEGETABLE, TASTE }; + + private static final String[] OBSERVED = { CONTAINS_BEEF, CONTAINS_PORK, + CONTAINS_POTATOS, CONTAINS_TOMATOS, }; + + public static Ontology createOntology() { + HashSet classes = new HashSet(); + + classes.add(CONTAINS_MEAT); + classes.add(CONTAINS_VEGETABLE); + + Ontology onthology = new Ontology(classes); + + onthology.define(CONTAINS_PORK, CONTAINS_MEAT); + onthology.define(CONTAINS_BEEF, CONTAINS_MEAT); + + onthology.define(CONTAINS_TOMATOS, CONTAINS_VEGETABLE); + onthology.define(CONTAINS_POTATOS, CONTAINS_VEGETABLE); + return onthology; + } + + private static Assignment build(String varible, String value) { + return new Assignment(new Variable(varible, DOMAIN), value); + } + + public static DataPoint normalize(DataPoint point, Ontology onto) { + // resolve onthology + DataPoint normPoint = new DataPoint(point); + for (String key : point.keySet()) { + if (onto.getInheritance().containsKey(key)) { + normPoint + .add(build(onto.getInheritance().get(key), TRUE_VALUE)); + } + } + + // implement closed world assumption + // everything unknown is false + for (String variable : VARIABLES) { + if (!normPoint.containsKey(variable)) { + normPoint.add(build(variable, FALSE_VALUE)); + } + } + return normPoint; + } + + public static DataSet getSurveyDataSet(Survey survey, RecipeBook recipeBook) { + DataSet data = FoodExampleBuilder.examples(); + Ontology onto = createOntology(); + + int nDishes = survey.getDishCount(); + for (int dinerIndex = 0; dinerIndex < survey.getDinerCount(); dinerIndex++) { + Diner diner = survey.getDiner(dinerIndex); + for (int dishIndex = 0; dishIndex < nDishes; dishIndex++) { + data.add(normalize(createDataPoint(recipeBook, survey.getDish(dishIndex), diner.getRating(dishIndex)),onto)); + } + } + return data; + } + + public static DataPoint createDataPoint(RecipeBook recipeBook, String recipeName, int weight) { + DataPoint point = new DataPoint(); + + Recipe recipe = recipeBook.getRecipe(recipeName); + Ingredients ingredients = recipe.getIngredients(); + + if (ingredients.contains(TYPE.BEEF)) { + point.add(build(CONTAINS_BEEF, TRUE_VALUE)); + } + if (ingredients.contains(TYPE.PORK)) { + point.add(build(CONTAINS_PORK, TRUE_VALUE)); + } + if (ingredients.contains(TYPE.POTATO)) { + point.add(build(CONTAINS_POTATOS, TRUE_VALUE)); + } + if (ingredients.contains(TYPE.TOMATO)) { + point.add(build(CONTAINS_TOMATOS, TRUE_VALUE)); + } + + point.add(build(TASTE, "" + weight)); + + return point; + } + + public static ProbabilityDistribution vegi() { + String names[] = { SOMEONE_VEGETARIAN }; + ProbabilityTable table = new ProbabilityTable(names); + table.setProbabilityForAssignment("true;", new Probability(0)); + table.setProbabilityForAssignment("false;", new Probability(1)); + return table; + } + + public static ProbabilityDistribution beef() { + String names[] = { CONTAINS_MEAT, CONTAINS_BEEF }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution pork() { + String names[] = { CONTAINS_MEAT, CONTAINS_PORK }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution meet() { + String names[] = { SOMEONE_VEGETARIAN, CONTAINS_MEAT }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution tomatos() { + String names[] = { CONTAINS_VEGETABLE, CONTAINS_TOMATOS }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution potatos() { + String names[] = { CONTAINS_VEGETABLE, CONTAINS_POTATOS }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution vegetables() { + String names[] = { CONTAINS_VEGETABLE, SOMEONE_VEGETARIAN }; + ProbabilityTable table = new ProbabilityTable(names); + return table; + } + + public static ProbabilityDistribution taste() { + String names[] = { TASTE, CONTAINS_BEEF, CONTAINS_PORK, + CONTAINS_POTATOS, CONTAINS_TOMATOS }; + ContinousDistribution distribution = new ContinousDistribution(names, 0); + return distribution; + } + + public static BayesNet createDishNet(Survey survey, RecipeBook recipeBook) { + BayesNet net = new BayesNet(VARIABLES); + + net.setDistribution(new Variable(SOMEONE_VEGETARIAN, DOMAIN), vegi()); + net.setDistribution(new Variable(CONTAINS_MEAT, DOMAIN), meet()); + net.setDistribution(new Variable(CONTAINS_VEGETABLE, DOMAIN), + vegetables()); + net.setDistribution(new Variable(CONTAINS_BEEF, DOMAIN), beef()); + net.setDistribution(new Variable(CONTAINS_PORK, DOMAIN), pork()); + net.setDistribution(new Variable(CONTAINS_POTATOS, DOMAIN), potatos()); + net.setDistribution(new Variable(CONTAINS_TOMATOS, DOMAIN), tomatos()); + net.setDistribution(new Variable(TASTE, RATING_DOMAIN), taste()); + + Ontology ontology = createOntology(); + for (String category : ontology.getClasses()) { + net.connect(category, SOMEONE_VEGETARIAN); + } + + for (String thing : OBSERVED) { + net.connect(thing, ontology.getInheritance().get(thing)); + net.connect(TASTE, thing); + } + + DataSet dataSet = getSurveyDataSet(survey, recipeBook); + + for (String category : ontology.getClasses()) { + MaximumLikelihoodEstimation.estimate(dataSet, net, category); + for (String thing : ontology.getClasses2thing().get(category)) { + MaximumLikelihoodEstimation.estimate(dataSet, net, thing); + } + } + + MaximumLikelihoodEstimation.estimate(dataSet, net, TASTE); + ContinousDistribution distribturion = (ContinousDistribution) net + .getNodes().get(TASTE); + + distribturion.estimate(); + + return net; + } +} \ No newline at end of file diff --git a/src/dkohl/bayes/inference/EnumerateAll.java b/src/dkohl/bayes/inference/EnumerateAll.java index 593061f..47bab52 100644 --- a/src/dkohl/bayes/inference/EnumerateAll.java +++ b/src/dkohl/bayes/inference/EnumerateAll.java @@ -27,8 +27,8 @@ public class EnumerateAll { * a set of assignments in this net. * @return */ - public static LinkedList enumerateAsk( - Variable query, BayesNet net, LinkedList assignments) { + public static List enumerateAsk( + Variable query, BayesNet net, List assignments) { LinkedList variables = net.getVariables(); LinkedList result = new LinkedList(); diff --git a/src/net/woodyfolsom/cs6601/p2/BayesChef.java b/src/net/woodyfolsom/cs6601/p2/BayesChef.java index 466106a..ec5344e 100644 --- a/src/net/woodyfolsom/cs6601/p2/BayesChef.java +++ b/src/net/woodyfolsom/cs6601/p2/BayesChef.java @@ -1,61 +1,112 @@ package net.woodyfolsom.cs6601.p2; import java.io.File; +import java.util.LinkedList; +import java.util.List; -import org.apache.commons.math3.stat.regression.SimpleRegression; +import net.woodyfolsom.cs6601.p2.Ingredient.TYPE; +import dkohl.bayes.bayesnet.BayesNet; +import dkohl.bayes.builders.FoodNetBuilder; +import dkohl.bayes.example.builders.FoodExampleBuilder; +import dkohl.bayes.inference.EnumerateAll; +import dkohl.bayes.probability.Assignment; +import dkohl.bayes.probability.ProbabilityAssignment; +import dkohl.bayes.probability.Variable; public class BayesChef { public static void main(String... args) { System.out.println("Reading recipe book."); - RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/survey_recipes.xml")); - - System.out.println("Read data for " + recipeBook.getSize() + " recipes."); + RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml")); System.out.println("Reading survey data."); - Survey survey = SurveyReader.readSurvey(new File("data/survey.xml")); + Survey survey = SurveyReader.readSurvey(new File("data/short_survey.xml")); - System.out.println("Read data for " + survey.getDinerCount() + " diner(s)."); + new BayesChef().reportBestMeal(recipeBook,survey); + } + + private void reportBestMeal(RecipeBook recipeBook, Survey survey) { + int numRecipes = recipeBook.getSize(); + System.out.println("Read data for " + numRecipes + " recipes."); + int numDiners = survey.getDinerCount(); + System.out.println("Read data for " + numDiners + " diner(s)."); + + /* System.out.println("Setting evidence for first 11 recipes."); System.out.println("Evaluating preference for remaining recipes."); //read survey prefs from survey.xml - double[][] surveyPrefs = new double[5][]; - for (int i = 0; i < 5; i++) { - surveyPrefs[i] = new double[11]; - for (int j = 0; j < 11; j++) { + double[][] surveyPrefs = new double[numDiners][]; + for (int i = 0; i < numDiners; i++) { + surveyPrefs[i] = new double[numRecipes/2]; + for (int j = 0; j < numRecipes/2; j++) { surveyPrefs[i][j] = survey.getDiner(i).getRating(j); } } //generating stub evaluated preferences to test RMSE calculation - double[][] calculatedPrefs = new double[5][]; - calculatedPrefs[0] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - calculatedPrefs[1] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - calculatedPrefs[2] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - calculatedPrefs[3] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - calculatedPrefs[4] = new double[] { 10.0, 10.0, 0.0, 10.0, 10.0, 4.0, 10.0, 10.0, 10.0, 10.0, 10.0 }; + double[][] calculatedPrefs = new double[numDiners][]; + calculatedPrefs[0] = new double[numRecipes/2]; - System.out.println("RMSE for recipes #12-22 (calculated vs. surveyed preference):"); + System.out.println("RMSE for recipes #" + numRecipes/2 + "-" + numRecipes +" (calculated vs. surveyed preference):"); for (int dinerIndex = 0; dinerIndex < survey.getDinerCount(); dinerIndex++) { SimpleRegression simpleRegression = new SimpleRegression(); - for (int i = 0; i < 11; i++) { + for (int i = 0; i < numRecipes/2; i++) { simpleRegression.addData(i,calculatedPrefs[dinerIndex][i]); } double calculatedMSE = simpleRegression.getMeanSquareError(); simpleRegression.clear(); - for (int i = 0; i < 11; i++) { + for (int i = 0; i < numRecipes/2; i++) { simpleRegression.addData(i,surveyPrefs[dinerIndex][i]); } double surveyMSE = simpleRegression.getMeanSquareError(); System.out.println("Diner # " + (dinerIndex + 1) + ": " + calculatedMSE + " vs. "+ surveyMSE); + }*/ + + BayesNet net = FoodNetBuilder.createDishNet(survey, recipeBook); + //BayesNet net = FoodExampleBuilder.dishNet(); + + printPreference(net, TYPE.PORK); + printPreference(net, TYPE.BEEF); + printPreference(net, TYPE.POTATO); + printPreference(net, TYPE.TOMATO); + } + + void printPreference(BayesNet net, TYPE type) { + List probs = EnumerateAll.enumerateAsk(new Variable( + FoodNetBuilder.TASTE, FoodNetBuilder.RATING_DOMAIN), + net, createQuery(type)); + double max_val = 0.0; + String max_arg = "N/A"; + for (ProbabilityAssignment p : probs) { + if (p.getProbability() > max_val) { + max_val = p.getProbability(); + max_arg = p.getValue(); + } } + + System.out.println("TASTE " + type + ": " + max_arg + " " + max_val); + } + + List createQuery(TYPE type) { + List assignment = new LinkedList(); + switch (type) { + case PORK: + case BEEF: + case POTATO: + case TOMATO: + assignment.add(new Assignment(new Variable(type.toString(), FoodNetBuilder.DOMAIN), + FoodNetBuilder.TRUE_VALUE)); + break; + default: + } + return assignment; } } diff --git a/src/net/woodyfolsom/cs6601/p2/Ingredient.java b/src/net/woodyfolsom/cs6601/p2/Ingredient.java index b27da77..26bbfe4 100644 --- a/src/net/woodyfolsom/cs6601/p2/Ingredient.java +++ b/src/net/woodyfolsom/cs6601/p2/Ingredient.java @@ -4,7 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; @XStreamAlias("ing") public class Ingredient { - public enum TYPE { ALCOHOL, DAIRY, EGGS, FISH, GLUTEN, GRAIN, NUTS, PORK, POULTRY, RED_MEAT, SHELLFISH, SPICE, SUGAR} + public enum TYPE { ALCOHOL, BEEF, DAIRY, EGGS, FISH, GLUTEN, GRAIN, NUTS, PORK, POULTRY, POTATO, SHELLFISH, SPICE, SUGAR, TOMATO} private String item; @@ -14,20 +14,31 @@ public class Ingredient { public boolean isType(TYPE type) { switch (type) { + case BEEF : + return item.contains("beef"); case DAIRY : return item.contains("margarine"); case EGGS : return item.equals("egg") || item.equals("eggs"); case GLUTEN : return item.contains("flour"); - case RED_MEAT : - return item.contains("beef"); + case PORK : + return item.contains("pork"); + case POTATO : + return item.contains("potato"); case SPICE : return item.endsWith("cinnamon") || item.endsWith("nutmeg") || item.endsWith("cloves"); case SUGAR : return item.endsWith("sugar"); + case TOMATO : + return item.contains("tomato"); default : //unknown ingredient, e.g. coffee, bananas, honey return false; } } + + public Object readResolve() { + item = item.toLowerCase(); + return this; + } } diff --git a/src/net/woodyfolsom/cs6601/p2/RecipeBook.java b/src/net/woodyfolsom/cs6601/p2/RecipeBook.java index 7f557ac..0dab8f9 100644 --- a/src/net/woodyfolsom/cs6601/p2/RecipeBook.java +++ b/src/net/woodyfolsom/cs6601/p2/RecipeBook.java @@ -15,6 +15,16 @@ public class RecipeBook { return recipes.get(index); } + //TODO build an index of recipes by name? + public Recipe getRecipe(String recipeName) { + for (Recipe recipe : recipes) { + if (recipeName.equalsIgnoreCase(recipe.getHead().getTitle())) { + return recipe; + } + } + return null; + } + public int getSize() { return recipes.size(); } diff --git a/test/dkohl/bayes/example/AlarmExampleTest.java b/test/dkohl/bayes/example/AlarmExampleTest.java index 303c225..97aa174 100644 --- a/test/dkohl/bayes/example/AlarmExampleTest.java +++ b/test/dkohl/bayes/example/AlarmExampleTest.java @@ -4,7 +4,7 @@ import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import java.util.LinkedList; +import java.util.List; import org.junit.Test; @@ -22,7 +22,7 @@ public class AlarmExampleTest { BayesNet sprinkler = AlarmNetBuilderTable.alarm(); sprinkler = AlarmNetBuilderTree.sprinkler(); // P(B | j, m) - LinkedList probs = EnumerateAll.enumerateAsk( + List probs = EnumerateAll.enumerateAsk( new Variable(AlarmNetBuilderTable.BURGLARY, AlarmNetBuilderTable.DOMAIN), sprinkler, AlarmNetBuilderTable.completeQueryBulgary()); diff --git a/test/dkohl/bayes/example/FoodExampleTest.java b/test/dkohl/bayes/example/FoodExampleTest.java index b75ac77..bbdc069 100644 --- a/test/dkohl/bayes/example/FoodExampleTest.java +++ b/test/dkohl/bayes/example/FoodExampleTest.java @@ -1,11 +1,11 @@ package dkohl.bayes.example; -import java.util.LinkedList; - import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import java.util.List; + import org.junit.Test; import dkohl.bayes.bayesnet.BayesNet; @@ -119,7 +119,7 @@ public class FoodExampleTest { + dist.getAssignments().get(assignment)); } - LinkedList probs = EnumerateAll.enumerateAsk( + List probs = EnumerateAll.enumerateAsk( new Variable(FoodExampleBuilder.TASTE, FoodExampleBuilder.RATING_DOMAIN), net, FoodExampleBuilder.completeQueryTasteBeef()); @@ -145,7 +145,7 @@ public class FoodExampleTest { } } - System.out.println("TASE PORK: " + max_arg + " " + max_val); + System.out.println("TASTE PORK: " + max_arg + " " + max_val); assertThat(max_arg, equalTo("10")); assertTrue("Error: max_val for TASTE_PORK should be > 2.6%", max_val > 0.026); } diff --git a/test/dkohl/bayes/example/builders/FoodExampleBuilder.java b/test/dkohl/bayes/example/builders/FoodExampleBuilder.java index b3b100f..3bcc9c8 100644 --- a/test/dkohl/bayes/example/builders/FoodExampleBuilder.java +++ b/test/dkohl/bayes/example/builders/FoodExampleBuilder.java @@ -3,6 +3,8 @@ package dkohl.bayes.example.builders; import java.util.HashSet; import java.util.LinkedList; +import net.woodyfolsom.cs6601.p2.Ingredient.TYPE; + import dkohl.bayes.bayesnet.BayesNet; import dkohl.bayes.estimation.MaximumLikelihoodEstimation; import dkohl.bayes.probability.Assignment; @@ -21,13 +23,13 @@ public class FoodExampleBuilder { public static final String SOMEONE_VEGETARIAN = "Vegetarian"; public static final String CONTAINS_MEAT = "Meat"; public static final String CONTAINS_VEGETABLE = "Vegetable"; - public static final String CONTAINS_BEEF = "Beef"; - public static final String CONTAINS_PORK = "Pork"; - public static final String CONTAINS_TOMATOS = "Tomatos"; - public static final String CONTAINS_POTATOS = "Potatos"; + public static final String CONTAINS_BEEF = TYPE.BEEF.toString(); + public static final String CONTAINS_PORK = TYPE.PORK.toString(); + public static final String CONTAINS_TOMATOS = TYPE.TOMATO.toString(); + public static final String CONTAINS_POTATOS = TYPE.POTATO.toString(); - public static final String TRUE_VALUE = "true"; - public static final String FALSE_VALUE = "false"; + public static final String TRUE_VALUE = Boolean.TRUE.toString(); + public static final String FALSE_VALUE = Boolean.FALSE.toString(); public static final String DOMAIN[] = { TRUE_VALUE, FALSE_VALUE }; diff --git a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java index a5af10c..3871b76 100644 --- a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java +++ b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java @@ -29,7 +29,7 @@ public class RecipeBookReaderTest { assertTrue(recipe.getIngredients().contains(TYPE.EGGS)); assertTrue(recipe.getIngredients().contains(TYPE.GLUTEN)); assertTrue(recipe.getIngredients().contains(TYPE.SPICE)); - assertFalse(recipe.getIngredients().contains(TYPE.RED_MEAT)); + assertFalse(recipe.getIngredients().contains(TYPE.BEEF)); assertFalse(recipe.getIngredients().contains(TYPE.POULTRY)); assertFalse(recipe.getIngredients().contains(TYPE.SHELLFISH)); @@ -37,4 +37,44 @@ public class RecipeBookReaderTest { System.out.println(recipeBook.getRecipe(rIndex).getHead().getTitle()); } } + + @Test + public void testReadShortSurveyDataset() { + RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml")); + assertNotNull(recipeBook); + assertThat(recipeBook.getSize(), is(equalTo(4))); + + for (int i = 0; i < 4; i++) { + Recipe recipe = recipeBook.getRecipe(i); + System.out.println(i + ": " +recipe.getHead().getTitle()); + } + + Recipe recipe = recipeBook.getRecipe(0); + assertThat(recipe.getHead().getTitle(), is(equalTo("Catalan Rice"))); + assertTrue(recipe.getIngredients().contains(TYPE.PORK)); + assertFalse(recipe.getIngredients().contains(TYPE.BEEF)); + assertFalse(recipe.getIngredients().contains(TYPE.POTATO)); + assertTrue(recipe.getIngredients().contains(TYPE.TOMATO)); + + recipe = recipeBook.getRecipe(1); + assertThat(recipe.getHead().getTitle(), is(equalTo("Hamburger Steak"))); + assertFalse(recipe.getIngredients().contains(TYPE.PORK)); + assertTrue(recipe.getIngredients().contains(TYPE.BEEF)); + assertFalse(recipe.getIngredients().contains(TYPE.POTATO)); + assertFalse(recipe.getIngredients().contains(TYPE.TOMATO)); + + recipe = recipeBook.getRecipe(2); + assertThat(recipe.getHead().getTitle(), is(equalTo("Potatoes in a Thick Sauce"))); + assertFalse(recipe.getIngredients().contains(TYPE.PORK)); + assertFalse(recipe.getIngredients().contains(TYPE.BEEF)); + assertTrue(recipe.getIngredients().contains(TYPE.POTATO)); + assertTrue(recipe.getIngredients().contains(TYPE.TOMATO)); + + recipe = recipeBook.getRecipe(3); + assertThat(recipe.getHead().getTitle(), is(equalTo("Tomato-Zucchini Casserole"))); + assertFalse(recipe.getIngredients().contains(TYPE.PORK)); + assertFalse(recipe.getIngredients().contains(TYPE.BEEF)); + assertFalse(recipe.getIngredients().contains(TYPE.POTATO)); + assertTrue(recipe.getIngredients().contains(TYPE.TOMATO)); + } }