Type at least 2 letters. Enter opens the first result, Esc closes.

    Time Series and Forecasting · Lesson 10 · Uncertainty and anomalies

    Probabilistic forecasting: quantiles, CRPS and conformal intervals

    Advanced 110 min 5 interactive figures 4 videos Colab notebook

    Before this lesson: backtesting and point metrics (lesson 03), ARIMA prediction intervals (lesson 06), forecasting with lag features and gradient boosting (lesson 08). From the probability-and-statistics track: the cumulative distribution function (CDF), quantiles, and the normal distribution. Calibration of classifiers from the ml-fundamentals track helps, but this lesson defines everything it uses. Time: about 110 minutes, plus the notebook.


    Why this matters #

    • Decisions depend on quantiles, not on the mean. A shop that loses 9 per missing unit and 1 per unsold unit should stock the 90 % quantile of demand (section 3.2). A grid operator keeps reserve power for the 99 % quantile of load. A point forecast cannot answer these questions.
    • Model intervals are often too narrow. The ARIMA and ETS intervals of lessons 04 and 06 assume that the model is right, that its parameters are exact and that the errors are Gaussian. In real backtests a "95 %" interval often covers clearly less than 95 % of the outcomes. Conformal methods correct this.
    • Benchmarks and competitions score distributions. The M5 uncertainty competition scored nine quantiles with a scaled pinball loss; the GEFCom2014 energy competition used the pinball loss; weather ensembles (ECMWF, and ML models such as GenCast) are scored with the CRPS; time-series foundation models such as Chronos and TimesFM output quantiles and are compared by a weighted quantile loss (lesson 09).
    • Monitoring. A value outside a calibrated 99 % interval is a natural anomaly alarm (lesson 11).

    1. Predict first #

    2. The picture #

    Four forms of a probabilistic forecast #

    Write yt+hy_{t+h} for the unknown future value and y^t+h∣t\hat y_{t+h\mid t} for a point forecast made at the forecast origin tt (the track notation). A probabilistic forecast describes the whole predictive distribution of yt+hy_{t+h} given the data up to time tt. It comes in four forms:

    Form What the model outputs Example Good for
    distribution a CDF Ft+h∣tF_{t+h\mid t} or its parameters N(y^,σ^h2)\mathcal N(\hat y, \hat\sigma_h^2) from ARIMA (lesson 06) any summary of one horizon
    quantiles q^τ\hat q_\tau for a few levels τ\tau q^0.1,q^0.5,q^0.9\hat q_{0.1}, \hat q_{0.5}, \hat q_{0.9} from a quantile model decisions at fixed levels
    interval [ℓ,u][\ell, u] with nominal coverage 1−α1 - \alpha a 90 % interval dashboards, alarms
    sample paths MM simulated futures yt+1(i),…,yt+H(i)y^{(i)}_{t+1}, \dots, y^{(i)}_{t+H} DeepAR samples (lesson 09) sums and maxima over many horizons

    The first three describe one horizon at a time (the marginal distribution of each yt+hy_{t+h}). Only sample paths keep the dependence between horizons. You need them for questions about several horizons at once, such as "what is the 90 % quantile of the total demand next week?" (section 3.7).

    The pinball loss turns a quantile into a training target #

    The τ\tau-quantile of a distribution is the value qq with probability τ\tau below it. To train a model to output a quantile, we need a loss whose best constant is that quantile. The squared error gives the mean, and the absolute error gives the median (lesson 03). The pinball loss (or quantile loss) tilts the absolute error: with the error u=y−qu = y - q,

    ρτ(u)={τ uif u≥0 (the forecast was too low),(τ−1) uif u<0 (the forecast was too high).\rho_\tau(u) = \begin{cases} \tau\,u & \text{if } u \ge 0 \text{ (the forecast was too low)},\\ (\tau - 1)\,u & \text{if } u < 0 \text{ (the forecast was too high)}. \end{cases}

    For τ=0.9\tau = 0.9, a forecast that is too low costs 0.90.9 per unit and a forecast that is too high costs only 0.10.1 per unit. So the best qq moves up, until only 10 % of the data lie above it.

    Interactive figure: loading…

    Move τ\tau, then move qq. The top panel is the loss of one error u=y−qu = y - q: slope τ\tau on the right and τ−1\tau - 1 on the left. The lower panel shows 39 blue data values and the orange mean loss L(q)L(q) over them. Its slope at qq is the share of data below qq minus τ\tau. Notice that the yellow minimum sits where the share below reaches τ\tau: at the empirical τ\tau-quantile. Press Move q to the minimum and compare with the order statistic.

    Calibration and sharpness #

    How do we check a probabilistic forecast? We cannot check one distribution with one outcome. But over many forecasts, events with a forecast probability of 80 % should happen about 80 % of the time. This is calibration. A simple check is the coverage of central intervals: the share of outcomes inside the 50 %, 80 % and 95 % intervals. A finer check is the PIT (probability integral transform): for each forecast, compute ut=Ft(yt)u_t = F_t(y_t), the forecast probability below the outcome. If the forecasts are calibrated, the utu_t are uniform on [0,1][0, 1] and their histogram is flat.

    Calibration is not enough. A forecast that ignores all current information and always predicts the long-run distribution of the series (the climatological forecast) is calibrated, but its intervals are wide. We also want sharpness: narrow intervals. The rule of Gneiting, Balabdaoui and Raftery (2007) is maximise sharpness subject to calibration.

    Interactive figure: loading…

    Pick a preset, then move the spread and the bias. Each of 300 cases has a known signal mtm_t and a noisy outcome yt=mt+εty_t = m_t + \varepsilon_t; the forecast is N(mt+b,s2)\mathcal N(m_t + b, s^2). The top panel shows the first 60 outcomes and their 80 % intervals; magenta outcomes fall outside. Too narrow gives a U-shaped PIT histogram and low coverage; too wide gives a hump; biased gives a slope. Notice that the flat PIT at s=1,b=0s = 1, b = 0 also has (up to sampling noise) the smallest mean CRPS (section 3.4), and that climatology is calibrated but has a much larger CRPS.

    Quick check

    The PIT histogram of a forecaster over one year is U-shaped: many values near 0 and near 1, few in the middle. What is wrong?

    3. Definitions and main results #

    3.1 Notation #

    • FF is the predictive CDF of yt+hy_{t+h} given the data up to tt: F(x)=P(yt+h≤x)F(x) = P(y_{t+h} \le x) under the forecast. We drop the indices when only one forecast is meant.
    • The quantile function is F−1(τ)=inf⁡{x:F(x)≥τ}F^{-1}(\tau) = \inf\{x : F(x) \ge \tau\} for τ∈(0,1)\tau \in (0, 1). A quantile forecast at level τ\tau is written q^τ\hat q_\tau.
    • A central (1−α)(1 - \alpha) interval is [F−1(α/2),F−1(1−α/2)][F^{-1}(\alpha/2), F^{-1}(1 - \alpha/2)]. Its nominal coverage is 1−α1 - \alpha; its empirical coverage is the share of outcomes inside it in a backtest.

    3.2 Quantiles and the pinball loss #

    Definition. For a level τ∈(0,1)\tau \in (0, 1), the pinball loss of a quantile forecast qq when the outcome is yy is

    ρτ(y−q)=max⁡{τ(y−q), (τ−1)(y−q)}=(y−q)(τ−1{y<q}).\rho_\tau(y - q) = \max\{\tau(y - q),\ (\tau - 1)(y - q)\} = (y - q)\big(\tau - \mathbf 1\{y < q\}\big).

    For τ=0.5\tau = 0.5 it is half the absolute error. It is never negative and it is 0 only when q=yq = y.

    Theorem (the pinball loss is minimised by the quantile). Let YY have a continuous CDF FF with finite mean. Then L(q)=E ρτ(Y−q)L(q) = \mathbb E\,\rho_\tau(Y - q) is convex in qq, and it is minimised at every qq with F(q)=τF(q) = \tau, that is at the τ\tau-quantile F−1(τ)F^{-1}(\tau).

    Why this is true, in one sentence. Moving qq up by a small δ\delta costs (1−τ)δ(1 - \tau)\delta for each outcome below qq (probability F(q)F(q)) and saves τδ\tau\delta for each outcome above qq (probability 1−F(q)1 - F(q)). The net change is δ [F(q)(1−τ)−(1−F(q))τ]=δ [F(q)−τ]\delta\,[F(q)(1 - \tau) - (1 - F(q))\tau] = \delta\,[F(q) - \tau].

    Proof.

    1. Split the expectation at qq: L(q)=τ∫q∞(y−q) dF(y)+(1−τ)∫−∞q(q−y) dF(y)L(q) = \tau\int_q^\infty (y - q)\,dF(y) + (1 - \tau)\int_{-\infty}^q (q - y)\,dF(y).
    2. Differentiate with respect to qq. The integrands are 0 at y=qy = q, so only the derivative of the integrands counts: L′(q)=−τ (1−F(q))+(1−τ) F(q)=F(q)−τL'(q) = -\tau\,(1 - F(q)) + (1 - \tau)\,F(q) = F(q) - \tau.
    3. FF is non-decreasing, so L′L' is non-decreasing and LL is convex.
    4. L′(q)<0L'(q) < 0 when F(q)<τF(q) < \tau and L′(q)>0L'(q) > 0 when F(q)>τF(q) > \tau. So LL decreases up to the τ\tau-quantile and increases after it: the minimum is where F(q)=τF(q) = \tau. ■\blacksquare

    The empirical version. For a sample y1,…,yny_1, \dots, y_n, the mean loss Ln(q)=1n∑iρτ(yi−q)L_n(q) = \frac1n\sum_i \rho_\tau(y_i - q) is piecewise linear with kinks at the data. Its slope is Fn(q)−τF_n(q) - \tau, where Fn(q)F_n(q) is the share of data ≤q\le q. If nτn\tau is not an integer, the unique minimiser is the ⌈nτ⌉\lceil n\tau\rceil-th smallest value (np.quantile(y, tau, method="inverted_cdf")). If nτn\tau is an integer, every qq between the nτn\tau-th and the (nτ+1)(n\tau + 1)-th smallest value is a minimiser.

    Quantile regression. Replace the constant qq by a model q^τ(x)\hat q_\tau(x) and minimise the mean pinball loss over the training data. This is quantile regression (Koenker and Bassett, 1978). The theorem, applied for each xx, says that the best model outputs the conditional τ\tau-quantile of yy given xx. It works with any model:

    • linear: sklearn.linear_model.QuantileRegressor(quantile=0.9) (a linear program);
    • gradient boosting: HistGradientBoostingRegressor(loss="quantile", quantile=0.9) on the lag features of lesson 08; LightGBM has objective="quantile";
    • neural networks: a multi-quantile head outputs q^τ1,…,q^τK\hat q_{\tau_1}, \dots, \hat q_{\tau_K} together and is trained with ∑kρτk\sum_k \rho_{\tau_k} (MQ-RNN, the Temporal Fusion Transformer, Chronos-Bolt; lesson 09).

    Quantile crossing. Models trained separately for each τ\tau can give q^0.9(x)<q^0.8(x)\hat q_{0.9}(x) < \hat q_{0.8}(x) for some xx. This is impossible for a real distribution. Simple fixes: sort the predicted quantiles at each xx (this never increases the total pinball loss; Chernozhukov, Fernández-Val and Galichon, 2010), or predict q^τ1\hat q_{\tau_1} and positive increments q^τk+1−q^τk=softplus⁡(⋅)\hat q_{\tau_{k+1}} - \hat q_{\tau_k} = \operatorname{softplus}(\cdot).

    The stocking decision (newsvendor problem). Order qq units. Each unsold unit costs coc_o and each missing unit costs cuc_u. The cost is cu(y−q)c_u(y - q) if y>qy > q and co(q−y)c_o(q - y) if y<qy < q. This is (cu+co) ρτ(y−q)(c_u + c_o)\,\rho_\tau(y - q) with τ=cu/(cu+co)\tau = c_u/(c_u + c_o). By the theorem, the best order is the quantile at the critical ratio τ=cu/(cu+co)\tau = c_u/(c_u + c_o). With cu=9c_u = 9 and co=1c_o = 1: τ=0.9\tau = 0.9. This answers question 1 of section 1: order the 90 % quantile of demand, not the mean or the median.

    Quick check

    A model is trained with the pinball loss at τ=0.9\tau = 0.9 on a large data set. What does its output estimate?

    3.3 Calibration, sharpness and the PIT #

    Definition. A sequence of forecasts FtF_t for outcomes yty_t is probabilistically calibrated if the PIT values ut=Ft(yt)u_t = F_t(y_t) are uniform on [0,1][0, 1]. Equivalently, for every level τ\tau, the share of outcomes below Ft−1(τ)F_t^{-1}(\tau) is τ\tau; so every central (1−α)(1 - \alpha) interval covers 1−α1 - \alpha of the outcomes.

    Theorem (the PIT of the true distribution is uniform). If YY has a continuous CDF FF, then F(Y)F(Y) is uniform on [0,1][0, 1].

    Proof. For u∈(0,1)u \in (0, 1), let xu=F−1(u)x_u = F^{-1}(u); continuity gives F(xu)=uF(x_u) = u. Then P(F(Y)≤u)=P(Y≤xu)=F(xu)=uP(F(Y) \le u) = P(Y \le x_u) = F(x_u) = u, which is the CDF of the uniform distribution. ■\blacksquare

    So a forecaster that knows the true conditional distribution produces a flat PIT histogram. How to read a histogram that is not flat:

    PIT histogram Coverage of central intervals Diagnosis
    flat as nominal calibrated
    U-shaped below nominal too narrow (under-dispersed, over-confident)
    hump in the middle above nominal too wide (over-dispersed)
    sloped (mass near 0) lower tail too often forecasts too high (bias)
    sloped (mass near 1) upper tail too often forecasts too low (bias)

    Calibration is necessary but not sufficient. The climatological forecast (always the long-run distribution) is calibrated, because the outcomes really come from that distribution on average. But it uses no information, so it is not useful. Sharpness is a property of the forecasts alone: the width of their intervals (or the spread of FtF_t). The paradigm of Gneiting, Balabdaoui and Raftery (2007) is: maximise sharpness subject to calibration. This answers question 2 of section 1: both forecasts are calibrated, but forecast B is sharper (if it uses real information) and therefore better. A proper scoring rule such as the CRPS (next section) sees the difference.

    Discrete outcomes and a flat PIT that hides problems

    For counts, FtF_t jumps, and Ft(yt)F_t(y_t) is not uniform even for the true distribution. Use the randomised PIT ut=Ft(yt−1)+Vt [Ft(yt)−Ft(yt−1)]u_t = F_t(y_t - 1) + V_t\,[F_t(y_t) - F_t(y_t - 1)] with VtV_t uniform on [0,1][0, 1], or the non-randomised version of Czado, Gneiting and Held (2009). Also note that a flat histogram over all times can hide errors that cancel: too narrow in winter and too wide in summer gives a flat total histogram (Hamill, 2001). Check the PIT in subgroups (season, horizon, level of the series) as well.

    3.4 Proper scoring rules and the CRPS #

    A scoring rule S(F,y)S(F, y) gives a number (lower is better here) to a forecast FF when yy happens. It is proper if, when yy really comes from GG, the expected score EY∼G S(F,Y)\mathbb E_{Y \sim G}\, S(F, Y) is smallest at F=GF = G; strictly proper if F=GF = G is the only minimiser. A proper score cannot be gamed: the best strategy is to report what you really believe. Coverage alone is not a score of this kind: an interval of infinite width always has perfect coverage.

    Definition. The continuous ranked probability score is

    CRPS⁡(F,y)=∫−∞∞(F(x)−1{x≥y})2 dx.\operatorname{CRPS}(F, y) = \int_{-\infty}^{\infty} \big(F(x) - \mathbf 1\{x \ge y\}\big)^2\,dx .

    It compares the forecast CDF with the "CDF" of the outcome, a step from 0 to 1 at yy. It is in the units of yy, and it is strictly proper for distributions with a finite mean (Gneiting and Raftery, 2007).

    Interactive figure: loading…

    Move μ\mu, σ\sigma and yy, or pick a preset. The orange curve is the forecast CDF, the blue step is the outcome. The lower panel shows the squared gap; its magenta area is the CRPS. The readouts give the area, the closed form and the kernel form: they agree. Notice: sharp and wrong costs about ∣y−μ∣|y - \mu|, and as σ→0\sigma \to 0 the CRPS becomes the absolute error of a point forecast. Wide is never far wrong but still pays for its width.

    Three equivalent forms. For FF with a finite mean:

    (1) Integral (threshold) form: the definition above.

    (2) Kernel form (Gneiting and Raftery, 2007): with X,X′X, X' independent draws from FF,

    CRPS⁡(F,y)=E∣X−y∣−12 E∣X−X′∣.\operatorname{CRPS}(F, y) = \mathbb E|X - y| - \tfrac12\,\mathbb E|X - X'| .

    The first term rewards forecasts close to yy; the second term rewards spread, so a forecast does not gain by collapsing to a point. For an ensemble or a set of sample paths x1,…,xMx_1, \dots, x_M, replace the expectations by means over the members.

    (3) Quantile form: the CRPS is twice the pinball loss, averaged over all levels:

    CRPS⁡(F,y)=2∫01ρτ(y−F−1(τ)) dτ.\operatorname{CRPS}(F, y) = 2\int_0^1 \rho_\tau\big(y - F^{-1}(\tau)\big)\,d\tau .
    Proof of the quantile form

    Assume FF is continuous and strictly increasing, so F−1(τ)>x  ⟺  τ>F(x)F^{-1}(\tau) > x \iff \tau > F(x).

    1. For a fixed qq, ρτ(y−q)=∫yq(1{x≥y}−τ) dx\rho_\tau(y - q) = \int_y^q \big(\mathbf 1\{x \ge y\} - \tau\big)\,dx. Check: if q>yq > y the integrand is 1−τ1 - \tau and the integral is (1−τ)(q−y)(1 - \tau)(q - y); if q<yq < y the integral is −∫qy(0−τ) dx=τ(y−q)-\int_q^y (0 - \tau)\,dx = \tau(y - q). Both agree with the definition.
    2. Put q=F−1(τ)q = F^{-1}(\tau) and integrate over τ\tau: 2∫01ρτ(y−F−1(τ)) dτ=2∫01∫yF−1(τ)(1{x≥y}−τ) dx dτ2\int_0^1 \rho_\tau(y - F^{-1}(\tau))\,d\tau = 2\int_0^1 \int_y^{F^{-1}(\tau)} (\mathbf 1\{x \ge y\} - \tau)\,dx\,d\tau.
    3. Swap the order of integration (Fubini). For x>yx > y, the point xx lies between yy and F−1(τ)F^{-1}(\tau) exactly when τ>F(x)\tau > F(x); it contributes ∫F(x)1(1−τ) dτ=12(1−F(x))2\int_{F(x)}^1 (1 - \tau)\,d\tau = \tfrac12 (1 - F(x))^2.
    4. For x<yx < y, the point xx lies between F−1(τ)F^{-1}(\tau) and yy exactly when τ<F(x)\tau < F(x); the integral runs from right to left, so it contributes −∫0F(x)(0−τ) dτ=12F(x)2-\int_0^{F(x)} (0 - \tau)\,d\tau = \tfrac12 F(x)^2.
    5. Multiply by 2 and add: ∫x<yF(x)2 dx+∫x>y(1−F(x))2 dx\int_{x < y} F(x)^2\,dx + \int_{x > y} (1 - F(x))^2\,dx. This is the integral of (F(x)−1{x≥y})2(F(x) - \mathbf 1\{x \ge y\})^2: the CRPS. ■\blacksquare

    Two special cases.

    • Point forecast. If FF is a step at y^\hat y, then (F(x)−1{x≥y})2=1(F(x) - \mathbf 1\{x \ge y\})^2 = 1 between y^\hat y and yy and 0 elsewhere, so CRPS⁡=∣y−y^∣\operatorname{CRPS} = |y - \hat y|. The CRPS generalises the absolute error, and you can compare a probabilistic forecast with a point forecast on the same scale.
    • Gaussian forecast F=N(μ,σ2)F = \mathcal N(\mu, \sigma^2), with z=(y−μ)/σz = (y - \mu)/\sigma, Φ\Phi the standard normal CDF and φ\varphi its density (Gneiting et al., 2005):
    CRPS⁡(N(μ,σ2),y)=σ[z(2Φ(z)−1)+2φ(z)−1π].\operatorname{CRPS}(\mathcal N(\mu, \sigma^2), y) = \sigma\Big[z\big(2\Phi(z) - 1\big) + 2\varphi(z) - \tfrac{1}{\sqrt\pi}\Big].

    Even a perfect mean (z=0z = 0) gives σ(2φ(0)−1/π)≈0.234 σ\sigma(2\varphi(0) - 1/\sqrt\pi) \approx 0.234\,\sigma: the price of the uncertainty.

    In practice: a finite set of quantiles. Many models output only KK quantiles. The quantile form suggests the approximation CRPS⁡≈2K∑kρτk(y−q^τk)\operatorname{CRPS} \approx \frac{2}{K}\sum_k \rho_{\tau_k}(y - \hat q_{\tau_k}) for evenly spaced levels. Summed over a test set and divided by ∑t∣yt∣\sum_t |y_t|, this is the weighted quantile loss (WQL) used, for example, with τ=0.1,0.2,…,0.9\tau = 0.1, 0.2, \dots, 0.9 to evaluate Chronos (Ansari et al., 2024) and in the GIFT-Eval benchmark (Aksu et al., 2024). Epidemic forecast hubs use the closely related weighted interval score (Bracher et al., 2021).

    Quick check

    A point forecast says y^=5\hat y = 5, and the outcome is y=7y = 7. What is the CRPS of this forecast?

    3.5 Split conformal prediction #

    The intervals so far come from a model. If the model is wrong, the coverage is wrong. Conformal prediction builds intervals around any point forecaster from its errors on held-out data, with a coverage guarantee that does not need a correct model (Vovk, Gammerman and Shafer, 2005; Angelopoulos and Bates, 2021).

    Split conformal for regression. You have a fitted point forecaster y^\hat y and a calibration set of nn new pairs that were not used to fit it.

    1. Compute the nonconformity scores si=∣yi−y^i∣s_i = |y_i - \hat y_i|, i=1,…,ni = 1, \dots, n.
    2. Set k=⌈(n+1)(1−α)⌉k = \lceil (n + 1)(1 - \alpha)\rceil. If k≤nk \le n, let q^\hat q be the kk-th smallest score; if k>nk > n, set q^=∞\hat q = \infty.
    3. For a new case, report the interval [y^−q^, y^+q^][\hat y - \hat q,\ \hat y + \hat q].

    Exchangeability. Random variables Z1,…,Zn+1Z_1, \dots, Z_{n+1} are exchangeable if their joint distribution does not change when you permute them. I.i.d. data are exchangeable; a time series with autocorrelation or a trend is not.

    Theorem (split conformal coverage). If the calibration scores and the test score s1,…,sn,sn+1s_1, \dots, s_n, s_{n+1} are exchangeable, then

    P(yn+1∈[y^n+1−q^, y^n+1+q^])≥1−α.P\big(y_{n+1} \in [\hat y_{n+1} - \hat q,\ \hat y_{n+1} + \hat q]\big) \ge 1 - \alpha .

    If the scores have no ties (for example, continuous data), the coverage is also below 1−α+1n+11 - \alpha + \frac{1}{n+1}.

    Proof.

    1. yn+1y_{n+1} is in the interval exactly when sn+1≤q^s_{n+1} \le \hat q.
    2. Assume no ties. Let RR be the rank of sn+1s_{n+1} among all n+1n + 1 scores (1 = smallest). By exchangeability, every rank from 1 to n+1n + 1 has the same probability 1n+1\frac{1}{n+1}.
    3. sn+1≤q^s_{n+1} \le \hat q (the kk-th smallest calibration score) means that fewer than kk calibration scores are below sn+1s_{n+1}, that is R≤kR \le k.
    4. So the coverage is P(R≤k)=kn+1P(R \le k) = \frac{k}{n+1}. Since k≥(n+1)(1−α)k \ge (n + 1)(1 - \alpha), this is ≥1−α\ge 1 - \alpha; since k<(n+1)(1−α)+1k < (n + 1)(1 - \alpha) + 1, it is <1−α+1n+1< 1 - \alpha + \frac{1}{n+1}.
    5. With ties, sn+1≤q^s_{n+1} \le \hat q also holds in some cases with R>kR > k, so the coverage can only grow. ■\blacksquare

    Answer to question 3 of section 1. With n=19n = 19 and α=0.1\alpha = 0.1: k=⌈20⋅0.9⌉=18k = \lceil 20 \cdot 0.9\rceil = 18. Use the 18th smallest error. The coverage is exactly 18/20=90 %18/20 = 90\,\% for continuous exchangeable data. The 17th would give only 17/20=85 %17/20 = 85\,\%.

    Interactive figure: loading…

    Move α\alpha and nn, then switch the noise. The blue series is the "monthly demand" series; the orange line is a least-squares forecast (trend and one yearly sine wave) fitted on t=1,…,40t = 1, \dots, 40 (left of the dashed line). The scores come from the aqua calibration window just before the yellow origin; the band is y^±q^\hat y \pm \hat q on the 40 test months. Magenta points fall outside. With constant noise the test coverage stays near the guarantee (press New noise to see it vary). With jumps after t = 80, the calibration errors no longer look like the test errors, and the coverage collapses. For small nn and small α\alpha, k>nk > n and the band is infinite.

    What the guarantee says, and what it does not.

    • It is marginal: an average over calibration sets and test cases. A single calibration set gives a coverage that varies around 1−α1 - \alpha (the variation shrinks like 1/n1/\sqrt n).
    • It is not conditional: a 90 % interval can cover 99 % in summer and 70 % in winter and still be 90 % on average. With a constant width, the interval is too wide where the noise is small and too narrow where it is large.
    • Conformalized quantile regression (CQR; Romano, Patterson and Candès, 2019) gives intervals whose width changes with xx. Fit quantile models q^α/2(x)\hat q_{\alpha/2}(x) and q^1−α/2(x)\hat q_{1-\alpha/2}(x); use the scores si=max⁡{q^α/2(xi)−yi, yi−q^1−α/2(xi)}s_i = \max\{\hat q_{\alpha/2}(x_i) - y_i,\ y_i - \hat q_{1-\alpha/2}(x_i)\}; report [q^α/2(x)−q^, q^1−α/2(x)+q^][\hat q_{\alpha/2}(x) - \hat q,\ \hat q_{1-\alpha/2}(x) + \hat q]. The same theorem gives coverage ≥1−α\ge 1 - \alpha.
    • The calibration set must not be used to fit the model. Training residuals are too small, and the intervals then under-cover.

    Why time series break exchangeability. Calibration errors come from the past and the test error from the future. (1) Errors are autocorrelated: a run of large errors in the calibration window makes all of them similar, so the window is effectively smaller than nn. (2) The series drifts: the level, the noise or the model quality change, as in the widget. (3) Errors at horizon hh are larger than at horizon 1, so scores must come from the same horizon. The theorem then gives no guarantee, though the method often still works reasonably when the changes are slow.

    Quick check

    You have n=99n = 99 calibration scores and want a split conformal interval with α=0.1\alpha = 0.1. Which score do you use as the half-width?

    3.6 Conformal methods for time series #

    Practical recipe. Run a rolling-origin backtest (lesson 03). For each horizon hh, keep the absolute hh-step errors of the last nn origins as the calibration scores, and recompute q^h\hat q_h at each new origin. The window follows slow changes; the guarantee is only approximate.

    Adaptive conformal inference (ACI; Gibbs and Candès, 2021) adds feedback. It keeps a working level αt\alpha_t and changes it after each outcome:

    1. Build the interval C^t(αt)\hat C_t(\alpha_t) with the conformal recipe at level αt\alpha_t (for example, the ⌈(n+1)(1−αt)⌉\lceil (n + 1)(1 - \alpha_t)\rceil-th smallest of the last nn scores). If αt≤0\alpha_t \le 0, the interval is the whole line; if αt≥1\alpha_t \ge 1, it is empty.
    2. Observe yty_t and set errt=1\mathrm{err}_t = 1 if yt∉C^t(αt)y_t \notin \hat C_t(\alpha_t), else 0.
    3. Update the level with a step size γ>0\gamma > 0:
    αt+1=αt+γ (α−errt).\alpha_{t+1} = \alpha_t + \gamma\,(\alpha - \mathrm{err}_t).

    After a miss, αt\alpha_t drops by γ(1−α)\gamma(1 - \alpha) and the next interval is wider; after a hit, αt\alpha_t rises by γα\gamma\alpha and the next interval is a little narrower.

    Theorem (long-run coverage of ACI; Gibbs and Candès, 2021). For any sequence of data (no assumption at all) and α1∈[0,1]\alpha_1 \in [0, 1],

    ∣1T∑t=1Terrt−α∣≤max⁡(α1,1−α1)+γγ T.\Big|\frac1T\sum_{t=1}^T \mathrm{err}_t - \alpha\Big| \le \frac{\max(\alpha_1, 1 - \alpha_1) + \gamma}{\gamma\,T} .

    Proof.

    1. αt\alpha_t stays in [−γ,1+γ][-\gamma, 1 + \gamma]. One step changes αt\alpha_t by at most γ\gamma. If αt<0\alpha_t < 0, the interval is the whole line, so errt=0\mathrm{err}_t = 0 and αt\alpha_t increases. If αt>1\alpha_t > 1, the interval is empty, so errt=1\mathrm{err}_t = 1 and αt\alpha_t decreases. So αt\alpha_t can leave [0,1][0, 1] by at most one step.
    2. Telescoping. Summing the update over t=1,…,Tt = 1, \dots, T gives αT+1−α1=γ∑t=1T(α−errt)\alpha_{T+1} - \alpha_1 = \gamma\sum_{t=1}^T(\alpha - \mathrm{err}_t).
    3. Divide by γT\gamma T: ∣α−1T∑terrt∣=∣αT+1−α1∣γT\big|\alpha - \frac1T\sum_t \mathrm{err}_t\big| = \frac{|\alpha_{T+1} - \alpha_1|}{\gamma T}.
    4. By step 1, ∣αT+1−α1∣≤max⁡(α1+γ, 1+γ−α1)|\alpha_{T+1} - \alpha_1| \le \max(\alpha_1 + \gamma,\ 1 + \gamma - \alpha_1). ■\blacksquare
    Interactive figure: loading…

    Move γ\gamma, then change the scenario. The top panel shows 400 forecast errors after an initial calibration period of 100. The orange band is ACI on the last 100 scores; the dashed lines are static split conformal from the first 100 scores. At the yellow line the noise triples. The middle panel shows αt\alpha_t; the bottom panel shows the coverage over the last 50 steps. Notice: static conformal drops to about 35 % coverage and never recovers; ACI dips briefly and returns to 90 %. With γ=0\gamma = 0, ACI becomes split conformal on a rolling window and recovers only after the window has refilled.

    What ACI does not promise. The guarantee is about the long-run average of misses. It says nothing about coverage at a given time, in a given season, or conditional on anything. The interval can be infinite for a few steps (when αt<0\alpha_t < 0). A large γ\gamma reacts fast but makes the width jumpy; a small γ\gamma is smooth but slow. Later methods choose γ\gamma online or combine several values.

    Two related methods, in short.

    • EnbPI (Xu and Xie, 2021) fits an ensemble of models on bootstrap samples of the training data. The out-of-bag residuals are the scores, and the newest residuals replace the oldest ones as data arrive. It has an approximate guarantee when the errors are stationary and the model is consistent.
    • Conformal PID control (Angelopoulos, Candès and Tibshirani, 2023) updates the quantile q^t\hat q_t directly, q^t+1=q^t+η(errt−α)\hat q_{t+1} = \hat q_t + \eta(\mathrm{err}_t - \alpha) (the "P" part, a quantile tracker), and adds an integral term and an optional forecast of the next score ("scorecaster"), as in a PID controller. It has the same kind of long-run guarantee.
    Quick check

    A conformal 90 % interval method covers 90 % of the outcomes over a whole year, but only 60 % in winter. Is its guarantee broken?

    3.7 Many horizons and sample paths #

    A forecast for each horizon is not enough for a question about several horizons. Let e1,e2e_1, e_2 be the errors of two days, each N(0,1)\mathcal N(0, 1) and independent. The 90 % quantile of each is 1.281.28. The 90 % quantile of the two-day total error is 1.282=1.811.28\sqrt 2 = 1.81, not 1.28+1.28=2.561.28 + 1.28 = 2.56. The quantile of a sum is not the sum of the quantiles; they agree only when the errors are perfectly correlated. With positive correlation, the truth is between the two numbers.

    So for weekly totals, maxima over a day, or "the first time the stock runs out", use sample paths: simulate many futures yt+1(i),…,yt+H(i)y^{(i)}_{t+1}, \dots, y^{(i)}_{t+H}, compute the quantity on each path, and take its empirical quantiles. Paths come from a model (simulate the future shocks of an ARIMA or ETS model, or resample past residuals: a bootstrap) or from a generative network such as DeepAR (lesson 09). Score them with the sample CRPS (kernel form) per horizon, or with a multivariate score such as the energy score.

    4. Worked example #

    (a) A quantile from the pinball loss. Data {2,4,5,7,12}\{2, 4, 5, 7, 12\}, τ=0.7\tau = 0.7. The mean pinball loss at q=7q = 7: the outcomes 2, 4, 5 are below qq and cost (1−0.7)(7−y)(1 - 0.7)(7 - y); the outcome 12 is above and costs 0.7⋅50.7 \cdot 5:

    L(7)=15[0.3⋅5+0.3⋅3+0.3⋅2+0+0.7⋅5]=15[1.5+0.9+0.6+3.5]=1.3.L(7) = \tfrac15\big[0.3 \cdot 5 + 0.3 \cdot 3 + 0.3 \cdot 2 + 0 + 0.7 \cdot 5\big] = \tfrac15[1.5 + 0.9 + 0.6 + 3.5] = 1.3 .

    In the same way L(5)=15[0.9+0.3+0+1.4+4.9]=1.5L(5) = \tfrac15[0.9 + 0.3 + 0 + 1.4 + 4.9] = 1.5 and L(12)=15[3+2.4+2.1+1.5+0]=1.8L(12) = \tfrac15[3 + 2.4 + 2.1 + 1.5 + 0] = 1.8. The slope just left of 7 is Fn=3/5=0.6F_n = 3/5 = 0.6 minus 0.70.7, negative; just right of 7 it is 4/5−0.7=0.14/5 - 0.7 = 0.1, positive. So q=7q = 7 is the minimiser. It is the 4th smallest value, since ⌈5⋅0.7⌉=4\lceil 5 \cdot 0.7\rceil = 4.

    (b) The CRPS three ways. Forecast N(0.3,1.52)\mathcal N(0.3, 1.5^2), outcome y=1y = 1. Then z=0.7/1.5=0.466667z = 0.7/1.5 = 0.466667, Φ(z)=0.679631\Phi(z) = 0.679631, φ(z)=0.357783\varphi(z) = 0.357783 and 1/π=0.5641901/\sqrt\pi = 0.564190. The three terms in the bracket are z(2Φ(z)−1)=0.466667⋅0.359262=0.167655z(2\Phi(z) - 1) = 0.466667 \cdot 0.359262 = 0.167655, 2φ(z)=0.7155672\varphi(z) = 0.715567 and −0.564190-0.564190:

    CRPS⁡=1.5 [0.167655+0.715567−0.564190]=1.5⋅0.319032=0.478549≈0.4785.\begin{aligned} \operatorname{CRPS} &= 1.5\,\big[0.167655 + 0.715567 - 0.564190\big] \\ &= 1.5 \cdot 0.319032 = 0.478549 \approx 0.4785 . \end{aligned}

    The kernel form gives E∣X−y∣−12E∣X−X′∣=1.324833−1.5/π=1.324833−0.846284=0.478549\mathbb E|X - y| - \frac12\mathbb E|X - X'| = 1.324833 - 1.5/\sqrt\pi = 1.324833 - 0.846284 = 0.478549, and the integral of 2ρτ2\rho_\tau over τ\tau gives 0.47850.4785 too (section 5 checks all three). For comparison, the absolute error of the median forecast is ∣1−0.3∣=0.7|1 - 0.3| = 0.7: the spread of the forecast lowers the score because the outcome was close to the centre.

    (c) A split conformal interval. The absolute errors of 9 calibration months are 0.4,1.1,0.7,2.3,0.2,1.6,0.9,3.0,1.30.4, 1.1, 0.7, 2.3, 0.2, 1.6, 0.9, 3.0, 1.3. For α=0.2\alpha = 0.2:

    1. k=⌈(9+1)(1−0.2)⌉=⌈8⌉=8k = \lceil (9 + 1)(1 - 0.2)\rceil = \lceil 8 \rceil = 8.
    2. Sorted: 0.2,0.4,0.7,0.9,1.1,1.3,1.6,2.3,3.00.2, 0.4, 0.7, 0.9, 1.1, 1.3, 1.6, 2.3, 3.0. The 8th smallest is q^=2.3\hat q = 2.3.
    3. If the next point forecast is y^=50\hat y = 50, the 80 % interval is [47.7, 52.3][47.7,\ 52.3].
    4. For exchangeable data the coverage is exactly 8/10=80 %8/10 = 80\,\%.

    (d) Two steps of ACI. α=0.1\alpha = 0.1, γ=0.05\gamma = 0.05, αt=0.1\alpha_t = 0.1.

    • The outcome falls outside: errt=1\mathrm{err}_t = 1, so αt+1=0.1+0.05(0.1−1)=0.055\alpha_{t+1} = 0.1 + 0.05(0.1 - 1) = 0.055. The next interval uses the ⌈(n+1)⋅0.945⌉\lceil (n + 1) \cdot 0.945\rceil-th score: it is wider.
    • Had it fallen inside: αt+1=0.1+0.05⋅0.1=0.105\alpha_{t+1} = 0.1 + 0.05 \cdot 0.1 = 0.105, slightly narrower.

    Nine hits move αt\alpha_t up by 9⋅0.005=0.0459 \cdot 0.005 = 0.045, and one miss moves it down by 0.0450.045: at a miss rate of exactly 10 %, αt\alpha_t stays where it is.

    5. In code #

    NumPy and SciPy check the worked example; the notebook adds quantile gradient boosting and ACI.

    import numpy as np
    from scipy.stats import norm
    
    def pinball(y, q, tau):
        u = y - q
        return np.maximum(tau * u, (tau - 1) * u)
    
    # (a) the empirical minimiser of the mean pinball loss is a sample quantile
    y = np.array([2., 4., 5., 7., 12.])
    grid = np.linspace(0, 14, 1401)
    L = [pinball(y, q, 0.7).mean() for q in grid]
    print(grid[np.argmin(L)], np.quantile(y, 0.7, method="inverted_cdf"))   # 7.0 7.0
    
    # (b) CRPS of N(0.3, 1.5^2) at y = 1, three ways
    mu, s, yo = 0.3, 1.5, 1.0
    z = (yo - mu) / s
    closed = s * (z * (2 * norm.cdf(z) - 1) + 2 * norm.pdf(z) - 1 / np.sqrt(np.pi))
    x = np.linspace(-15, 15, 300001)
    integral = np.trapezoid((norm.cdf(x, mu, s) - (x >= yo)) ** 2, x)
    taus = (np.arange(10000) + 0.5) / 10000
    quant = 2 * pinball(yo, norm.ppf(taus, mu, s), taus).mean()
    print(round(closed, 4), round(integral, 4), round(quant, 4))   # 0.4785 0.4785 0.4785
    
    # (c) split conformal half-width
    res = np.array([0.4, 1.1, 0.7, 2.3, 0.2, 1.6, 0.9, 3.0, 1.3])
    n, alpha = len(res), 0.2
    k = int(np.ceil((n + 1) * (1 - alpha)))
    print(k, np.sort(res)[k - 1])                                  # 8 2.3
    
    # (d) its coverage over many exchangeable data sets is k/(n+1) = 0.8
    rng = np.random.default_rng(0)
    scores = np.abs(rng.normal(size=(200000, n + 1)))   # n calibration scores + 1 test score
    qhat = np.sort(scores[:, :n], axis=1)[:, k - 1]
    print(round(np.mean(scores[:, n] <= qhat), 3))      # 0.801, close to k/(n+1) = 0.8
    

    np.trapezoid needs NumPy 2.0 or newer (older versions call it np.trapz).

    6. Where it shows up #

    • Retail and supply chains. Stock levels are quantiles at the critical ratio. The M5 uncertainty competition (Makridakis et al., 2022) asked for nine quantiles of Walmart sales and scored them with a weighted scaled pinball loss. Many of the top teams used gradient-boosted trees (LightGBM) on lag features (lesson 08) with quantile losses.
    • Energy. Load, wind and solar forecasts are quantile forecasts; the GEFCom2014 competition scored 99 quantiles with the pinball loss. Reserves and trading bids are set from upper quantiles.
    • Weather and climate (ML for science). Ensemble forecasts are evaluated with the CRPS and with rank or PIT histograms. GenCast (Price et al., 2024), a diffusion model for global weather, reports the ensemble CRPS against the ECMWF ensemble.
    • Epidemiology. The US COVID-19 Forecast Hub collected 23 quantiles per forecast and scored them with the weighted interval score, a quantile approximation of the CRPS (Bracher et al., 2021).
    • Foundation models. Chronos, Chronos-Bolt, TimesFM and Moirai give quantiles or samples (lesson 09). Check their coverage on your own data with a backtest, and wrap them with conformal intervals if it is wrong.
    • Software. Conformal intervals for forecasts exist in common libraries (for example MAPIE, and the conformal intervals of Nixtla's statsforecast and mlforecast). Read what the calibration set is: the guarantee depends on it.

    7. Common mistakes #

    • Judging intervals by coverage only. A very wide interval always covers. Report coverage and width, or use a proper score (CRPS, pinball loss, interval score).
    • Trusting model intervals without a backtest. ARIMA and ETS intervals assume a correct model; check their empirical coverage over many origins.
    • Adding quantiles over horizons. The 90 % quantile of a weekly total is not the sum of the daily 90 % quantiles. Use sample paths.
    • Calibrating on training residuals. In-sample errors are too small, so the interval is too narrow. The calibration data must be new to the model.
    • Shuffling time series before conformal calibration. Random splits mix future and past (leakage) and hide the drift. Calibrate on the most recent past and test on the future.
    • Using np.quantile(scores, 1 - alpha) instead of the ⌈(n+1)(1−α)⌉\lceil (n + 1)(1 - \alpha)\rceil-th smallest score. The difference is small for large nn, but the guarantee needs the n+1n + 1.
    • Ignoring quantile crossing. Sort the predicted quantiles, or use a monotone parametrisation.
    • Confusing the two meanings of α\alpha. In this lesson α\alpha is the miscoverage, not the smoothing parameter.

    8. Check yourself #

    1. Show that the pinball loss at τ=0.5\tau = 0.5 is half the absolute error, and say which constant forecast minimises its mean.
      AnswerFor u≥0u \ge 0, ρ0.5(u)=0.5u\rho_{0.5}(u) = 0.5u; for u<0u < 0, ρ0.5(u)=−0.5u\rho_{0.5}(u) = -0.5u. So ρ0.5(u)=∣u∣/2\rho_{0.5}(u) = |u|/2. The mean is minimised by the median (the 0.5-quantile), as for the absolute error.
    2. An unsold newspaper costs 0.2 and a missing one costs 0.6. Which quantile of demand should you stock?
      Answerτ=cu/(cu+co)=0.6/0.8=0.75\tau = c_u/(c_u + c_o) = 0.6/0.8 = 0.75: the 75 % quantile.
    3. The forecast is N(10,22)\mathcal N(10, 2^2) and the outcome is y=10y = 10. Compute the CRPS.
      Answerz=0z = 0, so CRPS⁡=2 [0+2φ(0)−1/π]=2 [0.7979−0.5642]=0.467\operatorname{CRPS} = 2\,[0 + 2\varphi(0) - 1/\sqrt\pi] = 2\,[0.7979 - 0.5642] = 0.467. Even a perfect mean has a positive CRPS, about 0.234 σ0.234\,\sigma.
    4. Why is a forecast that always gives the long-run distribution calibrated, and why is it still poor?
      AnswerThe outcomes really come from the long-run distribution on average, so the PIT values are uniform and every interval has the right coverage. But it uses no current information, so its intervals are as wide as possible. A proper score such as the CRPS rewards a forecast that is calibrated *and* sharp.
    5. You have n=9n = 9 calibration scores. What is the smallest α\alpha for which split conformal gives a finite interval?
      AnswerWe need k=⌈10(1−α)⌉≤9k = \lceil 10(1 - \alpha)\rceil \le 9, so 10(1−α)≤910(1 - \alpha) \le 9, that is α≥0.1\alpha \ge 0.1. For α<0.1\alpha < 0.1 the interval is infinite.
    6. In ACI with α=0.1\alpha = 0.1 and γ=0.01\gamma = 0.01, the method misses 5 times in a row. How much has αt\alpha_t changed?
      AnswerEach miss changes αt\alpha_t by γ(α−1)=−0.009\gamma(\alpha - 1) = -0.009, so five misses lower it by 0.0450.045: from 0.1 to 0.055. The intervals become wider.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Define the pinball loss ρτ(u)\rho_\tau(u) for the error u=y−qu = y - q.

    2. Which constant qq minimises the expected pinball loss E ρτ(Y−q)\mathbb E\,\rho_\tau(Y - q), and why?

    3. What is the best stock level when an unsold unit costs coc_o and a missing unit costs cuc_u?

    4. What is the PIT value of a forecast FtF_t, and what should its histogram look like?

    5. What does a U-shaped PIT histogram mean?

    6. What is the difference between calibration and sharpness?

    7. Give the definition and the kernel form of the CRPS.

    8. How is the CRPS related to the pinball loss?

    9. In split conformal with nn calibration scores and miscoverage α\alpha, which score is the half-width?

    10. Write the update rule of adaptive conformal inference.

    Open the review →

    9. Interview angle #

    • "How do you get prediction intervals from a gradient-boosting forecaster?" — Train two more models with the quantile loss (for example τ=0.05\tau = 0.05 and 0.950.95), sort the outputs to avoid crossing, and check the coverage in a rolling-origin backtest. Or keep the point model and add conformal intervals from recent backtest errors, one set of scores per horizon; use CQR to combine both.
    • "Why does the pinball loss give a quantile?" — Derivative F(q)−τF(q) - \tau: a step up costs 1−τ1 - \tau for the outcomes below and saves τ\tau for those above; the balance point has a share τ\tau below.
    • "How would you evaluate a probabilistic forecast?" — Calibration (coverage of several intervals, PIT histogram, also per subgroup) and a proper score (CRPS or the mean pinball loss over quantiles, scaled across series); compare with a seasonal naive forecast with bootstrapped intervals.
    • "What does conformal prediction guarantee, and what breaks it for time series?" — Marginal coverage ≥1−α\ge 1 - \alpha under exchangeability; dependence and drift break it; ACI restores a long-run average guarantee for any sequence, but not coverage at each time.

    10. Practice #

    The notebook for this lesson runs in Colab or in the browser. It has five exercises, each with a check cell and a folded solution:

    1. Write pinball(y, q, tau) and check that its empirical minimiser over a grid is the sample quantile.
    2. Write crps_gaussian(mu, sigma, y) and compare it with the sample kernel form and with twice the mean pinball loss over a grid of levels.
    3. Train HistGradientBoostingRegressor(loss="quantile") on lag features for τ=0.1,0.5,0.9\tau = 0.1, 0.5, 0.9 and measure the coverage of the 80 % interval on a test period.
    4. Write split_conformal(cal_scores, alpha) and check its coverage over 2000 simulated exchangeable data sets (between 1−α1 - \alpha and 1−α+1/(n+1)1 - \alpha + 1/(n + 1)).
    5. Write adaptive_conformal(scores, alpha, gamma) and compare its coverage after a variance jump with static split conformal.

    11. Watch and read #

    A hands-on tour of conformal prediction that follows the Angelopoulos and Bates paper in the reading list.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The quantile loss as a formula and as a graph, and a proof that it gives the quantile.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Conformal prediction intervals for time-series forecasts in Python, including data that are not stationary.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Advanced and optional; mathematical properties of the CRPS as a training and evaluation score.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play