The infographics above summarises our Rouxcommender (inspired by Michel Roux Snr and Jnr) family: what they are and how they might help to meet the customer needs in different stages.
Our Rouxcommender family has 3 members:
- Gousto Recommends: decides how to showcase the best of Gousto in a weekly menu to potential customers.
- Rouxcommender Junior: in charge of new customers, who have chosen at least one box.
- Rouxcommender Senior: in charge of existing customers, who have been with Gousto for some time, and might like to try new recipes.
Let’s meet each member of the family!
To-be Customers: to Gousto or not to Gousto?
My aunt ran a small coffee shop in Vietnam (for over 30 years). As kids me and my cousin’s jobs were to look after the customer motorcycles and we saw many of them were just passing by, looking at the menu for a few seconds and walking in or just moving on. Some will come for coffee, some for hot chocolate, some just for “banh mi” (if you haven’t tried yet, check this out). Maybe 90% of people will just come for coffee and only 10% come for the “banh mi”, and you’d need to make sure the menu reflects the need of not just “most” but “all” of our customers. This is the main focus of our first layer of the recommendation engine, Gousto Recommends.
The graph above shows how current Gousto Recommends presents the best recipes in a weekly menu to everyone who has some interest in Gousto (may not be a customer yet). The x-axis is the recipe ranking according to the model while the y-axis shows relative popularity of the recipes in that week. As we can see the model tends to rank more popular recipes higher, which makes sense, given this is a popularity-based model. However, what is missing here is that most of the higher rank recipes are of meat diet (all of the top 15) and while we have a very diverse menu with lots of choices from different diet types: fishes, vegetarian or vegan, these recipes have not been presented very well in the top ranks.
The question is whether the best for most is equal to the best for all? Put it another way, would we want to rank the most popular recipes the highest? If this is the case then how would a veggie/vegan customer feel when they first look at our menu, since veggie/vegan recipes have lower uptake than others? As you can imagine, the ideal menu that suits our veggie/vegan customers would look completely different, as demonstrated below.
We are working towards the next iteration of Gousto Recommends that takes into account not only the popularity of the recipes alone (hence “wisdom of the crowd” in the infographic above) but also how it can serve a variety of needs and tastes required (hence “power of choices”), so watch this space!
Ask and Listen: Rouxcommender Junior
Sometimes I saw my aunt talking to the customers who normally came around 7–8AM, and like any curious kid, I asked why. It turned out that those were customers who had just started a few days ago. She’d asked whether they’d like the same drinks as last time and whether the drinks or food were right to their tastes. Back to the Gousto story, those are our recently joined customers.
What we do is simple: we note what the customers ordered in their very first boxes and find something very similar in the latest menus for them. Well, one might ask “what do you mean by similarity?”. Yes, it varies case by case: a pair of recipes can be considered similar by either how close the attributes they share (protein types, carbs, cuisine) or the groups of customers who co-ordered them. Each approach has its own pros/cons, but let’s cover that in another post.
Ask: We at Gousto believe that if you are not sure about something, explicitly ask the customers. In Turnips, we’ve recently launched a feature called “recipe battle” where we give a pair of recipes and ask our customers which recipe they would prefer. For 5 answers, we can generate 10 examples for Rouxcommender to learn from or feed them to Rouxcommender Junior. Recipe Battle deserves its own story, from which questions to ask and how to interpret the answers, so I will save these for later…
Listen: Not only do we explicitly ask our customers, our recommendation engine can also learn what they love implicitly from the recipes they interacted with. After the customer finishes ordering their first box, this precious piece of information jumps straight to a high priority queue and feeds directly to the light-weight recommender Rouxcommender Junior. The recommender would then return a list of recommendations for box 2 menu based on weighted ranks. In general, the closer a recipe to all box-1 recipes, the higher it will be ranked in the recommendation list.
The figure above shows how we choose which recipes to recommend for box 2 right after the customer completes their first box. Each dot represents a recipe and the closer the dots, the more likely the recipes are purchased by similar groups of customers. In this example, a customer had ordered 4 recipes in box 1 (blue) and our recommender recommended all the recipes in red for box 2 menu. Yellow dots are recipes that are in box 2 but weren’t recommended by the model. The numbers associated with red dots are the ranking of the recipe in box 2 menu to be seen by the customer (up to top 15). Note that recipe ranked 7 was ordered in box 1 and also recommended in box 2 but the customer didn’t choose. As all of the recipes in box 1 were vegetarian , our model recommended many recipes within that diet type (the top left quarter of the graph) and got 3 hits (the circle dots — ranked 1, 6 and 10).
Worth noticing that Roux Junior also tried to inject some diversity/exploration elements into the recommendations by recommending meat recipes such as 8, 13, 11, 15 (the right part of the graph). These are popular meat recipes such as Steak Sandwich (8), Bangers ’N’ Mash (11) , Sticky Chilli Chicken(13) or Chicken Goujons (15). This will help to deal with the exploration/exploitation trade-off in our recommendations, especially for new customers or customers with a very diverse taste.
Rouxcommender Senior — The Green Oracle:
Every morning at 5AM our most regular customers started to arrive. No one ordered anything — they just read the newspaper, but 5 mins later, their tables were full of things, from coffee to banh mi. Again, I questioned my aunt, and she told me these were customers that came to the shop everyday, for many years. They tend to have the same orders again and again and my aunt just knew what to do, from using sweetener instead of sugar for diabetic or no coriander in their banh mi. This is how we built the most senior member of the Gousto recommender family: Rouxcommender (Senior).
At a glance, Rouxcommender Snr is a 2-tower recommender model that learns customers tastes and preferences based on their past orders. The first tower tries to understand customer information and encode them into embeddings while the second tower does similar tasks for recipes, including which carbs/proteins they have, or if they are Thai or Italian cuisines. We then combine these 2 towers together and apply a few dense layers before the output layer.
The main difference between Rouxcommender Senior and its junior counterpart is that the former would look for affinity between customers and other aspects of the recipes in addition to the recipes themselves as was in the Junior’s case. As a result, it would be able to tackle the so-called “cold-start” problem, which is a big issue as new recipes are released to our menu every week. In our last controlled experiment, Rouxcommender Snr has brought up a significant basket match uplift (basket match = % of recipes bought were chosen from our top 15 recommendations) compared to its predecessor. We also found out the model works better with customers who have had at least 5 boxes. This is when the dust settles and the patterns emerge.
Below are the 2D projections of a sample of Rouxcommender’s customer embeddings, colour-coded by the cluster/segment they belong to. The closer the dots, the more similar the customers are in terms of their taste profiles. I often refer to this graph as “the Gousto Bird” ;).
The clusters of our customers are easily identifiable and represent the diverse tastes of our customers very well. For example, the Veggie/Vegan cluster (blue/the head) is farthest to the Beef/American cluster (yellow, the bottom) while being close to the Fish/Healthy cluster (red/the neck). There is also a southwest/northeast divider that separates the cuisines (Asian/Oriental vs Western recipes). The shape of our customers’ embeddings also reflects that our customer behaviours evolve over time. The Gousto Bird used to look very much like a fish, so who knows what’s next? No worry, we’ll keep you updated ;)!
Above is a very high-level introduction to our Rouxcommender family, we hope to give a deeper dive into each component of our recommender system in future posts, as well as our thoughts while dealing with some challenges in Gousto such as cold-starts, operational constraints and, occasionally, the creativity of our chefs.
Having joined Gousto just over 6 months ago, I’d not for a second imagined how much we could do in such a short period of time, to bring our personalisation roadmap to life, block by block. Together we tackled problems one by one, trying to build things that improve the previous and if we are stuck (as we were so many times), there would be a lot to learn, be it directly from our customers or our massive (and messy ;)) datasets. The journey will be still long and bumpy with many exciting things still waiting for us, so if you are interested in joining our journey, here is the link.
BTW if you just want to try Gousto food instead of jobs, here is another link (you’ll get 60% OFF your first box and a chance to test our Rouxcommender family).
j/k: I meant “and 30% OFF your first month”!!!