درّبت نموذج تصنيف ببايثون، استخدمت train_test_split() لفصل بيانات التدريب والاختبار، ثم نفذت model.predict() وحصلت على توقعات. هنا يبدأ السؤال الأهم: هل النموذج جيد فعلًا؟
الجواب لا يأتي من رقم Accuracy وحده. في كثير من مسائل التصنيف نحتاج إلى معرفة نوع الخطأ الذي يرتكبه النموذج: هل يعطي إنذارات إيجابية خاطئة؟ هل يفوّت حالات إيجابية حقيقية؟ هل يؤدي جيدًا في الفئة الكبيرة بينما يفشل في الفئة الصغيرة؟
لهذا نستخدم أدوات تقييم مثل Confusion Matrix وPrecision وRecall وF1 Score وclassification_report. هذه المقاييس تحول قائمة التوقعات إلى صورة أوضح عن نقاط قوة النموذج ونقاط ضعفه.
في هذا الدرس سنفهم هذه المقاييس من الصفر باستخدام مثال تصنيف ثنائي، ثم نطبقها باستخدام scikit-learn، ونشرح معنى TP وTN وFP وFN، والفرق بين Precision وRecall، ولماذا قد تكون Accuracy = 95% مضللة، وكيف تقرأ macro avg وweighted avg وsupport داخل تقرير التصنيف.
{alertInfo} الخلاصة السريعة: Confusion Matrix تخبرك أين أخطأ النموذج، Precision تقيس دقة التوقعات الإيجابية، Recall تقيس قدرة النموذج على اكتشاف الحالات الإيجابية، وF1 Score توازن بين Precision وRecall. لا تختَر مقياسًا لأن رقمه أعلى؛ اختَره بحسب نوع الخطأ المهم في مشكلتك.
{getToc} $title={محتوى المقال}
أين يأتي تقييم النموذج في مسار تعلم الآلة؟
المسار المبسط يكون هكذا:
Data
↓
train_test_split
↓
model.fit(X_train, y_train)
↓
model.predict(X_test)
↓
y_pred
↓
Model Evaluation
لدينا قيمتان مهمتان عند مرحلة التقييم:
y_test: القيم الصحيحة التي لم يستخدمها النموذج في التدريب.y_pred: القيم التي توقعها النموذج لبيانات الاختبار.
كل المقاييس التي سنشرحها تبدأ بمقارنة الحقيقة y_test بالتوقع y_pred.
ما هي Confusion Matrix؟
مصفوفة الارتباك Confusion Matrix هي جدول يلخص نتائج نموذج التصنيف من خلال مقارنة الفئة الحقيقية بالفئة التي توقعها النموذج.
| الحالة | المعنى |
|---|---|
TP — True Positive | الحالة Positive فعلًا والنموذج توقع Positive بشكل صحيح. |
TN — True Negative | الحالة Negative فعلًا والنموذج توقع Negative بشكل صحيح. |
FP — False Positive | الحالة Negative لكن النموذج توقعها Positive بالخطأ. |
FN — False Negative | الحالة Positive لكن النموذج توقعها Negative بالخطأ. |
مثال Spam لفهم TP وTN وFP وFN
لنفترض أن الفئة الإيجابية 1 تعني Spam، والفئة السلبية 0 تعني رسالة عادية.
- TP: الرسالة Spam والنموذج قال Spam.
- TN: الرسالة عادية والنموذج قال عادية.
- FP: الرسالة عادية لكن النموذج حظرها باعتبارها Spam.
- FN: الرسالة Spam لكن النموذج سمح لها بالمرور باعتبارها عادية.
شكل Confusion Matrix في scikit-learn
في التصنيف الثنائي، وعندما يكون ترتيب الفئات [0, 1]، يكون الشكل:
[[TN, FP],
[FN, TP]]
بمعنى أن الصفوف تمثل القيم الحقيقية، والأعمدة تمثل القيم المتوقعة.
{alertWarning}انتبه: لا تحفظ مواقع TP وFP وFN وTN دون معرفة ترتيب labels. تفسير المصفوفة يعتمد على ترتيب الفئات المستخدم في الحساب.أول مثال باستخدام confusion_matrix
y_true = [
0, 0, 0, 0,
1, 1, 1, 1
]
y_pred = [
0, 0, 1, 0,
1, 0, 1, 1
]
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(
y_true,
y_pred,
labels=[0, 1]
)
print(cm)
الناتج:
[[3 1]
[1 3]]
أي أن TN = 3 وFP = 1 وFN = 1 وTP = 3.
استخراج TN وFP وFN وTP مباشرة
tn, fp, fn, tp = cm.ravel()
print("TN:", tn)
print("FP:", fp)
print("FN:", fn)
print("TP:", tp)
ما هي Accuracy؟
Accuracy تجيب عن سؤال: من جميع التوقعات، كم نسبة التوقعات الصحيحة؟
Accuracy = (TP + TN) / (TP + TN + FP + FN)
في مثالنا السابق تكون Accuracy = 6 / 8 = 0.75 أي 75%.
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(
y_true,
y_pred
)
print(accuracy)
لماذا Accuracy لا تكفي دائمًا؟
لنفترض أن لدينا 100 رسالة: 95 رسالة عادية و5 رسائل Spam. نموذج يتوقع أن جميع الرسائل عادية سيصيب 95 حالة من أصل 100، أي Accuracy = 95%، لكنه لم يكتشف أي Spam.
95 Normal → predicted Normal
5 Spam → predicted Normal
Accuracy = 95 / 100 = 95%
الرقم يبدو ممتازًا، لكن أداء الفئة الإيجابية التي نهتم بها يساوي صفرًا من ناحية الاكتشاف. هنا نحتاج إلى Precision وRecall وF1.
ما هي Precision؟
Precision تجيب عن السؤال: عندما قال النموذج إن الحالة Positive، كم مرة كان توقعه صحيحًا؟
Precision = TP / (TP + FP)
إذا كان TP = 8 وFP = 2، فإن Precision = 0.80.
from sklearn.metrics import precision_score
precision = precision_score(
y_true,
y_pred
)
print(precision)
متى تكون Precision مهمة؟
تصبح Precision مهمة عندما تكون False Positives مكلفة. في مثال الرسائل، إذا كانت الرسالة العادية التي يصنفها النموذج Spam قد تختفي عن المستخدم، فقد تكون تقليل الإنذارات الإيجابية الخاطئة أولوية مهمة.
ما هي Recall؟
Recall تجيب عن السؤال: من جميع الحالات Positive الحقيقية، كم حالة استطاع النموذج اكتشافها؟
Recall = TP / (TP + FN)
from sklearn.metrics import recall_score
recall = recall_score(
y_true,
y_pred
)
print(recall)
متى تكون Recall مهمة؟
تكون Recall مهمة عندما يكون تفويت الحالات الإيجابية الحقيقية، أي False Negative، مكلفًا. مثل نظام كشف الاحتيال: إذا كانت المعاملة الاحتيالية هي Positive، فقد تهتم بألا يفوت النموذج نسبة كبيرة منها.
الفرق بين Precision وRecall بطريقة سهلة
| المقياس | السؤال | يركز على |
|---|---|---|
| Precision | من الأشياء التي توقعتها Positive، كم واحدة كانت Positive فعلًا؟ | تقليل False Positives. |
| Recall | من كل Positive الحقيقية، كم واحدة اكتشفها النموذج؟ | تقليل False Negatives. |
ما هي F1 Score؟
F1 Score تجمع Precision وRecall في مقياس واحد باستخدام المتوسط التوافقي.
F1 = 2 × (Precision × Recall) / (Precision + Recall)
تكون F1 مرتفعة عندما تكون Precision وRecall مرتفعتين معًا، وتنخفض إذا كان أحدهما ضعيفًا.
from sklearn.metrics import f1_score
f1 = f1_score(
y_true,
y_pred
)
print(f1)
هل F1 Score دائمًا أفضل مقياس؟
لا. إذا كانت تكلفة FP مختلفة جدًا عن تكلفة FN، فقد يكون من الأفضل متابعة Precision وRecall بصورة منفصلة. F1 مفيدة عندما تريد مقياسًا واحدًا يوازن بينهما، لكنها ليست بديلًا عن فهم طبيعة المشكلة.
حساب المقاييس الأساسية معًا
from sklearn.metrics import (
accuracy_score,
precision_score,
recall_score,
f1_score
)
print("Accuracy:", accuracy_score(y_true, y_pred))
print("Precision:", precision_score(y_true, y_pred))
print("Recall:", recall_score(y_true, y_pred))
print("F1:", f1_score(y_true, y_pred))
ما هو classification_report؟
توفر scikit-learn الدالة classification_report() التي تعرض Precision وRecall وF1 Score وSupport لكل فئة، بالإضافة إلى Accuracy والمتوسطات.
from sklearn.metrics import classification_report
print(
classification_report(
y_true,
y_pred
)
)
كيف أقرأ classification_report؟
precision recall f1-score support
0 ... ... ... ...
1 ... ... ... ...
accuracy ... ...
macro avg ... ... ... ...
weighted avg ... ... ... ...
ما معنى support؟
support هو عدد العينات الحقيقية التابعة لكل فئة داخل بيانات التقييم. إذا كان support للفئة 0 يساوي 950 وللفئة 1 يساوي 50، فهذه إشارة واضحة إلى عدم توازن الفئات.
ما معنى macro avg؟
macro avg يحسب المقياس لكل فئة بشكل مستقل، ثم يأخذ متوسطًا غير موزون بين الفئات. كل فئة تحصل على الوزن نفسه مهما كان عدد عيناتها.
ما معنى weighted avg؟
weighted avg يزن نتيجة كل فئة بحسب support. لذلك تؤثر الفئات الكبيرة في النتيجة أكثر، وقد يبدو المتوسط جيدًا رغم ضعف فئة صغيرة.
| المتوسط | طريقة الحساب | المعنى |
|---|---|---|
macro avg | متوسط غير موزون بين الفئات. | مفيد عندما تريد إعطاء كل فئة أهمية متساوية. |
weighted avg | متوسط موزون بحسب support. | يعكس توزيع العينات، وقد تتغلب الفئة الكبيرة على الضعيفة. |
لماذا لا يظهر micro avg دائمًا؟
في التصنيف أحادي التسمية عند تقييم جميع الفئات، يمكن أن يساوي micro average قيمة Accuracy، ولذلك لا يعرضه classification_report دائمًا كصف مستقل.
إرجاع classification_report كقاموس
report = classification_report(
y_true,
y_pred,
output_dict=True
)
print(
report["weighted avg"]["f1-score"]
)
ما معنى zero_division؟
إذا لم يتوقع النموذج أي عينة لفئة معينة، قد تصبح بعض المقاييس غير معرفة بسبب القسمة على صفر. يمكن تحديد طريقة التعامل مع ذلك:
classification_report(
y_true,
y_pred,
zero_division=0
)
لكن لا تستخدم هذا الخيار فقط لإخفاء التحذير؛ عدم توقع فئة كاملة مشكلة تستحق التحقيق.
رسم Confusion Matrix في بايثون
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_predictions(
y_true,
y_pred,
display_labels=[
"Normal",
"Spam"
]
)
plt.show()
تطبيع Confusion Matrix إلى نسب
ConfusionMatrixDisplay.from_predictions(
y_true,
y_pred,
normalize="true"
)
plt.show()
| normalize | المعنى |
|---|---|
None | الأعداد الخام. |
"true" | تطبيع كل صف حسب الفئة الحقيقية. |
"pred" | تطبيع كل عمود حسب الفئة المتوقعة. |
"all" | تطبيع على جميع العينات. |
مثال عملي كامل: تدريب نموذج ثم تقييمه
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
accuracy_score,
confusion_matrix,
classification_report
)
X, y = make_classification(
n_samples=1000,
n_features=10,
n_informative=5,
n_redundant=2,
weights=[0.8, 0.2],
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
model = LogisticRegression(
max_iter=1000
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(
"Accuracy:",
accuracy_score(y_test, y_pred)
)
print(
confusion_matrix(y_test, y_pred)
)
print(
classification_report(y_test, y_pred)
)
كيف أقرأ نتيجة النموذج؟
- افحص توزيع الفئات داخل
y_test. - اقرأ Confusion Matrix وحدد نوع الأخطاء.
- افحص Precision وRecall وF1 لكل فئة.
- قارن macro avg وweighted avg عند وجود عدم توازن.
- اربط المقاييس بهدف المشروع، لا بمجرد الرقم الأعلى.
لا تختَر أفضل نموذج بناءً على Accuracy فقط
| النموذج | Accuracy | Recall للفئة المهمة |
|---|---|---|
| A | 96% | 40% |
| B | 93% | 82% |
إذا كان هدفك اكتشاف الفئة الإيجابية وعدم تفويتها، فقد يكون B أنسب رغم Accuracy الأقل.
كيف أختار بين Precision وRecall؟
ابدأ بالسؤال: أي خطأ أكثر تكلفة في مشكلتي، FP أم FN؟
| إذا كان الأهم | راقب |
|---|---|
| تقليل False Positives | Precision |
| تقليل False Negatives | Recall |
| الموازنة بينهما بمقياس واحد | F1 Score |
ما هي Positive Class؟
في التصنيف الثنائي تحتاج Precision وRecall وF1 إلى معرفة الفئة التي نعاملها على أنها Positive. مع labels رقمية 0 و1 تكون الفئة 1 هي Positive في الإعداد الثنائي الافتراضي غالبًا. وإذا كانت labels نصية يمكنك تحديد pos_label.
spam_recall = recall_score(
["normal", "spam", "spam"],
["normal", "spam", "normal"],
pos_label="spam"
)
Confusion Matrix في Multiclass Classification
إذا كان لديك ثلاث فئات، تصبح المصفوفة 3×3. كل صف يمثل الفئة الحقيقية وكل عمود يمثل توقع النموذج. القطر الرئيسي يمثل التوقعات الصحيحة، والخلايا خارج القطر تكشف أنواع الخلط بين الفئات.
cm = confusion_matrix(
y_true,
y_pred,
labels=[
"Cat",
"Dog",
"Bird"
]
)
Precision وRecall وF1 في Multiclass
عندما توجد عدة فئات تحتاج إلى تحديد طريقة المتوسط عند طلب رقم واحد.
macro_f1 = f1_score(
y_true,
y_pred,
average="macro"
)
weighted_f1 = f1_score(
y_true,
y_pred,
average="weighted"
)
هل weighted F1 يحل مشكلة عدم توازن البيانات؟
ليس بالضرورة. weighted F1 يعطي وزنًا أكبر للفئات الأكبر، لذلك قد يبقى جيدًا رغم ضعف فئة صغيرة. افحص F1 وRecall لكل فئة، وmacro avg، وConfusion Matrix.
مثال مباشر على Accuracy المضللة
y_true = (
[0] * 95
+
[1] * 5
)
y_pred = [0] * 100
print(
accuracy_score(y_true, y_pred)
)
print(
classification_report(
y_true,
y_pred,
zero_division=0
)
)
ستظهر Accuracy = 0.95 تقريبًا، لكن Recall للفئة 1 يساوي 0 لأن النموذج لم يكتشف أي عينة منها.
الربط مع train_test_split
X_train, X_test, y_train, y_test = train_test_split(...)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
confusion_matrix(y_test, y_pred)
نقيّم على بيانات الاختبار التي لم تدخل في تدريب النموذج.
أخطاء شائعة عند تقييم نماذج التصنيف
1. الاعتماد على Accuracy وحدها
قد تخفي فشل النموذج في فئة صغيرة أو مهمة.
2. الخلط بين FP وFN
حدد Positive Class أولًا، ثم اسأل: هل الخطأ كان توقع Positive لحالة Negative أم تفويت Positive حقيقية؟
3. قراءة المصفوفة بدون الانتباه لترتيب labels
حدد ترتيب الفئات صراحة عندما تحتاج تفسيرًا واضحًا.
4. اختيار Precision أو Recall دون فهم التكلفة
المقياس الصحيح مرتبط بهدف المشروع وتكلفة الخطأ.
5. الاكتفاء بـweighted avg
الفئة الكبيرة قد تخفي ضعف فئة صغيرة؛ افحص المقاييس لكل فئة.
6. تقييم النموذج على بيانات التدريب فقط
هذه النتيجة قد تكون متفائلة ولا تقيس التعميم بصورة عادلة.
هل تتغير Precision وRecall عند تغيير Threshold؟
نعم في المصنفات التي تنتج احتمالات. تغيير threshold يغير عادةً عدد FP وFN، وبالتالي تتغير Precision وRecall.
probabilities = model.predict_proba(
X_test
)[:, 1]
threshold = 0.4
y_pred_custom = (
probabilities >= threshold
).astype(int)
لا تغيّر threshold لمجرد رفع مقياس على Test Set بشكل عشوائي. اختيار العتبة جزء من عملية التحقق وضبط النموذج ويجب أن يتبع هدفًا واضحًا.
متى أستخدم Precision-Recall Curve؟
إذا أردت دراسة العلاقة بين Precision وRecall عبر thresholds مختلفة، توفر scikit-learn أدوات مثل precision_recall_curve وPrecisionRecallDisplay. لكن للمبتدئ، فهم Confusion Matrix والمقاييس الأساسية يأتي أولًا.
أفضل شكل لتقرير تقييم نموذج التصنيف
- حجم وتوزيع Test Data.
- Confusion Matrix.
- Accuracy.
- Precision وRecall وF1 لكل فئة.
- macro avg وweighted avg.
- تفسير تكلفة FP وFN في التطبيق.
دالة صغيرة لطباعة تقرير تقييم كامل
from sklearn.metrics import (
accuracy_score,
confusion_matrix,
classification_report
)
def evaluate_classifier(y_true, y_pred):
print(
"Accuracy:",
accuracy_score(y_true, y_pred)
)
print("\nConfusion Matrix:")
print(
confusion_matrix(y_true, y_pred)
)
print("\nClassification Report:")
print(
classification_report(
y_true,
y_pred,
zero_division=0
)
)
تمرين عملي
y_true = [
1, 0, 1, 1, 0,
0, 1, 0, 1, 0
]
y_pred = [
1, 0, 0, 1, 0,
1, 1, 0, 0, 0
]
احسب Confusion Matrix ثم TN وFP وFN وTP، وبعدها Accuracy وPrecision وRecall وF1، وأخيرًا اطبع classification_report.
قائمة فحص لتقييم نموذج تصنيف
- هل قيّمت النموذج على بيانات لم يستخدمها في التدريب؟
- هل تعرف Positive Class في مشروعك؟
- هل تعرف توزيع الفئات داخل Test Data؟
- هل قرأت Confusion Matrix بدل الاكتفاء بـAccuracy؟
- هل تعرف تكلفة FP وتكلفة FN؟
- هل فحصت Precision وRecall وF1 لكل فئة؟
- هل قارنت macro avg وweighted avg إذا كانت الفئات غير متوازنة؟
- هل حددت ترتيب labels عند الحاجة؟
- هل تفسر الأرقام وفق هدف التطبيق وليس كأرقام مجردة؟
روابط داخلية مفيدة من بايثون العرب
- شرح train_test_split في scikit-learn وتقسيم بيانات التدريب والاختبار
- مسار تعلم الآلة ببايثون للمبتدئين
- تعلم الذكاء الاصطناعي ببايثون من الصفر: خريطة طريق عملية
- أفضل مكتبات بايثون للذكاء الاصطناعي للمبتدئين
- تجهيز بيئة بايثون للذكاء الاصطناعي خطوة بخطوة
مصادر رسمية للتوسع
- توثيق confusion_matrix الرسمي في scikit-learn
- توثيق classification_report الرسمي
- توثيق ConfusionMatrixDisplay الرسمي
- جميع مقاييس sklearn.metrics الرسمية
الخلاصة
Confusion Matrix من أهم أدوات تقييم نماذج التصنيف لأنها لا تكتفي بقول «كم توقعًا كان صحيحًا»، بل توضح أين أخطأ النموذج من خلال True Positive وTrue Negative وFalse Positive وFalse Negative.
Accuracy مفيدة كصورة عامة عندما يكون استخدامها مناسبًا، لكنها قد تكون مضللة مع البيانات غير المتوازنة. Precision تخبرك بمدى موثوقية التوقعات الإيجابية، Recall تخبرك بقدرة النموذج على اكتشاف الحالات الإيجابية الحقيقية، وF1 Score توفر مقياسًا يوازن Precision وRecall.
أما classification_report() فيجمع أهم المقاييس لكل فئة ويعرض support وmacro avg وweighted avg. وعند تقييم نموذج حقيقي، لا تنظر إلى رقم واحد فقط؛ اربط المقاييس بنوع الخطأ المهم في مشروعك.
{alertSuccess}القاعدة المهمة: أفضل مقياس ليس صاحب الرقم الأعلى، بل المقياس الذي يعكس الخطأ الذي تريد تقليله والهدف الحقيقي من نموذج التصنيف.
أسئلة شائعة
ما هي Confusion Matrix في بايثون؟
هي مصفوفة تقارن القيم الحقيقية بتوقعات نموذج التصنيف، وتوضح عدد التوقعات الصحيحة والخاطئة لكل فئة. في التصنيف الثنائي تساعد على استخراج TN وFP وFN وTP.
كيف أحسب Confusion Matrix باستخدام scikit-learn؟
استخدم confusion_matrix(y_test, y_pred) من sklearn.metrics. ويمكن تحديد ترتيب الفئات باستخدام الخيار labels.
ما الفرق بين Precision وRecall؟
Precision تقيس نسبة التوقعات الإيجابية التي كانت صحيحة، بينما Recall تقيس نسبة الحالات الإيجابية الحقيقية التي استطاع النموذج اكتشافها.
ما معنى F1 Score؟
هي المتوسط التوافقي بين Precision وRecall، وتستخدم عندما تريد مقياسًا واحدًا يوازن بينهما. أفضل قيمة هي 1 وأسوأ قيمة هي 0.
متى تكون Accuracy مضللة؟
قد تكون مضللة خصوصًا عندما تكون الفئات غير متوازنة. نموذج يتوقع الفئة الأكبر دائمًا قد يحصل على Accuracy مرتفعة رغم فشله في الفئة الصغيرة.
ما معنى True Positive وFalse Positive؟
True Positive يعني أن الحالة Positive فعلًا والنموذج توقعها Positive. أما False Positive فيعني أن الحقيقة Negative لكن النموذج توقع Positive.
ما معنى False Negative؟
يعني أن الحالة Positive في الحقيقة، لكن النموذج توقعها Negative، أي أنه فوّت حالة إيجابية حقيقية.
ما معنى support في classification_report؟
هو عدد العينات الحقيقية الموجودة لكل فئة داخل بيانات التقييم.
ما الفرق بين macro avg وweighted avg؟
macro avg يعطي كل فئة وزنًا متساويًا عند حساب المتوسط، بينما weighted avg يزن نتيجة كل فئة بحسب عدد عيناتها أو support.
لماذا لا يظهر micro avg دائمًا في classification_report؟
في بعض حالات التصنيف أحادي التسمية عند تقييم جميع الفئات، يتطابق micro average مع Accuracy، ولذلك لا يعرضه التقرير دائمًا كصف مستقل.
كيف أرسم Confusion Matrix في بايثون؟
يمكنك استخدام ConfusionMatrixDisplay.from_predictions(y_test, y_pred) من scikit-learn ثم عرض الرسم باستخدام Matplotlib.
هل F1 Score أفضل من Accuracy؟
ليس دائمًا. كل مقياس يجيب عن سؤال مختلف. F1 مفيدة للموازنة بين Precision وRecall، بينما Accuracy قد تكون مناسبة في حالات أخرى.
ما أفضل مقياس للبيانات غير المتوازنة؟
لا يوجد مقياس واحد يناسب كل الحالات. افحص Precision وRecall وF1 لكل فئة، وmacro average وConfusion Matrix، ثم اختر ما يتناسب مع الفئة المهمة وتكلفة FP وFN.
كيف أقيّم نموذج تصنيف متعدد الفئات؟
استخدم Confusion Matrix بعدد الفئات، وclassification_report لمشاهدة Precision وRecall وF1 لكل فئة، مع فحص macro avg وweighted avg حسب هدفك.
هل Precision وRecall تتغيران عند تغيير threshold؟
نعم في المصنفات التي تعتمد على احتمالات أو درجات. تغيير threshold يغير عادةً عدد FP وFN، ولذلك تتغير Precision وRecall.



