> ## Documentation Index
> Fetch the complete documentation index at: https://nixtlaverse.nixtla.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Methods

> The seven conformal methods, grouped by whether they learn from their own mistakes, and how to pick one.

A **method** is one class holding the calibration math and the
orchestration around it: it takes forecasts and truths, and returns an
interval. Seven ship with `conformalforecast`, and they divide cleanly
in two.

**Offline methods** calibrate once on a block of past errors and then
apply a fixed correction. They are the classical conformal guarantee,
and they assume the calibration errors and the future errors are
exchangeable — that the world does not change between the two.

**Online and adaptive methods** keep learning after calibration. Each
consumes `update(prediction, truth)` as observations arrive and moves
its own knobs in response. They exist because time series break
exchangeability routinely: regimes shift, variance drifts, a model that
was well-calibrated last quarter is not this one.

## The seven

| Method | Group | Handles | Needs |
| - | - | - | - |
| [`SplitConformal`](split) | offline | the exchangeable baseline | nothing beyond point forecasts |
| [`ConformalizedQuantileRegression`](cqr) | offline | heteroscedastic errors — noise that varies with level or season | a **quantile-capable** forecaster |
| [`WeightedSplit`](weighted_split) | offline | covariate shift — the target’s features differ from the calibration set’s | target features (`adapt`) or target labels (`recalibrate`) |
| [`AdaptiveConformalInference`](aci) | online | distribution shift, by moving the target `alpha` itself | a learning rate `gamma` |
| [`AggregatedAdaptiveConformalInference`](agaci) | online | shift, without having to pick `gamma` | nothing — it runs a panel of `gamma`s |
| [`NonexchangeableConformalPrediction`](nexcp) | online | shift, by down-weighting stale residuals | a decay `rho` |
| [`SequentialPredictiveConformalInference`](spci) | online | *conditional* coverage — width that varies per step | the `spci` extra (quantile-forest) |

Each method is configuration, and calibrating it returns a fitted
object. The pages below drive the **forecaster surface** —
`fitted = method.calibrate_cv(forecaster, n_windows)` then
`fitted.predict(history)` — because that is what standalone users want.
The **array surface**, `fitted = method.fit(predictions, truths)` then
`fitted.interval(predictions)`, takes no forecaster at all; see
[Architecture](../concepts/architecture) for the split and
[Embedding](../concepts/embedding) for when to reach for it.

## Choosing one

Work down this list and stop at the first line that describes your
problem.

1. **You have never used conformal prediction here before.** Start with
   [split conformal](split). It is one page of math, it has no knobs,
   and its coverage is a theorem rather than a hope. Everything else on
   this list is a response to a way it can fail — measure that failure
   before you fix it.
2. **Your errors are much larger at some times than others** — a
   seasonal peak, a high-volume series in a panel — and a
   constant-width band is too wide most of the year and too narrow at
   the peak. Use [CQR](cqr), if your forecaster can emit quantiles.
   Constant-width is a property of the *score*, not of conformal
   prediction.
3. **Your measured coverage drifts away from target over time.** The
   world moved. Use an online method:
   * [ACI](aci) if you are willing to tune one learning rate, and
     want the simplest thing that provably recovers long-run
     coverage.
   * [AgACI](agaci) if you are not — it runs several learning rates
     at once and aggregates them, which is usually what you want in
     production.
   * [NexCP](nexcp) if you would rather express “recent errors matter
     more” as a decay on the calibration set than as a moving target.
4. **You are predicting a different domain than you calibrated on** — a
   new region, a new customer segment, a shifted operating range — and
   the difference shows up in *features* you can measure, not in the
   same panel drifting under you over time. That is the boundary
   against item 3: temporal drift on a fixed panel is an online-method
   problem, a domain that differs in measurable ways is this one. Use
   [weighted split conformal](weighted_split), which needs either
   target features
   (`adapt(weighting=DensityRatio(...),    target_X=...)`) or target
   labels (`recalibrate()`). See [Transfer and
   adaptation](../capabilities/transfer) for the full set of verbs and
   which one your data allows.
5. **Coverage is fine on average but wrong in identifiable places** —
   the interval is too wide in calm periods and too narrow in volatile
   ones. That is a conditional-coverage problem. Use [SPCI](spci),
   which fits a quantile regressor on the residual history and lets the
   width move with it.

Two of those choices have an **asymmetric** mode, which is a setting
rather than a different method, so it does not get its own line above.
Reach for it when the two tails do not cost the same — being short on
inventory is not the mirror image of being long on it — or when the
forecaster is biased and you would rather the band shifted than widened
on both sides. [Split conformal](split) with `symmetric=False` scores
signed residuals and takes one one-sided quantile per tail; it needs no
extra capability, works through every adapter, and costs more
calibration data, since each tail now enforces its own `ceil(1 / level)`
floor. [CQR](cqr) with the same flag tilts the quantile levels it
requests instead, which tracks asymmetry that varies with the input
rather than applying a constant offset — but no shipped Nixtla adapter
can serve those levels today.

> **Coverage is not the only thing to measure**
>
> Two methods can both hit 90% and differ enormously in usefulness: the
> wider one is trivially valid and tells you nothing. Compare width
> alongside coverage — the Winkler score in
> [Diagnostics](../capabilities/diagnostics) does exactly that,
> penalising width and misses on one scale.

## The guarantee, and its limits

Split conformal gives finite-sample marginal coverage under
exchangeability: for any forecaster, `P(y ∈ interval) ≥ 1 - alpha`.
Three qualifiers matter in practice.

* **Marginal, not conditional.** The probability is over draws,
  averaged across series and horizons. A particular series can be
  systematically under-covered while the average is exactly right.
* **Exchangeability rarely holds for time series.** The calibration
  residuals come from the past and the test residual comes from the
  future; if the process drifts, they are not exchangeable and the
  guarantee degrades. The online methods on this page replace it with
  a weaker but more honest long-run guarantee.
* **Finite calibration sets quantise the achievable coverage.** With
  `n` calibration windows the attainable levels are multiples of
  `1/(n+1)`, which is why every method demands at least
  `ceil(1/alpha)` effective windows per series (asymmetric split and
  SPCI demand more) and raises `InsufficientCalibrationSamples`
  otherwise.


## Related topics

- [Methods](/conformalforecast/methods.html.md)
