تحسين النموذج واختيار المتغيرات
ليست كثرة المتغيّرات قوّة؛ كيف نختار الأنفع ونتجنّب الحفظ؟ ⏱ نحو 50 دقيقة.
- تختار المتغيّرات بالارتباط بالهدف.
- توحّد المقاييس بـ
StandardScaler. - تتعرّف فرط التخصيص من فجوة التدريب والاختبار.
- توحّد بعد التقسيم لا قبله.
١ليست كل المتغيّرات مفيدة
بنيت نموذجًا؛ كيف تحسّنه؟ ليس بإضافة كل عمودٍ متاح. بعض المتغيّرات تضرّ: ثابتةٌ بلا معلومة، أو ضجيجٌ يشوّش. أولى خطوات التحسين: اختيار المتغيّرات المفيدة فعلًا.
import pandas as pddf = pd.DataFrame({ "seconds": [8, 120, 5, 240, 40, 180, 60, 300], "pages": [1, 4, 1, 6, 2, 5, 3, 9], "hour": [3, 14, 2, 20, 11, 19, 9, 21], "noise": [7, 7, 7, 7, 7, 7, 7, 7], # لا يتغيّر — بلا فائدة "bought": [0, 1, 0, 1, 0, 1, 0, 1],})# ارتباط كل متغيّر بالهدف: الأعلى (مطلقًا) أنفعcorr = df.corr(numeric_only=True)["bought"].drop("bought")print(corr.round(3))print("الأقوى ارتباطًا:", corr.abs().idxmax())
عمود noise الثابت ارتباطه صفر (بلا معلومة). seconds وpages الأقوى — هذه نُبقيها، والضعيفة نحذفها.
٢توحيد المقاييس: scaling
حين تختلف وحدات المتغيّرات (ثوانٍ بالمئات، صفحاتٌ بالآحاد)، تطغى الكبيرة على بعض النماذج. التوحيد StandardScaler يجعلها على مقياسٍ واحد:
from sklearn.preprocessing import StandardScalerimport numpy as np X = np.array([[8, 1], [240, 6], [40, 2], [300, 9]], dtype=float)scaled = StandardScaler().fit_transform(X)print("قبل: مدى العمود الأول", X[:,0].min(), "إلى", X[:,0].max())print("بعد (متوسط≈0, انحراف≈1):")print(np.round(scaled, 2))
٣فرط التخصيص Overfitting
أخطر فخّ: نموذجٌ يحفظ التدريب حرفيًّا فيبدع عليه ويفشل على الجديد. علامته: دقّةٌ عالية على التدريب، منخفضةٌ على الاختبار. علاجه: بياناتٌ أكثر، ومتغيّراتٌ أقلّ، ونموذجٌ أبسط:
| الحالة | تدريب | اختبار | التشخيص |
|---|---|---|---|
| متوازن | عالٍ | عالٍ | جيّد ✓ |
| فرط تخصيص | عالٍ جدًّا | منخفض | حفظ لا تعلّم |
| قصور تعلّم | منخفض | منخفض | النموذج أبسط من اللازم |
هنا تثمر قاعدة الدرس 20: التقييم على بياناتٍ لم يرها النموذج هو ما يكشف فرط التخصيص.
توقّع وتحقّق
متغيّر ثابت لا يتغيّر ارتباطه بالهدف:
لتوحيد مقاييس المتغيّرات:
دقّة عالية على التدريب ومنخفضة على الاختبار:
نوحّد المقياس:
الخلاصة
- ليست كل المتغيّرات مفيدة؛ احذف الثابتة والضعيفة الارتباط.
- التوحيد يضع المتغيّرات على مقياسٍ واحد، ويُطبَّق بعد التقسيم.
- فرط التخصيص: يبدع على التدريب ويفشل على الاختبار؛ علاجه التبسيط.
- التقييم على بياناتٍ لم يرها النموذج هو كاشف فرط التخصيص.
تحدٍّ برمجي: اختر الأنفع
متقدماحسب ارتباط كل متغيّر بالهدف، واطبع اسم المتغيّر الأقوى ارتباطًا، وعدد المتغيّرات التي ارتباطها المطلق أقل من 0.1 (مرشّحة للحذف).
- احسب ارتباط الأعمدة بـ
bought(عدا الهدف). - اطبع الأقوى ارتباطًا، ثم عدد ذوات الارتباط المطلق < 0.1.
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
import pandas as pddf = pd.DataFrame({ "seconds": [8, 120, 5, 240, 40, 180, 60, 300], "pages": [1, 4, 1, 6, 2, 5, 3, 9], "hour": [3, 14, 2, 20, 11, 19, 9, 21], "noise": [7, 7, 7, 7, 7, 7, 7, 7], # لا يتغيّر — بلا فائدة "bought": [0, 1, 0, 1, 0, 1, 0, 1],})# اطبع المتغيّر الأقوى ارتباطًا، وعدد ذوات الارتباط المطلق < 0.1
💡 تلميح 1
df.corr(numeric_only=True)["bought"].drop("bought").💡 تلميح 2
corr.abs().idxmax()؛ والضعيفة: (corr.abs() < 0.1).sum().حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import pandas as pddf = pd.DataFrame({ "seconds": [8, 120, 5, 240, 40, 180, 60, 300], "pages": [1, 4, 1, 6, 2, 5, 3, 9], "hour": [3, 14, 2, 20, 11, 19, 9, 21], "noise": [7, 7, 7, 7, 7, 7, 7, 7], # لا يتغيّر — بلا فائدة "bought": [0, 1, 0, 1, 0, 1, 0, 1],})corr = df.corr(numeric_only=True)["bought"].drop("bought")print(corr.abs().idxmax())print(int((corr.abs() < 0.1).sum()))