diff --git a/commons-math3-3.0-bin.tar.gz b/commons-math3-3.0-bin.tar.gz
deleted file mode 100644
index 4c642b2..0000000
Binary files a/commons-math3-3.0-bin.tar.gz and /dev/null differ
diff --git a/data/survey_recipes.xml b/data/long_recipebook.xml
similarity index 90%
rename from data/survey_recipes.xml
rename to data/long_recipebook.xml
index 74ace57..6727e03 100644
--- a/data/survey_recipes.xml
+++ b/data/long_recipebook.xml
@@ -452,7 +452,7 @@ on high speed until foamy.
- Breaded Veal Cutlet ( Weinerschnitzel )
+ Weinerschnitzel
Veal
@@ -673,7 +673,7 @@ baking powder and salt.
- Chinese: Cashew Chicken 1
+ Cashew Chicken
Cashews
@@ -2829,4 +2829,329 @@ Carbs 36 g.
FROM: MADELINE HIMY (NFBH49A)
+
+
+ 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/long_survey.xml b/data/long_survey.xml
new file mode 100644
index 0000000..2b6f832
--- /dev/null
+++ b/data/long_survey.xml
@@ -0,0 +1,275 @@
+
+
+
+
+ 0
+ Catalan Rice
+
+
+ 1
+ Hamburger Steak
+
+
+ 2
+ Potatoes in a Thick Sauce
+
+
+ 3
+ Tomato-Zucchini Casserole
+
+
+ 4
+ Honey Cake
+
+
+ 5
+ Cashew Chicken
+
+
+ 6
+ Kahlua Cake
+
+
+ 7
+ Ice Cream, Lowfat
+
+
+ 8
+ Blender Double Fudge Cake
+
+
+ 9
+ Weinerschnitzel
+
+
+
+
+ 0
+ vegetarian
+
+
+ 1
+ allergic-nuts
+
+
+
+ 0
+
+
+ 0
+ 10
+
+
+ 1
+ 2
+
+
+ 2
+ 5
+
+
+ 3
+ 5
+
+
+ 4
+ 5
+
+
+ 5
+ 5
+
+
+ 6
+ 5
+
+
+ 7
+ 5
+
+
+ 8
+ 5
+
+
+ 9
+ 5
+
+
+
+
+ 0
+ false
+
+
+ 1
+ false
+
+
+
+
+ 1
+
+
+ 0
+ 0
+
+
+ 1
+ 0
+
+
+ 2
+ 5
+
+
+ 3
+ 6
+
+
+ 4
+ 5
+
+
+ 5
+ 5
+
+
+ 6
+ 5
+
+
+ 7
+ 5
+
+
+ 8
+ 5
+
+
+ 9
+ 5
+
+
+
+
+ 0
+ true
+
+
+ 1
+ false
+
+
+
+
+ 2
+
+
+ 0
+ 9
+
+
+ 1
+ 2
+
+
+ 2
+ 2
+
+
+ 3
+ 2
+
+
+ 4
+ 5
+
+
+ 5
+ 0
+
+
+ 6
+ 5
+
+
+ 7
+ 5
+
+
+ 8
+ 5
+
+
+ 9
+ 5
+
+
+
+
+ 0
+ false
+
+
+ 1
+ true
+
+
+
+
+ 3
+
+
+ 0
+ 9
+
+
+ 1
+ 2
+
+
+ 2
+ 2
+
+
+ 3
+ 2
+
+
+ 4
+ 5
+
+
+ 5
+ 7
+
+
+ 6
+ 5
+
+
+ 7
+ 5
+
+
+ 8
+ 5
+
+
+ 9
+ 5
+
+
+
+
+ 0
+ false
+
+
+ 1
+ false
+
+
+
+
\ No newline at end of file
diff --git a/data/medium_recipebook.xml b/data/medium_recipebook.xml
new file mode 100644
index 0000000..317b3d6
--- /dev/null
+++ b/data/medium_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/medium_survey.xml b/data/medium_survey.xml
new file mode 100644
index 0000000..2d02b4c
--- /dev/null
+++ b/data/medium_survey.xml
@@ -0,0 +1,81 @@
+
+
+
+
+ 0
+ Catalan Rice
+
+
+ 1
+ Hamburger Steak
+
+
+ 2
+ Potatoes in a Thick Sauce
+
+
+ 3
+ Tomato-Zucchini Casserole
+
+
+
+
+ 0
+ vegan
+
+
+
+ 0
+
+
+ 0
+ 10
+
+
+ 1
+ 2
+
+
+ 2
+ 5
+
+
+ 3
+ 5
+
+
+
+
+ 0
+ false
+
+
+
+
+ 1
+
+
+ 0
+ 0
+
+
+ 1
+ 0
+
+
+ 2
+ 5
+
+
+ 3
+ 6
+
+
+
+
+ 0
+ true
+
+
+
+
\ No newline at end of file
diff --git a/data/short_survey.xml b/data/short_survey.xml
index 33805ec..dfebb14 100644
--- a/data/short_survey.xml
+++ b/data/short_survey.xml
@@ -21,19 +21,7 @@
0
-
- chocolate
-
-
-
- 1
-
- nuts
-
-
-
- 2
- shellfish
+ vegan
@@ -56,20 +44,12 @@
5
-
+
0
false
-
- 1
- false
-
-
- 2
- false
-
-
+
1
@@ -91,19 +71,11 @@
5
-
+
0
false
-
- 1
- false
-
-
- 2
- false
-
-
+
\ No newline at end of file
diff --git a/data/survey.xml b/data/survey.xml
deleted file mode 100644
index f2f9937..0000000
--- a/data/survey.xml
+++ /dev/null
@@ -1,628 +0,0 @@
-
-
-
-
- 0
- Honey cake
-
-
- 1
- Kahlua Cake
-
-
- 2
- Ice Cream, Lowfat
-
-
- 3
- Southwest Smoothie
-
-
- 4
- Margarita Sunrise
-
-
- 5
- Breaded Veal Cutlet ( Weinerschnitzel )
-
-
- 6
- Blender Double Fudge Cake
-
-
- 7
- Chinese: Cashew Chicken 1
-
-
- 8
- Bayou Shrimp Creole
-
-
- 9
- Crab Burgers
-
-
- 10
- Broiled Flounder
-
-
- 11
- Coconut Beer Batter Shrimp
-
-
- 12
- Coconut Fish Curry
-
-
- 13
- Catalan Rice
-
-
- 14
- Baked Steak And Lima Beans
-
-
- 15
- Tabasco Classic - Perfect Seared Steaks ****
-
-
- 16
- Salisbury Steak with Mushroom Sauce
-
-
- 17
- Meatless Loaf
-
-
- 18
- Black Bean Soup
-
-
- 29
- Fava Bean Burgers
-
-
- 20
- Angel Hair Pesto Primavera
-
-
- 21
- EGGPLANT LASAGNE
-
-
-
-
- 0
-
- chocolate
-
-
-
- 1
-
- nuts
-
-
-
- 2
-
- shellfish
-
-
-
-
- 0
-
-
- 0
- 10
-
-
- 1
- 10
-
-
- 2
- 10
-
-
- 3
- 10
-
-
- 4
- 10
-
-
- 5
- 10
-
-
- 6
- 10
-
-
- 7
- 10
-
-
- 8
- 10
-
-
- 9
- 10
-
-
- 10
- 10
-
-
- 11
- 10
-
-
- 12
- 10
-
-
- 13
- 10
-
-
- 14
- 10
-
-
- 15
- 10
-
-
- 16
- 10
-
-
- 17
- 10
-
-
- 18
- 10
-
-
- 19
- 10
-
-
- 20
- 10
-
-
-
-
- 0
- false
-
-
- 1
- false
-
-
- 2
- false
-
-
-
-
- 1
-
-
- 0
- 10
-
-
- 1
- 10
-
-
- 2
- 10
-
-
- 3
- 10
-
-
- 4
- 10
-
-
- 5
- 10
-
-
- 6
- 10
-
-
- 7
- 10
-
-
- 8
- 10
-
-
- 9
- 10
-
-
- 10
- 10
-
-
- 11
- 10
-
-
- 12
- 10
-
-
- 13
- 10
-
-
- 14
- 10
-
-
- 15
- 10
-
-
- 16
- 10
-
-
- 17
- 10
-
-
- 18
- 10
-
-
- 19
- 10
-
-
- 20
- 10
-
-
-
-
- 0
- false
-
-
- 1
- false
-
-
- 2
- false
-
-
-
-
- 2
-
-
- 0
- 10
-
-
- 1
- 10
-
-
- 2
- 10
-
-
- 3
- 10
-
-
- 4
- 10
-
-
- 5
- 10
-
-
- 6
- 10
-
-
- 7
- 10
-
-
- 8
- 10
-
-
- 9
- 10
-
-
- 10
- 10
-
-
- 11
- 10
-
-
- 12
- 10
-
-
- 13
- 10
-
-
- 14
- 10
-
-
- 15
- 10
-
-
- 16
- 10
-
-
- 17
- 10
-
-
- 18
- 10
-
-
- 19
- 10
-
-
- 20
- 10
-
-
-
-
- 0
- false
-
-
- 1
- false
-
-
- 2
- false
-
-
-
-
- 3
-
-
- 0
- 10
-
-
- 1
- 10
-
-
- 2
- 10
-
-
- 3
- 10
-
-
- 4
- 10
-
-
- 5
- 10
-
-
- 6
- 10
-
-
- 7
- 10
-
-
- 8
- 10
-
-
- 9
- 10
-
-
- 10
- 10
-
-
- 11
- 10
-
-
- 12
- 10
-
-
- 13
- 10
-
-
- 14
- 10
-
-
- 15
- 10
-
-
- 16
- 10
-
-
- 17
- 10
-
-
- 18
- 10
-
-
- 19
- 10
-
-
- 20
- 10
-
-
-
-
- 0
- false
-
-
- 1
- false
-
-
- 2
- false
-
-
-
-
- 4
-
-
- 0
- 10
-
-
- 1
- 10
-
-
- 2
- 10
-
-
- 3
- 10
-
-
- 4
- 10
-
-
- 5
- 10
-
-
- 6
- 10
-
-
- 7
- 10
-
-
- 8
- 10
-
-
- 9
- 10
-
-
- 10
- 10
-
-
- 11
- 10
-
-
- 12
- 10
-
-
- 13
- 10
-
-
- 14
- 10
-
-
- 15
- 10
-
-
- 16
- 10
-
-
- 17
- 10
-
-
- 18
- 10
-
-
- 19
- 10
-
-
- 20
- 10
-
-
-
-
- 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
index 677ea76..9dbb300 100644
--- a/src/dkohl/bayes/builders/FoodNetBuilder.java
+++ b/src/dkohl/bayes/builders/FoodNetBuilder.java
@@ -23,14 +23,19 @@ import dkohl.onthology.Ontology;
public class FoodNetBuilder {
public static final String TASTE = "Taste";
- public static final String SOMEONE_VEGETARIAN = "Vegetarian";
+
+ public static final String SOMEONE_VEGETARIAN = "vegetarian";
+ public static final String SOMEONE_ALLERGIC_NUTS = "allergic-nuts";
+
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 CONTAINS_NUTS = "Nuts";
+ public static final String CONTAINS_GENERIC_NUTS = TYPE.GENERIC_NUTS.toString();
+
public static final String TRUE_VALUE = "true";
public static final String FALSE_VALUE = "false";
@@ -39,27 +44,30 @@ public class FoodNetBuilder {
public static final String RATING_DOMAIN[] = { "1", "2", "3", "4", "5",
"6", "7", "8", "9", "10" };
- private static final String[] VARIABLES = { SOMEONE_VEGETARIAN,
+ private static final String[] VARIABLES = { SOMEONE_VEGETARIAN, SOMEONE_ALLERGIC_NUTS,
CONTAINS_BEEF, CONTAINS_MEAT, CONTAINS_PORK, CONTAINS_POTATOS,
- CONTAINS_TOMATOS, CONTAINS_VEGETABLE, TASTE };
+ CONTAINS_TOMATOS, CONTAINS_VEGETABLE, CONTAINS_NUTS, CONTAINS_GENERIC_NUTS, TASTE };
private static final String[] OBSERVED = { CONTAINS_BEEF, CONTAINS_PORK,
- CONTAINS_POTATOS, CONTAINS_TOMATOS, };
+ CONTAINS_POTATOS, CONTAINS_TOMATOS, CONTAINS_GENERIC_NUTS};
public static Ontology createOntology() {
HashSet classes = new HashSet();
classes.add(CONTAINS_MEAT);
+ classes.add(CONTAINS_NUTS);
classes.add(CONTAINS_VEGETABLE);
- Ontology onthology = new Ontology(classes);
+ Ontology ontology = new Ontology(classes);
- onthology.define(CONTAINS_PORK, CONTAINS_MEAT);
- onthology.define(CONTAINS_BEEF, CONTAINS_MEAT);
+ ontology.define(CONTAINS_PORK, CONTAINS_MEAT);
+ ontology.define(CONTAINS_BEEF, CONTAINS_MEAT);
- onthology.define(CONTAINS_TOMATOS, CONTAINS_VEGETABLE);
- onthology.define(CONTAINS_POTATOS, CONTAINS_VEGETABLE);
- return onthology;
+ ontology.define(CONTAINS_GENERIC_NUTS, CONTAINS_NUTS);
+
+ ontology.define(CONTAINS_TOMATOS, CONTAINS_VEGETABLE);
+ ontology.define(CONTAINS_POTATOS, CONTAINS_VEGETABLE);
+ return ontology;
}
private static Assignment build(String varible, String value) {
@@ -86,14 +94,13 @@ public class FoodNetBuilder {
return normPoint;
}
- public static DataSet getSurveyDataSet(Survey survey, RecipeBook recipeBook) {
+ public static DataSet getSurveyDataSet(Survey survey, RecipeBook recipeBook, int startIndex, int endIndex) {
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++) {
+ for (int dishIndex = startIndex; dishIndex < endIndex; dishIndex++) {
data.add(normalize(createDataPoint(recipeBook, survey.getDish(dishIndex), diner.getRating(dishIndex)),onto));
}
}
@@ -118,20 +125,41 @@ public class FoodNetBuilder {
if (ingredients.contains(TYPE.TOMATO)) {
point.add(build(CONTAINS_TOMATOS, TRUE_VALUE));
}
+ if (ingredients.contains(TYPE.GENERIC_NUTS)) {
+ point.add(build(CONTAINS_GENERIC_NUTS, TRUE_VALUE));
+ }
point.add(build(TASTE, "" + weight));
return point;
}
- public static ProbabilityDistribution vegi() {
+ public static ProbabilityDistribution vegi(Survey survey) {
String names[] = { SOMEONE_VEGETARIAN };
ProbabilityTable table = new ProbabilityTable(names);
- table.setProbabilityForAssignment("true;", new Probability(0));
- table.setProbabilityForAssignment("false;", new Probability(1));
+ if (survey.isDiner("vegetarian")) {
+ table.setProbabilityForAssignment("true;", new Probability(1));
+ table.setProbabilityForAssignment("false;", new Probability(0));
+ } else {
+ table.setProbabilityForAssignment("true;", new Probability(0));
+ table.setProbabilityForAssignment("false;", new Probability(1));
+ }
return table;
}
+ public static ProbabilityDistribution allergicNuts(Survey survey) {
+ String names[] = { SOMEONE_ALLERGIC_NUTS };
+ ProbabilityTable table = new ProbabilityTable(names);
+ if (survey.isDiner("allergic-nuts")) {
+ table.setProbabilityForAssignment("true;", new Probability(1));
+ table.setProbabilityForAssignment("false;", new Probability(0));
+ } else {
+ 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);
@@ -143,13 +171,25 @@ public class FoodNetBuilder {
ProbabilityTable table = new ProbabilityTable(names);
return table;
}
-
- public static ProbabilityDistribution meet() {
+
+ public static ProbabilityDistribution meat() {
String names[] = { SOMEONE_VEGETARIAN, CONTAINS_MEAT };
ProbabilityTable table = new ProbabilityTable(names);
return table;
}
-
+
+ public static ProbabilityDistribution genericNuts() {
+ String names[] = { CONTAINS_NUTS, CONTAINS_GENERIC_NUTS };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution nuts() {
+ String names[] = { SOMEONE_ALLERGIC_NUTS, CONTAINS_NUTS };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
public static ProbabilityDistribution tomatos() {
String names[] = { CONTAINS_VEGETABLE, CONTAINS_TOMATOS };
ProbabilityTable table = new ProbabilityTable(names);
@@ -170,27 +210,34 @@ public class FoodNetBuilder {
public static ProbabilityDistribution taste() {
String names[] = { TASTE, CONTAINS_BEEF, CONTAINS_PORK,
- CONTAINS_POTATOS, CONTAINS_TOMATOS };
+ CONTAINS_POTATOS, CONTAINS_TOMATOS, CONTAINS_GENERIC_NUTS };
ContinousDistribution distribution = new ContinousDistribution(names, 0);
return distribution;
}
- public static BayesNet createDishNet(Survey survey, RecipeBook recipeBook) {
+ public static BayesNet createDishNet(Survey survey, RecipeBook recipeBook, int startIndex, int endIndex) {
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(SOMEONE_VEGETARIAN, DOMAIN), vegi(survey));
+ net.setDistribution(new Variable(SOMEONE_ALLERGIC_NUTS, DOMAIN), allergicNuts(survey));
+
+ net.setDistribution(new Variable(CONTAINS_MEAT, DOMAIN), meat());
+ net.setDistribution(new Variable(CONTAINS_NUTS, DOMAIN), nuts());
+
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(CONTAINS_GENERIC_NUTS, DOMAIN), genericNuts());
+
net.setDistribution(new Variable(TASTE, RATING_DOMAIN), taste());
Ontology ontology = createOntology();
for (String category : ontology.getClasses()) {
net.connect(category, SOMEONE_VEGETARIAN);
+ net.connect(category, SOMEONE_ALLERGIC_NUTS);
}
for (String thing : OBSERVED) {
@@ -198,7 +245,7 @@ public class FoodNetBuilder {
net.connect(TASTE, thing);
}
- DataSet dataSet = getSurveyDataSet(survey, recipeBook);
+ DataSet dataSet = getSurveyDataSet(survey, recipeBook, startIndex, endIndex);
for (String category : ontology.getClasses()) {
MaximumLikelihoodEstimation.estimate(dataSet, net, category);
diff --git a/src/dkohl/util/RootMeanSquareError.java b/src/dkohl/util/RootMeanSquareError.java
index 3f10774..00eb797 100644
--- a/src/dkohl/util/RootMeanSquareError.java
+++ b/src/dkohl/util/RootMeanSquareError.java
@@ -4,32 +4,27 @@ import java.util.LinkedList;
public class RootMeanSquareError {
- private LinkedList expected;
- private LinkedList groundTruth;
-
- public RootMeanSquareError() {
- expected = new LinkedList();
- groundTruth = new LinkedList();
- }
-
- public void push(double predicted, double actual) {
- expected.add(predicted);
- groundTruth.add(actual);
- }
-
- public double error() {
- double mean = 0.0;
- for(Double val : groundTruth) {
- mean += val;
+ private LinkedList expected;
+ private LinkedList groundTruth;
+
+ public RootMeanSquareError() {
+ expected = new LinkedList();
+ groundTruth = new LinkedList();
}
- mean /= groundTruth.size();
-
- double err = 0.0;
- for(Double val : expected) {
- err += Math.pow(mean - val, 2);
+
+ public void push(double predicted, double actual) {
+ expected.add(predicted);
+ groundTruth.add(actual);
}
- return Math.sqrt(err);
- }
-
-
+
+ public double error() {
+ double mean = 0.0;
+ for (int i = 0; i < expected.size(); i++){
+ mean += Math.pow(expected.get(i) - groundTruth.get(i), 2);
+ }
+ mean /= groundTruth.size();
+
+ return Math.sqrt(mean);
+ }
+
}
diff --git a/src/net/woodyfolsom/cs6601/p2/BayesChef.java b/src/net/woodyfolsom/cs6601/p2/BayesChef.java
index f39cd59..e024008 100644
--- a/src/net/woodyfolsom/cs6601/p2/BayesChef.java
+++ b/src/net/woodyfolsom/cs6601/p2/BayesChef.java
@@ -6,24 +6,22 @@ import java.util.List;
import java.util.Set;
import net.woodyfolsom.cs6601.p2.Ingredient.TYPE;
-
-import org.apache.commons.math3.stat.regression.SimpleRegression;
-
import dkohl.bayes.bayesnet.BayesNet;
import dkohl.bayes.builders.FoodNetBuilder;
import dkohl.bayes.inference.EnumerateAll;
import dkohl.bayes.probability.Assignment;
import dkohl.bayes.probability.ProbabilityAssignment;
import dkohl.bayes.probability.Variable;
+import dkohl.util.RootMeanSquareError;
public class BayesChef {
public static void main(String... args) {
System.out.println("Reading recipe book.");
- RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml"));
+ RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/long_recipebook.xml"));
System.out.println("Reading survey data.");
- Survey survey = SurveyReader.readSurvey(new File("data/short_survey.xml"));
+ Survey survey = SurveyReader.readSurvey(new File("data/long_survey.xml"));
new BayesChef().reportBestMeal(recipeBook,survey);
}
@@ -36,29 +34,39 @@ public class BayesChef {
System.out.println("Read data for " + numDiners + " diner(s).");
System.out.println("Creating Bayes net for survey dataset...");
- BayesNet net = FoodNetBuilder.createDishNet(survey, recipeBook);
- System.out.println("Querying Bayes net for individual flavor preferences: ");
- double[][] flavorPrefs = new double[4][];
+ int numSurveyDishes = survey.getDishCount();
+ int bayesNetIndexStart = 0;
+ int bayesNetIndexEnd = numSurveyDishes / 2;
- flavorPrefs[0] = new double[] {0.0,printPreference(net, TYPE.PORK)};
- flavorPrefs[1] = new double[] {1.0,printPreference(net, TYPE.BEEF)};
- flavorPrefs[2] = new double[] {2.0,printPreference(net, TYPE.POTATO)};
- flavorPrefs[3] = new double[] {3.0,printPreference(net, TYPE.TOMATO)};
+ int comparisonIndexStart = bayesNetIndexEnd;
+ int comparisonIndexEnd = numSurveyDishes;
- SimpleRegression simpleRegression = new SimpleRegression();
- simpleRegression.addData(flavorPrefs);
+ //TODO change this to include min/max recipe indices for building the net
+ BayesNet net = FoodNetBuilder.createDishNet(survey, recipeBook, bayesNetIndexStart, bayesNetIndexEnd);
- System.out.println("Individual flavor pref MSE: " + simpleRegression.getMeanSquareError());
- simpleRegression.clear();
+ System.out.println("Querying Bayes net for predicted flavor preferences: ");
+ //TODO change this to query actual flavor combos from latter half of survey
+ double[] predictedRating = new double[numSurveyDishes - bayesNetIndexEnd];
- System.out.println("Querying Bayes net for recipe flavor preferences: ");
- flavorPrefs = new double[recipeBook.getSize()][];
-
- for (int i = 0; i < recipeBook.getSize(); i++) {
- simpleRegression.addData(i,printPreference(net, recipeBook.getRecipe(i)));
+ for (int i = comparisonIndexStart; i < comparisonIndexEnd; i++) {
+ predictedRating[i - comparisonIndexStart] = printPreference(net, recipeBook.getRecipe(survey.getDish(i)));
}
- System.out.println("Recipe flavor pref MSE: " + simpleRegression.getMeanSquareError());
+
+ System.out.println("Querying survey dataset for actual recipe flavor preferences: ");
+ double[] actualRating = new double[predictedRating.length];
+
+ for (int i = comparisonIndexStart; i < comparisonIndexEnd; i++) {
+ actualRating[i - comparisonIndexStart] = survey.getAverageRating(i);
+ System.out.println("Actual average rating for " + survey.getDish(i) + ": " + actualRating[i - comparisonIndexStart]);
+ }
+
+ RootMeanSquareError rmse = new RootMeanSquareError();
+ for (int i = 0; i < actualRating.length; i++) {
+ rmse.push(predictedRating[i], actualRating[i]);
+ }
+
+ System.out.println("Root Mean Squared Error (predicted vs. actual): " + rmse.error());
}
int printPreference(BayesNet net, Recipe recipe) {
@@ -69,7 +77,7 @@ public class BayesChef {
net, createQuery(ingredientTypes.toArray(new TYPE[ingredientTypes.size()])));
double max_val = 0.0;
- String max_arg = "N/A";
+ String max_arg = "0";
for (ProbabilityAssignment p : probs) {
if (p.getProbability() > max_val) {
max_val = p.getProbability();
@@ -106,6 +114,7 @@ public class BayesChef {
case BEEF:
case POTATO:
case TOMATO:
+ case GENERIC_NUTS:
assignment.add(new Assignment(new Variable(type.toString(), FoodNetBuilder.DOMAIN),
FoodNetBuilder.TRUE_VALUE));
break;
diff --git a/src/net/woodyfolsom/cs6601/p2/Diner.java b/src/net/woodyfolsom/cs6601/p2/Diner.java
index 2b70f7c..d9f6bd9 100644
--- a/src/net/woodyfolsom/cs6601/p2/Diner.java
+++ b/src/net/woodyfolsom/cs6601/p2/Diner.java
@@ -9,7 +9,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
public class Diner {
private int id;
private Map ratings = new HashMap();
- private Map allergies = new HashMap();
+ private Map categories = new HashMap();
public int getId() {
return id;
@@ -19,7 +19,7 @@ public class Diner {
return ratings.get(dishId);
}
- public boolean isAllergic(int categoryId) {
- return allergies.get(categoryId);
+ public boolean isCategory(int categoryId) {
+ return categories.get(categoryId);
}
}
diff --git a/src/net/woodyfolsom/cs6601/p2/Ingredient.java b/src/net/woodyfolsom/cs6601/p2/Ingredient.java
index 6ba48a4..d8c5854 100644
--- a/src/net/woodyfolsom/cs6601/p2/Ingredient.java
+++ b/src/net/woodyfolsom/cs6601/p2/Ingredient.java
@@ -1,15 +1,13 @@
package net.woodyfolsom.cs6601.p2;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("ing")
public class Ingredient {
- public enum TYPE { ALCOHOL, BEEF, DAIRY, EGGS, FISH, GLUTEN, GRAIN, NUTS, PORK, POULTRY, POTATO, SHELLFISH, SPICE, SUGAR, TOMATO}
+ public enum TYPE { ALCOHOL, BEEF, DAIRY, EGGS, FISH, GENERIC_NUTS, GLUTEN, GRAIN, PORK, POULTRY, POTATO, SHELLFISH, SPICE, SUGAR, TOMATO}
private String item;
@@ -30,11 +28,15 @@ public class Ingredient {
public boolean isType(TYPE type) {
switch (type) {
case BEEF :
- return item.contains("beef");
+ //For our purposes, veal is just expensive beef
+ return item.contains("beef") || item.contains("veal");
case DAIRY :
- return item.contains("margarine");
+ return item.contains("margarine") || item.contains("milk");
case EGGS :
return item.equals("egg") || item.equals("eggs");
+ case GENERIC_NUTS :
+ //cashews, peanuts or generic nuts
+ return item.contains("cashew") || item.contains("peanut") || item.contains("nuts");
case GLUTEN :
return item.contains("flour");
case PORK :
diff --git a/src/net/woodyfolsom/cs6601/p2/Survey.java b/src/net/woodyfolsom/cs6601/p2/Survey.java
index 877c872..3b1910a 100644
--- a/src/net/woodyfolsom/cs6601/p2/Survey.java
+++ b/src/net/woodyfolsom/cs6601/p2/Survey.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
@@ -16,6 +17,32 @@ public class Survey {
@XStreamImplicit(itemFieldName="diner")
private List diners = new ArrayList();
+ public double getAverageRating(int recipeIndex) {
+ double total = 0.0;
+ for (Diner diner : diners) {
+ total += diner.getRating(recipeIndex);
+ }
+ return total/diners.size();
+ }
+
+ public boolean isDiner(String category) {
+ for (int i = 0; i < diners.size(); i++) {
+ if (isCategory(i,category)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isCategory(int dinerIndex, String category) {
+ for (Entry entry : categories.entrySet()) {
+ if (entry.getValue().equals(category)) {
+ return diners.get(dinerIndex).isCategory(entry.getKey());
+ }
+ }
+ return false;
+ }
+
public Diner getDiner(int dinerIndex) {
return diners.get(dinerIndex);
}
diff --git a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
index 3871b76..0661047 100644
--- a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
+++ b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
@@ -18,10 +18,10 @@ import org.junit.Test;
public class RecipeBookReaderTest {
@Test
- public void testReadSurveyDataset() {
- RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/survey_recipes.xml"));
+ public void testReadLongRecipeBook() {
+ RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/long_recipebook.xml"));
assertNotNull(recipeBook);
- assertThat(recipeBook.getSize(), is(equalTo(22)));
+ assertThat(recipeBook.getSize(), is(equalTo(25)));
Recipe recipe = recipeBook.getRecipe(0);
System.out.println(recipe.getHead().getTitle());
@@ -39,7 +39,28 @@ public class RecipeBookReaderTest {
}
@Test
- public void testReadShortSurveyDataset() {
+ public void testReadMediumRecipeBook() {
+ RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/medium_recipebook.xml"));
+ assertNotNull(recipeBook);
+ assertThat(recipeBook.getSize(), is(equalTo(4)));
+
+ Recipe recipe = recipeBook.getRecipe(0);
+ System.out.println(recipe.getHead().getTitle());
+ assertThat(recipe.getHead().getTitle(), is(equalTo("Catalan Rice")));
+ assertFalse(recipe.getIngredients().contains(TYPE.EGGS));
+ assertFalse(recipe.getIngredients().contains(TYPE.GLUTEN));
+ assertTrue(recipe.getIngredients().contains(TYPE.SPICE));
+ assertFalse(recipe.getIngredients().contains(TYPE.BEEF));
+ assertFalse(recipe.getIngredients().contains(TYPE.POULTRY));
+ assertFalse(recipe.getIngredients().contains(TYPE.SHELLFISH));
+
+ for (int rIndex = 0; rIndex < recipeBook.getSize(); rIndex++) {
+ System.out.println(recipeBook.getRecipe(rIndex).getHead().getTitle());
+ }
+ }
+
+ @Test
+ public void testReadShortRecipeBook() {
RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml"));
assertNotNull(recipeBook);
assertThat(recipeBook.getSize(), is(equalTo(4)));
diff --git a/test/net/woodyfolsom/cs6601/p2/SurveyReaderTest.java b/test/net/woodyfolsom/cs6601/p2/SurveyReaderTest.java
index c000c97..0b86a18 100644
--- a/test/net/woodyfolsom/cs6601/p2/SurveyReaderTest.java
+++ b/test/net/woodyfolsom/cs6601/p2/SurveyReaderTest.java
@@ -12,13 +12,37 @@ import org.junit.Test;
public class SurveyReaderTest {
@Test
- public void testReadSurveyDataset() {
- Survey survey = SurveyReader.readSurvey(new File("data/survey.xml"));
+ public void testReadLongSurveyDataset() {
+ Survey survey = SurveyReader.readSurvey(new File("data/long_survey.xml"));
assertNotNull(survey);
- assertThat(survey.getDinerCount(), equalTo(5));
+ assertThat(survey.getDishCount(), equalTo(10));
+ assertThat(survey.getDinerCount(), equalTo(4));
+
+ assertThat(survey.isCategory(0,"vegetarian"), is(false));
+ assertThat(survey.isCategory(0,"allergic-nuts"), is(false));
+
+ assertThat(survey.isCategory(1,"vegetarian"), is(true));
+ assertThat(survey.isCategory(1,"allergic-nuts"), is(false));
+
+ assertThat(survey.isCategory(2,"vegan"), is(false));
+ assertThat(survey.isCategory(2,"allergic-nuts"), is(true));
+
+ assertThat(survey.isDiner("vegetarian"), is(true));
+ assertThat(survey.isDiner("allergic-nuts"), is(true));
+ assertThat(survey.isDiner("rastafarian"), is(false));
+ }
+
+ @Test
+ public void testReadMediumSurveyDataset() {
+ Survey survey = SurveyReader.readSurvey(new File("data/medium_survey.xml"));
+ assertNotNull(survey);
+
+ assertThat(survey.getDinerCount(), equalTo(2));
Diner diner = survey.getDiner(0);
- assertThat(diner.isAllergic(0), is(false));
+ assertThat(diner.isCategory(0), is(false));
+ diner = survey.getDiner(1);
+ assertThat(diner.isCategory(0), is(true));
}
}