mixle.stats.combinator.censored module¶
Censoring likelihood combinator with explicitly typed exact and interval evidence.
CensoredDistribution wraps a base distribution and scores censored observations – ones
that are not observed exactly but are known only to fall in some interval [a, b]. Such an
observation contributes its interval probability mass
P(a <= X <= b) = F(b) - F(a)
to the likelihood, where F is the base distribution’s CDF (for a discrete base, whose CDF has a
jump at a, the point mass P(X = a) is added back in – see Data type below). This is
distinct from truncation:
truncation renormalizes the density over a restricted support (the observation is exact but the
support is limited), whereas censoring keeps the original distribution and only coarsens what was
observed. Survival-analysis right/left/interval censoring (and Tobit-style bounds) are all this
combinator.
Data type: each observation is one of
ExactObservation(x)or a raw child valuex– exact evidence;
CensoredInterval(a, b)– interval evidence over the closed interval[a, b].
Raw two-element tuples are exact child observations, so bivariate child values remain representable. Censored evidence is a likelihood contribution, not an outcome sampled by the base model: an observation process must be modeled separately when interval selection itself is random.
The base distribution must expose cdf. Estimation of the base parameters under censoring has no
generic closed form (the censored MLE couples the bounds with the base parameters), so the supplied
estimator fits the base on the exact observations only and re-wraps; document and prefer a
dedicated censored MLE when the censored fraction is large.
- class ExactObservation(value)[source]
Bases:
objectExplicit exact evidence; useful when the child value could otherwise look like metadata.
- Parameters:
value (Any)
- class CensoredInterval(lower, upper)[source]
Bases:
objectClosed interval likelihood evidence with validated ordered bounds.
- class CensoredDistribution(base, name=None, keys=None, *, fit_receipt=None)[source]
Bases:
SequenceEncodableProbabilityDistributionA base distribution whose observations may be interval/left/right censored.
- Parameters:
- density(x)[source]
Return the contribution of
x(density for exact, interval mass for censored).
- log_density(x)[source]
Log-likelihood contribution of
x.Exact observation
x->log p_base(x); interval(a, b)->log P(a <= X <= b)(see_interval_log_mass()).
- seq_log_density(x)[source]
Per-row censored log-densities for an encoded batch.
- sampler(seed=None)[source]
Return exact evidence from the base; censoring requires a separate observation process.
- Parameters:
seed (int | None)
- Return type:
CensoredSampler
- estimator(pseudo_count=None)[source]
Return the explicit exact-only projection estimator with an effective-count receipt.
This is not a censored MLE. Use
likelihood_estimator()with a base-family-specific fitting callback when interval evidence must influence the fitted parameters.- Parameters:
pseudo_count (float | None)
- Return type:
ExactOnlyCensoredEstimator
- likelihood_estimator(fit)[source]
Return a likelihood-aware estimator backed by a declared base-family fitting callback.
fit(observations, weights, initial_base)receives validated exact/interval evidence and must optimize the full censored objective, returning a fitted base distribution.
- dist_to_encoder()[source]
Return the data encoder (exact observations + censoring intervals split out).
- Return type:
CensoredDataEncoder
- class CensoredSampler(dist, seed=None)[source]
Bases:
DistributionSamplerDraw exact values from the base distribution (the sampler is not censored).
- Parameters:
dist (CensoredDistribution)
seed (int | None)
- class CensoredExactOnlyFitReceipt(exact_weight, censored_weight, censored_fraction, likelihood_aware)[source]
Bases:
NamedTuple- Parameters:
- exact_weight: float
Alias for field number 0
- censored_weight: float
Alias for field number 1
- censored_fraction: float
Alias for field number 2
- likelihood_aware: bool
Alias for field number 3
- class CensoredExactOnlyStatistics(schema_version, child, exact_weight, censored_weight)[source]
Bases:
NamedTuple- schema_version: int
Alias for field number 0
- child: Any
Alias for field number 1
- exact_weight: float
Alias for field number 2
- censored_weight: float
Alias for field number 3
- class CensoredAccumulator(base_accumulator, keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulatorExplicit exact-only projection statistics with auditable discarded interval weight.
- Parameters:
base_accumulator (SequenceEncodableStatisticAccumulator)
keys (str | None)
- update(x, weight, estimate)[source]
Accumulate one weighted observation under an optional current estimate.
- initialize(x, weight, rng)[source]
Initialize sufficient statistics from one weighted observation.
- Parameters:
x (Any)
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(x, weights, estimate)[source]
Accumulate weighted sufficient statistics from sequence-encoded observations.
- seq_initialize(x, weights, rng)[source]
Initialize sufficient statistics from sequence-encoded observations.
- combine(suff_stat)[source]
Merge serialized sufficient statistics into this accumulator.
- Parameters:
suff_stat (CensoredExactOnlyStatistics)
- Return type:
CensoredAccumulator
- value()[source]
Return this accumulator’s serialized sufficient statistics.
- Return type:
CensoredExactOnlyStatistics
- from_value(x)[source]
Restore this accumulator from serialized sufficient statistics.
- Parameters:
x (CensoredExactOnlyStatistics)
- Return type:
CensoredAccumulator
- scale(c)[source]
Scale linear sufficient statistics in-place by
c.The structural default is correct for ordinary weighted sums, nested tuples/lists/dicts, and numeric arrays. Families whose
value()payload includes non-linear metadata such as support bounds must override this method and leave that metadata unscaled.- Parameters:
c (float)
- Return type:
CensoredAccumulator
- key_merge(stats_dict)[source]
Pool this accumulator’s statistics into
stats_dictunder its merge key.The structural default implements the common single-key pattern: store the accumulator under
self.keysthe first time the key is seen, elsecombineinto the one already there. Accumulators whose key does not cover their whole state (several named keys, a wrapped child accumulator, a non-accumulator payload) override this – and ONLY those: as of 2026-07-14 every whole-state family uses this default, after a sweep found sixteen hand-rolled copies that had drifted into three broken shapes. If you are tempted to reimplement this per family, don’t; extend the base or override withsuper()calls. AkeysofNone(the default) is a no-op.Why this exact shape is correct – and the drifted shapes are not: the POOL must live in the dict. Combining INTO the dict-held accumulator (below) mutates the pool in place, so after all sites merge, the dict entry holds everyone’s statistics and
key_replacehands that pool to every site. The observed broken variants each violate one half: pulling the dict’s stats intoselfwithout writing back (the dict keeps the FIRST site only – later sites’ data silently discarded); merging only when the key is already present (nobody ever inserts: both passes are no-ops and tying does nothing); and replacing by pushingselfINTO the dict (the LAST site overwrites the pool). The keyed-protocol sweep (keyed_protocol_sweep_test.py) enforces this behaviorally for every catalog family.
- key_replace(stats_dict)[source]
Replace this accumulator’s statistics from the pooled
stats_dictentry (see key_merge).
- acc_to_encoder()[source]
Return a sequence encoder compatible with this accumulator.
- Return type:
CensoredDataEncoder
- class CensoredAccumulatorFactory(base_factory, keys=None)[source]
Bases:
StatisticAccumulatorFactoryFactory for
CensoredAccumulator.- Parameters:
base_factory (StatisticAccumulatorFactory)
keys (str | None)
- make()[source]
Create an empty censored-data accumulator.
- Return type:
CensoredAccumulator
- class ExactOnlyCensoredEstimator(base_estimator, name=None, keys=None)[source]
Bases:
ParameterEstimatorProjection estimator that deliberately excludes interval evidence and reports its weight.
- accumulator_factory()[source]
Return a factory for censored-data sufficient-statistic accumulators.
- Return type:
CensoredAccumulatorFactory
- CensoredEstimator
alias of
ExactOnlyCensoredEstimator
- class CensoredLikelihoodStatistics(schema_version, observations, weights)[source]
Bases:
NamedTuple- schema_version: int
Alias for field number 0
- weights: ndarray
Alias for field number 2
- class CensoredEvidenceEncoder[source]
Bases:
DataSequenceEncoderIdentity encoder that validates explicit exact/interval evidence for likelihood fitting.
- seq_encode(x)[source]
Encode the iid observation sequence x for vectorized evaluation.
- row_count(x)[source]
Return the number of observations represented by
x.The default covers simple array/list encodings and structurally aligned tuples/dicts. Encoders with flattened, ragged, or otherwise specialized layouts must override this method so metadata wrappers can verify counts instead of trusting a caller assertion.
- class CensoredLikelihoodAccumulator[source]
Bases:
SequenceEncodableStatisticAccumulatorRetain validated evidence for a base-family-specific full censored-likelihood fit.
- update(x, weight, estimate)[source]
Accumulate one weighted observation under an optional current estimate.
- initialize(x, weight, rng)[source]
Initialize sufficient statistics from one weighted observation.
- Parameters:
x (Any)
weight (float)
rng (RandomState | None)
- Return type:
None
- seq_update(x, weights, estimate)[source]
Accumulate weighted sufficient statistics from sequence-encoded observations.
- seq_initialize(x, weights, rng)[source]
Initialize sufficient statistics from sequence-encoded observations.
- Parameters:
weights (ndarray)
rng (RandomState | None)
- Return type:
None
- combine(suff_stat)[source]
Merge serialized sufficient statistics into this accumulator.
- Parameters:
suff_stat (CensoredLikelihoodStatistics)
- Return type:
CensoredLikelihoodAccumulator
- value()[source]
Return this accumulator’s serialized sufficient statistics.
- Return type:
CensoredLikelihoodStatistics
- from_value(x)[source]
Restore this accumulator from serialized sufficient statistics.
- Parameters:
x (CensoredLikelihoodStatistics)
- Return type:
CensoredLikelihoodAccumulator
- key_merge(stats_dict)[source]
Pool this accumulator’s statistics into
stats_dictunder its merge key.The structural default implements the common single-key pattern: store the accumulator under
self.keysthe first time the key is seen, elsecombineinto the one already there. Accumulators whose key does not cover their whole state (several named keys, a wrapped child accumulator, a non-accumulator payload) override this – and ONLY those: as of 2026-07-14 every whole-state family uses this default, after a sweep found sixteen hand-rolled copies that had drifted into three broken shapes. If you are tempted to reimplement this per family, don’t; extend the base or override withsuper()calls. AkeysofNone(the default) is a no-op.Why this exact shape is correct – and the drifted shapes are not: the POOL must live in the dict. Combining INTO the dict-held accumulator (below) mutates the pool in place, so after all sites merge, the dict entry holds everyone’s statistics and
key_replacehands that pool to every site. The observed broken variants each violate one half: pulling the dict’s stats intoselfwithout writing back (the dict keeps the FIRST site only – later sites’ data silently discarded); merging only when the key is already present (nobody ever inserts: both passes are no-ops and tying does nothing); and replacing by pushingselfINTO the dict (the LAST site overwrites the pool). The keyed-protocol sweep (keyed_protocol_sweep_test.py) enforces this behaviorally for every catalog family.
- key_replace(stats_dict)[source]
Replace this accumulator’s statistics from the pooled
stats_dictentry (see key_merge).
- acc_to_encoder()[source]
Return a sequence encoder compatible with this accumulator.
- Return type:
CensoredEvidenceEncoder
- class CensoredLikelihoodAccumulatorFactory[source]
Bases:
StatisticAccumulatorFactory- make()[source]
Create a fresh accumulator instance.
- Return type:
CensoredLikelihoodAccumulator
- class CensoredLikelihoodEstimator(initial_base, fit, name=None, keys=None)[source]
Bases:
ParameterEstimatorDelegate full censored-objective optimization to a declared base-family callback.
- Parameters:
- accumulator_factory()[source]
Return the accumulator factory used to collect this estimator’s sufficient statistics.
- Return type:
CensoredLikelihoodAccumulatorFactory
- class CensoredDataEncoder(dist=None, base_encoder=None)[source]
Bases:
MaskedBaseEncoderSplit a batch into exact observations (base-encoded) and censoring intervals.
Encoded form is
(exact_enc, exact_idx, lows, highs, cens_idx)whereexact_idx/cens_idxare the original positions of the exact / censored rows soseq_log_densitycan scatter results back into the right order.- Parameters:
dist (CensoredDistribution | None)
base_encoder (DataSequenceEncoder | None)
- classmethod from_base_encoder(base_encoder)[source]
Create a censored encoder from an already configured base encoder.
- Parameters:
base_encoder (DataSequenceEncoder)
- Return type:
CensoredDataEncoder
- seq_encode(x)[source]
Encode a batch into exact values, interval bounds, and row indices.