F1-Score
The F1-score is the harmonic mean of precision and recall, so it stays low unless both are high. Formula, F-beta, macro vs. micro F1, and detection use.
The F1-score is a single metric that combines precision and recall as their harmonic mean: F1 = 2 × precision × recall / (precision + recall). It runs from 0 to 1 and reaches 1 only when a model has no false positives and no false negatives. A harmonic mean is pulled toward the smaller of its inputs, so F1 stays low whenever either precision or recall is low, which makes it the usual summary for imbalanced problems such as defect detection, fraud screening, and document retrieval, where accuracy is misleading. The F1-score is also called the balanced F-score or the F-measure, and on binary pixel masks it is the same quantity as the Dice coefficient.
How the F1-Score Is Calculated#
Written in confusion matrix counts, F1 = 2TP / (2TP + FP + FN). True negatives never appear in the formula, so F1 measures only how well the model handles the positive class. That suits tasks where positives are rare and negatives are of little interest, and when true negatives matter, the Matthews correlation coefficient or balanced accuracy covers all four cells. The harmonic mean is what separates F1 from a plain average: a model with a precision of 1.0 and a recall of 0.1 has an arithmetic mean of 0.55 and an F1 of 0.18.
F-Beta and Multi-Class Averaging#
F1 weighs precision and recall equally. The general F-beta score treats recall as β times as important as precision, so F2 favors recall, as in medical screening where a miss is costly, and F0.5 favors precision, as in spam filtering where a false alarm is costly.
With more than two classes, F1 is computed for each class and then averaged:
- Macro F1: the unweighted mean of the per-class scores, so a rare class counts as much as a common one.
- Weighted F1: the mean of the per-class scores weighted by each class's number of true examples.
- Micro F1: a single F1 from TP, FP, and FN pooled across all classes. In single-label multi-class tasks it equals accuracy.
from sklearn.metrics import f1_score
# Imbalanced inspection labels: 8 good parts, 2 defective parts
y_true = ["ok"] * 8 + ["defect"] * 2
y_pred = ["ok"] * 7 + ["defect"] + ["defect", "ok"]
# F1 for each class, then two ways to average them
per_class = f1_score(y_true, y_pred, labels=["ok", "defect"], average=None)
print(f"F1 ok: {per_class[0]:.3f}, F1 defect: {per_class[1]:.3f}")
print(f"Macro F1: {f1_score(y_true, y_pred, average='macro'):.3f}")
print(f"Micro F1: {f1_score(y_true, y_pred, average='micro'):.3f}")The script prints an F1 of 0.875 for good parts and 0.500 for defects, a macro F1 of 0.688, and a micro F1 of 0.800. The model labels 8 of 10 parts correctly, so micro F1 equals its 0.80 accuracy, and macro F1 is lower because the weak defect class counts as much as the majority class.
F1 in Object Detection#
A detector has a precision and a recall at every confidence threshold, so it also has an F1 curve over confidence. The peak of that curve marks the confidence threshold that best balances false detections against missed objects, the single operating point a deployed model runs at. F1 complements mean average precision (mAP), which integrates over all thresholds to rank models. YOLO26 validation saves this curve as BoxF1_curve.png and reports precision, recall, and per-class F1 at the confidence where mean F1 peaks.
from ultralytics import YOLO
# Load a pretrained YOLO26 nano detector
model = YOLO("yolo26n.pt")
# Validation sweeps confidence thresholds and saves BoxF1_curve.png
metrics = model.val(data="coco8.yaml")
# Precision, recall, and F1 at the confidence where mean F1 peaks
print(f"Precision: {metrics.box.mp:.3f}")
print(f"Recall: {metrics.box.mr:.3f}")
print(f"Mean F1: {metrics.box.f1.mean():.3f}")Mean F1 averages the per-class F1 values, so it can differ slightly from the harmonic mean of the mean precision and mean recall printed above it.










