Kodax

مشروع 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}")
اختبر فهمك