Prediction Semantics¶
This page defines the prediction-time terms used by predict,
PredictConfig, bivariate copulas, and vine copulas.
Three Different Questions¶
The library separates three questions that are easy to mix up:
- Predictive sampling asks what the next copula observation may look like after fitting on historical data.
- Conditional sampling fixes some components of that next observation, for example \(U_2 = 0.7\), and samples the remaining components.
- Dynamic conditioning optionally updates time-varying edge states using fixed prediction-time values before the remaining components are sampled.
In notation, after training data \(D_T = \{u_1, \ldots, u_T\}\), plain prediction draws from
Conditional prediction with given={j: a} draws from
where \(G\) is the set of fixed variables.
Dynamic conditioning changes the state used to form the copula parameters:
for supported dynamic edges. This is off by default.
The mathematical difference between filtered point states, posterior latent states, and one-step predictive latent states is summarized in Mathematical Contracts.
predict vs sample¶
Sampling names have the same meaning across model types:
pyscarcopula.api.sample(copula, data, result, n)reproduces a fitted bivariate or multivariate model;- fitted bivariate, multivariate, C-vine, and R-vine objects expose the same
operation as
model.sample(n, u=None, rng=None); - models with a scalar dependence parameter expose low-level generation as
model.sample_at_parameter(n, r, rng=None).
For stochastic fitted models, reproduction simulates a new latent or score-driven path.
predict(n, u=training_data) on a fitted object generates forecast
observations conditional on the supplied history. Omitting u uses the
history stored by the last fit. The top-level equivalent is
pyscarcopula.api.predict(copula, data, result, n). For MLE this uses the same
constant-parameter copula. Dynamic strategies such as GAS and SCAR-TM use
their fitted time-varying state.
Most sampling APIs accept rng=np.random.default_rng(seed). Use a fresh
generator with the same seed for exact reproducibility; reusing a generator
object advances its stream.
horizon¶
horizon selects which dynamic state is used before prediction:
horizon='current'uses the filtered or posterior state at the end of the observed sample, conceptually time \(T\).horizon='next'uses the one-step-ahead predictive state, conceptually time \(T+1\).
For SCAR-TM, current means the posterior latent state after the observed
sample, for example \(p(x_T \mid D_T)\) in the OU model or
\(p(\tau_T \mid D_T)\) in the Jacobi model. next means the corresponding
one-step-ahead state, such as \(p(x_{T+1} \mid D_T)\) or
\(p(\tau_{T+1} \mid D_T)\). For GAS, current uses the last filtered score state
and next applies the one-step score recursion. For MLE there is no dynamic
state, so the two horizons are equivalent.
The default is horizon='next', because predict is primarily a forecasting
API.
predictive_r_mode¶
predictive_r_mode controls how SCAR-TM predictive parameter samples are
drawn for APIs that need simulated edge parameters. Supported values are
None, 'grid', and 'histogram'. None uses the strategy default. Other
string values are rejected.
given¶
given is a predict-time conditioning value in pseudo-observation space:
samples = model.predict(
n=10_000,
u=u_train,
given={2: 0.7},
rng=np.random.default_rng(2026),
)
Keys are zero-based variable indices. Values must be in \((0, 1)\). The returned sample keeps fixed columns equal to the supplied values and samples the remaining columns from the fitted conditional copula.
For bivariate copulas, given can fix variable 0, variable 1, or both.
Static multivariate GaussianCopula and StudentCopula models provide exact
conditional generation through both sample_conditional(n, given, rng=...)
and predict(n, given=..., rng=...). Dynamic multivariate models apply their
fitted or predictive parameter path before sampling the free coordinates.
For every multivariate model, fixing all variables returns constant rows equal
to the supplied values.
For generic VineCopula models, including fixed C-vine, fixed D-vine, and
auto-selected R-vine structures, predict uses two paths:
- suffix exact path: used when the fixed variables can be placed at the end of the R-vine variable order, either directly or after rebuilding an equivalent natural-order matrix;
- approximate fallback path: used for arbitrary non-suffix conditioning patterns.
The suffix path is exact and fast. The arbitrary path is general but approximate and more expensive.
If given fixes every variable, prediction returns constant rows equal to the
supplied values.
given_vars¶
given_vars is a fit-time structure-selection hint for VineCopula.fit:
from pyscarcopula import VineCopula
vine = VineCopula().fit(
u_train,
method="scar-tm-ou",
given_vars=[0, 2],
)
It does not supply conditioning values. It says: "when building the R-vine, prefer structures that make this set easy to condition on exactly."
With conditional_strict=True, fit rejects a structure that cannot support
the target set through the exact suffix sampler. With
conditional_strict=False, fit can retain an unsupported structure, but
predict still raises ValueError for that unsupported fit-time target.
To allow approximate conditioning for that set, fit without given_vars and
pass the set only to predict(given=...). Other conditioning sets follow the
ordinary suffix or approximate routing.
Use given_vars when the conditioning indices are known before fitting and
the exact suffix path is required. Use given to supply their values when
calling predict.
dynamic_conditioning¶
dynamic_conditioning controls whether fixed prediction-time values update
dynamic edge states before sampling.
dynamic_conditioning='ignore'is the default. Edge parameters are predicted from \(D_T\) only, then conditional sampling treatsgivenas fixed values in the copula recursion.dynamic_conditioning='given_only'lets supported fixed observations update strategy-owned predictive states before downstream edge parameters are sampled.
This is intentionally separate from ordinary conditional sampling. Conditional sampling changes which variables are drawn. Dynamic conditioning changes the parameter state used by dynamic edges.
For R-vines, dynamic conditioning is applied on the suffix exact path, where fixed pseudo-observations can be propagated in a deterministic order through the vine. Diagnostics report which edges were updated and which were skipped.
For stateful observation-driven edges, given_only is intentionally strict:
updates are applied only with horizon='current'. With horizon='next', the
predictive state has already been advanced one step, so another
prediction-time update would advance the state again rather than condition the
same forecast state. Those edges are skipped with reason
next_horizon_would_advance_filter.
PredictConfig¶
Prediction options can be passed as explicit kwargs or as a PredictConfig:
import numpy as np
from pyscarcopula import PredictConfig
cfg = PredictConfig(
given={2: 0.7},
horizon="next",
dynamic_conditioning="given_only",
mcmc_steps=300,
mcmc_burnin=100,
return_diagnostics=True,
)
samples, diagnostics = vine.predict(
10_000,
u=u_train,
predict_config=cfg,
rng=np.random.default_rng(2027),
)
Explicit kwargs override the corresponding fields in PredictConfig, so
call-site options and reusable configuration objects can be mixed deliberately.
mcmc_steps and mcmc_burnin apply only when VineCopula.predict
automatically selects the approximate DAG+MCMC fallback. They control the
number of refinement updates and discarded burn-in updates. They do not affect
exact suffix sampling. conditional_method is an output diagnostics field,
not an argument accepted by predict.
Diagnostics¶
For VineCopula.predict(..., return_diagnostics=True), the result is
(samples, diagnostics).
The conditional_method field reports unconditional, suffix, or
dag_mcmc. The complete diagnostics schema, MCMC acceptance fields, and
dynamic-conditioning skip reasons are documented in
R-vine Conditioning.