Machine Learning Academy · درس

مقاييس التصنيف: Accuracy وPrecision وRecall وF1

احسب المقاييس الأربعة جميعها للتنبؤات نفسها، وافهم أيّها ينبغي إعطاؤه الأولوية بحسب تكلفة الإيجابيات الكاذبة في مقابل السلبيات الكاذبة

الدرس 1 من 413 خطوة

مقاييس التصنيف: Accuracy وPrecision وRecall وF1 درس مجاني في Machine Learning Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Machine Learning Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Machine Learning Academy 4 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

Why Accuracy Is Often Not Enough

Accuracy — the fraction of correct predictions — is the most intuitive metric, but it is misleading when classes are imbalanced. Consider a medical test for a disease that affects 1% of patients. A model that always predicts 'healthy' achieves 99% accuracy while being completely useless — it misses every actual disease case. In fraud detection, cancer screening, or rare event prediction, accuracy hides the model's failure to detect the rare but critical positive class. This is why we need metrics that separately measure performance on each class: precision, recall, and F1-score.

import numpy as np

# 1000 patients: 990 healthy, 10 sick
y_true = [0]*990 + [1]*10
y_pred_dummy = [0]*1000  # Always predict healthy

correct = sum(p == t for p, t in zip(y_pred_dummy, y_true))
accuracy = correct / len(y_true)
print(f'Dummy accuracy: {accuracy:.1%}')  # 99.0% -- misleadingly high!
print('But 0 sick patients correctly identified!')
print('This is why we need precision and recall.')

The Confusion Matrix: Ground Truth

The confusion matrix is the foundation of all classification metrics. For binary classification, it is a 2x2 table: True Positives (TP) — correctly predicted positive; True Negatives (TN) — correctly predicted negative; False Positives (FP) — predicted positive but actually negative (Type I error); False Negatives (FN) — predicted negative but actually positive (Type II error). Every classification metric is derived from some combination of these four numbers. Inspecting the raw confusion matrix reveals which type of error the model makes most.

from sklearn.metrics import confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

cm = confusion_matrix(y_true, y_pred)
print('Confusion Matrix:')
print(cm)
# [[TN, FP],
#  [FN, TP]]
TN, FP, FN, TP = cm.ravel()
print(f'TP={TP}, TN={TN}, FP={FP}, FN={FN}')

Accuracy: Simple but Limited

Accuracy = (TP + TN) / (TP + TN + FP + FN). It answers: of all predictions, what fraction were correct? Accuracy is a fair metric only when classes are roughly balanced and the costs of false positives and false negatives are similar. For example, handwritten digit recognition with ~10% of each digit class is balanced, making accuracy a reasonable measure. Use accuracy when: classes are balanced and all errors have equal cost. Avoid it when: classes are skewed (one class dominates) or false negatives cost more than false positives (or vice versa).

from sklearn.metrics import accuracy_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

acc = accuracy_score(y_true, y_pred)
print(f'Accuracy = {acc:.2f}')  # (TP+TN) / total

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
acc_manual = (TP + TN) / (TP + TN + FP + FN)
print(f'Manual: ({TP}+{TN}) / ({TP}+{TN}+{FP}+{FN}) = {acc_manual:.2f}')

Precision: Quality of Positive Predictions

Precision = TP / (TP + FP). It answers: of all the samples we predicted as positive, what fraction actually are positive? Precision is the metric to optimise when false positives are costly. In spam detection: a high-precision spam filter rarely marks legitimate email as spam. In drug testing: high precision means we rarely approve a drug that does not work. Low precision means many of our positive predictions are wrong — we are flooding users with false alarms. Precision tells you nothing about the false negatives — a model that only predicts one obvious case as positive has precision 1.0 but misses everything else.

from sklearn.metrics import precision_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

prec = precision_score(y_true, y_pred)
print(f'Precision = {prec:.2f}')

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
print(f'Manual: TP/(TP+FP) = {TP}/({TP}+{FP}) = {TP/(TP+FP):.2f}')
print('Of all PREDICTED positives, this fraction are truly positive.')

Recall: Coverage of Actual Positives

Recall = TP / (TP + FN) (also called Sensitivity or True Positive Rate). It answers: of all samples that actually are positive, what fraction did we find? Recall is the metric to optimise when false negatives are costly. In cancer screening: high recall means we identify most patients who actually have cancer. In fraud detection: high recall means we catch most fraudulent transactions. Low recall means we are missing too many actual positives — dangerous in medical or security contexts. Recall and precision are in tension: increasing one typically decreases the other.

from sklearn.metrics import recall_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

rec = recall_score(y_true, y_pred)
print(f'Recall = {rec:.2f}')

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
print(f'Manual: TP/(TP+FN) = {TP}/({TP}+{FN}) = {TP/(TP+FN):.2f}')
print('Of all ACTUAL positives, this fraction were correctly identified.')

The Precision-Recall Trade-Off

Precision and recall are inversely related when you adjust the classification threshold. As you lower the threshold (predict positive more aggressively), recall increases (you catch more actual positives) but precision decreases (more false positives get through). Raising the threshold has the opposite effect. There is no single threshold that simultaneously maximises both. Which metric to prioritise depends on the business problem: in email filtering, prioritise precision (do not annoy users with false spam alerts); in disease screening, prioritise recall (do not miss sick patients).

from sklearn.metrics import precision_score, recall_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=42)

clf = LogisticRegression(max_iter=10000)
clf.fit(X_tr, y_tr)
proba = clf.predict_proba(X_te)[:, 1]

for thresh in [0.3, 0.5, 0.7, 0.9]:
    y_pred = (proba >= thresh).astype(int)
    prec = precision_score(y_te, y_pred, zero_division=0)
    rec  = recall_score(y_te, y_pred)
    print(f'threshold={thresh}: precision={prec:.3f}, recall={rec:.3f}')

F1-Score: Harmonic Mean of Precision and Recall

F1-score = 2 * (Precision * Recall) / (Precision + Recall). The F1-score is the harmonic mean of precision and recall. Unlike the arithmetic mean, the harmonic mean punishes extreme values: a model with precision=1.0 and recall=0.0 gets F1=0, not 0.5. This makes F1 a fair aggregate metric that requires both precision and recall to be reasonably high. F1 is the standard metric for imbalanced text classification (NLP benchmarks always report it), fraud detection, and any problem where class imbalance makes accuracy misleading.

from sklearn.metrics import f1_score, precision_score, recall_score
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

prec = precision_score(y_true, y_pred)
rec  = recall_score(y_true, y_pred)
f1   = f1_score(y_true, y_pred)

print(f'Precision = {prec:.3f}')
print(f'Recall    = {rec:.3f}')
print(f'F1-Score  = {f1:.3f}')
print(f'Manual F1 = 2 * ({prec:.3f} * {rec:.3f}) / ({prec:.3f} + {rec:.3f}) = {2*prec*rec/(prec+rec):.3f}')

Fbeta-Score: Weighted Precision-Recall Balance

The Fbeta score generalises F1 by introducing a parameter beta that controls how much to weight recall relative to precision: F_beta = (1 + beta^2) * Precision * Recall / (beta^2 * Precision + Recall). When beta=1, this is the standard F1 score. When beta=2 (F2), recall is weighted twice as much as precision — useful when missing positives is twice as costly as false alarms. When beta=0.5 (F0.5), precision is weighted more — useful in recommendation systems where accuracy of suggestions matters more than coverage.

from sklearn.metrics import fbeta_score
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

for beta in [0.5, 1.0, 2.0]:
    score = fbeta_score(y_true, y_pred, beta=beta)
    print(f'F{beta:.1f} = {score:.3f}')

print()
print('beta=0.5: precision weighted 2x -> use when false alarms costly')
print('beta=1.0: balanced precision/recall -> standard F1')
print('beta=2.0: recall weighted 2x -> use when missing positives costly')

Multi-Class Averaging: Macro, Micro, and Weighted

For multi-class classification, you must aggregate per-class precision/recall/F1 into a single number. Macro average: compute metric for each class independently, then average — treats all classes equally regardless of size. Weighted average: same but weights by class support — gives larger classes more influence. Micro average: aggregate TP/FP/FN across all classes first, then compute — equivalent to accuracy for precision, recall, and F1 when there are no samples with multiple labels. Use macro for imbalanced datasets where small minority classes are important.

from sklearn.metrics import f1_score
import numpy as np

# Multi-class predictions
y_true = [0, 0, 1, 1, 2, 2, 2]
y_pred = [0, 1, 1, 1, 2, 0, 2]

print('Macro F1:    ', f1_score(y_true, y_pred, average='macro').round(3))
print('Micro F1:    ', f1_score(y_true, y_pred, average='micro').round(3))
print('Weighted F1: ', f1_score(y_true, y_pred, average='weighted').round(3))
print('Per-class F1:', f1_score(y_true, y_pred, average=None).round(3))
print()
print('Macro treats all classes equally (even rare ones)')
print('Weighted rewards correct prediction of common classes')

classification_report: All Metrics in One

classification_report() generates a formatted table showing precision, recall, F1-score, and support (number of true instances) for each class, plus macro/weighted averages. This is the standard output to include in any ML evaluation report. The 'support' column is especially important: a class with support=5 will have noisy precision/recall estimates and should be interpreted cautiously. Always check support values alongside F1 scores to assess metric reliability.

from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=42)

clf = RandomForestClassifier(random_state=42)
clf.fit(X_tr, y_tr)
y_pred = clf.predict(X_te)

print(classification_report(
    y_te, y_pred,
    target_names=load_iris().target_names
))

Balanced Accuracy for Imbalanced Classes

Balanced accuracy is the arithmetic mean of sensitivity (recall for each class). For binary classification: balanced_accuracy = (TPR + TNR) / 2 where TNR (True Negative Rate) = TN / (TN+FP). Unlike standard accuracy, balanced accuracy gives equal weight to each class regardless of how many samples it has. A model that always predicts the majority class gets balanced accuracy of 0.5 — correctly identifying it as no better than random. Use balanced accuracy when classes are imbalanced and you want a single metric that reflects performance on all classes equally, without the complexity of computing per-class metrics.

from sklearn.metrics import balanced_accuracy_score, accuracy_score
import numpy as np

# Imbalanced: 990 class 0, 10 class 1
y_true = np.array([0]*990 + [1]*10)
y_dummy = np.zeros(1000, dtype=int)  # Always predict class 0

acc_standard = accuracy_score(y_true, y_dummy)
acc_balanced = balanced_accuracy_score(y_true, y_dummy)

print(f'Standard accuracy: {acc_standard:.3f}')  # 99% -- misleading
print(f'Balanced accuracy: {acc_balanced:.3f}')  # 0.5 -- correctly shows no skill
print()
print('Balanced accuracy correctly penalises ignoring the minority class')

Quick Check

Test your understanding of Machine Learning with Python concepts from this lesson.

Lesson Recap

In this lesson you learned: accuracy is misleading for imbalanced classes — use the confusion matrix as ground truth, precision measures quality of positive predictions (minimise false positives) and recall measures coverage of actual positives (minimise false negatives), and F1-score harmonically combines both into a balanced metric. Next up we explore ROC curves and AUC-ROC for threshold-independent model evaluation.

البدء مجانًا

تعلم Python مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
30
الدروس
120

الأسئلة الشائعة

هل درس «مقاييس التصنيف: Accuracy وPrecision وRecall وF1» مجاني؟

نعم — نص درس «مقاييس التصنيف: Accuracy وPrecision وRecall وF1» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Machine Learning Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Machine Learning Academy 4 دروس في المجموع.

ماذا ستتعلم في «مقاييس التصنيف: Accuracy وPrecision وRecall وF1»؟

احسب المقاييس الأربعة جميعها للتنبؤات نفسها، وافهم أيّها ينبغي إعطاؤه الأولوية بحسب تكلفة الإيجابيات الكاذبة في مقابل السلبيات الكاذبة تتمرن على Machine Learning Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Machine Learning Academy؟

لا تُشترط خبرة سابقة. Machine Learning Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «مقاييس التصنيف: Accuracy وPrecision وRecall وF1»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Machine Learning Academy هذا؟

نعم. كل درس في Machine Learning Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مقاييس التصنيف: Accuracy وPrecision وRecall وF1
  2. منحنيات ROC وAUC-ROC
  3. مقاييس الانحدار: MAE وMSE وRMSE وR-Squared
  4. اختيار المقياس المناسب لمشكلتكم التجارية
← العودة إلى Machine Learning Academy