تعلمت في الدرس السابق أساسيات Python التي يحتاجها طالب الذكاء الاصطناعي. لكن كتابة الأوامر ليست سوى البداية؛ فالجزء الأكبر من العمل الحقيقي يبدأ عندما تستلم ملف بيانات لا تعرف إن كان منظمًا، ناقصًا، مكررًا أو يحتوي على أرقام مخزنة كنصوص.
الخطأ الشائع هو فتح الملف ثم الانتقال مباشرة إلى تدريب نموذج تعلم آلي. قد يعمل الكود ويعطيك دقة مرتفعة، لكن النتيجة قد تكون مضللة بسبب مشكلة بسيطة في البيانات لم تنتبه إليها.
في هذا الدرس ستتعلم استخدام NumPy وPandas لفهم البيانات قبل تحليلها، من خلال مختبر صغير لبيانات طلاب. الهدف ليس حفظ عشرات الأوامر، بل اكتساب طريقة تفكير تجعلك تسأل: ماذا يمثل كل صف؟ وهل القيم منطقية؟ وما الذي لا تخبرني به البيانات؟
ماذا ستتعلم في هذا الدرس؟
بنهاية الدرس ستكون قادرًا على:
- فهم الفرق بين مصفوفة NumPy وجدول Pandas.
- إنشاء مصفوفات وإجراء حسابات عليها دون تكرار يدوي.
- قراءة بنية جدول البيانات قبل تحليله.
- اكتشاف القيم المفقودة والصفوف المكررة وأنواع البيانات الخاطئة.
- تنظيف مشكلة رقمية بسيطة دون إخفاء الخطأ.
- إنشاء متغير جديد يفيد التحليل.
- تصدير نسخة نظيفة مع المحافظة على الملف الأصلي.
- كتابة تقرير مختصر يشرح ما عثرت عليه بدل الاكتفاء بعرض الكود.
لماذا نحتاج إلى NumPy وPandas معًا؟
تؤدي المكتبتان وظيفتين متكاملتين، وليستا أداتين متنافستين.
NumPy للحسابات والمصفوفات
تعتمد NumPy على بنية تسمى array، وهي مناسبة للتعامل مع مجموعة متجانسة من القيم وإجراء العمليات الحسابية عليها بكفاءة.
يمكنك استخدامها في:
- حساب المتوسط والانحراف المعياري.
- التعامل مع متجهات ومصفوفات متعددة الأبعاد.
- تنفيذ العملية نفسها على مجموعة كاملة من الأرقام.
- تجهيز البيانات العددية التي تستخدمها مكتبات تعلم الآلة.
Pandas للجداول ذات المعنى
تستخدم Pandas بنية تسمى DataFrame، وهي جدول يتكون من صفوف وأعمدة تحمل أسماء واضحة. قد يحتوي العمود الواحد على ساعات دراسة، والآخر على نسبة حضور، والثالث على نتيجة الطالب.
تساعدك Pandas في:
- قراءة ملفات CSV والجداول.
- اختيار صفوف أو أعمدة محددة.
- اكتشاف القيم المفقودة والتكرار.
- ترتيب البيانات وتجميعها.
- إنشاء أعمدة جديدة.
- حفظ نسخة نظيفة من البيانات.
القاعدة العملية هي: استخدم Pandas لفهم الجدول وتنظيمه، واستخدم NumPy عندما تحتاج إلى عمليات عددية ومصفوفات.
تجهيز بيئة العمل
يمكن تنفيذ المختبر داخل Google Colab دون تثبيت برامج على الجهاز، أو داخل بيئة Python محلية مثل VS Code وJupyter Notebook.
إذا كنت تخطط للتعامل مع بيانات كبيرة أو تشغيل نماذج محليًا، فراجع دليل اختيار كمبيوتر يدعم الذكاء الاصطناعي لمعرفة أهمية الذاكرة والمعالج والبطاقة الرسومية.
إذا كنت تعمل محليًا ولم تكن المكتبتان مثبتتين، نفّذ الأمر التالي في الطرفية:
pip install numpy pandas
وفي بداية ملف Python أو دفتر Jupyter استورد المكتبتين:
import numpy as npimport pandas as pd
الاختصار np مستخدم عادة مع NumPy، والاختصار pd مستخدم مع Pandas. استخدام هذه الاختصارات يجعل الكود أقصر وأسهل في القراءة.
التفكير بالمصفوفات بدل تكرار الأوامر
لنفترض أن لدينا عدد الساعات التي درسها خمسة طلاب خلال أسبوع:
study_hours = np.array([2, 5, 3, 8, 4])print(study_hours)print("المتوسط:", study_hours.mean())print("أعلى قيمة:", study_hours.max())print("أقل قيمة:", study_hours.min())
يمكن زيادة جميع القيم ساعة واحدة بعملية واحدة:
updated_hours = study_hours + 1print(updated_hours)
هذه العملية تسمى غالبًا Vectorization؛ أي تطبيق العملية على المصفوفة كاملة بدل كتابة حلقة لمعالجة كل قيمة منفردة.
يمكنك أيضًا فحص خصائص المصفوفة:
print("الشكل:", study_hours.shape)print("عدد الأبعاد:", study_hours.ndim)print("نوع البيانات:", study_hours.dtype)
لا تتجاهل نوع البيانات. وجود رقم على الشاشة لا يعني دائمًا أنه مخزن كرقم؛ فقد يصل الرقم من ملف خارجي على هيئة نص، وعندها قد تفشل العمليات الحسابية أو تنتج سلوكًا غير متوقع.
إنشاء جدول بيانات تدريبي
سننشئ جدولًا صغيرًا يحاكي بيانات طلاب. يحتوي الجدول عمدًا على قيمة مفقودة، وقيمة مكتوبة بطريقة غير صحيحة، وصف مكرر حتى نتعلم اكتشافها.
data = { "student_id": [101, 102, 103, 104, 104, 105], "study_hours": [5, 8, "4 ساعات", 7, 7, None], "attendance": [90, 95, 70, 88, 88, 60], "assignments": [8, 10, 6, 9, 9, 5], "passed": ["نعم", "نعم", "لا", "نعم", "نعم", "لا"]}df = pd.DataFrame(data)print(df)
كل صف يمثل طالبًا، وكل عمود يمثل خاصية عنه. قبل تنفيذ أي تحليل يجب التأكد من أن هذا المعنى ثابت في جميع الصفوف.
فحص الجدول قبل تنظيفه
ابدأ دائمًا بنظرة سريعة:
print(df.head())print(df.shape)print(df.columns)
head()يعرض الصفوف الأولى.shapeيعرض عدد الصفوف والأعمدة.columnsيعرض أسماء الأعمدة.
بعد ذلك افحص الأنواع والقيم المفقودة:
df.info()print(df.isna().sum())
ستلاحظ أن عمود study_hours قد لا يظهر كعمود عددي خالص، لأن إحدى قيمه تحتوي على كلمة «ساعات»، كما توجد فيه قيمة مفقودة.
افحص التكرار:
print("عدد الصفوف المكررة:", df.duplicated().sum())
ثم اعرض ملخصًا إحصائيًا:
print(df.describe(include="all"))
لا تتعامل مع describe() على أنها تقرير نهائي؛ فهي إشارة أولية تساعدك على ملاحظة القيم الغريبة، لكنها لا تفهم سياق البيانات نيابة عنك.
قاعدة دليل التقنية: اكتب عقد البيانات قبل تنظيفها
قبل حذف أي قيمة أو تعديلها، اكتب وصفًا مختصرًا لما يجب أن يمثله الجدول. يمكن تسمية هذا الوصف «عقد البيانات».
في مثالنا يكون العقد كالتالي:
- كل صف يمثل طالبًا واحدًا.
student_idرقم فريد لا يتكرر.study_hoursعدد ساعات من صفر فأعلى.attendanceنسبة بين 0 و100.assignmentsعدد الواجبات المكتملة.passedيأخذ إحدى قيمتين فقط: نعم أو لا.
هذه الخطوة البسيطة تمنع التنظيف العشوائي. فعندما تجد رقم طالب مكررًا، تعرف أن هناك مخالفة للعقد. وعندما تجد حضورًا يساوي 140، تعرف أن القيمة غير منطقية حتى لو قبلها البرنامج.
تنظيف البيانات دون إخفاء المشكلة
الاحتفاظ بالنسخة الأصلية
لا تعدّل النسخة الوحيدة من البيانات. أنشئ نسخة للعمل:
clean_df = df.copy()
تحويل ساعات الدراسة إلى أرقام
نحذف النص الزائد ثم نحاول تحويل القيم إلى أرقام:
clean_df["study_hours"] = ( clean_df["study_hours"] .astype("string") .str.replace(" ساعات", "", regex=False))clean_df["study_hours"] = pd.to_numeric( clean_df["study_hours"], errors="coerce")
استخدام errors="coerce" يحول القيم التي لا يمكن فهمها رقميًا إلى قيمة مفقودة بدل إيقاف البرنامج. هذا لا يعني أن الخطأ اختفى؛ بل أصبح ظاهرًا ويمكن قياسه.
افحص العمود بعد التحويل:
print(clean_df["study_hours"])print(clean_df["study_hours"].isna().sum())
إزالة الصف المكرر
clean_df = clean_df.drop_duplicates()
إذا كان التكرار يعتمد على هوية الطالب تحديدًا، يمكنك استخدام:
clean_df = clean_df.drop_duplicates( subset="student_id", keep="first")
لا تستخدم هذا الأمر تلقائيًا في بيانات حقيقية. قد يظهر الطالب أكثر من مرة لأن كل صف يمثل اختبارًا مختلفًا. ارجع أولًا إلى معنى الصف في عقد البيانات.
معالجة القيمة المفقودة
في هذا المختبر سنستخدم وسيط ساعات الدراسة:
median_hours = clean_df["study_hours"].median()clean_df["study_hours"] = clean_df["study_hours"].fillna( median_hours)
اختيار الوسيط مناسب للتجربة، لكنه ليس قاعدة ثابتة. أحيانًا يكون حذف الصف أفضل، وأحيانًا يجب الرجوع إلى المصدر، وقد تكون القيمة المفقودة نفسها معلومة مهمة.
إذا عالجت القيم المفقودة مستقبلًا ضمن مشروع تعلم آلي، احسب قيمة التعويض من بيانات التدريب فقط، لا من كامل البيانات؛ حتى لا تنتقل معلومات من مجموعة الاختبار إلى عملية التدريب.
فحص الحدود المنطقية
نتحقق من أن نسبة الحضور بين صفر ومئة:
invalid_attendance = clean_df[ ~clean_df["attendance"].between(0, 100)]print(invalid_attendance)
إذا ظهر جدول فارغ فهذا يعني أنه لم تُكتشف قيمة خارج النطاق، وليس دليلًا على أن البيانات كلها صحيحة.
إنشاء متغير له معنى
يمكننا إنشاء مؤشر تدريبي بسيط يجمع بين ساعات الدراسة ونسبة الحضور:
clean_df["engagement_score"] = ( clean_df["study_hours"] * clean_df["attendance"] / 100)
ثم نعرض الأعمدة المهمة:
print( clean_df[ [ "student_id", "study_hours", "attendance", "engagement_score", "passed" ] ])
إنشاء المتغيرات الجديدة يسمى Feature Engineering، لكنه لا يعني اختراع أرقام بلا مبرر. يجب أن يكون للمتغير تفسير واضح، وألا يستخدم معلومة لن تكون متاحة وقت إجراء التنبؤ.
المؤشر السابق تعليمي فقط؛ فهو لا يثبت أن الطالب سينجح، ولا ينبغي استخدامه لاتخاذ قرار حقيقي بشأن الطلاب دون دراسة أوسع.
تحليل أولي دون ادعاء السببية
يمكن مقارنة متوسطات بعض الأعمدة حسب النتيجة:
summary = clean_df.groupby("passed")[ ["study_hours", "attendance", "assignments"]].mean()print(summary)
إذا كان متوسط ساعات الدراسة أعلى لدى الناجحين، فهذا يوضح ارتباطًا داخل هذه العينة فقط. لا يثبت أن زيادة الساعات وحدها سببت النجاح؛ فقد توجد عوامل أخرى غير مسجلة، مثل صعوبة المقرر أو الخبرة السابقة أو جودة الدراسة.
هذه نقطة مهمة في الذكاء الاصطناعي: الجدول يعرض ما تم تسجيله، وليس كل ما حدث في الواقع.
فحص الدقة بطريقة لا توفرها الأوامر الجاهزة
قبل الانتقال إلى النموذج، نفّذ فحصًا يدويًا لثلاثة صفوف:
- اختر صفًا عشوائيًا من بداية الجدول.
- اختر صفًا من المنتصف.
- اختر صفًا من النهاية.
- قارن القيم بعد التنظيف بما كانت عليه في النسخة الأصلية.
- اكتب سبب كل تعديل أجريته.
يمكن أخذ عينة عشوائية باستخدام:
print(clean_df.sample(3, random_state=42))
تثبيت random_state يجعل اختيار العينة قابلًا للتكرار عند تشغيل الكود مرة أخرى.
هذا الفحص لا يحل محل الاختبارات الآلية، لكنه يكشف أخطاء قد تمر بصمت، مثل حذف جزء صحيح من النص أو تحويل وحدة قياس بطريقة غير مقصودة.
حفظ البيانات النظيفة
احفظ النتيجة في ملف جديد، ولا تكتب فوق الملف الأصلي:
clean_df.to_csv( "students_clean.csv", index=False, encoding="utf-8-sig")
يساعد الترميز utf-8-sig غالبًا على ظهور النص العربي بصورة صحيحة عند فتح ملف CSV في بعض إصدارات Excel.
استخدم أسماء توضح مرحلة الملف، مثل:
students_raw.csvللبيانات الأصلية.students_clean.csvللبيانات النظيفة.students_features.csvللبيانات بعد إنشاء المتغيرات.
تقرير فحص البيانات
لا يكتمل العمل بمجرد تشغيل الكود. أنشئ تقريرًا قصيرًا يحتوي على:
- عدد الصفوف والأعمدة قبل التنظيف وبعده.
- عدد القيم المفقودة في كل عمود.
- عدد الصفوف المكررة.
- القيم غير المنطقية التي عُثر عليها.
- القرارات التي اتخذتها وسبب كل قرار.
- الأعمدة الجديدة وطريقة حسابها.
- المشكلات التي لم تستطع حلها.
يمكن طباعة جزء من التقرير بالكود:
print("حجم البيانات الأصلي:", df.shape)print("حجم البيانات بعد التنظيف:", clean_df.shape)print("القيم المفقودة بعد التنظيف:")print(clean_df.isna().sum())
القيمة المهنية لهذا التقرير أنه يجعل خطواتك قابلة للمراجعة. إذا تغيرت النتائج لاحقًا، تستطيع معرفة ما فعلته بدل محاولة تذكره.
أخطاء شائعة يجب تجنبها
حذف جميع الصفوف الناقصة
الأمر dropna() سهل، لكنه قد يحذف نسبة كبيرة من البيانات أو يستبعد نوعًا معينًا من الحالات. افهم سبب النقص قبل الحذف.
استبدال كل القيم بالمتوسط
المتوسط ليس علاجًا عامًا. قد يشوه التوزيع ويخفي مشكلة في جمع البيانات.
اعتبار الرقم المخزن كنص رقمًا صالحًا
افحص أنواع الأعمدة باستخدام info()، ولا تعتمد على شكل القيمة عند طباعتها.
تنظيف بيانات التدريب والاختبار معًا
حساب المتوسطات أو الحدود من كامل البيانات قبل التقسيم قد يؤدي إلى تسرب البيانات ويعطي تقييمًا أفضل من الواقع.
الخلط بين الارتباط والسبب
وجود علاقة بين الحضور والنجاح لا يثبت أن أحدهما السبب الوحيد للآخر.
حذف الملف الأصلي
احتفظ دائمًا بنسخة خام لا تتغير، واحفظ كل مرحلة في ملف منفصل.
جمع بيانات أكثر مما تحتاج
ليس كل عمود مفيدًا. تجنب الاحتفاظ بأسماء الأشخاص أو أرقامهم أو معلوماتهم الحساسة إذا كان المشروع لا يحتاج إليها.
وقبل رفع أي ملف إلى خدمة خارجية، تعرّف على كيفية حماية صورك وملفاتك عند استخدام تطبيقات الذكاء الاصطناعي.
مختبر عملي مقترح
اختر ملف CSV صغيرًا لا يحتوي على معلومات شخصية حساسة، ثم نفّذ الخطوات التالية:
- اقرأ الملف باستخدام
pd.read_csv(). - اعرض أول خمسة صفوف.
- اكتب معنى كل صف وكل عمود.
- افحص الحجم والأنواع والقيم المفقودة.
- ابحث عن التكرار والقيم الخارجة عن النطاق.
- نظف مشكلة واحدة فقط مع توثيق قرارك.
- أنشئ عمودًا جديدًا له تفسير واضح.
- اعرض ملخصًا إحصائيًا قبل التنظيف وبعده.
- احفظ النتيجة باسم جديد.
- اكتب خمسة أسطر تشرح ما اكتشفته.
لقراءة ملف CSV استخدم:
df = pd.read_csv("file_name.csv")
ولا تستخدم ملفًا مجهول المصدر مباشرة داخل مشروع مهم. افحص مصدره، وترخيص استخدامه، ووصف الأعمدة، وتاريخ جمعه.
متى تكون مستعدًا للدرس التالي؟
أنت مستعد للانتقال عندما تستطيع الإجابة عن الأسئلة التالية:
- ماذا يمثل الصف الواحد؟
- ما نوع كل عمود؟
- كم قيمة مفقودة توجد؟
- هل هناك صفوف مكررة؟
- هل توجد قيم خارج الحدود المنطقية؟
- ماذا غيّرت أثناء التنظيف ولماذا؟
- هل حافظت على نسخة البيانات الأصلية؟
- هل تستطيع إعادة تنفيذ الخطوات والحصول على النتيجة نفسها؟
إذا لم تستطع الإجابة، فلا تنتقل إلى تدريب النموذج بعد. المشكلة ليست في أنك تحتاج خوارزمية أقوى؛ بل في أنك لم تفهم المدخلات بما يكفي.
أسئلة شائعة
هل أتعلم NumPy أم Pandas أولًا؟
تعلم من NumPy مفهوم المصفوفات والعمليات العددية الأساسية، ثم استخدم Pandas للتعامل مع الجداول. لا تحتاج إلى إتقان جميع تفاصيل NumPy قبل البدء في Pandas.
هل Excel بديل عن Pandas؟
Excel مفيد للفحص السريع والعمل اليدوي، لكن Pandas يجعل خطوات المعالجة قابلة للتكرار والتوثيق، ويكون أنسب عندما تكبر البيانات أو تتكرر المهمة.
هل يجب حفظ جميع أوامر Pandas؟
لا. ركز على فهم السؤال الذي تريد الإجابة عنه، وتعلم قراءة التوثيق الرسمي. الأهم أن تعرف كيف تفحص نتيجة الأمر قبل الاعتماد عليها.
هل تعني البيانات النظيفة أن النموذج سيكون جيدًا؟
لا. التنظيف يقلل بعض المشكلات، لكن جودة النموذج تعتمد أيضًا على تمثيل العينة، وصحة الهدف، وطريقة التقسيم والتقييم، وملاءمة النموذج للمشكلة.
هل يمكن استخدام بيانات الطلاب في مشروع جامعي؟
يمكن ذلك بعد الحصول على التصريح اللازم، وإزالة البيانات التي تكشف الهوية، وتقليل المعلومات إلى ما يحتاجه المشروع فقط. للممارسة، استخدم بيانات صناعية أو عامة ذات ترخيص واضح.
يمكنك معرفة موقع هذا الدرس وما يليه ضمن خريطة تعلم الذكاء الاصطناعي لطالب الجامعة، التي ترتب المسار من Python ومعالجة البيانات إلى تعلم الآلة والمشاريع.
الخلاصة
NumPy وPandas ليستا مجرد مكتبتين لتنفيذ الأوامر، بل وسيلتان لاختبار فهمك للبيانات. ابدأ بتعريف معنى الصف والأعمدة، ثم افحص الأنواع والنقص والتكرار والحدود المنطقية، ووثّق كل تعديل تجريه.
لا تقِس تقدمك بعدد الأوامر التي حفظتها. قِسه بقدرتك على اكتشاف قيمة غير منطقية، وشرح أثرها، واتخاذ قرار يمكن لشخص آخر مراجعته وإعادة تنفيذه.
بعد إتقان هذه الخطوات، تصبح جاهزًا للانتقال إلى تصوير البيانات واكتشاف الأنماط بصريًا قبل بناء أول نموذج تعلم آلي.
وللوصول إلى جميع المسارات والدروس العملية، انتقل إلى قسم طلاب الحاسب في دليل التقنية.


شاركنا رأيك