Analyzing recipes​
​by Firmiana Wang
Recipes consist of a list of required ingredients and a set of instructions used for preparing a specific dish. A recipe records the precise amount of ingredients used and in what way they are combined. In this project, my goal was to explore a recipe dataset and draw conclusions about the various aspects of recipes.

Setting Up the Data

The recipe data used in this project came from MIT's Recipe1M+ dataset found at this link: http://pic2recipe.csail.mit.edu/. Since most of my analysis was focused on each recipe's title, ingredient list, quantities, units, and instructions, I created a smaller dataset with this information.
Import the dataset:
rawData=CloudGet[CloudObject[
https://www.wolframcloud.com/obj/firmianaw/data
]];
Fix the ingredient list formatting:
In[]:=
fixIngredients[ingredientList_]:=If[#[[1]]=="spices"||#[[1]]=="sauce"||#[[1]]=="cereals ready-to-eat",#[[2]],#[[1]]]&/@(Flatten[StringSplit[#,", "]]&/@Values[ingredientList])
Convert the format of the other rows:
In[]:=
fixFormat[originalData_]:=Flatten[Values[originalData]]
Select the specific rows:
In[]:=
data=<|#[["title"]]-><|"ingredients"->fixIngredients[#[["ingredients"]]],"quantities"->fixFormat[#[["quantity"]]],"units"->fixFormat[#[["unit"]]],"instructions"->fixFormat[#[["instructions"]]]|>&/@rawData|>;

Techniques Used in Recipes

I first wanted to look at the frequency of the techniques used or actions performed in recipes. After looking through some of the recipe instructions, I noticed that most of the verbs that signify what action to perform were typically the first word of each step and occasionally after the word "and". For this analysis, I decided to focus on the verbs that came at the beginning of each step. Even so, there were cases where the first word in a step was a number, punctuation mark (such as a parentheses), or transitional words. To extract mainly verbs, I removed all punctuation characters, digit characters, and stop words.
Take the first word in each step of all recipe instructions:
In[]:=
firstWords=StringSplit[#][[1]]&/@Flatten[Values[newData][[All,"instructions"]]]//Short
Out[]//Short=
{Layer,Cream,Add,Mix,339849,Store,Julienne,Combine,Serve}
Remove all punctuation characters, digit characters, and stop words:
In[]:=
firstWordsClean=StringDelete[DeleteStopwords[firstWords],PunctuationCharacter|DigitCharacter];
Word cloud showing the most frequent actions performed in recipes:
WordCloudfirstWordsClean,

Out[]=
Although the word cloud still contained several adverbs, it shows that the most frequent actions performed in recipes include incorporating actions such as "add", "mix", "combine", and "stir". These results are consistent with the idea of a recipe, which provides a series of steps in combining ingredients to create a certain dish.

Baking vs. Non-Baking Recipes

One of the most common verbs shown in the technique word cloud above was "bake". Baking is a method of preparing food through dry heat and uses an oven. For the purpose of this project, I only considered recipes containing the word "bake" as baking recipes. With this in mind, I focused on looking at the differences in the number of ingredients, number of steps in the recipe's instructions (I will be referring to this as the recipe length), and ingredient frequency between baking and non-baking recipes.
To begin, I created a function to check if a recipe contains the word "bake".
Helper function to check if a recipe contains the word "bake":
hasBake[instructions_]:=If[Length[StringCases[StringJoin[instructions],"Bake",IgnoreCaseTrue]]==0,False,True]
For example, yogurt parfaits do not need to be baked:
In[]:=
hasBake[data[["Yogurt Parfaits","instructions"]]]
Out[]=
False
With this function, I associated either "baking" or "non-baking" to each recipe's number of ingredients, ingredient list, and recipe length.
Check for "bake" and associate with either "baking" or "non-baking":
In[]:=
bakeAssociations=If[hasBake[#[["instructions"]]],"baking"->{Length[#[["ingredients"]]],#[["ingredients"]],Length[#[["instructions"]]]},"non-baking"->{Length[#[["ingredients"]]],#[["ingredients"]],Length[#[["instructions"]]]}]&/@data;
Then, I needed to separate the baking recipes from the non-baking recipes.
Take the values that are associated with “baking”:
In[]:=
bakeRecipes=Values[GatherBy[Values[bakeAssociations],First][[2]]];
In[]:=
bakeRecipes//Short
Out[]//Short=
{{7,{sugars,oil,4,wheat flour},9},12581}
Take the values that are associated with "non-baking":
In[]:=
noBakeRecipes=Values[GatherBy[Values[bakeAssociations],First][[1]]];
In[]:=
noBakeRecipes//Short
Out[]//Short=
{{3,{yogurt,strawberries,granola},1},31492}

Distribution of Bake and Non-Baking Recipes

With my baking and non-baking recipes separated from each other, I could then compare the two types of recipes. The first thing I looked at was the ratio of baking to non-baking recipes in the dataset.
Pie chart displaying the number of recipes in each category (baking or non-baking):
In[]:=
PieChart{Length[bakeRecipes],Length[noBakeRecipes]},

Out[]=
Approximately one-fourth of the recipes in the dataset are considered baking recipes.

Distribution of the Number of Ingredients in Baking and Non-Baking Recipes

Next, I looked at the distribution of the number of ingredients based on the type of recipe (baking or non-baking). Since baking recipes only made up around 25% of the entire dataset, I graphed the probabilities of each type of recipe instead of the quantities to show their distributions relative to each recipe category.
Probability histogram displaying the distributions of the number of ingredients of baking to non-baking recipes:
In[]:=
Histogram{bakeRecipes[[All,1]],noBakeRecipes[[All,1]]},

Out[]=
Baking Recipes
Non-Baking Recipes
In general, the number of ingredients did not vary drastically between baking and non-baking recipes. However, the distribution of the baking recipes was less skewed compared to the non-baking recipes, meaning that on average, baking recipes required more ingredients.

Distribution of Recipe Lengths in Baking and Non-Baking Recipes

Similarly, I looked at the distribution of the number of steps in the recipe’s instructions (recipe length) through a probability histogram.
Probability histogram displaying the distributions of recipe lengths of baking to non-baking recipes:
In[]:=
Histogram{bakeRecipes[[All,3]],noBakeRecipes[[All,3]]},

Out[]=
Baking Recipes
Non-Baking Recipes
Because the distribution of baking recipe lengths was less skewed, baking recipes contained more instruction steps on average compared to non-baking recipes.

Frequency of Ingredients in Baking and Non-Baking Recipes

The last thing I compared between the two types of recipes were their ingredient frequencies. For a better visual understanding, I created two word clouds of baking and non-baking recipe ingredients.
Word cloud showing the frequency of baking recipe ingredients:
Word cloud showing the frequency of non-baking recipe ingredients:
Since many pastries and breads are baked, the abundance of wheat flour and leavening agents in baking recipes is reasonable.

Oven Temperatures

After looking at the distributions of the baking and non-baking recipes, I decided to focus on analyzing baking recipes. Since baking recipes utilize ovens, I examined their oven temperatures.
To find the oven temperature of a recipe, I needed to parse through the instructions to find a mention of the word "degrees". However, some of the recipes contained detailed instructions where the usage of the word "degrees" referred to angle measurements. To avoid extracting angle measurements, I checked for the shortest case where the word "bake" or "preheat" was followed by a phrase and ended in some variation of the word "degrees".
Parse through the instructions and extract the phrase between "bake" or "preheat" and before "degrees":
Once I retrieved the phrases, I only wanted to keep the numerical values, which were the oven temperatures.
Extract only the numbers and convert them to integers:
Even though I took out all of the numbers, not all of them were valid oven temperatures. According to General Electric Appliances https://products.geappliances.com/appliance/gea-support-search-content?contentId=18501, most ovens range from 170 to 550 degrees Fahrenheit.
Keep only the numbers that are within the oven range (170-550F)
With all of the oven temperatures extracted, I then created a histogram and word cloud that shows the distribution of the oven temperatures.
Histogram showing the distribution of the oven temperatures in this dataset:
Word cloud that shows the frequency of the oven temperatures:
By far, the most frequent oven temperature was 350 degrees Fahrenheit.

Find Recipes to Bake Given a Specific Temperature

Today, ovens typically have a range of temperatures it can heat to, but what would happen if your oven only heated to one specific temperature? I decided to find baking recipes based on a specific temperature.
In order to find baking recipes with a specific oven temperature, I created a function that allowed me to find the oven temperature from a set of instructions. This process is similar to the one described in the previous section.
Extract the phrase between "bake" or "preheat" and before "degrees":
Take the numbers from the phrases that are in the oven range (170F-550F):
Now that we can find the oven temperature from a specific set of instructions, we can also find the oven temperature for a specific recipe.
Select the recipe titles given an oven temperature:
Example of what could be baked at 400 degrees Fahrenheit:

Find Common Temperatures Based on Food Name

What would happen if I needed to bake a type of food, but I lost the instructions that told me what temperature to set my oven to? After finding recipes based on oven temperature, I looked at the common oven temperatures of a type of food.
First, I needed to find all of the recipes where the title of the recipe contained a specific keyword (type of food).
Select cases from the dataset where the title includes the keyword:
Then, I needed to find all of the temperatures in each of the recipes.
Find all of the temperatures given a keyword:
Once I had all of the temperatures, I took out the most frequently occurring oven temperature.
Find the most common temperature given a type of food:
Example of the most common oven temperature for cookies:
I also created a function to generate a pie chart with the top five oven temperatures of a given food.
Function to create a pie chart of the top five most common temperatures:
Example pie chart for cookies:

Bake Times

Each baking recipe consists of an oven temperature and an amount of time that the food should be baked. I used a process similar to the one described in the section above to find the bake times of recipes.
Extract the phrases between the word "bake" and a variation of "minutes":
Replace instances of "to" with "-" and take the last part of each phrase:
Replace occurrences of "~" with "-":
Because each bake time was formatting differently, I created a couple of helper functions to format each case.
Find the average between a range of times:
Convert numbers missing a "-":
Keep only the numerical times separated by "-":
Convert written out numbers into their numerical form:
With these helper functions, I could now fix all of the bake times.
Function to fix all times:
Fix all times:
Word cloud showing the frequency of bake times:
Histogram showing the distribution of bake times:

Find Common Bake Times Based on Food Name

Similar to finding the common oven temperature of a type of food, I used the same process to find the common bake time for a specific type of food.
Find times in a set of instructions:
Find the bake times for a given food type:
Find the most common bake time for a given food type:
Function to create a pie chart that displays the five most common bake times for a given type of food:
Example pie chart displaying the five most common bake times for cookies:

How to Bake?

Because I could find the common oven temperature and bake time for a given food, I could then suggest how to bake something.
Function that returns a response to how long a food is typically baked for and at what temperature:
Example answer to baking cookies:

Is Bake Time Related to Oven Temperature?

Since I looked at both oven temperatures and bake times, I thought it would also be interesting to see if there was a correlation between the temperature of the oven and the amount of time the food needed to be baked for.
First, I retrieved the oven temperature and bake time for each recipe.
Get all temperatures and bake times:
Not all of the recipes had an oven temperature and a bake time. I only kept the values that had both.
Only keep the pairs that have an oven temperature and a bake time:
Some recipes had more than one oven temperature and more than one bake time. For the purpose of this project, I only considered the first mentioned oven temperature and bake time.
Only keep the first and last values in each pair:
Once I had all of the temperature and time pairs, I plotted them on a graph.
Plot all pairs:
Although there is a slight correlation between bake time and oven temperature, the correlation is not very strong. To see if there was a clearer correlation, I plotted only the most common bake time for each oven temperature.
Take the most frequent bake time for each oven temperature:
Plot the most common bake time for each oven temperature:
This plot shows the correlation between the bake times and oven temperatures somewhat more clearly, but the bake times do not seem to be strongly correlated to oven temperatures.

Conclusion

Overall, this project provided some insight into the various aspects of recipes. Most frequently, incorporation verbs are used in recipe instructions, and baking recipes have more ingredients and more steps in their instructions. I found that the most common oven temperature is 350 degrees Fahrenheit and the most common bake time is 15 minutes. As for the correlation between bake times and oven temperatures, they are not strongly correlated, but this could be due to the exclusion of some bake times and oven temperatures from recipes that have multiple of each.

Acknowledgements

I would like to thank my amazing mentor, Eryn Gillam, for guiding me through this project and patiently answering all of my questions. I would also like to thank all of the Wolfram Summer Camp staff for providing me with this incredible experience this summer.