mixle.stats.combinator.copula module¶
Copula combinator: glue arbitrary marginal distributions to a dependence structure (Sklar’s theorem).
GaussianCopulaDistribution (mixle.stats.multivariate) models only dependence, on the unit cube
(0,1)^d – it assumes its inputs are already the uniform scores u_i. This combinator is the piece
that makes copulas composable: give it your marginals (any mixle leaves exposing cdf – a Gamma, a
StudentT, a VonMises, mixed freely) and a copula core, and it forms the joint
f(x_1, …, x_d) = c(F_1(x_1), …, F_d(x_d)) * prod_i f_i(x_i) (Sklar)
where each F_i = marginals[i].cdf is the probability-integral transform (PIT) and c is the copula
density. That is the whole point of copulas: pick any marginals you like and couple them through one
dependence object, instead of hand-writing a bespoke multivariate leaf for every marginal combination.
Estimation is IFM (Inference Functions for Margins): fit each marginal on its own column, PIT the data through the fitted marginals, then fit the copula on the uniform scores. This is exact in a single M-step (the accumulator buffers the raw columns, the same pattern the neural leaves use), not an approximate coupled iteration.
The copula core is pluggable: any distribution on (0,1)^d implementing the mixle five-piece contract
works. GaussianCopulaDistribution is the first supported
core; Clayton/Frank/t cores can be dropped in later with no change here.
Reference: Nelsen, An Introduction to Copulas (2nd ed., Springer, 2006); Joe, Dependence Modeling with Copulas (CRC, 2014).
- class CopulaDistribution(marginals, copula, name=None, keys=None)[source]
Bases:
SequenceEncodableProbabilityDistributionJoint over
dscalar fields =dmarginals coupled by a copula core (Sklar’s theorem).marginalsis a length-dsequence of mixle leaves, each exposinglog_density,cdf, asampler()withsample(), and the estimator/encoder contract.copulais a distribution on(0,1)^d(e.g.GaussianCopulaDistribution). An observation is a length-dtuple/array of scalars(x_1, ..., x_d).- Parameters:
- density(x)[source]
Return the joint density at one raw observation.
- log_density(x)[source]
Sklar’s decomposition: sum of marginal log-densities + the copula log-density at the PIT scores.
- seq_log_density(enc)[source]
Vectorized: per-column marginal log-densities (summed) plus the copula log-density at the PIT scores.
- sampler(seed=None)[source]
Return a sampler that draws copula scores and inverts the marginals.
- Parameters:
seed (int | None)
- Return type:
CopulaSampler
- estimator(pseudo_count=None)[source]
Return an IFM estimator for marginals followed by the copula core.
- Parameters:
pseudo_count (float | None)
- Return type:
CopulaEstimator
- dist_to_encoder()[source]
Return an encoder that preserves marginal encodings and raw columns.
- Return type:
CopulaDataEncoder
- class CopulaSampler(dist, seed=None)[source]
Bases:
DistributionSamplerSample by drawing uniform scores from the copula, then inverting each marginal by its quantile.
Requires each marginal’s sampler to expose
quantileOR the marginal itself to exposeppf/quantile; falls back to inverse-CDF root finding oncdfwhen neither is present, so anycdf-bearing marginal is sampleable.- Parameters:
dist (CopulaDistribution)
seed (int | None)
- class CopulaDataEncoder(marginal_encoders)[source]
Bases:
DataSequenceEncoderEncode a batch as
(per-marginal encodings, raw (n, d) column array).The raw columns ride along because the copula’s uniform scores
u = F(x)depend on the marginals’ current parameters (they change during fitting), so they cannot be baked in at encode time – they are recomputed byCopulaDistribution._pit_columns()against whatever distribution is scoring/estimating.- Parameters:
marginal_encoders (Sequence[DataSequenceEncoder])
- class CopulaAccumulator(marginal_accumulators, dim, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorDelegate per-column sufficient stats to marginal sub-accumulators; buffer raw columns for the copula.
The copula stage is fit AFTER the marginals (IFM): it needs the marginals’ fitted CDFs to PIT the data, so the raw columns are buffered (weighted) here and PIT-ed inside
CopulaEstimator.estimate(). This is the same buffer-the-rows pattern the neural leaves use, and it makes the IFM fit exact in one M-step.- update(x, weight, estimate)[source]
Update marginal accumulators and buffer one raw observation for IFM copula fitting.
- initialize(x, weight, rng)[source]
Initialize marginal accumulators and buffer one raw observation.
- Parameters:
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(enc, weights, estimate)[source]
Update marginal accumulators and buffer encoded raw columns for IFM.
- seq_initialize(enc, weights, rng)[source]
Initialize marginal accumulators and buffer encoded raw columns.
- Parameters:
enc (Any)
weights (ndarray)
rng (RandomState | None)
- Return type:
None
- combine(suff_stat)[source]
Merge marginal sufficient statistics and buffered raw columns.
- value()[source]
Return marginal stats, buffered raw columns, and buffered weights.
- from_value(x)[source]
Restore marginal stats and raw-column buffers from
valueoutput.
- key_merge(stats_dict)[source]
Delegate keyed merges to marginal accumulators.
- key_replace(stats_dict)[source]
Delegate keyed replacements to marginal accumulators.
- acc_to_encoder()[source]
Return an encoder composed from the marginal accumulator encoders.
- Return type:
CopulaDataEncoder
- class CopulaAccumulatorFactory(marginal_factories, dim, keys=None)[source]
Bases:
StatisticAccumulatorFactoryCreate accumulators for IFM copula estimation.
- make()[source]
Create an empty copula accumulator.
- Return type:
CopulaAccumulator
- class CopulaEstimator(marginal_estimators, copula_estimator, dim, name=None, keys=None)[source]
Bases:
ParameterEstimatorIFM estimator: fit each marginal from its sub-stats, PIT the buffered data, fit the copula on the scores.
- Parameters:
- accumulator_factory()[source]
Return a factory for IFM copula sufficient-statistic accumulators.
- Return type:
CopulaAccumulatorFactory
- estimate(nobs, suff_stat)[source]
Estimate marginals, transform buffered data by PIT, and estimate the copula core.
- copula_estimator_prototype()[source]
A copula instance usable for PIT-encoding before the copula is refit – the estimator’s own default.
- Return type:
SequenceEncodableProbabilityDistribution