تحليل البيانات باستخدام بايثون – سجلات الوفيات والاصابات بفيروس كورونا كمثال
في ظل حالة الطوارئ التي يعيشها العالم بأسره بسبب انتشار فيروس كورونا، بدأ يزداد في المجتمعات العلمية والتقنية الحديث عن دور تحليل البيانات ودور خوارزمات تعليم الألة والذكاء الاصطناعي في المساعدة في التنبؤ بمستقبل البشرية وكيفية انتقال وانتشار الأوبئة في العالم. تحليل البيانات باستخدام بايثون هو أحد الأدوات المهمة التي يعتمد عليها الكثير من العُلماء والباحثين.
لا شك أن تعليم الألة والذكاء الاصطناعي وكافة المجالات المرتبطة بهما له دور كبير وأساسي في معرفة أسباب انتشار الوباء وكيفية تفشيه والتنبؤ بمستقبله. في هذا المقال من بايثونات، نقدم لكم شرحًا في مجال تحليل البيانات باستخدام بايثون والهدف منه هو تقديم تحليل مُبسط لبيانات ذات هيلكية بسيطة خاصة بعدد حالات الاصابة بفيروس كورونا وعدد حالات الوفاة عبر دول العالم منذ بدء تفشي الفيروس. لا تحتوي البيانات التي نتعامل معها هنا على الكثير من الخصائص، فأبرز المعلومات تتمثل في عدد الوفيات والاصابات اليومية على مستوى الدُول.
ينبغي على من يريد تطبيق الجانب العملي من المقال أن يكون على دراية بأساسيات بايثون ومكتبات خاصة مثل pandas و numpy و matplotlib بالاضافة إلى معرفته باستخدام أداة jupyter.
لن نتطرق في هذا المقال إلى طُرق متقدمة او مُعقدة في التحليل، إنما سنُركز على مهارات تحليل البيانات باستخدام بايثون مثل:
1- كيفية استيراد البيانات.
2- كيفية معالجة البيانات وتحضيرها لمرحلة التحليل.
3- الحصول على معلومات أساسية عن البيانات.
4- اظهار معلومات من البيانات على شكل رسومات بيانية.
قبل البدء بتحليل بيانات فيروس كورونا، أنصح القُراء الأفاضل بأخذ جولة على المقالات المرجعية التالية، وخاصة للمبتدئين في تحليل البيانات باستخدام بايثون :
مكتبات علم البيانات بالبايثون | 5 مكتبات مشهورة
مكتبة Numpy – الخطوة الأولى في علم البيانات بلغة البايثون
مكتبة Pandas – الخطوة الثانية في علم البيانات بلغة البايثون – الجزء الأول
مكتبة Pandas – الخطوة الثانية في علم البيانات بلغة البايثون – الجزء الثاني
مكتبة Matplotlib – الخطوة الثالثة في علم البيانات بالبايثون
نظرة عامة على البيانات
يتكون ملف البيانات الذي نتعامل معه في هذا المقال من 8 أعمدة وعدد سجلات يتغير مع كل يوم في ظل تسجيل حالات جديدة بالمرض ووجود وفيات يوميًا. الملف هنا هو حتى تاريخ 25 مارس لسنة 2020، لذا وجب الانتباه إلى أن النتائج ستكون مختلفة عند تطبيقك لأمثلة المقال اذا استخدمت ملف يحتوي على بيانات أحدث أو مختلفة.
تم الحصول على البيانات من موقع المركز الأوروبي للوقاية من الأمراض ومكافحتها ECDC وذلك عبر بوابة البيانات العامة من خلال الرابط التالي:
الاحصاءات اليومية لعدد الاصابات والوفيات بمرض كورونا (Covid-19) حول العالم
خصائص البيانات (الأعمدة)
[spbtbl_sc id=9]
آلية التحليل
يُوجد الكثير من الاجتهادات والنصائح حول الخطوات التي ينبغي اتباعها عند تحليل مجموعة من البيانات، ولكن الثابت فيها أننا في البداية نقوم بالحصول على البيانات من مصادرها ثم معالجتها بحيث يتم ازالة التكرارات وازالة الأعمدة او السجلات التي ليس لها قيمة او أثر، بالاضافة الى معالجة القيم الفارغة. الهدف من مرحلة المعالجة هي تجهيز البيانات لتصبح صالحة لمرحلة التحليل والاستكشاف واظهار المعلومات على شكل رسومات بيانية.
بعد أن يتم تجهيز البيانات وتحويلها للشكل المطلوب، تبدأ عملية التحليل واستخراج المعلومات منها عبر تطبيق الدوال الاحصائية والخوارزميات الخاصة وعمليات الإظهار المرئي Data Visualization.
تحليل البيانات باستخدام بايثون – المرحلة الأولى (قراءة البيانات)
بعد تنزيل الملف من الرابط المذكور في الأعلى، نُنشى مجلد للعمل وليكن باسم corona data analysis ثم نحفظ الملف بداخله. نُشغل أداة Jupyter وننشى مستند جديد لتحليل البيانات باسم corona data analysis doc. في البداية نقوم باستيراد المكتبات التي سنحتاجها للعمل:
سنحتاج أيضًا قبل البدء بالعمل إلى تجهيز بعض الاعدادات التي لها بالعمل كالتالي:
من خلال matplotlib inline سنتمكن من اظهار الرسومات البيانية في نفس المستند، ثم بعد ذلك نُحدد أبعاد الرسوم البيانات وحجم الخط ثم نقوم باختيار تنسيق الرسومات من خلال دالة set_style.
لقراءة البيانات وحفظها في اطار البيانات نستخدم دالة read_csv الموجودة في مكتبة Pandas، وللحصول على عينة من البيانات بعد قراءتها نستخدم دالة head التابعة لاطار البيانات والتي ستعيد لنا أول 5 سجلات من البيانات، ويُمكننا استخدام دالة sample للحصول على عينة عشوائية.
تحليل البيانات باستخدام بايثون – المرحلة الثانية (تحضير البيانات)
في هذه المرحلة نعمل على تجهيز البيانات بشكل يُناسب عملية التحليل، وتُعتبر هذه المرحلة مهمة جدًا قبل تنفيذ التحليل، وحتى في مجال تعليم الألة وتطبيق خورازميات الذكاء الاصطناعي على البيانات. تشمل مرحلة تحضير البيانات للملف الذي نعمل عليه هنا الخطوات التالية:
- ازالة عمودي DateRep و GeoId باعتبار أنهما أعمدة مُكررة.
- التأكد من عدم وجود قيم فارغة في البيانات.
- تحويل عمود “احصائية السكان Pop_Data.2018” إلى قيم عددية صغيرة بقِيم مقاربة، فمثلًا 3562065 الى 3.5 مليون تقريبًا.
- تغيير اسماء بعض الأعمدة.
- إزالة كافة السجلات الصفرية، وأعني هنا السجلات التي ليس لها قيمة لكل دولة (عدد الاصابات والوفيات تساوي 0) والتي تكون قبل أول حالة اصابة في الدولة.
الهدف من الخطوة الأخيرة هو الحصول على معدلات صحيحة لعدد الوفيات والإصابات بعد تسجيل أول حالة اصابة بالفيروس في كل دولة. فمثلًا، حتى يكون متوسط عدد الاصابات أو الوفيات لدولة أفغانستان، يجب علينا ازالة السجلات الصفرية الخاصة بها قبل تاريخ 25/2/2020 وهو تاريخ تسجيل أول حالة اصابة، وسيتم تنفيذ ذلك على كل الدُول.
1- ازالة عمودي DateRep و GeoId باعتبار أنهما أعمدة مُكررة
2- التأكد من عدم وجود قيم فارغة في البيانات
حتى تاريخ 25/3/2020، وهو تاريخ أخر نسخة للبيانات والتي استخدمناها في هذا المقال، لم نجد قيم فارغة في البيانات إلا في عمود احصائية السكان.
لإزالة القيم الفارغة يُوجد العديد من الطُرق والخيارات المتاحة. في حالتنا لن نستطيع حذف السجلات التي لديها قيم فارغة في عمود احصائية السكان، والسبب في ذلك يعود لوجود بيانات مهمة في تلك السجلات والتي لها علاقة بعدد الاصابات والوفيات في بعض الدول. لذلك سنعتمد تغيير القيمة الفارغة الى صفر باستخدام دالة fillna كما يلي:
3- تحويل عمود “احصائية السكان Pop_Data.2018” إلى قيم عددية صغيرة
هنا نرى أن إبقاء القيم الخاصة بإحصائية السكان لكل دولة كما هي عليه سيكون دون فائدة، ونُفضل أن تكون الأرقام مُقربة بالمليون، لذا سنعمل على قسمة القيم الموجودة في هذا العمود على قيمة 1,000,000 كما يلي:
4- تغيير اسماء بعض الأعمدة
باستخدام دالة rename يُمكننا تغيير أسماء الأعمدة التي نريدها، وذلك عبر تمرير الأسماء القديمة والجديدة كقاموس dictionary كما يلي:
5- إزالة كافة السجلات الصفرية
هذه الخطوة تتضمن عدة عمليات داخلية لتنفيذها، وهي كالتالي:
- تجزئة اطار البيانات الرئيسي إلى مجموعة اطارات بيانات فرعية حسب الدولة.
- الحصول على فهرس index لأول يوم تُسجل فيه اصابات بالفيروس في كل اطار فرعي، وحفظ قيمة الفهرس في متغير باسم first_infected_day.
- حذف السجلات الصفرية في كل الاطار الفرعي التي تكون فيها عدد الاصابات والوفيات صفر وتكون فهارسها قبل first_infected_day.
- اعادة تجميع الاطارات الفرعية في اطار بيانات واحد باسم corona_updated.
الدالة drop_zero_days ستقوم بالخطوات رقم 1 و 2 و 3، بينما ستتولى دالة concatenate_countries_dfs بتجميع الاطارات الفرعية:
بعد أن جهزنا الدوال الخاصة بخطوة ازالة السجلات الصفرية، سنحتاج إلى الحصول على قائمة بأسماء الدول الموجوة في اطار البيانات الرئيسي. بعد ذلك نُعرف قائمة فارغة باسم corona_dfs_list لحفظ الاطارات الفرعية فيها. نُعرف بعدها حلقة تكرار for loop تقوم بالمرور على اسماء الدول وتستدعي دالة drop_zero_days لكل دولة، وناتجها الذي هو عبارة عن الاطار الفرعي يتم حفظه في قائمة corona_dfs_list.
بعد أن حصلنا على قائمة الاطارات الفرعية، نستدعي دالة concatenate_countries_dfs لتجميعها في إطار واحد باسم corona_updated:
إلى هنا نكون انتهينا من مرحلة تجهيز البيانات، ونستطيع الانتقال لمرحلة استكشاف البيانات ومن ثم تحليلها.
تحليل البيانات باستخدام بايثون – المرحلة الثالثة (استكشاف البيانات)
نحاول خلال مرحلة استكشاف البيانات الحصول على معلومات مبدئية أو أولية عن البيانات، وغالبًا ستكون هذه المعلومات هي معلومات احصائية وأرقام تُمثل المتوسط، الوسيط، القيم الكُبرى والصُغرى لكل خاصية، درجة الارتباط Coorealtion بين الخصائص.
لحسن الحظ أن مكتبة Pandas الرائعة تُوفر الكثير من الدوال التي تساعدنا في الحصول على المعلومات السابقة. للحصول على معلومات عن الخصائص في اطار البيانات، نستخدم الدالة info والتي تُعيد لنا أسماء الأعمدة وعدد السجلات في اطار البيانات وحجم الاطار في الذاكرة ومعلومات أخرى:
تقدم لنا دالة describe الكثير من المعلومات الاحصائية عن البيانات:
من خلال المعلومات التي ظهرت لنا، عرفنا أن أكبر عدد للوفيات منذ بدء تفشي وباء فيروس كورونا كان 795 في يوم واحد لأحد الدول، ولكن لا نعلم أي دولة إلى الأن. كذلك بالنسبة لعدد حالات الاصابة، فأكبر عدد وصل الى 15141 اصابة في يوم واحد.
كذلك من خلال المعلومات السابقة، تبين لنا وجود قيمة غير منطقية لأقل عدد اصابات، حيث نجد أن الدالة describe أرجعت قيمة -9 لأقل قيمة في عمود Cases. لمعرفة أي دولة سُجل لها أكبر عدد وفيات حتى تاريخ 25/3/2020 وأي دولة وصل فيها عدد الاصابات لأكبر قيمة بالاضافة لمعرفة السجل الذي يحتوي على قيمة غير منطقية في عمود عدد حالات الاصابة:
يُمكن الحصول على المعلومات السابقة بطريقة أخرى، وسنذكرها في شُروحات أخرى.
للحصول على عدد السجلات لكل دولة على حدة، نستخدم دالة value_counts ونُطبقها على عمود الدُول كما يلي:
سنجد هنا أن للصين يُوجد 83 سِجل تليها اليابان بـ 71 سِجل ثم باقي الدُول.
لمعرفة درجة الارتباط بين خصائص البيانات نستدعي دالة corr لإطار البيانات corona_updated كما يلي:
وستكون النتيجة عبارة عن قيم درجة الارتباط بين الخصائص. نلاحظ أنه يوجد ارتباط قوي بين عمود عدد الوفيات وعمود عدد الإصابات:
تحليل البيانات باستخدام بايثون – المرحلة الرابعة (تحليل البيانات)
يجب علينا قبل البدء بتحليل البيانات، وبعد أن تعرفنا سريعا على البيانات، أن نُحدد مجموعة من الأسئلة التي تُمثل “المشكلة”. الاجابة على هذه الأسئلة ستكون من خلال عملية التحليل. الأسئلة التي نفترضها هي كالتالي:
- ما هو معدل عدد الإصابات والوفيات اليومي على مستوى العالم منذ بدء تفشي الفيروس؟
- ما هو معدل عدد الإصابات والوفيات اليومي حسب الدُول؟
- كم يبلغ مجموع الاصابات والوفيات الشهري على مستوى العالم؟
- كم يبلغ مجموع الاصابات والوفيات شهريا حسب كل دولة؟
- من هي أعلى 5 دُول في عدد الوفيات والاصابات منذ بداية تفشي الفيروس؟
- السلسلة الزمنية لعدد الوفيات والاصابات
1- ما هو معدل عدد الإصابات والوفيات اليومي على مستوى العالم منذ بدء تفشي الفيروس؟
في ظل هذه الأزمة الصعبة التي تمر على العالم، قد يسأل الكثير السؤال التالي: ما هو المعدل اليومي للوفيات والاصابات بالفيروس على مستوى العالم؟ ايجاد اجابة على هذا السؤال ستعطي تصورًا أدق عن حجم الوباء.
في البداية لابد أن نوضح آلية احتساب المعدل اليومي للاصابات وعدد الوفيات. يتم احتساب المعدل اليومي للوفيات عبر ايجاد مجموع عدد الوفيات على مستوى العالم وتقسيم قيمة المجموع على عدد أيام الأزمة والتي بدأت بتاريخ 1/12/2019 وحتى وقت تجهيز هذا المقال.
لإظهار المعلومات السابقة على شكل بياني من نوع bar:
حتى تاريخ 25/3/2020 وصل معدل الوفيات اليومي من فيروس كورونا منذ بدء نفشيه إلى 161.43 حالة وفاة يوميًا على مستوى العالم ومعدل عدد الاصاابات إلى 3625.35 حالة اصابة يوميا، وهذه أرقام أقل ما يُقال عنها أنها مُرعبة.
2- ما هو معدل عدد الإصابات والوفيات اليومي حسب الدُول؟
سنستخدم هنا خاصية التجميع حسب الدولة في اطار البيانات corona_updated. سنُجمع السجلات وفق الدولة ونُطبق دالة الجمع، بحيث تكون النتيجة عبارة عن مجموع عدد الوفيات والاصابات حسب كل دولة، ثم سنقوم بتقسيم المجموع على عدد الأيام لإيجاد المعدل:
لاحظ أننا رتبنا النتيجة حسب مجموع عدد الوفيات بطريقة تصاعدية. للحصول على أعلى 5 معدلات يومية في الاصابات والوفيات واظهار ذلك على شكل bar chart نستخدم دالة tail ونمرر لها القيمة 5. في هذه الحالة، ولأن البيانات مُرتبة ترتيبًا تصاعديا، سنحصل على آخر 5 قيم في معدلات الوفيات بالطريقة التالية:
ونفس الأمر للحصول على معدل الاصابات اليومية لأعلى 5 دول:
3- كم يبلغ مجموع الاصابات والوفيات الشهري على مستوى العالم؟
سنستخدم هنا نفس المفهوم السابق، وهو التجميع، ولكن هذه المرة حسب الشهر:
لإظهار المعلومات السابقة بشكل رسومي، من الممكن أن نستخدم شكل جديد، وهو pie chart كما يلي:
وكذلك بالنسبة لمجموع الاصابات:
4- كم يبلغ مجموع الاصابات والوفيات شهريا حسب كل دولة؟
سنستخدم هنا نفس طريقة التجميع، ولكن التجميع سيكون باستخدام أكثر من عمود. في البداية سنُجمع البيانات حسب الدولة، ثم حسب الشهر كما يلي:
ستكون النتيجة عبارة عن اطار بيانات يتضمن كُل دولة ومجموع الوفيات والاصابات حسب الشهر. يُمكننا الاستعلام من النتيجة عن دولتي الصين وايطاليا كما يلي:
5- من هي أعلى 5 دُول في عدد الوفيات والاصابات منذ بداية تفشي الفيروس؟
قد نكون أجبنا على هذا السؤال بشكل غير مباشر في النقطة رقم 2 السابقة والتي مثلت كيفية إيجاد المعدل اليومي للوفيات. هنا نُريد أن نعرف بالضبط أول 5 دُول تفشى فيها الفيروس وكان بها أكبر عدد من الوفيات والإصابات.
سنحتاج هنا الى تجميع البيانات حسب الدولة، ثم نستدعي دالة المجموع ونُطبقها على عمود الوفيات كما يلي:
للحصول على أول 5 دُول تحتل أعلى مجموع وفيات نستخدم دالة head او tail حسب حالة الترتيب:
لإظهار المعلومات بشكل رُسومي كما يلي:
السلسلة الزمنية لعدد الوفيات
نعمل في هذا العنوان على إيجاد معلومات تُوضح كيفية انتشار المرض من حيث عدد الاصابات والوفيات زمنيًا. أبرز ما يُمثل هذا الأمر هو السلسلة الزمنية Time Series والتي يكون فيها محور x عبارة عن الزمن أو بيانات مُرتبة تُمثل الزمن.
سنعمل على بناء دالة تستقبل مُعامل واحد نصي يُعبر عن دولة ما، وعند استدعاء الدالة، تُقوم برسم السلسلة الزمنية لعدد الوفيات والاصابات للدولة التي حددناها. الشيفرة البرمجية الكاملة لهذه الدالة كما يلي:
في البداية نُعرف الدالة باسم time_series_by_country وتكون بمُعامل اسمه country سيُمثل اسم الدولة المُدخلة. نُعرف بعدها مُتغير باسم corona_by_day_ser وهو عبارة عن اطار بيانات يُمثل بيانات الدولة الُمدخلة مُرتبة حسب السنة ثم الشهر ثم اليوم مع إعادة تهيئة قيمة الفهرس ليكون مُرتبًا ترتيبًا تصاعديا يُماثل الترتيب الزمني للسجلات. سيكون مُحور x عبارة عن فهرس اطار البيانات للدولة، ومحور y عبارة عن عدد الوفيات والإصابات اليومية كما يلي:
في الشكل الذي سيُمثل السلسلة الزمنية، نُريد أن نوضح في الشكل القيمة الكُبرى لعدد الاصابات والوفيات. يلزمنا لذلك أن نُحدد هذه القيم والفهارس الخاص بها:
الان لدينا اطار البيانات الخاصة بالدولة، والقيمة الكُبرى المُسجلة لعدد الوفيات والقيمة الكُبرى لعدد الإصابات، نستطيع الأن البدء بتجهيز الشكل البياني الذي سيكون السلسلة الزمنية:
نستخدم الدالة annotate لإضافة النص على السلسة الزمنية والذي يُوضح القيمة الكُبرى لعدد الوفيات والإصابات.
عند استدعاء الدالة لدولة مثل الصين كما يلي:
ستكون السلسلة الزمنية الخاصة بها كالتالي:
وستكون لإيطاليا وايران كما يلي:
إلى هنا نكون قد أتمننا عملية تحليل ملف البيانات الخاص بمرض كورونا. للحصول على مستند Jupyter الخاص بهذا المقال من خلال الرابط التالي:
جزاك الله خير على اللي تقدمه وجعلها الله في موازين حسناتك ..
وياليت تقدم دروس عن برنامج spyder
أهلا ومرحبا بكم..سنعمل على ذلك ان شاء الله
[…] تحليل البيانات باستخدام بايثون – سجلات الوفيات والاصا… […]
شكرًا جزيلًا على هذا المجهود وجعله الله في موازين حسناتك،، المثال رائع للمبتدئين ياليت كل فترة تشرح مثال متكامل نفس هذا المثال.
شكرًا جزيلًا على هذا المجهود وجعله الله في موازين حسناتك
العفو منكم، يُشرفنا مروركم الكريم
شكرا على مجهودك
ممكن رقم واتس للتواصل
جزاكم الله خيرا على هذا العطاء الرائع
شكرا لك علي الشرح الرائع
لكن لاحظت اننا لم نستخدم كافة المكتبات المستوردة مثلا numpay وكنت اود لو هناك مثال يشرح لنا كيفية استخدام Numpay في تحليل البيانات
كيف اسوي regression او classification
لمثل هذا الدراسه و تحليله؟
شكرًا جزيلًا على هذا المجهود وجعله الله في موازين حسناتك
مقال رائع ومفيد جدا
شكرا استاذي الفاضل على هذا المجهود
الجوبتر ماشتغل ايش السبب
برنامج الجوبتر الي في المستند لم يشتغل