Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kierakeating/2e4e7936d5a9f5249700 to your computer and use it in GitHub Desktop.
Save kierakeating/2e4e7936d5a9f5249700 to your computer and use it in GitHub Desktop.

FOOD RECIPES RECOMMENDATION GRAPH

Introduction

The purpose of this food recommendation system is to isolate peoples' certain heath problems and preferences and give recommendations to recipes that satisfy their needs. This model organizes a collection of food recipes and combines it with a social network of people. This way, people can cook for their friends based on things that they both love and that will not be detrimental to their health.

Nodes and Attributes

There are three types of nodes that are taken into consideration:

Each person node represents a single person from a group of friends, each with unique attributes. In total, there are 6 people within the group of friends.

  • Person

  • Recipe

  • Product

The recipe nodes represent recipes for different foods and dishes. The attributes of it taken into consideration are: the name of the recipe; the formula; and the type of meal it is designed for, such as whether it is a dessert or a main dish. There are 5 total recipes.

The product nodes represent the ingredients found within the recipes or within the allergies that each person had. There are 16 total products.

Relationships

There are many types of relationships and the attributes for each type.

IS_FRIEND_OF relationship is used to describe if a person is friends with another person.

  • ex. Bob IS_FRIEND_OF Alice

IS_ALLERGIC_TO describes if one person is allergic to a specific product or ingredient.

  • ex. Bob IS_ALLERGIC_TO potato

LOVES is used to describe if a person loves a specific product.

  • ex. Bob LOVES pasta

HATES is used to describe if a person hates a specific product.

  • ex. Bob HATES rice

HAS_INGREDIENT is used to form a relationship between the recipe and the product.

  • ex. potatoes HAS_INGREDIENT potato

Nodes Connecting Relationships

The three different nodes used in this Food Recipes Recommendation Graph can be linked in the five different ways described in the relationship section.

  • Person uses the Is_FRIEND_OF relationship to connect to another Person

  • Person uses the IS_ALLERGIC_TO relationship to connect to a specific Product

  • Person uses the LOVES relationship to connect to a specific Product

  • Person uses the HATES relationship to connect to a specific Prodcut

  • Recipe uses the HAS_INGREDIENT relationship to connect it to a Product

Data Summary

The table below summarizes the data for each person that we have added to the database.

Person Is Friend Of Is Allergic To Loves Hates

Michael

Cathy

cow milk

chocolate

bananas

Mateo

gluten

wheat

Cathy

Michael

nuts

chocolate

wheat

Mateo

Michael

strawberries

apples

Peter

John

gluten

Mary

John

Peter

gluten

Mary

Peter

cow milk

apples

This table organizes the Recipes and which ingredients they use.

Recipe Type Ingredients

chocolate soup

dessert

passion fruit, coconut milk, chocolate, sugar

chocolate cake

dessert

chocolate, wheat, sugar, eggs

strawberry ice cream

dessert

water, surgar, strawberries

tomato soup

starter

tomatoes, water, rice

tomato sauce

sauce

tomatoes, water, onion

Queries

The application can be used to identify and answer specific questions pertaining to the different peopele and their food allergies. Below are examples of queries that can be used to find reccomendations:

Who are Peter’s friends?

MATCH (m:Person { name:"Peter" })-[IS_FRIEND_TO]-(f:Person)
RETURN f

This query would be useful if you were just getting an idea of who is friends with who. If you are having a dinner party and invited Peter, you could see who he may bring to the party as well. Using this information, you could create a query that found a recipe that they would all enjoy.

What are the different dessert recipes?

MATCH(n:Recipe{type:"dessert"})
Return n

If your database had a lot of recipes, you could choose to just look at the desserts. This query would filter out all of the recipes and give you back just ones with the type "dessert".

What ingredients are in ___?

MATCH(n:Recipe{name:"Chocolate soup"})-[:HAS_INGREDIENT]->(r:Product)
Return r
MATCH(n:Recipe{name:"Chocolate cake"})-[:HAS_INGREDIENT]->(r:Product)
Return r
MATCH(n:Recipe{name:"Tomato soup"})-[:HAS_INGREDIENT]->(r:Product)
Return r
MATCH(n:Recipe{name:"Strawberry icecream"})-[:HAS_INGREDIENT]->(r:Product)
Return r
MATCH(n:Recipe{name:"Tomato sauce"})-[:HAS_INGREDIENT]->(r:Product)
Return r

This query is useful in looking at all the ingredients that are used to make a specific recipe. You would use this information if you were going to buy the ingredients.

What are people allergic to?

MATCH(n:Person)-[:IS_ALLERGIC_TO]->(r:Product)
Return n,r

You could use this query to get an overall picture of what people are allergic to. By looking at this query you can see that Cathy is allergic to nuts, Cathy and Michael are allergic to wheat, Michael and Mary are allergic to cow milk, Mary is allergic to apple, and Michael, Peter, and John are allergic to gluten. This could be useful if you want to see an ingredient tht the most people are allergic to before making a recipe.

What does Cathy love?

MATCH (m:Person { name:"Cathy" })-[:LOVES]->(good_food:Product)
WITH m, good_food
RETURN good_food

This query returns one ingredient that Cathy loves, which is chocolate. Maybe if you are making a recipe for Cathy using this data, you would make chocolate soup or chocolate cake since it contains an ingredient that she loves.

What recipe can I make that Cathy would love?

//check what ingredients Cathy loves
MATCH (m:Person { name:"Cathy" })-[:LOVES]->(good_food:Product)
WITH m, good_food

//checking what Cathy should not eat
MATCH (m:Person { name:"Cathy" })-[:IS_ALLERGIC_TO|HATES]->(bad_food:Product)
WITH m, bad_food

//checking the recipes that Cathy should not eat
MATCH (r:Recipe)-[:HAS_INGREDIENT]->(p:Product)
WITH m, bad_food, p, r
WHERE p = bad_food
WITH m, bad_food, r AS bad_recipe

//checking the recipes that Cathy can eat
MATCH (r:Recipe)-[:HAS_INGREDIENT]->(p:Product)
WITH m, bad_recipe, r
WHERE NOT (r = bad_recipe)
WITH r AS rec_recipe, m

//return recipe that she can eat that includes ingredient she loves
MATCH (m)-[:LOVES]->(favorite:Product)<-[HAS_INGREDIENT]-(rec_recipe)
RETURN DISTINCT rec_recipe.name as recommended_recipe

This query takes into consideration Cathy’s ingredient that she loves. First it checks what ingredient Cathy loves, then it checks what ingredients she is allergic to or hates, then it eliminates the recipes that contain these bad ingredients. Finally, it returns a recipe that includes the ingredient she loves and is safe for her to eat based on her wants and needs.

What are the least common food allergies?

MATCH ()-[:IS_ALLERGIC_TO]->(r:Product)
WITH COUNT(*) AS total
MATCH ()-[a:IS_ALLERGIC_TO]->(r:Product)
WITH total, r.name AS name, count(a) AS each_sum
RETURN name,(each_sum*100.0)/(total)*1.0 AS percentage
ORDER BY percentage ASC , name

What are the most common food allergies?

MATCH ()-[:IS_ALLERGIC_TO]->(r:Product)
WITH COUNT(*) AS total
MATCH ()-[a:IS_ALLERGIC_TO]->(r:Product)
WITH total, r.name AS name, count(a) AS each_sum
RETURN name,(each_sum*100.0)/(total)*1.0 AS percentage
ORDER BY percentage DESC , name

Finding the least and most commmon food allergies would be especially useful if throwing a party. If you were to invite a lot of people, you could see what ingredient most people are allergic to so that you can avoid that in all your dishes, if possible.

What products are the most often used in desserts?

MATCH (r:Recipe{type:"dessert"})-[i:HAS_INGREDIENT]->(p:Product)
WITH p.name as name, count(i) as sum
RETURN name
ORDER BY sum desc

You could look at the products that are most often used in desserts if you aren’t sure what you want to make. If you saw that cow milk was a common ingredient and you didn’t have very much, then you would maybe decide to make something else.

I (Michael) feel like eating a dessert, what can I cook?

//checking what Michael should not eat
MATCH (m:Person { name:"Michael" })-[:IS_ALLERGIC_TO|HATES]->(bad_food:Product)
WITH m, bad_food

//checking the recipes for desserts that Michael should not eat
MATCH (r:Recipe { type:"dessert" })-[:HAS_INGREDIENT]->(p:Product)
WITH m, bad_food, p, r
WHERE p = bad_food
WITH m, bad_food, r AS bad_recipe

//checking the recipes for dessert that Michael can eat
MATCH (r:Recipe { type:"dessert" })-[:HAS_INGREDIENT]->(p:Product)
WITH m, bad_recipe, r
WHERE NOT (r = bad_recipe)
WITH r AS rec_dessert, m

//checking the favourite ingredients that the allowed recipe can contain
MATCH (m)-[:LOVES]->(favorite:Product)<-[HAS_INGREDIENT]-(rec_dessert)
RETURN DISTINCT rec_dessert.name as recommended_dessert

If Michael wanted a dessert, the program would check what Michael is allergic to or hates, and then check the recipes that include these ingredients. It would then eliminate the recipes that included the "bad food" and find recipes of the desserr type that had an ingredient that he loves and is not allergic to. This query would ensure that the dessert recommended was safe for him to eat and that he would enjoy it.

I (Michael) feel like cooking something of tomatoes and rice, what can I cook with these products (taking into account my preferences)?

//checking products Michael should not eat
MATCH (m:Person { name:"Michael" })-[:IS_ALLERGIC_TO|HATES]->(bad_food:Product)
WITH bad_food

//checking the recipes that Michael should not eat
MATCH (r:Recipe)-[:HAS_INGREDIENT]->(p:Product)
WITH bad_food, p, r
WHERE p = bad_food
WITH bad_food, r AS bad_recipe

//checking if 2 ingredients match somewhere and Michael can eat this food
MATCH (tomato:Product{ name:"tomato" })<-[:HAS_INGREDIENT]-(r:Recipe)-[:HAS_INGREDIENT]->(rice:Product{ name:"rice" })
WITH r, bad_food, bad_recipe
WHERE NOT (r = bad_recipe)
MATCH (r)-[:HAS_INGREDIENT]->(p:Product)
WITH r.name as recipe, p
return recipe, collect(p.name) as ingredients

In this scenario, Michael wants to focus on the products of tomatoes and rice. First it would look at what he is allergic to and hates and then eliminate the recipes that contain these ingredients. Then, it would match the tomato and rice ingredients to a recipe that was safe for him and that he liked that also contained tomatoes and rice.

My friends are coming, what can I (Michael) cook for a dessert to please them all?

//cheching products Michael and his friends should not eat
MATCH (my_bad_food:Product)<-[:IS_ALLERGIC_TO|HATES]-(m:Person { name:"Michael" })-[IS_FRIEND_TO]-(f:Person)-[:IS_ALLERGIC_TO|HATES]->(bad_food:Product)
WITH m, bad_food, my_bad_food

//checking the recipes for desserts that they should not eat
MATCH (r:Recipe { type:"dessert" })-[:HAS_INGREDIENT]->(p:Product)
WITH m, bad_food, my_bad_food, p, r
WHERE p = bad_food OR p = my_bad_food
WITH m, r AS bad_recipe

//checking the recipes for dessert that they can eat
MATCH (r:Recipe { type:"dessert" })-[:HAS_INGREDIENT]->(p:Product)
WITH m,  bad_recipe, r
WHERE NOT (r = bad_recipe)
WITH r AS rec_dessert, m

//checking the favourite ingredients that the allowed recipe can contain
MATCH (m)-[:LOVES]->(favorite:Product)<-[:HAS_INGREDIENT]-(rec_dessert)
RETURN DISTINCT rec_dessert.name as recommended_dessert

This scenario would be the most realisitc to what I see the program being used for. If you want to find a dessert that satisfies all of your friends' wants and needs, you would first eliminate the recipes that contained ingredients that you nad your connection of friends hated and are allergic to. Then, you would narrow down the recipes to just the desserts and see which recipe contains the most favored ingredients. This recipe would be recommended for you to make because it takes into consideration all of your friends, their allergies, and their likes and dislikes.

Conclusion

This type of food recommendation system could be really useful on a recipe social network site. People could create a profile and input ingredients they are allergic to, things the love, and things they hate. The site can then narrow down personalized recipes that fit their needs. People could also link with their friends' profiles and search recipes that match both of their needs if they are going to cook something together. It could also be useful when preparing something for a friend, as you will be able to see their allergies and if they love or hate certain ingredients. I think this would be most useful if you coul dcreate "Events" and the website can find recipes that everyone will like and be able to eat.

Data Model

62f589ad
//Person
CREATE (michael:Person{name:'Michael'}),
       (cathy:Person{name:'Cathy'}),
       (mateo:Person{name:'Mateo'}),
       (peter:Person{name:'Peter'}),
       (john:Person{name:'John'}),
       (mary:Person{name:'Mary'})

//Product
CREATE (chocolate:Product{name:'chocolate'}),
       (cow_milk:Product{name:'cow_milk'}),
       (gluten:Product{name:'gluten'}),
       (nuts:Product{name:'nuts'}),
       (wheat:Product{name:'wheat'}),
       (passion_fruit:Product{name:'passion fruit'}),
       (coconut_milk:Product{name:'coconut milk'}),
       (sugar:Product{name:'sugar'}),
       (egg:Product{name:'egg'}),
       (apple:Product{name:'apple'}),
       (tomato:Product{name:'tomato'}),
       (water:Product{name:'water'}),
       (rice:Product{name:'rice'}),
       (banana:Product{name:'banana'}),
       (strawberry:Product{name:'strawberry'}),
       (onion:Product{name:'onion'})

//Recipe
CREATE (chocolate_soup:Recipe{name:'Chocolate soup', type:'dessert', formula:'formula for the Chocolate soup'}),
       (chocolate_cake:Recipe{name:'Chocolate cake', type:'dessert', formula:'formula for the Chocolate cake'}),
       (tomato_soup:Recipe{name:'Tomato soup', type:'starter', formula:'formula for the Tomato soup'}),
       (strawberry_icecream:Recipe{name:'Strawberry icecream', type:'dessert', formula:'formula for the Strawberry icecream'}),
       (tomato_sauce:Recipe{name:'Tomato sauce', type:'sauce', formula:'formula for the Tomato sauce'})

//Friendship
CREATE michael-[:IS_FRIEND_OF]->cathy,
       cathy-[:IS_FRIEND_OF]->michael,
       michael-[:IS_FRIEND_OF]->mateo,
       mateo-[:IS_FRIEND_OF]->michael,
       peter-[:IS_FRIEND_OF]->john,
       john-[:IS_FRIEND_OF]->peter,
       peter-[:IS_FRIEND_OF]->mary,
       mary-[:IS_FRIEND_OF]->peter


//Allergies and preferences
CREATE michael-[:IS_ALLERGIC_TO]->cow_milk,
       michael-[:IS_ALLERGIC_TO]->gluten,
       michael-[:IS_ALLERGIC_TO]->wheat,
       michael-[:LOVES]->chocolate,
       michael-[:HATES]->banana,

       cathy-[:IS_ALLERGIC_TO]->nuts,
       cathy-[:IS_ALLERGIC_TO]->wheat,
       cathy-[:LOVES]->chocolate,

       mateo-[:LOVES]->strawberries,
       mateo-[:HATES]->apples,

       peter-[:IS_ALLERGIC_TO]->gluten,
       john-[:IS_ALLERGIC_TO]->gluten,
       mary-[:IS_ALLERGIC_TO]->cow_milk,
       mary-[:IS_ALLERGIC_TO]->apple

//Recipes made of Products
CREATE chocolate_soup-[:HAS_INGREDIENT]->passion_fruit,
       chocolate_soup-[:HAS_INGREDIENT]->coconut_milk,
       chocolate_soup-[:HAS_INGREDIENT]->chocolate,
       chocolate_soup-[:HAS_INGREDIENT]->sugar,
       chocolate_cake-[:HAS_INGREDIENT]->chocolate,
       chocolate_cake-[:HAS_INGREDIENT]->wheat,
       chocolate_cake-[:HAS_INGREDIENT]->sugar,
       chocolate_cake-[:HAS_INGREDIENT]->egg,
       strawberry_icecream-[:HAS_INGREDIENT]->water,
       strawberry_icecream-[:HAS_INGREDIENT]->sugar,
       strawberry_icecream-[:HAS_INGREDIENT]->strawberry,
       tomato_soup-[:HAS_INGREDIENT]->tomato,
       tomato_soup-[:HAS_INGREDIENT]->water,
       tomato_soup-[:HAS_INGREDIENT]->rice,
       tomato_sauce-[:HAS_INGREDIENT]->tomato,
       tomato_sauce-[:HAS_INGREDIENT]->water,
       tomato_sauce-[:HAS_INGREDIENT]->onion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment