Skip to the content.

Recipe Rating Analysis

Introduction

The datasets used in this project contain recipes and ratings from food.com. They contain the recipes and reviews posted since 2008.

What types of recipes tend to have higher ratings?

Insights about patterns that make a recipe highly rated can help anyone improve their cooking. For example, recipe creators can design recipes that are more likely to be enjoyed by their community, while recipe searchers can more easily find recipes that they love.

The raw dataset has 83,782 rows, and the cleaned dataset used for modeling has 81,173 rows. The columns that are relevant to this question are minutes (the preparation time in minutes), submitted (the year and month that the recipe was submitted), nutrition (nutritional information), n_steps (the number of steps), and n_ingredients (the number of ingredients).

Data Cleaning and Exploratory Data Analysis

Data Cleaning

Splitting nutrition data into columns: The nutrition information was in the form of a single string - I split this string into individual columns representing key nutrients like calories, total_fat, sugar, etc. This allowed each nutrient to be treated as a separate variable, leading to more meaningful exploratory data analysis.

Handling timestamps: The submitted column contains recipe submission dates, and I split it into two columns, year_submitted and month_submitted. This allowed me to identify any potential seasonal trends, as well as the distribution of ratings over time.

Capping extreme values: Through plotting the data, I found that there were extreme outliers in features like n_steps, minutes, and calories, so I capped the values at reasonable limits based on my general knowledge of cooking. For example:

This reduced the influence of outliers, which may have skewed predictions.

Filtering nutrition percent daily values (PDVs): Nutrition features like total_fat, sugar, and protein represent percentages of daily values. I capped these at 100%, keeping only realistic PDVs. This made the nutritonal data more valuable for investigation by making it more realistic.

Handling missing values: I replaced blank or None values with np.nan to standardize missing data across the dataset. Rows missing the target variable (rating) were removed at the time of modeling. This allowed for consistency in missing data during exploratory data analysis and predictive modeling.

First 5 rows of the relevant columns of the cleaned table:

name minutes year_submitted month_submitted n_steps n_ingredients rating calories total_fat sugar sodium protein saturated_fat carbohydrates
1 brownies in the world best ever 40 2008 10 10 9 4 138.4 10 50 3 3 19 6
412 broccoli casserole 40 2008 5 6 9 5 194.8 20 6 32 22 36 3
2000 meatloaf 90 2012 3 17 13 5 267 30 12 12 29 48 2
5 tacos 20 2013 5 5 9 4 249.4 26 4 6 39 39 0
blepandekager danish apple pancakes 50 2013 7 10 10 5 358.2 30 62 14 19 54 12

Univariate Analysis

The histogram above shows the distribution of preparation times for recipes in the dataset. Most recipes require 20-50 minutes, with a sharp decline in recipes taking longer than 50 minutes. This shows that recipes with shorter preparation times are more common, potentially suggesting user prefrence for quicker dishes.

This insight ties back to our initial question: What types of recipes tend to have higher ratings? By understanding that shorter preparation times are more common, we can hypothesize that user ratings might favor recipes that are quicker and easier to prepare.

Bivariate Analysis

I had hypothesized that older recipes on the website would have a greater number of ratings, and therefore a potentially higher average rating. The bar chart above shows the number of ratings submitted per year. There is a noticeable downward trend over time, with recipes from 2008 having the greatest number of ratings.

This suggests that recipes that have been on the website for longer likely have more engagement. This is relevant to the initial question because it highlights the need to consider time-related factors when analyzing recipe ratings.

Interesting Aggregates

Year Avg Rating Recipe Count
2008 4.60 21,770
2009 4.62 16,077
2010 4.64 8,551
2011 4.68 5,264
2012 4.68 3,667
2013 4.66 2,715
2014 4.62 733
2015 4.65 212
2016 4.47 129
2017 4.43 172
2018 4.78 98

The table above provides an overview of the average recipe ratings and the number of recipes submitted each year. The Avg Rating column shows the average rating of recipes submitted in that year, while the Recipe Count column indicates how many recipes were submitted.

This table adds to the visual analysis by offering detailed insights into the trends. It answers part of the initial question by showing that recipe submissions vary greatly over the years, but average recipe ratings do not.

Imputation

After investigation, I found that the only two columns with missing values were rating and description. I did not perform any imputation since missing target values would have to be dropped in modeling and missing values in the description column were already filled with np.nan during data cleaning.

Framing a Prediction Problem

For the prediction problem, I am trying to predict the average rating of a recipe. This is a regression problem because the response variable, rating, is continuous. I chose this variable because it may lead to insights about what types of recipes users prefer, allowing recipe creators to reach their target audience and recipe users to find what recipes they like best.

The metric I chose to evaluate my model is mean absolute error (MAE). MAE directly measures the average absolute difference between predicted and actual ratings in the same unit as the target, rating, making it easily interpretable. Unlike mean squared error (MSE), MAE is less sensitive to outliers. Since we’re predicting ratings on a fixed scale (1.0 to 5.0), MAE is a good choice to minimize the average deviation.

At the time of prediction, the variables I will be using include n_steps (the number of steps), n_ingredients (the number of ingredients),minutes (preparation time in minutes), year_submitted (the year the recipe was submitted), and calories (the amount of calories).

Baseline Model

For the baseline model, I used a linear regression model to predict the average rating of recipes based on the number of ingredients (n_ingredients) and the number of steps (n_steps). Both of these features are quantitative variables, so I performed a log transformation using a FunctionTransformer to address any skewness in the data. This helps make sure that the features are distributed more normally, which can improve model performance.

The model was evaluated using mean absolute error (MAE). The training MAE was 0.458, and the testing MAE was 0.464. This suggests that the model is performing similarly on both the training and testing data, meaning it is neither underfitting nor overfitting.

While the model’s performance was reasonable, I do not consider it to be “good” because the features used were very basic and lacked meaningful transformations. I also feel they do not encompass the most meaningful features in the prediction of average rating. The model could be improved by adding more features or using feature engineering techniques to capture more complex patterns in the data.

Final Model

For the final model, I added several features to capture more complexity in the data and improve the predictions:

The modeling algorithm I used is linear regression, which works well with prediction of continuous variables. I used grid search cross-validation (GridSearchCV) to tune the hyperparameter of the degree of polynomial, to find the optimal complexity of the model. After running the grid search, I found the best degree for the polynomial and fitted the model with those optimal parameters.

In terms of performance, the training MAE of the final model was 0.456, only slightly better than that of the baseline model, and the testing MAE did not change. The slight improvement in the training MAE comes from the added complexity of the new features and polynomial degree to reduce prediction errors and make the model more accurate. My hypothesis, after testing several different combinations of features, is that the testing error did not change because the features barely affect the average rating. This is potentially due to the imbalance of average rating values (most being above 4), as well as the lack of disparity between them.