Heim  >  Artikel  >  Backend-Entwicklung  >  Gesundheit mit Data Engineering verfolgen – Kapitel Mahlzeitenoptimierung

Gesundheit mit Data Engineering verfolgen – Kapitel Mahlzeitenoptimierung

PHPz
PHPzOriginal
2024-07-19 11:24:31766Durchsuche

Einführung

Hallo zusammen! Dies wird mein erster Beitrag sein, seien Sie also hart zu mir und kritisieren Sie mich dort, wo ich mich Ihrer Meinung nach verbessern kann, und ich werde es beim nächsten Mal auf jeden Fall berücksichtigen.

In den letzten Monaten habe ich mich intensiv mit der Gesundheit beschäftigt, hauptsächlich trainiert und darauf geachtet, was ich esse, und jetzt, da ich denke, dass ich es gut im Griff habe, wollte ich sehen, wie ich es noch weiter optimieren kann Falls es einige Dinge gibt, die ich möglicherweise übersehen habe.

Ziele

In diesem Kapitel möchte ich mich mit meinen Mahlzeiten während meiner gesamten Gesundheitsreise befassen und mit einem Essensplan für die nächste Woche abschließen, der (1) meinen Mindestproteinbedarf deckt, (2) mein Kalorienlimit nicht überschreitet, (3) erfüllt meinen Mindestfaserbedarf und (4) minimiert die Kosten.

Datensatz

Wir beginnen mit der Einführung des Datensatzes, der Lebensmittel, die wir mit Cronometer verfolgt haben. Cronometer hat auf meiner Reise Seite an Seite mit mir zusammengearbeitet und jetzt werde ich die von mir eingegebenen Daten exportieren, um sie selbst mit den zuvor aufgeführten Zielen zu analysieren.

Glücklicherweise ermöglicht mir Cronometer den problemlosen Export von Daten in eine .csv-Datei auf ihrer Website.
Screenshot of the export options from Cronometer

Für dieses Kapitel exportieren wir nur den Datensatz „Lebensmittel- und Rezepteinträge“.

Wir beginnen mit der Untersuchung der Daten, die wir aus „Lebensmittel- und Rezepteinträge“ erhalten haben. Der Datensatz ist sehr umfangreich, was sicher für zukünftige Kapitel großartig sein wird! In diesem Kapitel möchten wir uns auf den Namen des Lebensmittels, seine Menge, Protein, Kalorien und Ballaststoffe beschränken.

# Importing and checking out the dataset
df = pd.read_csv("servings.csv")
df.head()

Datenvorverarbeitung

Wir haben bereits einige Spalten für uns eingerichtet, in „Lebensmittelname“, „Menge“, „Energie (kcal)“, „Ballaststoffe (g)“ und „Protein (g)“. Perfekt! Jetzt fehlt uns nur noch die Ermittlung der Kosten für jedes Lebensmittel bei einer bestimmten Menge, da diese nicht im Datensatz erfasst wurden. Zum Glück war ich derjenige, der die Daten als Erster eingegeben hat, sodass ich die Preise eingeben kann, die ich kenne. Allerdings werde ich nicht für alle Lebensmittel Preise eingeben. Stattdessen fragen wir unseren guten alten Freund ChatGPT nach seinem Kostenvoranschlag und geben die Preise ein, die wir kennen, indem wir die CSV-Datei anpassen. Wir speichern den neuen Datensatz in „cost.csv“, den wir abgeleitet haben, indem wir die Spalten „Food Name“ und „Amount“ aus dem Originaldatensatz übernommen haben.

# Group by 'Food Name' and collect unique 'Amount' for each group
grouped_df = df.groupby('Food Name')['Amount'].unique().reset_index()

# Expand the DataFrame so each unique 'Food Name' and 'Amount' is on a separate row
expanded_df = grouped_df.explode('Amount')

# Export the DataFrame to a CSV file
expanded_df.to_csv('grouped_food_names_amounts.csv')

# Read the added costs and save as a new DataFrame
df_cost = pd.read_csv("cost.csv").dropna()
df_cost.head()

Einige Lebensmittel wurden einfach weggelassen, weil sie zu merkwürdig spezifisch waren und nicht in den Datenbereich kalorienarm, nahrhaft und/oder billig fielen (oder weil ich einfach keine Lust hatte, das Rezept noch einmal zu machen). ). Wir müssten dann zwei Datenrahmen zusammenführen, den ursprünglichen Datensatz und den mit den Kosten, um den vermeintlichen „endgültigen“ Datensatz zu erhalten. Da der Originaldatensatz die Einträge für jedes Lebensmittel enthält, bedeutet dies, dass der Originaldatensatz mehrere Einträge zu demselben Lebensmittel enthält, insbesondere zu denen, die ich wiederholt esse (z. B. Eier, Hähnchenbrust, Reis). Wir möchten auch Spalten ohne Werte mit „0“ füllen, da die wahrscheinlichste Problemquelle hier die Spalten „Energie“, „Ballaststoffe“, „Protein“ und „Preis“ wären.

merged_df = pd.merge(df, df_cost, on=['Food Name', 'Amount'], how='inner')

specified_columns = ['Food Name', 'Amount', 'Energy (kcal)', 'Fiber (g)', 'Protein (g)', 'Price']
final_df = merged_df[specified_columns].drop_duplicates()
final_df.fillna(0, inplace=True)
final_df.head()

Optimierung

Perfekt! Unser Datensatz ist fertig und jetzt beginnen wir mit dem zweiten Teil, der Optimierung. Unter Berücksichtigung der Ziele der Studie möchten wir die geringsten Kosten bei einer minimalen Menge an Protein und Ballaststoffen und einer maximalen Menge an Kalorien ermitteln. Die Option hier besteht darin, jede einzelne Kombination brutal zu erzwingen, aber in der Branche ist der richtige Begriff „lineare Programmierung“ oder „lineare Optimierung“, aber zitieren Sie mich dazu nicht. Dieses Mal werden wir puLP verwenden, eine Python-Bibliothek, die genau darauf abzielt. Ich weiß nicht viel über die Verwendung, abgesehen davon, dass ich der Vorlage folge. Schauen Sie sich also die Dokumentation an, anstatt meine unprofessionelle Erklärung zu lesen, wie es funktioniert. Aber für diejenigen, die sich meine lockere Erklärung des Themas anhören möchten: Wir lösen im Grunde nach y = ax1 + bx2 + cx3 + ... + zxn.

Die Vorlage, der wir folgen werden, ist die Vorlage für die Fallstudie zum Mischproblem, in der wir ähnliche Ziele verfolgen, in diesem Fall jedoch unsere Mahlzeiten über den Tag verteilt mischen möchten. Um zu beginnen, müssten wir den DataFrame in Wörterbücher umwandeln, insbesondere den „Lebensmittelnamen“ als Liste unabhängiger Variablen, die als Reihe von x dienen, und dann Energie, Ballaststoffe, Protein und Preis als ein solches Wörterbuch „Lebensmittelname“: Wert für jeden. Bitte beachten Sie, dass auf die Angabe der Menge von nun an verzichtet wird und diese stattdessen mit dem „Namen des Lebensmittels“ verkettet wird, da wir ihn nicht quantitativ verwenden.

# Concatenate Amount into Food Name
final_df['Food Name'] = final_df['Food Name'] + ' ' + final_df['Amount'].astype(str)
food_names = final_df['Food Name'].tolist()

# Create dictionaries for 'Energy', 'Fiber', 'Protein', and 'Price'
energy_dict = final_df.set_index('Food Name')['Energy (kcal)'].to_dict()
fiber_dict = final_df.set_index('Food Name')['Fiber (g)'].to_dict()
fiber_dict['Gardenia, High Fiber Wheat Raisin Loaf 1.00 Slice'] = 3
fiber_dict['Gardenia, High Fiber Wheat Raisin Loaf 2.00 Slice'] = 6
protein_dict = final_df.set_index('Food Name')['Protein (g)'].to_dict()
price_dict = final_df.set_index('Food Name')['Price'].to_dict()

# Display the results
print("Food Names Array:", food_names)
print("Energy Dictionary:", energy_dict)
print("Fiber Dictionary:", fiber_dict)
print("Protein Dictionary:", protein_dict)
print("Price Dictionary:", price_dict)

For those without keen eyesight, continue scrolling. For those who did notice the eerie 2 lines of code, let me explain. I saw this while I was grocery shopping but the nutrition facts on Gardenia's High Fiber Wheat Raisin loaf do not actually have 1 slice be 9 grams of Fiber, it has 2 slices for 6 grams. This is a big deal and has caused me immeasurable pain knowing that the values may be incorrect due to either a misinput of data or a change of ingredients which caused the data to be outdated. Either way, I needed this justice corrected and I will not stand for any less Fiber than I deserve. Moving on.

We go straight into plugging in our values using the template from the Case Study data. We set variables to stand for the minimum values we want out of Protein and Fiber, as well as the maximum Calories we are willing to eat. Then, we let the magical template code do its work and get the results.

# Set variables
min_protein = 120
min_fiber = 40
max_energy = 1500

# Just read the case study at https://coin-or.github.io/pulp/CaseStudies/a_blending_problem.html. They explain it way better than I ever could.
prob = LpProblem("Meal Optimization", LpMinimize)
food_vars = LpVariable.dicts("Food", food_names, 0)
prob += (
    lpSum([price_dict[i] * food_vars[i] for i in food_names]),
    "Total Cost of Food daily",
)
prob += (
    lpSum([energy_dict[i] * food_vars[i] for i in food_names]) <= max_energy,
    "EnergyRequirement",
)
prob += (
    lpSum([fiber_dict[i] * food_vars[i] for i in food_names]) >= min_fiber,
    "FiberRequirement",
)
prob += (
    lpSum([protein_dict[i] * food_vars[i] for i in food_names]) >= min_protein,
    "ProteinRequirement",
)
prob.writeLP("MealOptimization.lp")
prob.solve()
print("Status:", LpStatus[prob.status])
for v in prob.variables():
    if v.varValue > 0:
        print(v.name, "=", v.varValue)
print("Total Cost of Food per day = ", value(prob.objective))

Results

Image description

In order to get 120 grams of protein and 40 grams of fiber, I would need to spend 128 Philippine Pesos on 269 grams of chicken breast fillet, and 526 grams of mung beans. This... does not sound bad at all considering how much I love both ingredients. I will definitely try it out, maybe for a week or a month just to see how much money I would save despite having just enough nutrition.

That was it for this chapter of Tracking Health with Data Engineering, if you want to see the data I worked on in this chapter, visit the repository or visit the notebook for this page. Do leave a comment if you have any and try to stay healthy.

Das obige ist der detaillierte Inhalt vonGesundheit mit Data Engineering verfolgen – Kapitel Mahlzeitenoptimierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn