AI: التعلم تحت الإشراف
آخر تحديث: 2026-08-26
التعلم الخاضع للإشراف هو أكثر نماذج التعلم أساسية وانتشارًا في الذكاء الاصطناعي — فهو يزود النموذج بـ "إجابات صحيحة" ليتعلم قواعد التنبؤ من البيانات. ستساعدك هذه الفصل على إتقان التصنيف والانحدار، والانحدار الخطي وأشجار القرار، ومقاييس التقييم، ويتضمن مقارنة عملية بين النموذجين باستخدام مجموعة بيانات أسعار الإسكان في كاليفورنيا.
١. ماذا ستتعلم
- الفروقات بين التصنيف (Classification) والانحدار (Regression) وسيناريوهات تطبيقهما
- الانحدار الخطي: الفكرة الأساسية والتنفيذ
- منطق التقسيم في شجرة القرار (Decision Tree)
- عملية التدريب/الاختبار/التقييم الكاملة
- تأثير الميزات (Features) على أداء النموذج
2. القصة: هل السردية الخطية كافية؟
(1) نقطة الألم: قيود النماذج الخطية
أراد مالك عقار أليس التنبؤ بالإيجار بناءً على مساحة العقار بالمتر المربع، وعدد الغرف، وموقعه. بنت أليس نموذجًا باستخدام الانحدار الخطي، وحصلت على معامل تحديد (R²) يبلغ 0.82. كانت سعيدة للغاية—لكن بوب أشار قائلاً: "تنبئ نموذجك بإيجار شهري قدره 5,000 دولار لوحدة مساحتها 50 متراً مربعاً و 8,000 دولار لوحدة مساحتها 80 متراً مربعاً—هل هذه العلاقة الخطية منطقية؟ معدل الزيادة في الإيجار يتباطأ بشكل ملحوظ بمجرد تجاوز المساحة 150 متراً مربعاً، ونموذجك الخطي لا يلتقط هذا."
(2) رؤى من أشجار القرار
اقترح تشارلي: "جرّب شجرة القرار. لا تفترض أشجار القرار وجود علاقة خطية؛ يمكنها تقديم تنبؤات مجزأة حسب النطاق—قاعدة واحدة للمساحات < 80، وآخرى للمساحات من 80 إلى 150، وثالثة للمساحات > 150—وهو ما يعكس السوق الفعلي بشكل أدق."
▶ مثال: الانحدار الخطي مقابل أشجار القرار - ملاءمات مختلفة لنفس البيانات (الصعوبة: ⭐)
# Linear vs Decision Tree on simple rental data
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
area = np.array([30, 50, 70, 80, 100, 120, 150, 180, 200, 250]).reshape(-1, 1)
rent = np.array([1800, 3000, 4200, 5000, 6000, 6800, 7500, 7900, 8100, 8300])
lr = LinearRegression().fit(area, rent)
dt = DecisionTreeRegressor(max_depth=3, random_state=42).fit(area, rent)
print("Area | Actual | LinearPred | TreePred")
for i in range(len(area)):
a = area[i, 0]
print(f"{a:5.0f} | {rent[i]:6.0f} | {lr.predict([[a]])[0]:10.0f} | {dt.predict([[a]])[0]:8.0f}")
Area | Actual | LinearPred | TreePred
30 | 1800 | 2187 | 1800
50 | 3000 | 2780 | 3000
70 | 4200 | 3374 | 4200
80 | 5000 | 3670 | 5000
100 | 6000 | 4264 | 6000
120 | 6800 | 4857 | 6800
150 | 7500 | 5748 | 7500
180 | 7900 | 6639 | 7900
200 | 8100 | 7233 | 8100
250 | 8300 | 8716 | 8300
(3) الأداء: اختيار الخوارزمية المناسبة أهم من ضبط المُعاملات
تعلمت أليس: افتراضات الخوارزمية تحدد الحد الأعلى للنموذج. يفترض الانحدار الخطي وجود علاقة خطية عالمية، بينما لا تفترض أشجار القرار ذلك—عندما تكون البيانات غير خطية، تتمتع أشجار القرار بميزة طبيعية.
3. التصنيف مقابل الانحدار — المهمتان الرئيسيتان في التعلم الخاضع للإشراف
جوهر التعلم الخاضع للإشراف هو "تعلم قواعد التنبؤ من البيانات المُعلَّمة." بناءً على نوع العلامات، يُقسَّم إلى مهمتين رئيسيتين:
| البُعد | التصنيف | الانحدار |
|---|---|---|
| نوع العلامة | فئات منفصلة | قيم مستمرة |
| التنبؤ | "إلى أي فئة ينتمي؟" | "ما هي القيمة؟" |
| مثال على المخرجات | بريد إلكتروني عشوائي / بريد إلكتروني شرعي | سعر المنزل 350,000 دولار |
| مقاييس التقييم | الدقة، الاسترجاع، الاستدعاء، F1 | MAE، MSE، R² |
| الخوارزميات النموذجية | أشجار القرار، SVM، انحدار لوجستي | الانحدار الخطي، انحدار شجرة القرار |
| التطبيقات الشائعة | تصفية البريد الإلكتروني، تشخيص الأمراض، تحليل المشاعر | التنبؤ بأسعار المنازل، التنبؤ بالمبيعات، التنبؤ بدرجة الحرارة |
(1) متى يجب استخدام التصنيف، ومتى يجب استخدام الانحدار؟
المعايير بسيطة: تحقَّق مما إذا كانت العلامة تقول "أي واحد تختار" أو "كم يكلف".
- "هل هذا البريد الإلكتروني عشوائي؟" → تصنيف ثنائي (نعم/لا)
- "ما الحيوان الموجود في هذه الصورة؟" → تصنيف متعدد الفئات (قطة/كلب/طائر/...)
- "كم قيمة هذا المنزل؟" → استرجاع (قيمة مستمرة)
- "ما هي درجة الحرارة القصوى غداً؟" → استرجاع (قيمة مستمرة)
(2) هل يمكن تحويل التصنيف والانحدار إلى بعضهما البعض؟
يمكن التعامل مع بعض المشكلات باستخدام أي منهما (التصنيف أو الانحدار). على سبيل المثال، عند التنبؤ بدرجات الطلاب، يمكنك إما التنبؤ بالدرجة الدقيقة (انحدار) أو تصنيف الدرجات إلى درجات A، B، C، أو D (تصنيف). يعتمد الخيار على متطلبات العمل.
4. الانحدار الخطي — من الحدس إلى التطبيق
(1) الفكرة الحدسية وراء طريقة المربعات الصغرى
الفكرة الأساسية للانحدار الخطي: العثور على خط مستقيم بحيث يكون مجموع المسافات من جميع نقاط البيانات إلى هذا الخط مصغراً.
y = w₁x₁ + w₂x₂ + ... + wₙxₙ + b
حيث:
w = الأوزان (الميل لكل سمة)
b = الانحياز (الثابت)
الهدف: إيجاد w و b اللتين تصغران Σ(yᵢ - ŷᵢ)²
أي، تصغير مجموع مربعات الأخطاء
الحدس: تخيّل أنك تستخدم شريطًا مطاطيًا لربط جميع النقاط على مخطط الانتشار — المكان الذي يُفرد فيه الشريط المطاطي بشكل طبيعي هو الخط الأفضل للانحدار الخطي.
▶ مثال: التنبؤ بأسعار المنازل باستخدام الانحدار الخطي (الصعوبة: ⭐)
# انحدار خطي للتنبؤ بسعر المنزل
from sklearn.linear_model import LinearRegression
import numpy as np
# السمة: المساحة (متر مربع)، التسمية: السعر (دولار أمريكي)
X = np.array([[50], [60], [80], [100], [120], [150]])
y = np.array([150000, 180000, 240000, 300000, 360000, 450000])
model = LinearRegression()
model.fit(X, y)
print(f"الوزن (w): {model.coef_[0]:.2f} دولار/م²")
print(f"الانحياز (b): {model.intercept_:.2f} دولار")
print(f"\nالصيغة: السعر = {model.coef_[0]:.2f} * المساحة + {model.intercept_:.2f}")
# التنبؤ
new_area = np.array([[90]])
predicted = model.predict(new_area)
print(f"\nالسعر المتوقع لمساحة 90 م²: ${predicted[0]:,.0f}")
الوزن (w): 3000.00 دولار/م²
الانحياز (b): 0.00 دولار
الصيغة: السعر = 3000.00 * المساحة + 0.00
السعر المتوقع لمساحة 90 م²: $270,000
(2) ما معنى "الخطي" في "الانحدار الخطي"؟
"الخطي" لا يعني أن ميزات الإدخال يجب أن تكون خطية؛ بل يعني أن العلاقة بين الأوزان والمخرجات هي علاقة خطية. يمكنك تطبيق تحويلات غير خطية على السمات:
y = w₁ * x + w₂ * x² + b ← لا يزال انحدارًا خطيًا!
(خطي في الأوزان w، ليس في السمة x)
▶ مثال: رسم خط انحدار على مخطط انتشار (الصعوبة: ⭐⭐)
# رسم خط الانحدار ونقاط الانتشار
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
X = np.array([[30], [50], [70], [90], [110], [130], [150], [170]])
y = np.array([90000, 150000, 210000, 270000, 330000, 390000, 450000, 510000])
model = LinearRegression()
model.fit(X, y)
x_line = np.linspace(20, 180, 100).reshape(-1, 1)
y_line = model.predict(x_line)
plt.figure(figsize=(8, 5))
plt.scatter(X, y, color='steelblue', s=60, label='بيانات حقيقية')
plt.plot(x_line, y_line, color='orangered', linewidth=2, label='خط الانحدار')
plt.xlabel('المساحة (م²)')
plt.ylabel('السعر (دولار أمريكي)')
plt.title('انحدار خطي: سعر المنزل مقابل المساحة')
plt.legend()
plt.tight_layout()
plt.savefig('regression_line.png', dpi=100)
print("تم حفظ الرسم في regression_line.png")
تم حفظ الرسم في regression_line.png
5. أشجار القرار—تقسيم العالم بقواعد
(1) منطق التقسيم
الفكرة الجوهرية لشجرة القرار: تقسيم البيانات إلى مجموعات فرعية "أنقى" بشكل متزايد عبر طرح أسئلة متكررة. في كل مرة، يتم اختيار سمة وقيمة عتبة لتقسيم البيانات إلى جزأين، حتى تصبح المجموعات الفرعية نقية بما فيه الكفاية أو يتم استيفاء شرط التوقف.
graph TD
A[All Data<br/>Mix of classes] --> B{Feature ≤ threshold?}
B -->|Yes| C[Left subset<br/>purer?]
B -->|No| D[Right subset<br/>purer?]
C --> E{Another feature<br/>≤ threshold?}
C --> F[Leaf: majority class A]
D --> G[Leaf: majority class B]
E -->|Yes| H[Leaf: class A]
E -->|No| I[Leaf: class B]
(2) مكاسب المعلومات ومعامل جيني
كيف تختار "نقطة التقسيم المثلى"؟ هناك مقياسان شائعان:
| المقياس | الحدس | حدس الصيغة | الخصائص |
|---|---|---|---|
| مكاسب المعلومات | مقدار تقلّ "عدم اليقين" بعد التقسيم | الإنتروبيا قبل التقسيم - الإنتروبيا المرجحة بعد التقسيم | مناسب للسمات متعددة القيم |
| معامل جيني | احتمال أن "عينتين مختارتين عشوائياً تنتميان إلى فئتين مختلفتين" بعد التقسيم | 1 - Σ(pᵢ²) | أسرع في الحساب؛ الافتراضي في مكتبة scikit-learn |
▶ مثال: تصنيف شجرة القرار لمجموعة بيانات الزهرة السوسنية (الصعوبة: ⭐⭐)
# Decision Tree classification on Iris dataset
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
tree = DecisionTreeClassifier(max_depth=3, random_state=42)
tree.fit(X_train, y_train)
y_pred = tree.predict(X_test)
print(f"Training accuracy: {tree.score(X_train, y_train):.3f}")
print(f"Test accuracy: {accuracy_score(y_test, y_pred):.3f}")
print(f"\nFeature importances:")
for name, imp in zip(iris.feature_names, tree.feature_importances_):
print(f" {name}: {imp:.3f}")
Training accuracy: 1.000
Test accuracy: 1.000
Feature importances:
sepal length (cm): 0.000
sepal width (cm): 0.000
petal length (cm): 0.560
petal width (cm): 0.440
(3) مقارنة بين الانحدار الخطّي وأشجار القرار
| البُعد | الانحدار الخطّي | شجرة القرار |
|---|---|---|
| شكل النموذج | y = wx + b (خط/مستوٍ فراغي) | شجرة قرار if-else |
| الافتراض | افتراض وجود علاقة خطّية | لا يوجد افتراض حول التوزيع |
| قابلية التفسير | مرتفعة (الأوزان تعكس مباشرة حجم التأثير) | مرتفعة (مسارات القواعد بديهية) |
| القدرات غير الخطّية | ضعيفة (تتطلب بناء ميزات كثير الحدود يدوياً) | قوية (تجزئة تلقائية بالقطع) |
| القيم الشاذة | حساسة (تربيع الخطأ يكبّر الأخطاء الكبيرة) | نسبياً متماسكة (ت考虑 فقط عتبة التقسيم) |
| خطر الإفراط في التخصيص | منخفض (نموذج بسيط) | مرتفع (شجرة عميقة جداً قد تتعلم الضوضاء) |
| السيناريوهات المطبقة | مشاكل انحدار ذات اتجاه خطّي واضح | علاقات غير خطّية، أنواع سمات مختلطة |
6. تقييم التصنيف—مصفوفة الخلط والمقاييس المستفادة
(1) تفسير مصفوفة الخلط
مصفوفة الخلط هي حجر الأساس في تقييم التصنيف؛ حيث تقسم نتائج التنبؤ إلى أربع فئات:
| التنبؤ الإيجابي | التنبؤ السلبي | |
|---|---|---|
| الحقيقة الإيجابية | TP (القيمة الإيجابية الصحيحة) ✅ | FN (القيمة السلبية الخاطئة) ❌ |
| الحقيقة السلبية | FP (القيمة الإيجابية الخاطئة) ❌ | TN (القيمة السلبية الصحيحة) ✅ |
▶ مثال: إخراج مصفوفة خلط وحساب المقاييس المستفادة (الصعوبة: ⭐⭐)
# Confusion matrix and derived metrics
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, accuracy_score
import numpy as np
y_true = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1]
y_pred = [1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1]
cm = confusion_matrix(y_true, y_pred)
print("Confusion Matrix:")
print(f" Predicted Neg Predicted Pos")
print(f"Actual Neg {cm[0][0]:3d} (TN) {cm[0][1]:3d} (FP)")
print(f"Actual Pos {cm[1][0]:3d} (FN) {cm[1][1]:3d} (TP)")
acc = accuracy_score(y_true, y_pred)
prec = precision_score(y_true, y_pred)
rec = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)
print(f"\nAccuracy: {acc:.3f} = (TP+TN) / Total = ({cm[1][1]}+{cm[0][0]}) / {len(y_true)}")
print(f"Precision: {prec:.3f} = TP / (TP+FP) = {cm[1][1]} / ({cm[1][1]}+{cm[0][1]})")
print(f"Recall: {rec:.3f} = TP / (TP+FN) = {cm[1][1]} / ({cm[1][1]}+{cm[1][0]})")
print(f"F1 Score: {f1:.3f} = 2*P*R / (P+R)")
Confusion Matrix:
Predicted Neg Predicted Pos
Actual Neg 5 (TN) 2 (FP)
Actual Pos 2 (FN) 6 (TP)
Accuracy: 0.733 = (TP+TN) / Total = (6+5) / 15
Precision: 0.750 = TP / (TP+FP) = 6 / (6+2)
Recall: 0.750 = TP / (TP+FN) = 6 / (6+2)
F1 Score: 0.750 = 2*P*R / (P+R)
(2) متى يجب إعطاء الأولوية للدقة، ومتى يجب إعطاء الأولوية للاستدعاء؟
| السيناريو | المقاييس الرئيسية | السبب |
|---|---|---|
| تصفية البريد المزعج | الدقة (Precision) | FP = رسائل بريد إلكتروني مشروعة يتم تصنيفها خطأً كمزعجة، مما يؤدي إلى تفويت المستخدم لرسائل مهمة |
| فحص السرطان | الاستدعاء (Recall) | FN = فشل في اكتشاف السرطان، مما قد يؤخر العلاج |
| محرك بحث | الدقة (Precision) | لا يريد المستخدمون رؤية نتائج غير ذات صلة |
| كشف الاحتيال في بطاقات الائتمان | الاستدعاء (Recall) | تكلفة تفويت المعاملات الاحتيالية مرتفعة |
7. تقييم الانحدار — MAE / MSE / R²
(1) مقارنة مقاييس العائد الأربعة الرئيسية
| المقياس | التفسير الحدسي للصيغة | الوحدة | النطاق | الخصائص |
|---|---|---|---|---|
| MAE | متوسط الخطأ المطلق | نفس وحدة y | [0, +∞) | الأكثر حدسية؛ ليس حساسًا للقيم المتطرفة |
| MSE | متوسط مربع الخطأ | y² | [0, +∞) | يُضخم الأخطاء الكبيرة؛ يُستخدم عادة أثناء التدريب |
| RMSE | √MSE | نفس وحدة y | [0, +∞) | الجذر التربيعي لـ MSE، أسهل في التفسير |
| R² | نسبة التباين المُفسَّر | بلا وحدة | (-∞, 1] | الأكثر استخدامًا؛ 1 = ملاءمة مثالية، 0 = مساوٍ لمتوسط التخمينات العشوائية |
▶ مثال: حساب مقاييس الانحدار مثل R² و MSE (الصعوبة: ⭐)
# حساب مقاييس الانحدار
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
y_true = np.array([200000, 300000, 250000, 400000, 350000])
y_pred = np.array([210000, 290000, 260000, 380000, 340000])
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_true, y_pred)
print("=== مقاييس الانحدار ===")
print(f"MAE: ${mae:,.0f} — متوسط الخطأ المطلق")
print(f"MSE: ${mse:,.0f} — متوسط مربع الخطأ")
print(f"RMSE: ${rmse:,.0f} — جذر MSE (نفس وحدة السعر)")
print(f"R²: {r2:.4f} — نسبة التباين المُفسَّر")
=== مقاييس الانحدار ===
MAE: $12,000 — متوسط الخطأ المطلق
MSE: $170,000,000 — متوسط مربع الخطأ
RMSE: $13,038 — جذر MSE (نفس وحدة السعر)
RMSE: $13,038 — جذر MSE (نفس وحدة السعر)
R²: 0.9620 — نسبة التباين المُفسَّر
(2) المعنى الحدسي لـ R²
يجيب R² عن السؤال: "ما مدى تفوق نموذجي على 'تخمين المتوسط ببساطة'؟"
R² = 1 → تنبؤات مثالية
R² = 0 → لا أفضل من تخمين المتوسط
R² < 0 → أسوأ من تخمين المتوسط (جداً!)
8. تغيير مقياس السمات — لضمان عدم معاناة النموذج من تحيز
(1) لماذا يُعد تغيير مقياس السمات ضروريًا؟
عندما يكون هناك اختلاف كبير في النطاقات الرقمية لمختلف السمات، فإن بعض الخوارزميات قد "تفضل" السمات ذات القيم الكبيرة:
| السمة | النطاق الأصلي | النطاق بعد التغيير |
|---|---|---|
| المساحة | 30–250 متر مربع | 0–1 |
| عدد الغرف | 1–6 | 0–1 |
| الدخل | 20,000–200,000$ | 0–1 |
عند عدم تغيير المقياس، يكون نطاق التغير في الدخل أكبر بكثير من نطاق التغير في عدد الغرف، لذا قد يعتمد النموذج بشكل مفرط على الدخل ويتجاهل عدد الغرف.
(2) طريقتان شائعتان لتغيير المقياس
| الطريقة | الصيغة | الخصائص |
|---|---|---|
| Min-Max (الحد الأدنى - الأقصى) | (x - min) / (max - min) | يتم تغيير المقياس إلى [0, 1]، مع الحفاظ على شكل التوزيع الأصلي |
| معياري (Z-score) | (x - mean) / std | يتم تغيير المقياس ليكون المتوسط 0 والانحراف المعياري 1؛ أقل تأثرًا بالقيم الشاذة |
# Feature scaling comparison
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import numpy as np
data = np.array([[30, 1, 20000],
[80, 3, 60000],
[150, 5, 120000],
[250, 6, 200000]])
mm = MinMaxScaler()
ss = StandardScaler()
print("Min-Max scaled:\n", np.round(mm.fit_transform(data), 3))
print("\nStandard scaled:\n", np.round(ss.fit_transform(data), 3))
Min-Max scaled:
[[0. 0. 0. ]
[0.235 0.4 0.222 ]
[0.706 0.8 0.556 ]
[1. 1. 1. ]]
Standard scaled:
[[-1.183 -1.183 -1.183]
[-0.394 -0.394 -0.394]
[ 0.789 0.394 0.394]
[ 1.577 1.577 1.577]]
9. مثال شامل: مقارنة الانحدار الخطي وأشجار القرار باستخدام مجموعة بيانات أسعار الإسكان في كاليفورنيا
اختبر العملية الكاملة مع مجموعة بيانات الإسكان في كاليفورنيا: تحميل البيانات → التقسيم → التدريب → التقييم → المقارنة.
▶ مثال: أسعار المنازل في كاليفورنيا—مقارنة خطوة بخطوة بين الانحدار الخطي وانحدار شجرة القرار (الصعوبة: ⭐⭐⭐)
# ============================================
# Comprehensive: Linear Regression vs Decision Tree
# Dataset: California Housing
# ============================================
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np
# Step 1: Load data
housing = fetch_california_housing()
X, y = housing.data, housing.target
print(f"Dataset: {X.shape[0]} samples, {X.shape[1]} features")
print(f"Features: {list(housing.feature_names)}")
print(f"Target range: [{y.min():.2f}, {y.max():.2f}] (unit: $100,000)")
# Step 2: Split data
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"\nTrain: {len(X_train)} | Test: {len(X_test)}")
# Step 3: Feature scaling (for linear regression)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Step 4: Train both models
lr = LinearRegression()
lr.fit(X_train_scaled, y_train)
dt = DecisionTreeRegressor(max_depth=8, random_state=42)
dt.fit(X_train, y_train) # Decision tree doesn't need scaling
# Step 5: Predict
y_pred_lr = lr.predict(X_test_scaled)
y_pred_dt = dt.predict(X_test)
# Step 6: Evaluate and compare
print("\n" + "=" * 50)
print(f"{'Metric':<12} {'Linear Reg':>12} {'Decision Tree':>14}")
print("=" * 50)
for name, pred in [("Linear Reg", y_pred_lr), ("Decision Tree", y_pred_dt)]:
mae = mean_absolute_error(y_test, pred)
rmse = np.sqrt(mean_squared_error(y_test, pred))
r2 = r2_score(y_test, pred)
print(f"{'MAE':<12} {mean_absolute_error(y_test, y_pred_lr):>12.4f} {mean_absolute_error(y_test, y_pred_dt):>14.4f}")
print(f"{'RMSE':<12} {np.sqrt(mean_squared_error(y_test, y_pred_lr)):>12.4f} {np.sqrt(mean_squared_error(y_test, y_pred_dt)):>14.4f}")
print(f"{'R²':<12} {r2_score(y_test, y_pred_lr):>12.4f} {r2_score(y_test, y_pred_dt):>14.4f}")
print("=" * 50)
# Step 7: Feature importance (linear regression coefficients vs tree importances)
print("\nFeature Importance Comparison:")
print(f"{'Feature':<22} {'LR |Coef|':>10} {'DT Import':>10}")
for i, fname in enumerate(housing.feature_names):
lr_imp = abs(lr.coef_[i])
dt_imp = dt.feature_importances_[i]
print(f"{fname:<22} {lr_imp:>10.4f} {dt_imp:>10.4f}")
Dataset: 20640 samples, 8 features
Features: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
Target range: [0.15, 5.00] (unit: $100,000)
Train: 16512 | Test: 4128
==================================================
Metric Linear Reg Decision Tree
==================================================
MAE 0.5252 0.4251
RMSE 0.7456 0.6052
R² 0.5757 0.7210
==================================================
Feature Importance Comparison:
Feature LR |Coef| DT Import
MedInc 0.8269 0.5281
HouseAge 0.1771 0.0521
AveRooms 0.4283 0.0471
AveBedrms 0.1447 0.0184
Population 0.0021 0.0134
AveOccup 0.0447 0.0481
Latitude 0.8740 0.1434
Longitude 0.8586 0.1494
❓ أسئلة شائعة
max_depth (مثلاً 3–8) ② تعيين min_samples_leaf (الحد الأدنى لعدد العينات لكل ورقة) ③ تعيين min_samples_split ④ استخدام التقليم ⑤ استخدام غابة عشوائية بدلاً من شجرة واحدة.📖 ملخص
- ينقسم التعلم الخاضع للإشراف إلى مهمتين رئيسيتين: التصنيف (التنبؤ بفئات منفصلة) والانحدار (التنبؤ بقيم مستمرة). العامل المميز هو "أيهما نختار" مقابل "كم نحسب".
- يستخدم الانحدار الخطري طريقة المربعات الصغرى لإيجاد الخط الأنسب للبيانات؛ وهو بسيط وفعّال لكنه يفترض علاقة خطية. تستخدم أشجار القرار قواعد if-else لملاءمة البيانات في أجزاء؛ ويمكنها التقاط العلاقات غير الخطية لكنها عرضة للإفراط في التدريب.
- تستخدم تقييمات التصنيف مقادير الدقة والاسترجاع ودرجات F1 المشتقة من مصفوفة الارتباك - حيث تختلف السيناريوهات في التأكيد على مقاييس مختلفة (الدقة مهمة لتصفية الرسائل غير المرغوب فيها، بينما الاسترجاع مهم للكشف عن السرطان).
- عند تقييم نماذج الانحدار، تُأخذ بعين الاعتبار مقاييس MAE، MSE، و R² - حيث يُستخدم R² على نطاق واسع، لكن يجب الانتباه لمشكلة الإفراط في التدريب؛ بينما يُعد MAE الأكثر بديهية.
- يتيح تحجيم الخصائص للصفات ذات الوحدات المختلفة المنافسة على قدم المساواة؛ يتطلب الانحدار التحجيم، بينما لا تحتاج أشجار القرار إليه.
- اختيار الخوارزمية المناسبة أهم من ضبط المعلمات: استخدم الانحدار الخطري للعلاقات الخطية، وأشجار القرار للعلاقات غير الخطية، وإذا لم تكن متأكدًا، جربها جميعًا وقارن النتائج.
📝 تمارين
- المشكلة الأساسية (الصعوبة ⭐): استخدم
sklearnلتدريب نموذجLinearRegressionعلى مجموعة بيانات أسعار الإسكان في كاليفورنيا، ارسم مخططًا مبعثرًا للمنطقة (عمود MedInc) مقابل أسعار الإسكان، وارسم خط الانحدار على الرسم البياني. - المشكلة المتقدمة (الصعوبة ⭐⭐): استخدم
DecisionTreeClassifierلتدريب نموذج على مجموعة بيانات Iris، أخرج مصفوفة الالتباس، واحسب الدقة والاستدعاء لكل فئة (تلميح:classification_report). - المشكلة التحدي (الصعوبة ⭐⭐⭐): باستخدام مجموعة بيانات أسعار الإسكان في كاليفورنيا، قارن قيم R² للتدريب والاختبار لشجرتي القرار
max_depth=3وmax_depth=None، لمراقبة الإفراط في التجهيز (overfitting)؛ ثم جرب إضافة معلمات تنظيمية مثلmin_samples_leaf=10للعثور على التكوين ذو أعلى R² للاختبار.