"My detector scored 0.96 F1 on the benchmark. Then I replaced it with a coin flip and scored 0.97. The coin flip was cheaper, so I shipped that."
A Chastened AI Agent
Why this section matters
Every previous section in this chapter built a detector; this one decides whether the detector is real. For most of the last decade, time-series anomaly detection was evaluated with a scoring trick called point-adjustment that quietly inflated results so much that trivial baselines, including uniform random noise, outscored carefully engineered models. Whole tables of published state-of-the-art numbers turned out to measure the metric, not the method. If you monitor a fleet of pumps or turbines, an over-optimistic F1 is not an academic embarrassment: it is a maintenance program that dispatches technicians to healthy machines and misses the bearing that actually seized. This section explains exactly how point-adjustment cheats, shows you a random "detector" beating the reported scores in a dozen lines of code, and then equips you with the evaluation protocols that survive scrutiny: range-aware and affiliation metrics, threshold-free area-under-the-curve variants, and the TSB-AD benchmark that was built specifically to stop the cheating.
Honest evaluation here rests on the leakage-safe splitting discipline of Chapter 5 and the general benchmarking protocols of Chapter 65; this section is the anomaly-detection-specific instance of those rules. It also closes a loop opened in Section 37.4, where we built residual-to-alarm pipelines but deferred the reckoning about how to score them, and it extends the point-adjust warning first raised for classical detectors in Chapter 12. Prerequisites are light: precision, recall, and the precision-recall curve from any first ML course, plus the notion of a calibrated score threshold from Chapter 18.
The point-adjustment trap
Anomalies in machine data are almost always segments, not isolated points: a cavitating pump stays cavitated for hundreds of samples. A detector emits a per-sample score, you threshold it, and you would like credit for "catching the event" even if you did not flag every single sample inside it. Point-adjustment (PA), introduced with the Donut and OmniAnomaly detectors around 2018, encodes that wish as a rule: if the detector flags at least one sample inside a ground-truth anomaly segment, mark the entire segment as correctly detected. Then compute ordinary point-wise precision, recall, and F1 on the adjusted predictions.
The intent is defensible; the arithmetic is not. Consider a segment of length \(L\). Under PA, a single true-positive sample is promoted to \(L\) true positives. As anomaly segments in the popular benchmarks are long (tens to hundreds of samples), recall becomes almost free: any score that occasionally pokes above threshold inside a long segment harvests the whole thing. Because the benchmarks are also heavily imbalanced, precision is dominated by those inflated true positives, and F1 rockets toward 1. The pathology is that PA rewards hitting a segment anywhere far more than it penalizes flooding the normal regime with false alarms, which is precisely the tradeoff a condition-monitoring system must get right.
A metric a random number generator can win is not a metric
Kim and colleagues (2022) proved the point rather than argued it: they fed uniform random anomaly scores through the point-adjustment protocol and matched or beat the published state of the art on the standard benchmarks (SMD, MSL, SMAP, SWaT). The reason is structural. With enough anomaly segments and a modest flagging rate, a random detector will, by chance, drop at least one flag inside most segments, and PA converts each lucky hit into a full-segment reward. The lesson is not "these papers were fraudulent." It is that a scoring protocol under which noise is competitive cannot rank real methods, so any leaderboard built on raw PA-F1 is uninformative regardless of how good the underlying models are.
Watch a coin flip win
The fastest way to internalize this is to run it. The code below builds a synthetic monitoring trace with 40 anomaly segments, defines a useless detector that flags 5% of samples uniformly at random, and reports its F1 before and after point-adjustment. Raw F1 sits near chance; the point-adjusted F1 leaps into the range that gets papers accepted.
import numpy as np
def point_adjust(pred, label):
"""If any flagged sample lands inside a true anomaly segment,
promote the whole segment to 'detected' (the standard PA rule)."""
pred = pred.copy()
in_seg, start = False, 0
for i in range(len(label)):
if label[i] and not in_seg:
in_seg, start = True, i
if not label[i] and in_seg:
if pred[start:i].any():
pred[start:i] = 1
in_seg = False
if in_seg and pred[start:].any():
pred[start:] = 1
return pred
def f1(pred, label, eps=1e-9):
tp = np.sum((pred == 1) & (label == 1))
fp = np.sum((pred == 1) & (label == 0))
fn = np.sum((pred == 0) & (label == 1))
p, r = tp / (tp + fp + eps), tp / (tp + fn + eps)
return 2 * p * r / (p + r + eps)
rng = np.random.default_rng(0)
T, label = 20_000, np.zeros(20_000, dtype=int)
for s in rng.integers(0, T - 60, size=40): # 40 anomaly events
label[s:s + rng.integers(30, 60)] = 1
pred = (rng.random(T) > 0.95).astype(int) # a USELESS detector
print("raw F1 :", round(f1(pred, label), 3))
print("point-adjusted F1:", round(f1(point_adjust(pred, label), label), 3))
# raw F1 : 0.05
# point-adjusted F1: 0.86
Metrics that survive scrutiny
Rejecting PA does not mean reverting to naive point-wise F1, which is too harsh in the opposite direction: it demands you flag every sample of an event and gives no partial credit for a slightly early or slightly late detection. The field has converged on a small set of range-aware alternatives, and you should report at least one from each idea below.
Range-based precision and recall (Tatbul et al., 2018) generalize the point-wise definitions to intervals, with tunable terms for existence (did you touch the event at all), size (how much of it), and position (front-biased credit when early detection matters, which it usually does in prognostics). Affiliation metrics (Huet et al., 2022) score the average temporal distance between predicted and true events and normalize against a random baseline, so a detector must beat chance by construction, closing the exact loophole PA leaves open. Threshold-free area metrics avoid the separate sin of tuning the alarm threshold on the test set: instead of one operating point, report the area under the precision-recall curve (preferred over ROC because anomalies are rare and PR is not fooled by the enormous true-negative mass), or its range-aware generalization VUS (Volume Under the Surface, Paparrizos et al., 2022), which integrates over both the threshold and a temporal tolerance so no single lucky cutoff can be cherry-picked. When you must report a single-threshold number, use PA%K, which only credits a segment if at least \(K\%\) of its samples are flagged and sweeps \(K\) to expose the sensitivity that plain PA hides.
For condition monitoring specifically, add two operational numbers no leaderboard captures: detection delay (samples or seconds from fault onset to first alarm, because a correct alarm that arrives after the failure is worthless) and false-alarm rate per machine-day (the quantity that decides whether operators keep the system switched on). The calibration machinery of Chapter 18 turns a raw residual into a threshold that targets that false-alarm rate directly, rather than an arbitrary quantile.
A wind-farm dashboard that looked perfect and dispatched no one
An operator of a 60-turbine wind farm evaluated a gearbox anomaly detector on twelve months of SCADA vibration and temperature logs and reported 0.94 point-adjusted F1. In the field, technicians ignored it within a fortnight: it raised roughly nine alarms per turbine per week, almost all on healthy units, while a real high-speed-shaft bearing fault crept up over three weeks and triggered its first alarm only two days before the gearbox failed. Re-scored without point-adjustment, the same model sat at 0.19 range-based F1 with a median detection delay of nineteen days. The 0.94 was never a property of the detector; it was a property of long fault segments plus a permissive metric. Switching the target to VUS-PR and a false-alarm budget of one alarm per turbine per month forced a retune that cut nuisance alarms tenfold and, in the following season, flagged two developing bearing faults with a fortnight of lead time.
TSB-AD and honest benchmarking
Fixing the metric is necessary but not sufficient, because several classic benchmarks are themselves flawed: they contain mislabeled anomalies, trivially detectable single spikes, and train/test contamination that a leakage audit would reject. TSB-AD (Time-Series Benchmark for Anomaly Detection, Liu and Paparrizos, NeurIPS 2024) is the community's response. It curates over a thousand time series across univariate and multivariate domains, manually screens out mislabeled and trivial cases, standardizes on threshold-free VUS and range-aware metrics rather than point-adjusted F1, and evaluates dozens of statistical, machine-learning, and deep methods under one protocol. Its headline finding is deflating and useful: once the metric is fixed, simple, well-tuned methods (nearest-neighbor distances, sub-sequence clustering, classical forecasting residuals) are competitive with or ahead of many elaborate deep models, echoing the "model normal, score the residual" pragmatism of Section 37.4. TSB-AD is the benchmark to report against for a new detector, and its leaderboard is the sanity check when your in-house number looks too good.
Where the field is heading (2024 to 2026)
The current frontier is threefold. First, evaluation is being extended to foundation-model detectors: zero-shot scoring with TimesFM, MOMENT, and Chronos (the reconstruction-based approaches of Section 37.5) is only meaningful under leakage-audited, PA-free protocols, and TSB-AD-style suites are being adapted to test whether a pretrained model has effectively seen the benchmark during its own pretraining, a new and subtle leakage channel. Second, affiliation-style and VUS metrics are being combined with cost-sensitive objectives so the reported number reflects the operator's real false-alarm budget rather than a symmetric F1. Third, work on label quality itself (re-annotating legacy benchmarks, quantifying annotator disagreement on where a fault "begins") is maturing, because a metric can only be as honest as the labels underneath it. Expect the next generation of condition-monitoring papers to report VUS-PR on TSB-AD plus an operational delay-versus-false-alarm curve, and to treat a bare point-adjusted F1 as a red flag.
Right tool: do not reimplement the metrics
The range-based, affiliation, VUS, and PA%K definitions are fiddly to code correctly, and a subtle off-by-one in segment handling silently changes your conclusions. The reference implementations ship ready to use: the affiliation-metrics package computes affiliation precision/recall in two calls, and the TSB-AD repository exposes VUS-PR, VUS-ROC, range-based F1, and PA%K behind a single evaluate(scores, labels) entry point. Adopting them replaces roughly 150 to 250 lines of easy-to-get-wrong interval bookkeeping with about five lines, and, more importantly, it makes your numbers directly comparable to the published leaderboard instead of to your own private definition of "detected."
Exercise
Take the synthetic trace from the code above. (a) Sweep the random flagging rate from 0.1% to 20% and plot both raw F1 and point-adjusted F1 against it; identify the flagging rate that maximizes PA-F1 and explain why the peak exists. (b) Now shrink every anomaly segment to length 3 and repeat. Explain, using the segment-length argument, why PA-F1 collapses toward raw F1 as segments get short, and what that implies about which benchmarks PA flatters most. (c) Re-score your best detector from Section 37.4 on a MIMII-DG machine using VUS-PR and range-based F1, and report how far its PA-F1 overstated it.
Self-check
1. In one sentence, why can a uniform-random score achieve high F1 under point-adjustment but not under range-based recall with a position term?
2. Why is area under the precision-recall curve preferred over area under the ROC curve when anomalies make up under 1% of samples?
3. Your model reports 0.9 PA-F1 in-house but 0.3 VUS-PR on TSB-AD. Give two distinct explanations, one about the metric and one about the data, and how you would tell them apart.
Lab 37
build a first-shot machine-condition anomaly detector on MIMII-DG; evaluate cross-machine generalization.
Bibliography
The point-adjustment critique
The paper that showed a random anomaly score beats published state of the art under point-adjustment, and proposed PA%K to expose the effect. Required reading before you trust any PA-F1 table.
The work that popularized the point-adjustment protocol. Read it to see the reasonable original motivation, then read Kim et al. to see why the shortcut backfired.
Metrics that survive scrutiny
Introduces range-based precision/recall with tunable existence, size, and position terms. The foundation for scoring segment anomalies without the PA loophole.
Distance-based, random-baseline-normalized precision/recall for events. Because it scores against chance, no random detector can look good, closing the gap PA leaves.
Defines VUS-PR and VUS-ROC, threshold-free measures that integrate over a temporal tolerance so no single cutoff can be cherry-picked. The metric TSB-AD standardizes on.
Honest benchmarks
A curated, mislabel-screened, leakage-audited benchmark of 1000+ series scored with VUS and range-aware metrics. The reference suite for evaluating a new detector honestly.
A blunt audit of the legacy benchmarks (mislabeled points, trivial anomalies, run-to-failure triviality) that motivated the move to curated suites like TSB-AD.
Domain context
The machine-sound dataset used in Lab 37; its official protocol already reports domain-split AUC and pAUC, a real-world example of leakage-aware anomaly evaluation.
What's Next
In Chapter 38, we push anomaly detection from "a machine is degrading" to "a machine is under attack." When the abnormal readings are produced by an adversary rather than a worn bearing, the physics-based process invariants, the attack-versus-fault distinction, and the evaluation protocols all change, and the honest-metric discipline you just learned becomes a security requirement rather than a scientific nicety.