The F1 score is the harmonic mean of precision and recall, combining how many detected anomalies are correct with how many true anomalies are found. section 3.8.2
Compute it from true positives, false positives, and false negatives: precision measures detection accuracy, recall measures anomaly coverage, and F1 balances both. If either precision or recall is low, the F1 score is pulled down. section 3.8.2 section 6.4
Use the score to compare anomaly detectors while preserving the underlying trade-off:
- Reducing a prediction interval usually labels more points as anomalous, increasing recall but producing more false positives and lowering precision. section 3.8.2
- Prefer recall when missing anomalies is more costly; prefer precision when false positives must be minimized. section 3.8.2
- Treat a higher F1 score as a better balance, not as proof that one model is universally superior; comparisons here use a single dataset. section 5.8 section 6.4
Anomaly-detection comparison
One evaluation produced precision 0.38, recall 0.75, and F1 0.50: the detector found three of four true anomalies, but many flagged points were false positives. In another comparison, Moirai reached an F1 score of 0.53, while Chronos had perfect recall but only 21% precision. section 3.8.2 section 6.4
Listing 3.26 Function to evaluate anomaly detection
def evaluate_anomaly_detection(df, preds_col, actual_col):
tp = ((df[preds_col] == 1) & (df[actual_col] == 1)).sum()
tn = ((df[preds_col] == 0) & (df[actual_col] == 0)).sum()
fp = ((df[preds_col] == 1) & (df[actual_col] == 0)).sum()
fn = ((df[preds_col] == 0) & (df[actual_col] == 1)).sum()
precision = tp / (tp + fp) if (tp + fp) != 0 else 0
recall = tp / (tp + fn) if (tp + fn) != 0 else 0
f1_score = 2 * (precision * recall) / (precision + recall) if
➥(precision + recall) != 0 else 0
return precision, recall, f1_score
Inspect the Python function that counts confusion-matrix outcomes and returns precision, recall, and the F1 score with zero-denominator safeguards. section 3.8.2













