"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > تتبع الصحة باستخدام هندسة البيانات - الفصل الأمثل للوجبات

تتبع الصحة باستخدام هندسة البيانات - الفصل الأمثل للوجبات

تم النشر بتاريخ 2024-08-07
تصفح:339

مقدمة

أهلا بالجميع! ستكون هذه أول مشاركة لي، لذا كن قاسيًا معي، وانتقدني حيث تعتقد أنه يمكنني التحسين وسأأخذ ذلك بعين الاعتبار بالتأكيد في المرة القادمة.

خلال الأشهر القليلة الماضية، كنت مهتمًا بصحتي بشكل عميق، حيث كنت أمارس الرياضة بشكل أساسي وأشاهد ما أتناوله من طعام، والآن بعد أن أعتقد أنني حصلت على فهم قوي لذلك، أردت أن أرى كيف يمكنني تحسين المزيد في في حالة وجود بعض الأشياء التي ربما فاتني.

أهداف

بالنسبة لهذا الفصل، أود أن أبدأ في دراسة وجباتي طوال رحلتي الصحية وأن أختتم بخطة وجبات للأسبوع التالي (1) تلبي الحد الأدنى من متطلبات البروتين، (2) لا تتجاوز الحد الأقصى من السعرات الحرارية، (3) يحقق الحد الأدنى من متطلبات الألياف، و(4) يقلل التكلفة.

مجموعة البيانات

نبدأ بتقديم مجموعة البيانات، الطعام الذي قمنا بتتبعه باستخدام الكرونومتر. لقد كان جهاز Cronometer يعمل معي جنبًا إلى جنب في رحلتي، والآن، سأقوم بتصدير البيانات التي أدخلتها لتحليلها بنفسي مع الأهداف التي ذكرتها سابقًا.

لحسن الحظ بالنسبة لي، يتيح لي Cronometer تصدير البيانات إلى ملف بتنسيق ‎.csv بسهولة على موقعه على الويب.
Screenshot of the export options from Cronometer

في هذا الفصل، سنقوم بتصدير مجموعة بيانات "إدخالات الأطعمة والوصفات" فقط.

نبدأ بفحص البيانات التي حصلنا عليها من "إدخالات الأطعمة والوصفات". مجموعة البيانات شاملة للغاية، وأنا متأكد من أنها ستكون رائعة للفصول المستقبلية! وفي هذا الفصل نريد أن نقتصر على اسم الطعام وكميته والبروتين والسعرات الحرارية والألياف.

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

المعالجة المسبقة للبيانات

لدينا بالفعل بعض الأعمدة المحددة لنا، في "اسم الطعام"، و"الكمية"، و"الطاقة (السعرات الحرارية)"، و"الألياف (جم)"، و"البروتين (جم)". ممتاز! الآن، الشيء الوحيد الذي ينقصنا هو الحصول على تكلفة كل طعام مقابل مبلغ معين لأنه لم يتم تتبعه في مجموعة البيانات. ولحسن الحظ بالنسبة لي، كنت أنا من أدخل البيانات في المقام الأول حتى أتمكن من إدخال الأسعار التي أعرفها. ومع ذلك، لن أقوم بإدخال أسعار جميع المواد الغذائية. وبدلاً من ذلك، نسأل صديقنا القديم ChatGPT عن تقديراته ونملأ الأسعار التي نعرفها عن طريق تعديل ملف ‎.csv. نقوم بتخزين مجموعة البيانات الجديدة في ملف "cost.csv" الذي اشتقناه عن طريق أخذ عمودي "اسم الغذاء" و"الكمية" من مجموعة البيانات الأصلية.

# 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()

تم إسقاط بعض الأطعمة ببساطة لأنها كانت محددة بشكل غريب للغاية ولن تدخل في نطاق بيانات كونها منخفضة السعرات الحرارية و/أو مغذية و/أو رخيصة (أو ببساطة لأنني لا أستطيع أن أزعج نفسي بإعداد الوصفة مرة أخرى ). سنحتاج بعد ذلك إلى دمج إطارين من البيانات، مجموعة البيانات الأصلية والأخرى ذات التكلفة، من أجل الحصول على مجموعة البيانات "النهائية" المفترضة. نظرًا لأن مجموعة البيانات الأصلية تحتوي على إدخالات لكل طعام، فهذا يعني أن مجموعة البيانات الأصلية تحتوي على إدخالات متعددة لنفس الطعام، خاصة تلك التي أتناولها بشكل متكرر (مثل البيض وصدر الدجاج والأرز). نريد أيضًا ملء الأعمدة التي لا تحتوي على قيم بالرقم "0" لأن المصدر الأكثر احتمالاً للمشاكل هنا هو أعمدة "الطاقة" و"الألياف" و"البروتين" و"السعر".

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()

تحسين

ممتاز! تم الانتهاء من مجموعة البيانات الخاصة بنا، والآن نبدأ بالجزء الثاني، وهو التحسين. وبالتذكير بأهداف الدراسة، نريد تحديد أقل تكلفة بالنظر إلى الحد الأدنى من البروتين والألياف والحد الأقصى من السعرات الحرارية. الخيار هنا هو استخدام القوة الغاشمة لكل مجموعة، ولكن في الصناعة المصطلح المناسب هو "البرمجة الخطية" أو "التحسين الخطي" ولكن لا تقتبس مني ذلك. هذه المرة، سوف نستخدم PuLP وهي مكتبة بايثون تهدف إلى القيام بذلك بالضبط. لا أعرف الكثير عن استخدامه إلى جانب اتباع القالب، لذا تصفح وثائقهم بدلاً من قراءة شرحي غير المهني لكيفية عمله. لكن بالنسبة لأولئك الذين يريدون الاستماع إلى شرحي غير الرسمي للموضوع، فإننا نحل بشكل أساسي المعادلة y = ax1 bx2 cx3... zxn.

القالب الذي سنتبعه هو نموذج لدراسة حالة مشكلة المزج، حيث نتبع أهدافًا مماثلة ولكن في هذه الحالة، نريد مزج وجباتنا على مدار اليوم. للبدء، سنحتاج إلى تحويل DataFrame إلى قواميس، وتحديدًا "اسم الغذاء" كقائمة من المتغيرات المستقلة التي تعمل بمثابة سلسلة x، ثم الطاقة والألياف والبروتين والسعر كقاموس مثل ذلك "اسم الطعام": القيمة لكل منها. لاحظ أنه سيتم التنازل عن المبلغ من الآن فصاعدًا، وبدلاً من ذلك سيتم ربطه بـ "اسم الطعام" لأننا لن نستخدمه كميًا.

# 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)

بالنسبة لأولئك الذين ليس لديهم بصر حاد، استمر في التمرير. بالنسبة لأولئك الذين لاحظوا وجود سطرين غريبين من التعليمات البرمجية، اسمحوا لي أن أشرح ذلك. لقد رأيت هذا بينما كنت أتسوق من البقالة ولكن الحقائق الغذائية الموجودة في رغيف زبيب القمح عالي الألياف من جاردينيا لا تحتوي في الواقع على شريحة واحدة تحتوي على 9 جرام من الألياف، بل تحتوي على شريحتين لكل 6 جرام. هذه مشكلة كبيرة وقد سببت لي ألمًا لا يُقاس مع العلم أن القيم قد تكون غير صحيحة إما بسبب سوء إدخال البيانات أو تغيير المكونات مما تسبب في جعل البيانات قديمة. وفي كلتا الحالتين، كنت بحاجة إلى تصحيح هذه العدالة ولن أؤيد أي ألياف أقل مما أستحق. المضي قدمًا.

ننتقل مباشرة إلى توصيل قيمنا باستخدام القالب من بيانات دراسة الحالة. لقد قمنا بتعيين متغيرات لتمثل الحد الأدنى من القيم التي نريد الحصول عليها من البروتين والألياف، بالإضافة إلى الحد الأقصى من السعرات الحرارية التي نرغب في تناولها. ثم نترك كود القالب السحري يقوم بعمله ويحصل على النتائج.

# 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]) = 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))

نتائج

Image description

من أجل الحصول على 120 جرامًا من البروتين و40 جرامًا من الألياف، سأحتاج إلى إنفاق 128 بيزو فلبيني على 269 جرامًا من شرائح صدور الدجاج، و526 جرامًا من حبوب المونج. هذا... لا يبدو سيئًا على الإطلاق بالنظر إلى مدى حبي لكلا المكونين. سأجرب ذلك بالتأكيد، ربما لمدة أسبوع أو شهر فقط لأرى مقدار المال الذي سأوفره على الرغم من حصولي على ما يكفي من التغذية.

كان هذا هو الحال بالنسبة لهذا الفصل من تتبع الصحة باستخدام هندسة البيانات، إذا كنت تريد رؤية البيانات التي عملت عليها في هذا الفصل، فقم بزيارة المستودع أو قم بزيارة دفتر الملاحظات الخاص بهذه الصفحة. اترك تعليقًا إذا كان لديك أي تعليق وحاول أن تظل بصحة جيدة.

بيان الافراج تم إعادة نشر هذه المقالة على: https://dev.to/wilyanse/tracking-health-with-data-engineering-chapter-1-meal-optimization-2cl7?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3