الأسبوع 7: التحليل أحادي المتغيّر والتصور البصري
🎯 أهداف التعلّم
بنهاية هذا الأسبوع ستكون قادرًا على:
- تصور توزيع عمود رقمي بمدرج تكراري، وتوزيع عمود فئوي بمخطط شريطي.
- قراءة مخطط صندوقي كملخّص مُكثَّف لأرباع توزيع وقيمه المتطرفة.
- اختيار نوع الرسم الصحيح لنوع المتغيّر، ووضع علامات على الرسوم بحيث تكون مقروءة بمفردها.
- شرح لماذا عدد صناديق المدرج التكراري نفسه اختيار ذو معنى، وليس افتراضيًا عشوائيًا.
الدرس
لماذا التصور البصري، لا التلخيص بالأرقام فقط؟
يصف mean/median/std الأسبوع 6 توزيعًا بثلاثة أرقام — لكن توزيعات مختلفة جدًا يمكن أن تشترك بنفس المتوسط والانحراف المعياري. يُظهر الرسم الشكل: هل هو متماثل، منحرف، ذو قمتين (bimodal)، مليء بقيم متطرفة؟ هذا السبب الجوهري لكون التصور أحادي المتغيّر يسبق أي شيء أكثر تقدمًا.
المدرجات التكرارية: توزيع متغيّر رقمي
يُقسّم المدرج التكراري قيم عمود رقمي إلى صناديق ويُظهر كم يقع في كل صندوق — تصور مباشر لتوزيع التردد، النسخة المرسومة من أرقام mean/median/std الأسبوع الماضي:
import matplotlib.pyplot as plt
df["math_score"].hist(bins=20, edgecolor="black")
plt.xlabel("Math score")
plt.ylabel("Number of students")
plt.title("Distribution of math scores")
plt.show()
ضع دائمًا علامات على محاورك وعنوانًا لرسمك — رسم لا يُفهم إلا بوجود الكود الذي أنتجه بجانبه غير مكتمل.
عدد الصناديق اختيار حقيقي، لا افتراضي تتجاهله
صناديق قليلة جدًا تُخفي بنية حقيقية (كل شيء يمتزج في كتلة أو كتلتين)؛ صناديق كثيرة جدًا تُظهر ضوضاء وكأنها بنية ذات معنى (كل صندوق به نقاط قليلة جدًا لقول أي شيء موثوق). لا يوجد رقم واحد صحيح عالميًا — جرّب بضع قيم وانظر أيها يروي القصة الأوضح والأكثر صدقًا:
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
for ax, n_bins in zip(axes, [5, 20, 50]):
df["math_score"].hist(bins=n_bins, ax=ax, edgecolor="black")
ax.set_title(f"{n_bins} bins")
plt.tight_layout()
plt.show()
تُنشئ plt.subplots(1, 3, figsize=(12, 4)) رسمًا واحدًا بـ3 لوحات جنبًا إلى جنب (axes عندها قائمة من 3 مناطق رسم منفردة) — نمط مفيد كلما أردت مقارنة بضعة تنويعات لنفس الرسم دفعة واحدة، ستعيد استخدامه في الأسبوع 9.
المخططات الصندوقية: الأرباع والقيم المتطرفة بلمحة
يرسم المخطط الصندوقي المئين الخامس والعشرين، الوسيط، والمئين الخامس والسبعين كصندوق، بـ"شوارب" (whiskers) تمتد للمدى النموذجي والنقاط المنفردة بعده مُعلَّمة كقيم متطرفة محتملة — تصور مُكثَّف بالضبط لأرقام الأرباع التي أعطتك إياها .describe() بالفعل، وبالضبط نفس قاعدة من الأسبوع الماضي، مرسومة بصريًا:
df.boxplot(column="math_score")
plt.ylabel("Math score")
plt.title("Math score spread")
plt.show()
تصبح المخططات الصندوقية مفيدة بشكل خاص بمجرد مقارنة توزيعات عدة مجموعات جنبًا إلى جنب — وهو بالضبط موضوع ثنائي المتغيّر الأسبوع القادم.
المخططات الشريطية: توزيع متغيّر فئوي
لعمود فئوي، .value_counts() (الأسبوع 6) مرسومة مباشرة كمخطط شريطي تُظهر أي الفئات شائعة مقابل نادرة:
df["parental_level_of_education"].value_counts().plot(kind="bar")
plt.xlabel("Parental level of education")
plt.ylabel("Number of students")
plt.title("Parental education levels in the dataset")
plt.xticks(rotation=45, ha="right")
plt.tight_layout()
plt.show()
تُدوّر plt.xticks(rotation=45, ha="right") علامات الفئات الطويلة بحيث لا تتداخل — إصلاح صغير لكن شائع لسهولة القراءة بمجرد أن تصبح العلامات أطول من بضعة أحرف. تمنع plt.tight_layout() العلامات الدوّارة/الطويلة من القطع عند حافة الرسم.
اختيار الرسم الصحيح
| نوع المتغيّر | الرسم |
|---|---|
| رقمي، تريد شكل التوزيع | مدرج تكراري |
| رقمي، تريد الأرباع/القيم المتطرفة، خصوصًا عبر مجموعات | مخطط صندوقي |
| فئوي، تريد تردد كل فئة | مخطط شريطي |
مخطط شريطي لعمود رقمي (معاملة كل درجة فريدة كـ"فئة" خاصة بها) أو مدرج تكراري لعمود فئوي كلاهما عادة اختياران خاطئان — مطابقة الرسم لنوع المتغيّر الفعلي هو قرار التصميم الأول، قبل أي تنسيق.
⚠️ أخطاء شائعة
- نسيان علامات المحاور والعنوان. رسم يتطلب من القارئ معرفة ما يُظهره مسبقًا غير مكتمل — ضع علامات دائمًا على كلا المحورين وأضف عنوانًا، حتى لرسم "استكشاف فقط" ستحذفه لاحقًا.
- اختيار عدد صناديق واحد وعدم التشكيك فيه أبدًا. كما هو موضح أعلاه، يمكن لنفس البيانات أن تروي قصصًا بصرية مختلفة بشكل ملحوظ عند 5 مقابل 20 مقابل 50 صندوقًا — تحقق منطقيًا دائمًا بعددي صناديق على الأقل قبل الثقة بما يبدو أن شكل المدرج التكراري يقوله.
- استخدام الرسم الخاطئ لنوع المتغيّر. مدرج تكراري لعمود فئوي (مثل
gender) أو مخطط شريطي لقيم رقمية خام غير مُجمَّعة كلاهما علامة على عدم استشارة جدول اختيار الرسم أعلاه أولًا. - نسيان
plt.show()(أو تعبير مجرد أخير) لعرض الرسم فعليًا، خصوصًا عند تسلسل عدة استدعاءات رسم — بحسب بيئتك، رسم بُني عبر عدة أسطر قد لا يُعرَض حتى يُطلَب صراحة.
🧩 تحديات
ارسم مدرجًا تكراريًا لـreading_score بمحاور مُعلَّمة وعنوان.
أنشئ مخططًا صندوقيًا لـwriting_score. عند النظر إليه، هل يبدو التوزيع متماثلًا، أم الوسيط أقرب بشكل ملحوظ لحافة واحدة من الصندوق؟
ارسم مخططًا شريطيًا لعدّات فئات عمود test_preparation_course، بمحاور مُعلَّمة.
يرسم شخص ما df["gender"].hist(). اشرح لماذا هذا اختيار رسم خاطئ، وماذا يجب أن يستخدم بدلًا من ذلك.
ارسم writing_score كمدرج تكراري بـ5 صناديق، ثم مجددًا بـ50 صندوقًا. صف كيف يتغيّر الشكل الظاهر للتوزيع بين الاثنين.
أنشئ مخططًا صندوقيًا واحدًا يُظهر أعمدة الدرجات الثلاثة (math_score، reading_score، writing_score) جنبًا إلى جنب، بحيث يمكن مقارنة تباعدها بلمحة.
🤔 أسئلة سقراطية
- يمكن لتوزيعين أن يكون لهما نفس المتوسط والانحراف المعياري لكن أشكالًا مختلفة جدًا (مثلًا واحد متماثل، وآخر بقمتين منفصلتين). لماذا يلتقط المدرج التكراري هذا الفرق بينما
mean/stdوحدهما لا يستطيعان؟ - يُعلّم المخطط الصندوقي النقاط بعد الشوارب كـ"قيم متطرفة" محتملة. هل يعني ذلك تلقائيًا أن نقاط البيانات تلك أخطاء يجب إزالتها؟ ماذا آخر قد يفسّر قيمة غير معتادة لكن صحيحة بشكل مشروع؟
- لماذا تهم
plt.xticks(rotation=45, ha="right")أكثر لـparental_level_of_education(أسماء فئات طويلة) منها لـgender(قصيرة)؟ أي قاعدة عامة عن طول العلامة وسهولة قراءة الرسم توحي بها هذه؟ - لو أراك زميل مدرجًا تكراريًا واحدًا فقط بـ50 صندوقًا لمتغيّر وادّعى رؤية "ثلاث مجموعات متمايزة"، ماذا تريد أن تتحقق منه قبل الثقة بذلك الادعاء، بمعطى ما تعرفه الآن عن حساسية عدد الصناديق؟