مشروع ML متكامل — تعلم الآلة
مشروع: التنبؤ بأسعار المنازل
المشروع يجمع الدورة كلها على بيانات حقيقية (California Housing، تُحمَّل تلقائياً من scikit-learn عند أول تشغيل وتحتاج اتصالاً بالإنترنت). الهدف: متوسط سعر المنزل في الحي (بمئات آلاف الدولارات).
الخطوات وما يجب أن تفكر فيه
1. الاستكشاف: الأبعاد، التوزيعات، القيم الشاذة. هل هناك قيم مقطوعة عند حد أعلى؟ (في هذه البيانات الأسعار مقطوعة عند 5.0.)
2. التقسيم: اختبار 20% يُعزل فوراً ولا يُلمس حتى النهاية.
3. خط الأساس: ما خطأ التنبؤ بالمتوسط دائماً؟ أي نموذج يجب أن يتفوق عليه بوضوح.
4. المقارنة: عدة نماذج داخل Pipelines، بـ Cross-Validation على التدريب فقط.
5. الضبط: GridSearchCV أو RandomizedSearchCV للنموذج الأفضل.
6. التقييم النهائي: على الاختبار مرة واحدة، بمقياس مفهوم (MAE بالدولار).
7. التحليل: أين يخطئ النموذج أكثر؟ ما الميزات الأهم؟
قرارات مهمة في الكود
| القرار | السبب |
|---|---|
| Pipeline يحتوي التقييس | يمنع تسرب البيانات داخل Cross-Validation |
| مقارنة R² و MAE | R² للمقارنة، MAE لشرح الخطأ بوحدة مفهومة |
| random_state ثابت | نتائج قابلة للتكرار والمقارنة |
| مقارنة Train و CV | فجوة كبيرة = Overfitting (لاحظها في الغابة العشوائية) |
أفضل الممارسات
- ابدأ بالبسيط، ثم زد التعقيد فقط إن تحسنت النتائج فعلاً على CV.
- وثّق كل تجربة: الإعدادات والنتيجة.
- احفظ النموذج النهائي مع Pipeline كاملاً (joblib.dump) — لا تنسَ المقياس.
تحسينات مقترحة
1. ميزات جديدة: عدد الغرف لكل أسرة، نسبة غرف النوم.
2. HistGradientBoostingRegressor مع RandomizedSearchCV.
3. تحليل الأخطاء: ارسم الخطأ مقابل السعر الحقيقي — هل يخطئ النموذج أكثر في الأحياء الغالية؟
4. استخدم permutation_importance لتفسير النموذج.
بعد هذه الدورة: التعلم العميق للصور والنصوص والبيانات غير الجدولية.
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
# ===== 1. تحميل البيانات =====
from sklearn.datasets import fetch_california_housing
data = fetch_california_housing()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
print("=== استكشاف البيانات ===")
print(X.head())
print(f"\nالحجم: {X.shape}")
print(f"\nالإحصائيات:\n{X.describe()}")
# ===== 2. تحضير البيانات =====
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# ===== 3. تجربة النماذج =====
models = {
'Linear Regression': LinearRegression(),
'Ridge': Ridge(alpha=1.0),
'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingRegressor(n_estimators=100, random_state=42)
}
print("\n=== مقارنة النماذج ===")
results = {}
for name, model in models.items():
# Cross-validation
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5, scoring='r2')
# تدريب على كل التدريب
model.fit(X_train_scaled, y_train)
train_score = model.score(X_train_scaled, y_train)
test_score = model.score(X_test_scaled, y_test)
results[name] = {
'CV Mean': cv_scores.mean(),
'Train R²': train_score,
'Test R²': test_score
}
print(f"{name}:")
print(f" CV: {cv_scores.mean():.3f} (+/- {cv_scores.std()*2:.3f})")
print(f" Train R²: {train_score:.3f}, Test R²: {test_score:.3f}")
# ===== 4. أفضل نموذج =====
best_model = GradientBoostingRegressor(n_estimators=100, random_state=42)
best_model.fit(X_train_scaled, y_train)
y_pred = best_model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"\n=== النتائج النهائية ===")
print(f"RMSE: {rmse:.3f}")
print(f"R² Score: {r2:.3f}")
# أهمية الميزات
print("\nأهمية الميزات:")
for name, importance in sorted(zip(X.columns, best_model.feature_importances_),
key=lambda x: x[1], reverse=True):
print(f" {name}: {importance:.3f}")اختبر فهمك