In [1]:
#!pip install pandas
In [ ]:
#!pip install numpy
In [ ]:
#!pip install scikit-learn

Tutorial Nutrition - MealPlan¶

  • kaggle
  • documento
In [1]:
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import seaborn as sns
In [2]:
# Step 1: Load the datasets
bmi_df = pd.read_csv('./nutrition/bmi.csv')
meals_df = pd.read_csv('./nutrition/mealplans.csv')
#nutrition_df = pd.read_csv('./nutrition/nutrition.csv')
dishes_df = pd.read_csv('./nutrition/dishes_adv.csv')
In [8]:
print(f'Numerosità dataset bmi: {bmi_df.shape[0]}')
print(f'Numerosità dataset meals: {meals_df.shape[0]}')
print(f'Numerosità dataset dishes: {dishes_df.shape[0]}')
Numerosità dataset bmi: 741
Numerosità dataset meals: 275290
Numerosità dataset dishes: 44612
In [9]:
# Step 2: Clean and preprocess the BMI data
bmi_df.dropna(inplace=True)
bmi_df['Bmi'] = bmi_df['Weight'] / (bmi_df['Height'] ** 2)
bmi_df['BmiClass'] = pd.cut(bmi_df['Bmi'], bins=[0, 18.5, 24.9, 29.9, 34.9, 39.9, np.inf],
                            labels=['Underweight', 'Normal weight', 'Overweight', 'Obese Class 1', 'Obese Class 2', 'Obese Class 3'])
In [10]:
bmi_df.to_dict('records')[0]
Out[10]:
{'Age': 61,
 'Height': 1.85,
 'Weight': 109.3,
 'Bmi': 31.935719503287068,
 'BmiClass': 'Obese Class 1'}
In [11]:
breakfast0_col = meals_df.columns.to_list().index('breakfast0')
In [12]:
#columns_to_normalize = meals_df.columns.to_list()[1:breakfast0_col]
columns_to_normalize = ['calories', 'totalFat', 'cholesterol', 'sodium', 'dietaryFiber', 'protein']
columns_to_visualize = meals_df.columns.to_list()[breakfast0_col:]
In [13]:
dict_dishes = dishes_df.to_dict('records')
map_dishes = {d['id']:d['title'] for d in dict_dishes}
def plan_exp(value):
    if pd.isna(value):
        return np.nan
    return map_dishes[int(value)]
for col in meals_df[columns_to_visualize]:
    meals_df[col] = meals_df[col].apply(plan_exp)
In [14]:
meals_df.to_dict('records')[0]
Out[14]:
{'id': 150001,
 'calories': 2455.0,
 'caloriesFromFat': 1156.0,
 'totalFat': 128.5,
 'saturatedFat': 50.4,
 'cholesterol': 694.0,
 'sodium': 4477.0,
 'potassium': 3377.0,
 'totalCarbohydrates': 239.8,
 'dietaryFiber': 17.6,
 'protein': 91.7,
 'sugars': 107.0,
 'vitaminA': 3850.0,
 'vitaminC': 229.8,
 'calcium': 910.0,
 'iron': 29.34,
 'thiamin': 3.015,
 'niacin': 55.2,
 'vitaminB6': 2.54,
 'magnesium': 356.0,
 'folate': 1.184,
 'breakfast0': 'Easy Breakfast Sausage Burgers',
 'breakfast1': 'Zucchini with Egg',
 'breakfast2': nan,
 'lunch0': 'Saucy Summer Fruit Salad',
 'lunch1': 'Sri Lankan Potato Curry II',
 'lunch2': nan,
 'lunch3': nan,
 'lunch4': nan,
 'dinner0': 'Honey Wheat Sandwich Rolls',
 'dinner1': 'Mushroom and Ricotta Bruschetta',
 'dinner2': 'Pork Green Chile',
 'dinner3': nan,
 'dinner4': nan,
 'dinner5': nan,
 'dinner6': nan,
 'snacks0': "Great Grandad's Sugar Cookies",
 'snacks1': 'Super Bowl(R) Crunch'}
In [29]:
# Remove rows with NaN values after preprocessing
meals_df.dropna(subset=columns_to_normalize, inplace=True)

scaler = StandardScaler()
meals_normalized = scaler.fit_transform(meals_df[columns_to_normalize])
meals_normalized_df = pd.DataFrame(meals_normalized, columns=columns_to_normalize)
In [30]:
# Step 6: Perform clustering on the nutrition data
kmeans = KMeans(n_clusters=6, random_state=42)
meals_df['cluster'] = kmeans.fit_predict(meals_normalized_df)
In [31]:
meals_df.to_csv('./nutrition/mealplans_adv.csv')
In [32]:
# Step 7: Visualize clusters
plt.figure(figsize=(12, 8))
sns.scatterplot(x='calories', y='protein', hue='cluster', data=meals_df, palette='viridis')
plt.title('Clusters of Meals Based on Nutritional Information')
plt.show()
No description has been provided for this image
In [33]:
# Step 8: Generate meal plans based on BMI
def generate_meal_plan(df_in,bmi_class, num_days):
    if bmi_class == 'Underweight':
        cluster = 0
    elif bmi_class == 'Normal weight':
        cluster = 1
    elif bmi_class == 'Overweight':
        cluster = 2
    elif bmi_class == 'Obese Class 1':
        cluster = 3
    elif bmi_class == 'Obese Class 2':
        cluster = 4
    else:
        cluster = 5
    print(f'cluster: {cluster}\nbmi_class: {bmi_class}')
    meal_plan = df_in[df_in['cluster'] == cluster].sample(num_days)
    return meal_plan
In [34]:
user_bmi = 30
In [35]:
# Determine the user's BMI class
if user_bmi < 18.5:
    bmi_class = 'Underweight'
elif user_bmi < 24.9:
    bmi_class = 'Normal weight'
elif user_bmi < 29.9:
    bmi_class = 'Overweight'
elif user_bmi < 34.9:
    bmi_class = 'Obese Class 1'
else:
    bmi_class = 'Obese Class 2'

# Generate a 30-day meal plan
num_days = 30
meal_plan = generate_meal_plan(meals_df,bmi_class, num_days)
cluster: 3
bmi_class: Obese Class 1
In [40]:
meal_plan.to_dict('records')[0]
Out[40]:
{'id': 160200,
 'calories': 2490.0,
 'caloriesFromFat': 990.0,
 'totalFat': 109.9,
 'saturatedFat': 44.1,
 'cholesterol': 578.0,
 'sodium': 4167.0,
 'potassium': 2280.0,
 'totalCarbohydrates': 232.5,
 'dietaryFiber': 16.8,
 'protein': 125.9,
 'sugars': 64.0,
 'vitaminA': 17350.0,
 'vitaminC': 104.4,
 'calcium': 1560.0,
 'iron': 32.58,
 'thiamin': 1.725,
 'niacin': 83.4,
 'vitaminB6': 2.88,
 'magnesium': 348.0,
 'folate': 0.956,
 'breakfast0': 'Broccoli Cheese Squares',
 'breakfast1': nan,
 'breakfast2': nan,
 'lunch0': 'Garlic Penne Pasta',
 'lunch1': 'Schnitzel',
 'lunch2': nan,
 'lunch3': nan,
 'lunch4': nan,
 'dinner0': 'Divacello',
 'dinner1': 'Leftover Moroccan Meat Pie',
 'dinner2': 'Lime-Garlic Chicken and Spinach Salad',
 'dinner3': nan,
 'dinner4': nan,
 'dinner5': nan,
 'dinner6': nan,
 'snacks0': nan,
 'snacks1': nan,
 'cluster': 3}
In [ ]: