الدرس 4 من 9
تقييم الموديل صح
أهم درس عشان متخدعش نفسك ولا تخدع مديرك.
فخ الـ Accuracy
بنك عنده ١٠٠٠٠ معاملة، منهم ٥٠ بس احتيال. لو عملت «موديل» بيقول على كل حاجة «سليمة»، هيبقى دقيق بنسبة ٩٩.٥٪! ومع ذلك مالوش أي لازمة، لأنه مامسكش ولا عملية احتيال.
import numpy as np from sklearn.metrics import accuracy_score, recall_score y_true = np.array([1] * 50 + [0] * 9950) # 50 frauds out of 10,000 y_lazy = np.zeros(10_000) # "model" that always says: not fraud print(f"Accuracy: {accuracy_score(y_true, y_lazy):.1%}") print(f"Frauds caught: {recall_score(y_true, y_lazy):.0%}")
الـ Confusion Matrix
جدول بيوريك الموديل صاب فين وغلط فين بالظبط، مش رقم واحد مجمّع:
| الموديل قال: هيمشي | الموديل قال: هيفضل | |
|---|---|---|
| فعلاً مشي | ✓ True Positive | ✗ False Negative (فاتنا) |
| فعلاً فضل | ✗ False Positive (إنذار كاذب) | ✓ True Negative |
import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import ConfusionMatrixDisplay df = pd.read_csv("churn.csv") df["yearly"] = (df["contract"] == "yearly").astype(int) features = ["tenure", "bill", "complaints", "data_gb", "yearly"] X_train, X_test, y_train, y_test = train_test_split( df[features], df["churned"], test_size=0.2, random_state=42, stratify=df["churned"]) model = LogisticRegression(max_iter=1000).fit(X_train, y_train) ConfusionMatrixDisplay.from_estimator( model, X_test, y_test, display_labels=["stayed", "churned"], cmap="Blues") plt.title("Churn model on test set") plt.show()
Precision و Recall
precision من اللي قلت عليهم «هيمشوا»، كام واحد مشي فعلاً؟ بتقيس الإنذارات الكاذبة.recall من اللي مشيوا فعلاً، مسكت كام واحد؟ بتقيس اللي فاتك.F1 رقم واحد بيوازن بين الاتنين.import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report df = pd.read_csv("churn.csv") df["yearly"] = (df["contract"] == "yearly").astype(int) features = ["tenure", "bill", "complaints", "data_gb", "yearly"] X_train, X_test, y_train, y_test = train_test_split( df[features], df["churned"], test_size=0.2, random_state=42, stratify=df["churned"]) model = LogisticRegression(max_iter=1000).fit(X_train, y_train) print(classification_report(y_test, model.predict(X_test), target_names=["stayed", "churned"]))
الموازنة: غيّر الـ threshold
لو نزّلت الحد، هتمسك ناس أكتر (recall يزيد) بس هتكلم ناس مكانوش هيمشوا (precision يقل). جرب:
threshold = 0.5 # precision = 0.68 recall = 0.42 # flagged: 44 of 300 customers
الافتراضي. إنذارات كاذبة قليلة، بس فاتنا عدد كبير من اللي مشيوا.
🩺 اختار حسب التكلفةفي تشخيص مرض خطير، recall أهم: متفوتش عيان حتى لو قلقت ناس سليمة. في فلتر spam، precision أهم: إيميل شغل مهم يروح spam أسوأ من إعلان يعدي. مفيش رقم صح لكل المشاكل، فيه رقم صح لمشكلتك.