Building your Diet using Artificial Intelligence, with Python*ApuL_yq20RO5tAEI

Original Source Here

Building your Diet using Artificial Intelligence, with Python

Photo by Brooke Lark on Unsplash

Disclaimer! I am not a dietician and I absolutely do not think that this article can replace one. This experiment is only valid from a point of view of a Data Scientist. Please take this lightly and talk to a certified professional when you make your diet.

When I was in Italy, I was training as a kickboxer for the Red Devils team known as the Italian Martial Arts Academy. We traveled throughout Europe and the world, training like professionals.

All professional athletes know that nothing is random when you train at those levels. You need to sleep well, you need to train hard, you need to train your mindset, and you need to eat well. A good diet is essential to being a good athlete, being healthy, and avoiding injuries.

I have spoken about and followed multiple nutrition plans, and I know how tough a job it is. You need to consider multiple factors, like being in a specific weight range, having a specific percentage of muscle, having a good mindset, not having a diet that is too strict, and keeping up with the exhausting training sessions and the calorie range. And then you have to trust your dietician, and your dietician has to trust you. Possibly, your coach, your mental coach, your physiotherapist, and your dietician should work together. It is a tough job. It is.

This means that, as I said in the introduction, this article clearly states that artificial intelligence is not able to build the perfect diet for you. I strongly believe that at least today, we still need a proper doctor who analyzes our case and gives us our best nutrition plan.

Nonetheless, I believe that building the nutrition plan can be formalized as an (extremely complex) optimization problem. In very simple terms, you have to eat enough (not too much or too little) to reach a certain goal.
This means that, if we are aware that we are simplifying the problem a lot, we can try and treat this task as an optimization one and build an algorithm to solve it.

Let’s get it started!

1. Formalizing the problem

There are a lot of things to consider when building a nutrition plan, and I am sure I am ignoring a lot of them.

For this reason, I talked to a friend of mine, Cristian Beniamino Milito, who is a certified dietician. He agreed with me that things are way more difficult than I am making them seem, but he gave me some guidelines.

We should get:

  1. One gram of protein per day per kg of the person (e.g. 70g of proteins per day if you’re a 70 kg person)
  2. The carbohydrates should be half of the calories you assume per day.
  3. The remaining part should be fat

So the proportion of fat, carbohydrates, and proteins for a 70 kg person with 1500 calories should be something like this:

Image by author

Now actually, rather than fix the number of calories, we are more interested in keeping the calories as small as possible because we have a certain number of grams of protein, carbohydrates, and fat.

This is where the optimization algorithm comes in. We will have an indicative number of calories that we want to achieve, but we will rather try to minimize it, keeping in mind that we strictly have to satisfy the number of proteins, carbohydrates, and fat that we have in our plan.

Let’s formalize it.

2. About Optimization

The following is a technical definition of optimization:

An algorithm is an optimization if it finds the minimum or maximum of a function in a given domain.

For example, let’s take the following function:

Image by author

In this case, the domain of the function is the interval [-1, 1]. The minimum of the function in that domain is x = 0 and y = 0. We want an algorithm that can find the minimum.

Image by author

Ok, but everybody can create their own custom problem and it doesn’t necessarily mean that it is interesting enough. 😅

Why do we study optimization? Why did we make this kind of algorithm? And why are we talking about it now?

Let’s state this: we use optimization in our everyday lives a lot. Sometimes we do it without even thinking about it.

Let’s say you are buying groceries and you need to buy razor blades. Of course, if you buy 10,000 razor blades, you won’t have any money left in your bank. Nonetheless, if you buy 4 razor blades, you will need to buy them again in 4 days (assuming that you shave daily), and you will spend more money on gas, which is not smart. So what we usually do is mentally solve an optimization problem.

Image by author

We buy an amount that is something in between:

  • Large enough to have a good amount of razor blades and be ok for a week or 2
  • Small enough to still have money left in the bank account 🙂
Image by author

This is why optimization has its name and has been studied for so long. A more friendly word that we could use is “compromise”: we want the best value (minimum or maximum) of an objective (loss) given certain conditions (domain).

So now we know why we have these optimization algorithms. Great. Now, why do we use them now?

Well, our goal at this point is to optimize the number of calories. In particular, we want to minimize them. At the same time, we do want our nutrition plan to be varied, and we want it to satisfy the requirements of protein, carbohydrates, and fat that we want to achieve.

So how do we do that?

3. About Simplex

So, let’s build a mathematical representation of our problem.
As we said, we are trying to minimize a cost-loss function. To solve this task using the following method, the loss function has to be linear.
This means that given a set of variables x,

Image by author

Our loss function will be something like that:

Image by author

where c is a fixed vector of costs.
What is x in our case? And what is c? Well, as we have to minimize the calories, it is pretty evident that c has to be the vector of calories that each food has, let’s say, in 100 grams. And as we said, it is fixed*.

*I’d love for it not to be fixed, and I’d love to change it to 0.5 calories per kg of chocolate, but unfortunately, it’s not like this.

Fantastic. Now, what is x? If you followed the idea, I think it is clear that now, let’s say, x_1 has to be the units (relative to 100 g) of “food number 1” that we decide to eat.

Great. So let’s say that I tell you to minimize L(x), and I tell you nothing else. Well, in that case, the answer is pretty simple: x = 0 and L(0) = 0. But I heard that it is challenging to survive without eating.

This means that we have to minimize the function, provided that we respect certain constraints. These constraints are, as we said, the number of grams of protein, carbohydrates, and fat that we need to put in our bellies.

In a similar way to what we have done before, we will now describe three other vectors, which we will call:

  • f, that is the vector of fat (e.g. 100 grams of food number 1 have f_1 grams of fat)
Image by author
  • e, that is the vector of carbohydrates (e.g. 100 grams of food number 1 have c_1 grams of carbohydrates)
Image by author

I didn’t use c because I already have it in my loss function. I know. Poor business move. Sorry 😒

  • p, that is the vector of proteins (e.g. 100 grams of food number 1 have p_1 grams of proteins)
Image by author

And the constraints look like this:

Image by author

where E, P, and F are the grams of carbohydrates, proteins, and fat that we need to eat.

So in a few words, yes, we want to eat the fewest calories possible, but we also want them to be enough to provide the right amount of energy for our bodies.

As we have a lot of food, we try all the possible combinations that satisfy the constraints above and pick the one with the minimum amount of calories (the so-called minimum is not a possibility). This is rather a case of continuous linear optimization, which has a well-known algorithm that can be used to solve it, and it is called simplex.

Specifying exactly how these algorithm works is beyond the scope of this article. Let’s just say that the idea is that we are inside a domain, and the minimum or maximum of the function inside that domain is located at the extreme points.

We will use the simplex algorithm, in particular, with Python and a library that is known as PuLP. Let’s dive in.

4. Hands-On Coding

4.1 Preprocessing

At this point, we have all that we need. Let’s import some libraries:

Now, what we need to do is download the data. They are on Kaggle, free, and ready to use (CC0: Public Domain).

Once we have done that, we can easily import them like that:

Let’s give it a summary look:

A lot of information, probably a little too much. What we really need for our simplified experiment is the following:

  • serving_size
  • carbohydrates
  • total_fat
  • calories
  • protein

That is all we really need, so let’s select those columns:

Great. Let’s move on. First of all, all the serving_size look to be 100g. If that is the case, we don’t need that column at all. Let’s check it out:

Yep. Super-useless column. Let’s get rid of it.

Now we need to change the carbohydrate, protein, and total_fat columns into float number columns:

Now an important step of the diet is to be variegate*. We’ll reach this goal by allowing our model to look at only specific random portions of the dataset instead of the whole dataset. That’s how we’ll do it:

*By “variegate” I mean we won’t be eating the same food 7 days a week, 5 meals a day. By looking at random portions of the dataset we have, for each day, a different dataset of foods to look at.

So, for example, this Monday we will have this list of food that we can eat*:

*Note: It is very easy to imagine that this step can be improved if we don’t consider random splits but if we try and build this “day datasets” with a specific criterion. It is also necessary to have some kind of domain knowledge to implement this criterion, which I do not have because I am not a dietician.

In chapter 1 we were discussing about the number of grams of food and calories that a person should eat. In order to compute these (indicative) values, we can use the following two functions:

So let’s say that our weight is 70 kg and we need to eat 2000 calories per day. We will need to eat:

In terms of grams, this means:

4.2 Optimization

Everything we said and discussed can be implemented and summarized int the following lines of code:

So, for example, for a person that weighs 70 kg and has to eat 1500 calories we run the following model:

And we get the following result:

4.3 Final Product

Let’s loop it over all the days with these functions:

It’s time to run it! Assume a 70 kg person with a 3000 calorie requirement:

And this is the diet:

5. Bonus!

Now, this model is a little too simple. I am sure that if your dietician is going to give you a list of foods that you need to eat, you are going to change dieticians, and you are right.

Even if our model is simplified, we should at least try to acknowledge the fact that we have 3–5 meals per day and act accordingly. Now, how do we do that?

Well, there are a few ways to do that.
The most brutal is to divide the grams of food by the number of meals. For example, if we should eat 134 grams of lamb (see Monday) we could try and say: “Let’s eat 134/3 grams in the morning (ouch…), 134/3 grams for lunch, and 134/3 grams for dinner.”

This doesn’t sound great at all. So I asked my angel (Cristian Beniamino Milito) to tell me how to do it.

He told me that in terms of calories we should think of something like that:

  • Around 10% for the snack number 1
  • Around 10% for the snack number 2
  • Around 30% for dinner
  • 35% for lunch
  • 15 % for breakfast
Image by author

In order to incorporate this in our model we need to do the following things:

  • Random split our day data in 5 (one per meal). We already did this split to consider 7 different size, remember?
split_size = np.linspace(0,len(data),8)

we will do the same, to split our day data in meal data. To summarize we will split our full length data in 7*5 random bits.

  • Build new constraints, based on what we said before. Formally speaking, the new constraints look like this:
Image by author

Where now we will have:

Image by author

And to respect what we said before we will have:

  • d(Breakfast) = 1/0.15
  • d(Lunch) = 1/0.35
  • d(Dinner) = 1/0.30
  • d(Snack 1)= d(Snack 2) = 1/0.10

We can build a new function, which we will call better_model, and it will give us a complete diet, that is what we expect. By “complete diet” I mean a diet that is not only divided by day, but divided by “meal” as well.

This is the function:

Let me show you the results for a 70 kg person eating 1500 calories:

This is the diet for Monday. As we see, you have 5 different meals: Snack 1, Snack 2, Breakfast, Lunch, and Dinner.

Let me show you some more examples:

This is what we’ll eat Saturday lunch:

This is what we’ll eat Sunday for breakfast:

This is what we’ll eat as a snack on Monday:

6. Considerations

Well, there are a lot of things to consider. The first one is pretty obvious. This model does not work as well as a certified dietician would. Dietitians are always studying quantity, what is good and bad for our bodies, and what is healthy for us and for our minds. Nonetheless, it is true that through this model we are absolutely certain we are eating the lower amount of calories we can while still respecting our needs of proteins, fat and carbohydrates.

How did we do that? Let me recap.

  1. We defined the problem. We saw how many calories we should eat based on the domain knowledge of a real world professional (Cristian Beniamino Milito)
  2. We defined the mathematical model. We introduced the concepts of optimization in mathematical terms
  3. We saw how can we interpret our problem (building a diet) as an optimization problem.
  4. We implemented the code using Python and PuLP.

While we have a lot to improve here, and dieticians have 100% still to be present in the process, I do believe that this could be a good starting point into the idea of using AI for suggestions we can use in our workplace.

7. Conclusions

If you liked the article and you want to know more about Machine Learning, or you just want to ask me something you can:

A. Follow me on Linkedin, where I publish all my stories
B. Subscribe to my newsletter. It will keep you updated about new stories and give you the chance to text me to receive all the corrections or doubts you may have.
C. Become a referred member, so you won’t have any “maximum number of stories for the month” and you can read whatever I (and thousands of other Machine Learning and Data Science top writers) write about the newest technology available.


Trending AI/ML Article Identified & Digested via Granola by Ramsey Elbasheer; a Machine-Driven RSS Bot

%d bloggers like this: