Loading
Loading
Random Forest هي واحدة من أقوى وأكثر خوارزميات ML موثوقيةً في الواقع العملي. الفكرة بسيطة وعبقرية: بدلاً من شجرة واحدة قد تُخطئ، نبني مئات الأشجار ونأخذ التصويت الأغلبي.
التجربة الكلاسيكية: اطلب من 1000 شخص تخمين وزن ثور — متوسط إجاباتهم أدق من أي خبير منفرد.
Random Forest يطبّق نفس المبدأ:
شجرة 1: تنبؤ = A
شجرة 2: تنبؤ = B
شجرة 3: تنبؤ = A
...
شجرة 100: تنبؤ = A
───────────────────
النتيجة النهائية = A (الأغلبية)
الخطوة 1 — Bootstrapping: لكل شجرة، نأخذ عيّنة عشوائية بإعادة الوضع من بيانات التدريب (~63% من البيانات الأصلية، مع تكرار بعض العناصر).
الخطوة 2 — عشوائية الميزات: في كل تقسيم، لا نجرّب كل الميزات — بل نختار عشوائياً m = √p ميزة (حيث p = عدد الميزات الكلي).
الخطوة 3 — بناء الأشجار بالتوازي: كل شجرة تتدرب بشكل مستقل على بياناتها وميزاتها الخاصة.
الخطوة 4 — التجميع:
| الجانب | Decision Tree | Random Forest | |--------|--------------|---------------| | Overfitting | مرتفع | منخفض | | الدقة | متوسطة | عالية | | التفسير | سهل | أصعب | | السرعة | سريع | أبطأ (لكن موازٍ) | | الاستخدام الفعلي | للتفسير | للدقة |
RandomForestClassifier(
n_estimators=100, # عدد الأشجار (أكثر = أفضل، لكن أبطأ)
max_depth=None, # لا حد بالافتراضي (مع RF هذا مقبول)
max_features="sqrt", # √p ميزة في كل تقسيم
min_samples_leaf=1, # أقل عدد في الورقة
bootstrap=True, # استخدام Bootstrapping
n_jobs=-1, # استخدام كل الـ CPU cores
random_state=42
)
ميزة رائعة في Random Forest: كل شجرة تُدرَّب على ~63% من البيانات. الـ 37% المتبقية (OOB samples) تُستخدم كـ validation set تلقائي:
model = RandomForestClassifier(oob_score=True, ...)
print(model.oob_score_) # تقدير الدقة بدون test set منفصل
✅ بيانات جدولية (tabular) — يتفوق على معظم الخوارزميات ✅ لا تريد الكثير من preprocessing ✅ تريد أهمية الميزات (feature importance) ✅ لديك وقت تدريب كافٍ ✅ البيانات تحتوي قيماً مفقودة كثيرة
❌ صور أو نصوص (Deep Learning أفضل) ❌ تحتاج نموذجاً قابلاً للتفسير الكامل
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, classification_report
from sklearn.datasets import make_classification
print("=" * 55)
print("Random Forest: المقارنة مع Decision Tree")
print("=" * 55)
# بيانات معقدة
X, y = make_classification(
n_samples=2000, n_features=20, n_informative=10,
n_redundant=5, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# ─────────────────────────────────────────
# 1. Decision Tree للمقارنة
# ─────────────────────────────────────────
dt = DecisionTreeClassifier(random_state=42)
dt.fit(X_train, y_train)
dt_train = accuracy_score(y_train, dt.predict(X_train))
dt_test = accuracy_score(y_test, dt.predict(X_test))
print(f"\nDecision Tree:")
print(f" Train Accuracy: {dt_train:.3f}")
print(f" Test Accuracy: {dt_test:.3f}")
print(f" Overfit gap: {dt_train - dt_test:.3f}")
# ─────────────────────────────────────────
# 2. Random Forest
# ─────────────────────────────────────────
rf = RandomForestClassifier(
n_estimators=200,
max_features="sqrt",
oob_score=True,
n_jobs=-1,
random_state=42
)
rf.fit(X_train, y_train)
rf_train = accuracy_score(y_train, rf.predict(X_train))
rf_test = accuracy_score(y_test, rf.predict(X_test))
print(f"\nRandom Forest (200 trees):")
print(f" Train Accuracy: {rf_train:.3f}")
print(f" Test Accuracy: {rf_test:.3f}")
print(f" OOB Score: {rf.oob_score_:.3f} ← مجاني!")
print(f" Overfit gap: {rf_train - rf_test:.3f}")
# ─────────────────────────────────────────
# 3. تأثير عدد الأشجار
# ─────────────────────────────────────────
print("\n3. تأثير عدد الأشجار على الدقة:")
for n in [1, 5, 10, 50, 100, 200, 500]:
rf_n = RandomForestClassifier(n_estimators=n, n_jobs=-1, random_state=42)
rf_n.fit(X_train, y_train)
acc = accuracy_score(y_test, rf_n.predict(X_test))
bar = "█" * int(acc * 30)
print(f" n={n:4d}: {acc:.3f} {bar}")
# ─────────────────────────────────────────
# 4. أهمية الميزات
# ─────────────────────────────────────────
importance_df = pd.DataFrame({
"feature": [f"feature_{i}" for i in range(20)],
"importance": rf.feature_importances_
}).sort_values("importance", ascending=False)
print("\n4. أهم 10 ميزات:")
for _, row in importance_df.head(10).iterrows():
bar = "█" * int(row["importance"] * 200)
print(f" {row['feature']:12s}: {row['importance']:.4f} {bar}")