"They kept asking which samples I looked at. I only ever wanted to answer a simpler question: what would this signal have needed to be for me to relax?"
A Contrastive AI Agent
Prerequisites
This section builds on the attribution methods of Section 67.1 and the saliency pitfalls of Section 67.2, which answered "which parts of the input mattered?" Here we answer a different question: "what would the input have had to be to change the decision?" We assume the notion of a decision boundary and a differentiable or queryable classifier from Chapter 13, the idea of a plausible signal manifold from the self-supervised representations of Chapter 17, and basic sensor physics constraints from Chapter 2. No prior exposure to evolutionary algorithms is required; we introduce the pieces we use.
The Big Picture
An attribution map tells an operator that the third second of the vibration trace was "important." It does not tell them what to do about it. A counterfactual explanation answers the actionable question directly: it produces the closest alternative signal the model would have classified differently. "This window was flagged as a bearing fault; had the amplitude around 40 ms stayed below this level, it would have read as healthy." For sensor time series this is uniquely powerful and uniquely hard. Powerful, because the answer is a concrete, inspectable trace an engineer can compare against the real one. Hard, because a naive minimal edit produces a jagged, physically impossible signal no real sensor could emit. This section teaches the two dominant strategies for plausible time-series counterfactuals, TSEvo (evolutionary multi-objective search) and MASCOTS (a symbolic model-agnostic approach), and the desiderata that separate a useful counterfactual from a misleading one.
What a time-series counterfactual is, and why sensors make it hard
Formally, given a classifier \(f\), an input signal \(x\) with predicted class \(f(x)=y\), and a target class \(y' \neq y\), a counterfactual is a signal \(x'\) that solves
$$ x' = \arg\min_{z}\; d(x, z) \quad \text{subject to}\quad f(z) = y', $$where \(d\) measures how far the counterfactual strayed. This is the tabular recipe of Wachter and colleagues transplanted onto a sequence, and the transplant fails in three ways for sensors. First, sparsity is not enough: changing a scattered handful of samples yields spiky discontinuities that violate the bandwidth and inertia of any real transducer, so we want the changes contiguous (a few coherent segments, not confetti). Second, Euclidean proximity is a poor proxy for physical closeness: two traces one sample apart in \(L_2\) can differ by a phantom impulse a mechanical system cannot produce. Third, and most important, the counterfactual must be plausible: it must look like something the sensor could have measured, otherwise the model is interrogated off-manifold, the failure mode that made adversarial-looking saliency untrustworthy in Section 67.2. A good time-series counterfactual therefore optimizes four coupled objectives at once: validity (it flips the label), proximity (it stays close), sparsity or contiguity (few, connected regions change), and plausibility (it stays on the data manifold).
Key Insight
Attribution and counterfactual explanations are duals. Attribution decomposes a decision that already happened; a counterfactual constructs the nearest decision that did not. The counterfactual is more actionable because it is contrastive in the way humans reason: people ask "why this and not that?", and a counterfactual literally exhibits the "that." But this power is real only if \(x'\) is plausible. An off-manifold counterfactual is an adversarial example wearing an explanation's clothes: it flips the label with a perturbation no physical process could generate, so it explains the model's blind spot rather than the phenomenon. Plausibility is the load-bearing objective, not a nicety.
TSEvo: evolutionary multi-objective search
TSEvo (Höllig, Kulbach, and Thoma, ICMLA 2022) treats counterfactual generation as multi-objective optimization solved with a genetic algorithm, specifically the non-dominated sorting genetic algorithm NSGA-II. Rather than collapsing validity, proximity, and sparsity into one weighted scalar (which forces you to guess the weights), it evolves a population of candidates and returns the Pareto front: the set where no candidate can improve on one objective without worsening another. The operator picks a point on that front, trading proximity against sparsity to taste.
Two choices make TSEvo suited to sensors. It is model-agnostic and gradient-free: it only queries \(f(z)\), so it works on a random forest, a boosted-tree fault classifier, or a deployed black box, which matters because much industrial sensing still runs the classical models from Chapter 12. And its mutation operators are signal-aware: instead of adding white noise it splices segments from real instances of the target class, or mutates in the frequency domain, so offspring inherit plausible sensor structure. This "authentic" mutation keeps candidates on the manifold without an explicit density model. It handles multivariate signals natively, evolving which channels change, which is what you need when a counterfactual must decide whether the fault story lives in the accelerometer or the temperature channel.
Step-Through: exonerating a gearbox on the factory floor
A wind-turbine operator runs a black-box classifier on triaxial nacelle vibration; it flags a gearbox window as "stage-2 bearing wear" and schedules an expensive teardown. The maintenance lead wants to know what would have made it read "healthy." TSEvo is pointed at the deployed model with target class healthy. Its authentic-mutation operator splices short segments from known-healthy windows of the same turbine into the flagged trace, and NSGA-II evolves toward validity while minimizing the changed region. The Pareto front offers a sparse counterfactual: flipping the verdict required suppressing a single narrow amplitude burst around the gear-mesh frequency in only the radial axis, roughly 60 ms, leaving the axial and tangential channels untouched. That is a diagnosis a vibration engineer can act on: it localizes the model's evidence to a specific harmonic in a specific axis, which they cross-check against the order-tracking analysis of Chapter 37. The counterfactual did not just say "the vibration mattered"; it said which burst, which axis, how much, and the teardown was deferred pending a targeted re-measurement.
MASCOTS: symbolic, model-agnostic counterfactuals
Evolutionary search is flexible but can be slow, and its edits, while authentic, are not always human-legible. MASCOTS (a Model-Agnostic Symbolic COunterfactual method for Time Series, 2025) takes a different route: it lifts the signal into a symbolic representation before searching. Using a discretization in the family of SAX (Symbolic Aggregate approXimation) and bag-of-patterns encodings, it turns a continuous trace into a short string of symbols over piecewise segments. Counterfactual search then becomes editing symbols, "this rising segment becomes flat," rather than nudging thousands of samples. Two benefits follow. The edits are inherently contiguous and interpretable, because a symbol spans a whole segment. And plausibility comes cheaply, because edited symbols map back to shapes drawn from the observed vocabulary, so the reconstruction is composed of segment shapes the sensor has actually produced. MASCOTS is query-only like TSEvo and extends to multivariate signals by symbolizing each channel. The trade is granularity: symbolic edits are coarser than TSEvo's sample-level splices, more readable but occasionally less minimal.
Research Frontier
The state of the art is converging on plausibility measured, not assumed. TSEvo and MASCOTS both encode plausibility structurally (authentic mutation, symbolic vocabularies), but recent work pushes toward generative plausibility: constraining \(x'\) to a manifold learned by a variational autoencoder or diffusion model over the sensor stream, so the counterfactual is sampled from an explicit density rather than assembled from fragments. Parallel efforts add actionability constraints that respect sensor physics (a temperature channel cannot jump 50 K in one sample; a phase and its quadrature must stay consistent), turning the generic distance \(d\) into a physics-aware cost. The open benchmark question, taken up in Section 67.7, is how to score these methods on validity, proximity, plausibility, and sparsity simultaneously without one metric hiding a failure in another.
Building a minimal contiguous counterfactual
The four objectives are easier to internalize by coding the smallest honest version: a gradient-free search that flips a black-box classifier by editing one contiguous segment while penalizing the size of the change. Code 67.3.1 is the conceptual kernel that TSEvo scales up with a real evolutionary operator and MASCOTS reframes symbolically.
import numpy as np
def contiguous_counterfactual(x, classify, target, seg_len=8,
n_iter=400, step=0.4, seed=0):
"""Flip a black-box classifier by perturbing ONE contiguous window.
Objectives: validity (reach target) + proximity (small L2) +
contiguity (a single short segment, set by seg_len)."""
rng = np.random.default_rng(seed)
n = len(x)
best, best_cost = None, np.inf
for _ in range(n_iter):
start = rng.integers(0, n - seg_len) # pick one window
z = x.copy()
z[start:start + seg_len] += step * rng.normal(size=seg_len)
if classify(z) == target: # validity satisfied
proximity = np.linalg.norm(z - x) # how far we strayed
cost = proximity # contiguity fixed by seg_len
if cost < best_cost:
best, best_cost = z, cost
return best, best_cost
# Toy detector: "fault" if any sample in the mid-window exceeds 1.5
def classify(sig):
return "fault" if sig[20:40].max() > 1.5 else "healthy"
t = np.linspace(0, 1, 64)
x = 0.3 * np.sin(2 * np.pi * 5 * t)
x[28] += 1.8 # inject a fault spike
cf, cost = contiguous_counterfactual(x, classify, target="healthy")
print("original:", classify(x), " counterfactual:", classify(cf),
" L2 moved:", round(cost, 3))
Running Code 67.3.1 returns a counterfactual that suppresses just the injected spike, the localized answer the gearbox example delivered at scale. Notice what is missing: there is no plausibility term, so on a real sensor this kernel could still produce a slightly unnatural dip. That gap is what TSEvo's authentic mutation and MASCOTS's symbolic vocabulary close, and why you should reach for them rather than hand-rolling search in production.
Right Tool: TSInterpret instead of rolling your own
The TSInterpret library ships TSEvo and other time-series counterfactual methods behind a single explain call that consumes any query-only classifier and returns the counterfactual trace plus its objective scores. A from-scratch NSGA-II with signal-aware mutation, Pareto bookkeeping, and multivariate channel handling is several hundred lines and easy to get subtly wrong (dominated-solution leaks, mutation that drifts off-manifold). Through the library it is roughly a 5-line call: instantiate the explainer, call it on the flagged window, read the front. That is a several-hundred-line to about-5-line reduction. The full human-review workflow around TSInterpret and Captum is the subject of Section 67.6; use the library for the search and spend your effort validating plausibility.
Exercise
Take a wearable human-activity classifier (the modeling side is in Chapter 26) that reads a 3-axis accelerometer window and predicts "walking." (a) Extend Code 67.3.1 to a 3-channel signal and add a plausibility penalty equal to the \(L_2\) distance from the counterfactual to its nearest neighbor among a set of real "running" windows. (b) Generate a counterfactual to the target "running" and report the four objective values (validity, proximity, contiguity as edited length, plausibility). (c) Compare the counterfactual you get with the plausibility term against the one without it, and explain in three sentences why the plausible version is the one you would show a physiotherapist.
Self-Check
- State the four objectives a sensor counterfactual should satisfy, and give a concrete failure that results from dropping the plausibility objective.
- Why does TSEvo return a Pareto front instead of a single counterfactual, and what does the operator gain from being handed the whole front?
- MASCOTS edits symbols rather than samples. Name one advantage and one cost of this choice relative to TSEvo's sample-level splicing.
What's Next
In Section 67.4, we move from per-instance contrastive edits to explanations that name recurring, human-meaningful structure: concept- and prototype-based methods that say "this window matches the impending-stall prototype" rather than editing a single trace. Where counterfactuals answer "what would have changed the verdict?", prototypes answer "what does this remind the model of?", and together they give an operator both a contrastive and a case-based account of the same alert.