Uncertainty quantification (tsbootstrap.uq)
The uncertainty-quantification surface is also re-exported at the top level, so
from tsbootstrap import EnbPIEnsemble works alongside from tsbootstrap.uq
import EnbPIEnsemble. scikit-learn (the uq extra) is imported lazily inside
the out-of-bag path, so importing these names on a core-only install is safe; it
is required only when an EnbPI ensemble is fitted.
Note
forecast_intervals() currently supports the
AR model only and raises
MethodConfigError for ARIMA or VAR. Out-of-sample
forecast intervals for ARIMA and VAR are tracked on the roadmap.
Uncertainty quantification built on the bootstrap.
Two task-appropriate paths (see the v0.2.0 design notes):
In-sample / out-of-sample regression,
EnbPIEnsembleis a MAPIE-style fit/predict object: it bootstraps the row indices, fits a clone of the estimator per resample, records the out-of-bag ensemble residuals (Xu & Xie 2021), and retains the fitted clones so intervals can be produced for newX. The half-width comes from a chosen calibrator over the residual buffer,static_halfwidths()(global quantile),sliding_window_halfwidths()(time-local EnbPI), or the drift-adaptiveaci_halfwidths()/nexcp_quantile().enbpi_intervals()andfit_predict_oob()are thin wrappers for the simple in-sample, static-width path.Forecasting,
forecast_intervals()simulates the fitted model forward and takes empirical path quantiles over the horizon.
These carry honest, assumption-appropriate coverage claims: approximate / asymptotic under temporal dependence, not finite-sample distribution-free.
- class tsbootstrap.uq.EnbPIEnsemble[source]
Bases:
objectFit/predict EnbPI ensemble: retain the bootstrap clones, calibrate on demand.
fitbootstraps the row indices with an observation-resampling method, fits a clone ofestimatoron each in-bag resample, and computes the out-of-bag ensemble prediction per row (the mean over the replicates in which the row was held out) and the out-of-bag absolute residuals|y - oob_pred|. The residuals are the raw calibration scores, decoupled from any particular calibrator.predict_intervalthen centers an interval at the out-of-bag prediction (in sample) or the retained-clone ensemble mean (out of sample) and applies the chosen calibrator to the residual buffer to get the half-width. Coverage is approximately1 - alphaunder a strong-mixing condition (Xu & Xie 2021), not finite-sample distribution-free.- fit(estimator: _SklearnLike, X: object, y: object, *, method: BaseMethodSpec, n_bootstraps: int = 100, random_state: int | Generator | SeedSequence | None = None, store_estimators: bool = True) EnbPIEnsemble[source]
Fit the bootstrap ensemble and record the out-of-bag calibration scores.
- Parameters:
estimator (object) – An unfitted, order-invariant sklearn-style regressor; cloned per replicate.
X (array-like) – Design matrix
(n, d)(1-D is treated as(n, 1)) and targets(n,).y (array-like) – Design matrix
(n, d)(1-D is treated as(n, 1)) and targets(n,).method (object) – An observation-resampling method (IID or a block method). Recursive model methods are rejected with
MethodConfigError.n_bootstraps (int) – Number of bootstrap replicates.
random_state (object) – Seed or generator forwarded to the bootstrap.
store_estimators (bool) – Retain the fitted clones on the instance (default
True). Required for out-of-samplepredict_interval(); setFalseto save memory when only in-sample intervals are needed.
- property oob_residuals: ndarray[tuple[int, ...], dtype[float64]]
The out-of-bag absolute residuals (calibration scores), in time order.
Raw and decoupled from calibration: every calibrator reads from this buffer.
- property oob_prediction: ndarray[tuple[int, ...], dtype[float64]]
The in-sample out-of-bag ensemble prediction, one per training row.
- predict_interval(X_new: object | None = None, *, alpha: float = 0.1, calibrator: Annotated[Static | SlidingWindow | ACI | NexCP | AgACI, FieldInfo(annotation=NoneType, required=True, discriminator='kind')] = Static(kind='static'), test_data: object | None = None) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Prediction interval
(lower, upper, point)for the chosen calibrator spec.- Parameters:
X_new (array-like, optional) – New design matrix. If
None(default), returns in-sample intervals centered at the out-of-bag prediction. Otherwise the point prediction is the mean of the retained clones’ predictions onX_new(requires the ensemble to have been fitted withstore_estimators=True).alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.calibrator (CalibratorSpec) –
A frozen calibrator spec from
tsbootstrap.uq.calibratorsthat decides how the residual buffer becomes interval endpoints. Every option lives on the spec, so a misspelled option fails at spec construction rather than being silently ignored:Static, one global1 - alphaquantile for every row (the default).SlidingWindow, rolling1 - alphaquantile (time-local EnbPI);windowdefaults tomin(len, 50).ACI, Adaptive Conformal Inference; needstest_data(the time-ordered realized|y_t - prediction_t|, one per row).NexCP, recency-weighted quantile.AgACI, Aggregated Adaptive Conformal Inference (Zaffran et al. 2022): asymmetric bounds. Needstest_data(the time-ordered SIGNED, finitey_t - prediction_t, one per row).
test_data (array-like, optional) – The realized runtime observation a drift-adaptive calibrator needs: the ACI scores or the AgACI signed residuals. Left
Nonefor the calibrators that read only the residual buffer (Static,SlidingWindow,NexCP). It is a runtime argument, not a spec field, because it is data rather than configuration.
- Returns:
(lower, upper, point), each shape(n_rows,).- Return type:
tuple of ndarray
- tsbootstrap.uq.fit_predict_oob(estimator: _SklearnLike, X: object, y: object, *, method: BaseMethodSpec, n_bootstraps: int = 100, random_state: int | Generator | SeedSequence | None = None) ndarray[tuple[int, ...], dtype[float64]][source]
Out-of-bag ensemble predictions, one per row.
Each in-bag resample fits a clone of
estimator; the held-out rows are predicted and averaged per row over the replicates in which the row was out-of-bag. Rows never held out getnan.A thin convenience wrapper over
EnbPIEnsemble; use the class directly when you also need calibrated intervals or out-of-sample prediction.
- tsbootstrap.uq.enbpi_intervals(estimator: _SklearnLike, X: object, y: object, *, method: BaseMethodSpec, alpha: float = 0.1, n_bootstraps: int = 100, random_state: int | Generator | SeedSequence | None = None) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
EnbPI prediction intervals:
(lower, upper, oob_prediction).The interval is centered at the out-of-bag ensemble prediction with half-width the
1 - alphaquantile of the out-of-bag absolute residuals. Coverage is approximately1 - alphaunder a strong-mixing condition (Xu & Xie 2021), not finite-sample distribution-free.A thin convenience wrapper for the simple in-sample, static-width path; equivalent to
EnbPIEnsemble().fit(...).predict_interval(calibrator=Static()). For time-local widths, out-of-sample prediction, or the adaptive calibrators, useEnbPIEnsembledirectly.
- tsbootstrap.uq.forecast_intervals(X: object, *, model: object, horizon: int, alpha: float = 0.1, n_bootstraps: int = 999, random_state: int | Generator | SeedSequence | None = None) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Bootstrap forecast intervals:
(lower, upper, median), each(horizon,).The fitted model is simulated
horizonsteps past the datan_bootstrapstimes with resampled, centered innovations; the per-step quantiles form the interval.
- tsbootstrap.uq.aci_halfwidths(calibration_scores: object, test_scores: object, *, alpha: float = 0.1, gamma: float = 0.05) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Adaptive Conformal Inference: online-adapted interval half-widths.
- Parameters:
calibration_scores (array-like, shape (m,)) – Nonconformity scores (e.g.
|residual|) from the bootstrap calibration set.test_scores (array-like, shape (T,)) – Realized scores
|y_t - prediction_t|over the test sequence, in time order.alpha (float) – Target miscoverage (interval target coverage is
1 - alpha).gamma (float) – Adaptation step size.
gamma = 0recovers static conformal.
- Returns:
halfwidths (ndarray, shape (T,)) – Interval half-width
q_tto use at each step (prediction_t ± q_t).alphas (ndarray, shape (T,)) – The adapted miscoverage level used at each step.
The update is
alpha_{t+1} = alpha_t + gamma * (alpha - err_t)with``err_t = 1`` when step ``t`` is miscovered (a miss shrinks the level and widens the)
next interval. Coverage converges to
1 - alpharegardless of how the scores drift.
- tsbootstrap.uq.nexcp_quantile(scores: object, *, alpha: float = 0.1, decay: float = 0.99) float[source]
Recency-weighted (nonexchangeable) conformal quantile of the scores.
Weights score
i(0 = oldest, last = most recent) bydecay ** (n - 1 - i)and returns the smallest score whose normalized weighted CDF reaches1 - alpha. Withdecay = 1this is the ordinary empirical quantile; smallerdecayputs more weight on recent residuals, widening the interval when recent volatility rises.
- tsbootstrap.uq.agaci_bounds(calibration_scores: object, test_residuals: object, *, alpha: float = 0.1, gammas: Sequence[float] | ndarray[tuple[int, ...], dtype[float64]] | None = None, boa_regret_constant: float = 2.2, infinite_sentinel: float | None = None, require_signed: bool = True) AgACIBounds[source]
Aggregated Adaptive Conformal Inference (AgACI): asymmetric adaptive half-widths.
Run a grid of ACI experts (one
aci_halfwidths()pass per step sizegamma) and aggregate their lower and upper interval endpoints with two independent Bernstein Online Aggregations under the pinball loss attau = alpha / 2andtau = 1 - alpha / 2. The online weights track whichever step size is currently best in pinball loss, so no singlegammahas to be chosen and, unlike a large-gammaACI expert, the aggregated interval is always finite. Section 3 of Zaffran et al. (2022) constructs AgACI exactly this way: the per-gamma ACI experts are symmetric over the absolute residuals, and the asymmetry of the final bounds comes entirely from the two independent BOA aggregations, not from the experts.- Parameters:
calibration_scores (array-like, shape (m,)) – The absolute out-of-bag residual buffer (e.g.
EnbPIEnsemble.oob_residuals). Same role and coercion asaci_halfwidths()’calibration_scores.test_residuals (array-like, shape (T,)) – The SIGNED realized residuals
s_t = y_t - prediction_t, time-ordered. This deliberately diverges fromaci_halfwidths()(which takes absolute scores): AgACI’s two-sided pinball gradient needs the sign of each miss to load it onto the lower versus the upper bound. Must be finite;Tis driven entirely by its length. The per-expert ACI pass is driven byabs(test_residuals)internally.alpha (float) – Target miscoverage. Split into
tau_lower = alpha / 2andtau_upper = 1 - alpha / 2. Must be in(0, 1).gammas (array-like or None) – The ACI step-size grid; each entry is one ACI expert (
K = len(gammas)). All entries must be finite and non-negative.NoneselectsDEFAULT_AGACI_GAMMAS(the K=30 grid of Zaffran et al.).boa_regret_constant (float) –
opera’s fixed Bernstein constant in the BOA learning-rate accumulation. Must be positive; exposed for faithfulness and pinning.infinite_sentinel (float or None) – Finite clip for
+infexpert half-widths (emitted when a large-gammaexpert drives its level below 0, i.e. “cover everything”).Noneselects a deterministic, data-adaptive defaultmin(10.0 * range_ref, 1e150)whererange_refis the larger of the finite expert half-widths andmax(abs(test_residuals))(falling back to1.0only for genuinely all-zero data). It scales linearly with the inputs, soagaci_boundsis scale-equivariant and the cover-everything expert stays the WIDEST at any data magnitude (a fixed floor would break that); the1e150cap is only an overflow guard for the squared-regret accumulator and is far beyond any real data. This default is deliberately not bit-comparable toopera’s fixed +/-1000.require_signed (bool) – When
True(default),test_residualswith zero strictly-negative entries on a stream of length >= 8 raisesValueError: an all-non-negative stream is the near-certain signature of a caller passing absolute scores by ACI habit, which makes the lower-bound indicator constant and biases that bound with no error. SetFalsefor genuinely one-sided residual data.
- Returns:
Named tuple
(lower, upper), each shape(T,), float64, non-negative, and finite. The interval at steptis[prediction_t - lower[t], prediction_t + upper[t]]. BOTH fields are load-bearing, unlikeaci_halfwidths()’ diagnostic second element.- Return type:
Notes
Coverage: AgACI carries a regret/efficiency guarantee (via BOA it is asymptotically no worse in pinball loss than the best fixed-
gammaexpert in the grid, withO(sqrt(T log K))regret) but NO finite-T or asymptotic coverage certificate: aggregating the two endpoints breaks the bounded-level-excursion argument that gives single ACI its long-run coverage guarantee. Empirically it keeps marginal coverage close to1 - alphawhile producing shorter, always-finite intervals. Do not read this as a guarantee of1 - alphacoverage.Interval crossing is structurally impossible: every lower expert offset
-q_k <= 0and every upper offset+q_k >= 0, and a convex BOA combination preserves the sign, solowerandupperare both non-negative and the interval never crosses.A deliberate fidelity divergence from the R source: when
alpha_t >= 1an ACI expert returnsq = 0(a finite confident expert) where the R source emits the absolute empty interval(0, 0); here that feeds BOA as a finite expert, not the+infsentinel path. Non-bit-comparable tooperain that rare regime.References
Zaffran, M., Feron, O., Goude, Y., Josse, J., and Dieuleveut, A. (2022). Adaptive Conformal Predictions for Time Series. Proceedings of the 39th International Conference on Machine Learning (ICML), PMLR 162, pp. 25834-25866.
Wintenberger, O. (2017). Optimal learning with Bernstein Online Aggregation. Machine Learning 106(1), pp. 119-141.
Gibbs, I. and Candes, E. (2021). Adaptive Conformal Inference Under Distribution Shift. Advances in Neural Information Processing Systems 34.
- class tsbootstrap.uq.AgACIBounds(lower: NDArray[np.float64], upper: NDArray[np.float64])[source]
Bases:
NamedTupleThe two load-bearing asymmetric half-widths AgACI produces per step.
Unlike
aci_halfwidths(), whose second return element is a discardable diagnostic, BOTH fields here are load-bearing: the interval at steptis[prediction_t - lower[t], prediction_t + upper[t]]. Destructuring away either field (hw, _ = agaci_bounds(...)) is a bug, not an idiom.
- tsbootstrap.uq.static_halfwidths(residuals: ndarray[tuple[int, ...], dtype[float64]], n_rows: int, *, alpha: float = 0.1) ndarray[tuple[int, ...], dtype[float64]][source]
Constant half-width: the global
1 - alphaquantile, broadcast ton_rows.- Parameters:
residuals (ndarray, shape (m,)) – Time-ordered out-of-bag absolute residuals (the calibration scores).
n_rows (int) – Number of prediction rows to emit a width for.
alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.
- Returns:
The same scalar
1 - alphaquantile repeated for every row.- Return type:
ndarray, shape (n_rows,)
- tsbootstrap.uq.sliding_window_halfwidths(residuals: ndarray[tuple[int, ...], dtype[float64]], n_rows: int, *, alpha: float = 0.1, window: int | None = None) ndarray[tuple[int, ...], dtype[float64]][source]
Time-local half-widths: a rolling
1 - alphaquantile of the residuals.For row
tthe width is the1 - alphaquantile of the most recentwindowresiduals ending att(the trailing window shrinks at the start of the series, where fewer residuals are available). The width therefore widens in high-volatility stretches and tightens in calm ones, which is the defining time-local mechanism of EnbPI (Xu & Xie 2021) and the static calibrator’s missing piece.- Parameters:
residuals (ndarray, shape (m,)) – Time-ordered out-of-bag absolute residuals (the calibration scores).
n_rows (int) – Number of prediction rows to emit a width for. Each row
tuses the window of residuals ending atmin(t, m - 1), so out-of-sample rows beyond the calibration set reuse the final trailing window.alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.window (int, optional) – Trailing window length. Defaults to
min(len(residuals), 50).
- Returns:
Per-row half-width; non-constant whenever local volatility varies.
- Return type:
ndarray, shape (n_rows,)
- class tsbootstrap.uq.BaseCalibratorSpec[source]
Bases:
BaseModelOpen base for every calibrator spec: immutable, hashable, strict about options.
Third-party calibrators subclass this, declare a unique
kindLiteral, and register a function withregister_calibrator();predict_interval()then dispatches to them exactly like a built-in. Runtime safety comes from the registry, which raises for an unregistered spec.- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tsbootstrap.uq.Static(*, kind: Literal['static'] = 'static')[source]
Bases:
BaseCalibratorSpecOne global
1 - alphaquantile, the same half-width for every row (original EnbPI).- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tsbootstrap.uq.SlidingWindow(*, kind: Literal['sliding_window'] = 'sliding_window', window: Annotated[int | None, Ge(ge=1)] = None)[source]
Bases:
BaseCalibratorSpecRolling
1 - alphaquantile over a trailing window (time-local EnbPI, Xu and Xie 2021).- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tsbootstrap.uq.ACI(*, kind: Literal['aci'] = 'aci', gamma: float = 0.05)[source]
Bases:
BaseCalibratorSpecAdaptive Conformal Inference (Gibbs and Candes 2021): online-adapted quantile level.
Requires the realized test scores as
test_data;gammais the adaptation step size (gamma = 0recovers static conformal).- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tsbootstrap.uq.NexCP(*, kind: Literal['nexcp'] = 'nexcp', decay: float = 0.99)[source]
Bases:
BaseCalibratorSpecNonexchangeable conformal prediction (Barber et al. 2023): a recency-weighted quantile.
decayin(0, 1]weights recent residuals more heavily;decay = 1recovers the ordinary empirical quantile.- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class tsbootstrap.uq.AgACI(*, kind: Literal['agaci'] = 'agaci', gammas: tuple[float, ...] | None = None, require_signed: bool = True, boa_regret_constant: float = 2.2, infinite_sentinel: float | None = None)[source]
Bases:
BaseCalibratorSpecAggregated Adaptive Conformal Inference (Zaffran et al. 2022): asymmetric adaptive bounds.
Aggregates a grid of ACI experts with Bernstein Online Aggregation, so no single step size has to be chosen. Requires the SIGNED realized residuals as
test_data. The fields mirroragaci_bounds()one-to-one;gammas=Noneselects the K=30 grid of the paper.- model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- tsbootstrap.uq.percentile_interval(statistics: ndarray[tuple[int, ...], dtype[float64]], *, alpha: float = 0.05) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Percentile interval: the
alpha/2and1 - alpha/2replicate quantiles.- Parameters:
statistics (ndarray, shape (B,) or (B, k)) – Bootstrap replicate statistics, one row per replicate.
alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.
- Returns:
lower, upper – The two-sided percentile bounds (0-d arrays for a scalar statistic). The quantiles use numpy’s linear interpolation.
- Return type:
ndarray, shape
statistics.shape[1:]
- tsbootstrap.uq.basic_interval(statistics: ndarray[tuple[int, ...], dtype[float64]], theta_hat: ndarray[tuple[int, ...], dtype[float64]], *, alpha: float = 0.05) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Basic (reflected-percentile) interval around the point estimate.
The percentile interval is reflected through
theta_hat:lower = 2 * theta_hat - q_hiandupper = 2 * theta_hat - q_lo, whereq_loandq_hiare thealpha/2and1 - alpha/2replicate quantiles. This corrects the percentile interval’s bias when the replicate distribution is shifted relative totheta_hat.- Parameters:
statistics (ndarray, shape (B,) or (B, k)) – Bootstrap replicate statistics, one row per replicate.
theta_hat (ndarray, shape
statistics.shape[1:]) – The statistic evaluated on the original series.alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.
- Returns:
lower, upper – The two-sided basic-interval bounds.
- Return type:
ndarray, shape
statistics.shape[1:]
- tsbootstrap.uq.jackknife_statistics(x: ndarray[tuple[int, ...], dtype[float64]], statistic: Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object]) ndarray[tuple[int, ...], dtype[float64]][source]
Delete-one jackknife: the statistic recomputed on each leave-one-row-out sample.
- Parameters:
x (ndarray, shape (n,) or (n, d)) – The original observations, one row per observation.
statistic (callable
(values, indices) -> scalar | array) – The reducer to recompute on each leave-one-out sample. It is called withindices=None(the helper operates on a raw array with no resampling provenance), matching thebootstrap_reduce()contract.
- Returns:
The
nleave-one-out statistics stacked along axis 0.- Return type:
ndarray, shape
(n,)or(n, k)
- tsbootstrap.uq.block_jackknife_se(values: ndarray[tuple[int, ...], dtype[floating]], statistic: Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object], *, block_length: int, indices: ndarray[tuple[int, ...], dtype[int32]] | None = None) ndarray[tuple[int, ...], dtype[float64]][source]
Delete-a-group (block) jackknife standard error, Kunsch 1989.
The rows are split into
g = n // block_lengthnon-overlapping blocks; the statistic is recomputed with each block deleted, and the standard error issqrt((g - 1) / g * sum_j (theta_(j) - mean_j)^2). Deleting whole blocks rather than single rows keeps the estimate consistent under temporal dependence. Withblock_length=1this reduces exactly to the classic delete-one jackknife variance.- Parameters:
values (ndarray, shape (n,) or (n, d)) – The observations, one row per observation.
statistic (callable
(values, indices) -> scalar | array) – The reducer to recompute on each block-deleted sample.block_length (int) – Number of consecutive rows per deleted block.
indices (ndarray of int32, shape (n,), optional) – Original-observation indices to slice in lockstep with
values: when supplied, the same block of rows is removed fromindicesand passed tostatisticalongside the deleted-block values.None(the default) passesNoneto the reducer.
- Returns:
The block-jackknife standard error per statistic component.
- Return type:
ndarray, shape
()or(k,)
- tsbootstrap.uq.studentized_interval(statistics: ndarray[tuple[int, ...], dtype[float64]], se_statistics: ndarray[tuple[int, ...], dtype[float64]], theta_hat: ndarray[tuple[int, ...], dtype[float64]], se_hat: ndarray[tuple[int, ...], dtype[float64]], *, alpha: float = 0.05) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Studentized (bootstrap-t) interval from per-replicate standard errors.
Each replicate is pivoted to
t_b = (theta_b - theta_hat) / se_b; the interval inverts the pivot,lower = theta_hat - t_{1 - alpha/2} * se_hatandupper = theta_hat - t_{alpha/2} * se_hat. The pivot’s upper quantile therefore sets the lower bound (the minus sign flips the orientation), which is what makes the interval second-order correct for smooth statistics whense_bandse_hatare dependence-aware (e.g.block_jackknife_se()).- Parameters:
statistics (ndarray, shape (B,) or (B, k)) – Bootstrap replicate statistics.
se_statistics (ndarray, same shape as
statistics) – The per-replicate standard error of each statistic.theta_hat (ndarray, shape
statistics.shape[1:]) – The statistic on the original series.se_hat (ndarray, shape
statistics.shape[1:]) – The standard error oftheta_haton the original series.alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.
- Returns:
lower, upper – The two-sided studentized bounds.
- Return type:
ndarray, shape
statistics.shape[1:]- Raises:
ValueError – If any per-replicate or point standard error is zero (the pivot is undefined).
- tsbootstrap.uq.jackknife_acceleration(x: ndarray[tuple[int, ...], dtype[float64]], statistic: Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object]) ndarray[tuple[int, ...], dtype[float64]][source]
Efron’s BCa acceleration constant from the delete-one jackknife.
The acceleration is
a = sum(d_i^3) / (6 * (sum(d_i^2))^{3/2})withd_i = mean(theta_jack) - theta_(i)the centred leave-one-out statistics (Efron 1987). It measures the skewness of the statistic’s sampling distribution. Where the denominator is zero (a constant jackknife, e.g. a degenerate sample) the acceleration is defined as zero.- Parameters:
x (ndarray, shape (n,) or (n, d)) – The original observations, one row per observation.
statistic (callable
(values, indices) -> scalar | array) – The reducer whose acceleration is estimated.
- Returns:
The acceleration per statistic component.
- Return type:
ndarray, shape
()or(k,)
- tsbootstrap.uq.bca_interval(statistics: ndarray[tuple[int, ...], dtype[float64]], theta_hat: ndarray[tuple[int, ...], dtype[float64]], acceleration: ndarray[tuple[int, ...], dtype[float64]], *, alpha: float = 0.05) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Bias-corrected and accelerated (BCa) interval, Efron 1987.
The two endpoint probability levels are adjusted for median bias (the bias-correction
z0) and skewness (theacceleration) before reading the replicate quantiles.z0comes from the tie-adjusted fraction of replicates belowtheta_hat,p0 = (#{theta_b < theta_hat} + 0.5 * #{theta_b == theta_hat}) / B. Withz0 = 0andacceleration = 0the interval reduces exactly topercentile_interval().This function is method-agnostic pure math: it takes a precomputed
acceleration. The jackknife acceleration (jackknife_acceleration()) is defined under independent sampling, so restricting BCa to the IID method spec is an orchestrator-level concern, not enforced here.- Parameters:
statistics (ndarray, shape (B,) or (B, k)) – Bootstrap replicate statistics.
theta_hat (ndarray, shape
statistics.shape[1:]) – The statistic on the original series.acceleration (ndarray, shape
statistics.shape[1:]) – The precomputed acceleration constant per component.alpha (float) – Target miscoverage; the interval target coverage is
1 - alpha.
- Returns:
lower, upper – The two-sided BCa bounds.
- Return type:
ndarray, shape
statistics.shape[1:]- Raises:
ValueError – If the bias-correction fraction
p0is 0 or 1 for any component (z0is infinite, so BCa is degenerate).
- tsbootstrap.uq.conf_int(X: object, statistic: str | tuple[str, float] | Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object], *, method: BaseMethodSpec, kind: Literal['percentile', 'basic', 'studentized', 'bca'] = 'percentile', alpha: float = 0.05, n_bootstraps: int = 999, random_state: int | Generator | SeedSequence | None = None, backend: Literal['numpy', 'compiled'] = 'numpy', se_statistic: Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object] | None = None, se_block_length: int | None = None) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Bootstrap confidence interval for a statistic of one series, in one call.
Runs a single
bootstrap_reduce()pass withmethodand reads the requested interval from the replicate statistics. To reuse an existing run instead, call the interval functions directly on itsstatisticsarray (e.g.percentile_interval(result.statistics)).- Parameters:
X (array-like, shape (n,) or (n, d)) – The observed series (any input
bootstrap()accepts).statistic (str, (“quantile”, q) tuple, or callable
(values, indices) -> theta) – The statistic to bootstrap. Built-in names ("mean","var","std") are required forbackend="compiled".method (BaseMethodSpec) – Any method spec. BCa additionally requires
IID(see below).kind ({"percentile", "basic", "studentized", "bca"}) – The interval family.
studentizedcomputes a dependence-aware per-replicate standard error viablock_jackknife_se()(orse_statistic);bcais available for theIIDspec only, because its jackknife acceleration is defined under independent sampling (Efron 1987; for dependent data usestudentized, the second-order-correct route of Gotze and Kunsch 1996).alpha (float) – Target miscoverage; the interval targets
1 - alphacoverage.n_bootstraps (int) – Number of bootstrap replicates.
random_state (int, Generator, SeedSequence, or None) – Seeding, with the library’s per-replicate determinism contract.
backend ({"numpy", "compiled"}) –
"compiled"acceleratespercentile/basicwith a built-in string statistic;studentized/bcaneed Python callables per replicate and raise a typed error under the compiled backend.se_statistic (callable, optional) – Override for the per-replicate standard-error estimator (studentized only).
se_block_length (int, optional) – Override for the block-jackknife block length (studentized only).
- Returns:
lower, upper, point – Interval bounds and the statistic on the original series, each shaped like one replicate’s statistic (0-d for a scalar statistic).
- Return type:
ndarray
- tsbootstrap.uq.conf_int_panel(panel: object, statistic: str | tuple[str, float] | Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object], *, method: BaseMethodSpec, indptr: object | None = None, kind: Literal['percentile', 'basic', 'studentized'] = 'percentile', alpha: float = 0.05, n_bootstraps: int = 999, random_state: int | Generator | SeedSequence | None = None, backend: Literal['numpy', 'compiled'] = 'numpy', se_statistic: Callable[[ndarray[tuple[int, ...], dtype[floating]], ndarray[tuple[int, ...], dtype[int32]] | None], object] | None = None, se_block_length: int | None = None) tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]]][source]
Per-series bootstrap confidence intervals over a ragged panel, in one pass.
The panel counterpart of
conf_int(), built onbootstrap_reduce_panel()(observation-resampling methods only, matching that function’s contract). Returns arrays with a leadingnum_seriesaxis.BCa is not offered for panels: it is gated to IID data at the single-series level and a per-series jackknife acceleration sweep is deliberately out of scope. The studentized kind requires an explicit block length (either
se_block_lengthor an integer block length on the method spec): replicate reducers see one series at a time without its identity, so a per-series automatic block length cannot be resolved honestly, and one Politis-White fit on a mixed panel would be statistically arbitrary.