mixle.stats.combinator.optional module¶
Optional distributions for explicit missing-value mass.
This distribution assigns a probability (p) to data being missing. With probability (1-p) the data is assumed to come from a base distribution set by the user.
The OptionalDistribution allows for potentially missing data. The value p (the probability of being missing) must be specified to sample from the distribution.
The two modes, and why only one of them is a law. p is optional, and leaving it out does not
mean “p is zero” – it selects a different object:
pgiven – a normalized mixture: masspon the sentinel, the base family scaled by1-peverywhere else. It integrates to one,density_semantics()reportsEXACT, and it samples.p is None– the missing outcome is MARGINALIZED, i.e.log_density(sentinel)is0.0and the base density is passed through unscaled. This is a likelihood FACTOR conditioned on an externally modeled missingness mechanism, not a law: its total mass is 1 (the base) + 1 (the sentinel scored at probability one) = 2, sentinel rows cost exactly zero nats, anddensity_semantics()reportsLIKELIHOOD_FACTORto say so. It cannot be sampled (NonGenerativeOptionalError).
Two consequences worth knowing before choosing. First, .p reads 0.0 in the marginalized mode
– has_p is the attribute that distinguishes “no rate was ever fitted” from “the rate was fitted
and came out zero”, and repr prints p=None for the former. Second, the free sentinel rows
mean a marginalized model cannot be compared on likelihood against a proper one over the same data:
it wins by construction, by -log(p) nats per sentinel row, and the paired comparison helpers in
mixle.inference (vuong_test, clarke_test, compare_elpd) take plain score arrays and
so cannot see the flag that would have warned them. Auto-inference accordingly fits the rate for
every sentinel it introduces (see mixle.utils.automatic.DatumNode.get_estimator()); the
marginalized mode is for callers who ask for it deliberately.
- exception NonGenerativeOptionalError[source]
Bases:
TypeErrorRaised when a marginalized optional likelihood factor is used to generate data.
- class OptionalDistribution(dist, p=None, missing_value=None, name=None, prior=None)[source]
Bases:
SequenceEncodableProbabilityDistributionMixture-style wrapper that models missing observations explicitly.
- Parameters:
- compute_capabilities()[source]
Return compute capabilities inherited from the observed-data distribution.
- set_prior(prior)[source]
Distribute the joint prior
(p_prior, dist_prior)to the missing probability and base dist.prior=Noneis a no-op (point model, existing behavior byte-identical). Otherwise the first element is a conjugate Beta prior onp(caching the digamma expectations used byexpected_log_density) and the second is pushed to the base distribution’sset_prior.
- expected_log_density(x)[source]
Posterior-expected log-density
E_q[log p(x)]atx.With a conjugate Beta prior on
pthe expectation overpis available in closed form via digamma terms (missing =>da - dab; observed =>db - dab + dist.expected_log_density(x)); otherwise this falls back to the plug-inlog_density.- Parameters:
x (T)
- Return type:
- seq_expected_log_density(x)[source]
Vectorized posterior-expected log-density; falls back to
seq_log_densitywithout a prior.
- compute_declaration()[source]
Return a structured declaration for the optional missingness wrapper.
- density(x)[source]
Evaluate the density of the Optional distribution at x.
See log_density() for details.
- Parameters:
x (T) – Observation from base dist or missing value.
- Returns:
Density at x.
- Return type:
- density_semantics()[source]
Return child semantics for a proper gate or likelihood-factor semantics for MAR.
- property marginalized_core
Return the wrapped law when this is a pure marginalization, else None.
Without a missingness rate this distribution is a likelihood factor: it contributes 1 where the value is absent rather than a normalized density over values-plus-missing. That makes it non-generative, but only because
pwas not supplied – the wrapped law is untouched, and givingpmakes the whole thing generative again. Callers that need to tell “unnormalized because we are marginalizing over missingness” apart from “intrinsically cannot generate” (a scoring-only leaf) read this: the former returns its core, the latter has no such attribute.
- log_density(x)[source]
Evalute the log density of the Optional distribution at x.
If x is a missing value: return log(p) if p is not None, else return 0.0 If x is not the missing_value: if p is not None, return the log_denisty(x) at base dist + log(1-p) else: return log_density(x).
- Parameters:
x (T) – Observation from base dist or missing value.
- Returns:
Log-density at x.
- Return type:
- seq_log_density(x)[source]
Return vectorized log-density values for sequence-encoded observations.
- backend_seq_log_density(x, engine)[source]
Engine-neutral vectorized log-density for optional encoded data.
- gradient_fit_state(engine, torch, leaves, recurse, tensor_param)[source]
Return distribution-owned state for autograd fitting.
- classmethod backend_stacked_params(dists, engine)[source]
Return stacked optional-wrapper parameters for homogeneous mixture kernels.
- classmethod backend_stacked_log_density(x, params, engine)[source]
Return an
(n, k)matrix of optional-wrapper log densities.
- classmethod backend_stacked_sufficient_statistics_with_estimator(x, weights, params, engine, estimator)[source]
Return per-component legacy optional-wrapper sufficient statistics.
- to_fisher(**kwargs)[source]
Fisher view for the optional/missing-gate.
- sampler(seed=None)[source]
Return a sampler for drawing observations from this distribution.
- Parameters:
seed (int | None)
- Return type:
OptionalSampler
- estimator(pseudo_count=None)[source]
Return an estimator for fitting this distribution from data.
- Parameters:
pseudo_count (float | None)
- Return type:
OptionalEstimator
- dist_to_encoder()[source]
Return the data encoder used by this distribution for vectorized methods.
- Return type:
OptionalDataEncoder
- enumerator()[source]
Returns an OptionalEnumerator iterating the support (including the missing value) in descending probability order.
- Return type:
OptionalEnumerator
- class OptionalEnumerator(dist)[source]
Bases:
DistributionEnumeratorEnumerate the optional support by merging missing mass with observed support.
- Parameters:
dist (OptionalDistribution)
- class OptionalSampler(dist, seed=None)[source]
Bases:
DistributionSamplerSample from an optional distribution by first drawing the missingness gate.
- Parameters:
dist (OptionalDistribution)
seed (int | None)
- class OptionalEstimatorAccumulator(accumulator, missing_value=None, name=None, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorAccumulate missing/observed gate weights plus observed-branch statistics.
- Parameters:
- update(x, weight, estimate)[source]
Update from a single observation, routing observed values to the child accumulator.
- Parameters:
x (T)
weight (float)
estimate (OptionalDistribution)
- Return type:
None
- initialize(x, weight, rng)[source]
Initialize from a single observation using the child initializer when observed.
- Parameters:
x (T)
weight (float)
rng (RandomState)
- Return type:
None
- seq_update(x, weights, estimate)[source]
Update from encoded optional data and observation weights.
- seq_update_engine(x, weights, estimate, engine)[source]
Engine-resident E-step: missing/observed mass is summed on the active engine and the observed child accumulator is routed through the engine. Matches seq_update.
- seq_initialize(x, weights, rng)[source]
Initialize from encoded optional data and weights.
- combine(suff_stat)[source]
Merge missing/observed weights and child sufficient statistics.
- value()[source]
Return gate weights together with observed-branch sufficient statistics.
- from_value(x)[source]
Restore gate weights and observed-branch sufficient statistics.
- scale(c)[source]
Scale missing/observed weights and delegate observed statistics.
- Parameters:
c (float)
- Return type:
OptionalEstimatorAccumulator
- key_replace(stats_dict)[source]
Replace own + wrapped-child statistics from the pooled
stats_dict(see key_merge).
- key_merge(stats_dict)[source]
Merge own statistics under
self.keysand DELEGATE to the wrapped child.The delegation is the point of the override: without it, a keyed estimator nested under an Optional never pooled at all (its key pass was unreachable – the dead-keys shape the keyed-protocol sweep hunts). The own-key pooling itself is the base-class canonical protocol.
- acc_to_encoder()[source]
Return the optional encoder matching the wrapped child accumulator.
- Return type:
OptionalDataEncoder
- class OptionalEstimatorAccumulatorFactory(estimator, missing_value=None, keys=None, name=None)[source]
Bases:
StatisticAccumulatorFactoryCreate accumulators for optional missingness estimators.
- make()[source]
Create an empty optional estimator accumulator.
- Return type:
OptionalEstimatorAccumulator
- class OptionalEstimator(estimator, missing_value=None, est_prob=False, pseudo_count=None, name=None, keys=None, prior=None)[source]
Bases:
ParameterEstimatorEstimate optional missingness probability and observed-data distribution parameters.
- Parameters:
- accumulator_factory()[source]
Return an accumulator factory for optional sufficient statistics.
- Return type:
OptionalEstimatorAccumulatorFactory
- get_prior()[source]
Return the joint prior as
(p_prior, dist_prior)from this estimator and the base estimator.
- set_prior(prior)[source]
Distribute
(p_prior, dist_prior)to this estimator’spprior and the base estimator.prior=Noneis a no-op (empirical/pseudo-count path stays byte-identical). The first element is a conjugate Beta prior onp; the second is pushed to the base estimator viaset_prior.
- model_log_density(model)[source]
Sum the Beta-prior log-density at
pand the base estimator’s term (ELBO global term).- Parameters:
model (OptionalDistribution)
- Return type:
- class OptionalDataEncoder(encoder, missing_value=None)[source]
Bases:
DataSequenceEncoderEncode optional data as missing indices, observed indices, and child-encoded data.
- Parameters:
encoder (DataSequenceEncoder)
missing_value (Any)
- seq_encode(x)[source]
Split a sequence into missing positions and encoded observed values.
- OptionalAccumulator
alias of
OptionalEstimatorAccumulator
- OptionalAccumulatorFactory
alias of
OptionalEstimatorAccumulatorFactory
- class OptionalFisherView(dist)[source]
Bases:
EmpiricalMetricFixedFisherViewFisher view for optional distributions with gate and observed-branch statistics.
- Parameters:
dist (Any)
- mean_statistics(stats=None, model=True, **kwargs)[source]
Return model or empirical mean statistics for the optional Fisher view.
- fisher_information(stats=None, diagonal=False, ridge=1.0e-8, **kwargs)[source]
Return Fisher information, falling back to empirical statistics when needed.
- fisher_vectors(stats=None, metric='diagonal', center=None, fisher=None, ridge=1.0e-8, **kwargs)[source]
Return Fisher-whitened statistic vectors for optional observations.