mixle.stats.latent.hierarchical module

Hierarchical (partial-pooling) normal model – the plate / random-effects structure.

Grouped data (many drill sites, survey lines, lab batches, taxa) is best modelled with a plate: each group has its own parameter drawn from a shared population distribution. Fitting each group alone (no pooling) overfits small groups; pooling everything (complete pooling) ignores real between-group variation. Partial pooling – the hierarchical model – learns the population spread and shrinks each group’s estimate toward the population mean by an amount set by its sample size.

HierarchicalNormalDistribution is a first-class mixle leaf whose observation is a whole group (a sequence of values): y[g,i] ~ N(theta[g], sigma^2) with theta[g] ~ N(mu, tau^2). Marginalizing the latent group mean gives a closed-form group likelihood y_g ~ N(mu*1, sigma^2 I + tau^2 11^T), so it follows the Distribution / Sampler / Estimator / Accumulator / DataEncoder contract: it fits through estimate(groups, dist.estimator()) (empirical-Bayes EM over the latent means), scores groups with log_density / seq_log_density, and exposes the per-group shrinkage posteriors. Part of the earth-science/multiphysics/UQ plan (Phase 7, composition expressiveness: plates / hierarchy).

class HierarchicalNormalDistribution(mu, tau, sigma, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Two-level normal hierarchy over groups: y[g,i] ~ N(theta[g], sigma^2), theta[g] ~ N(mu, tau^2).

Each observation is one group (a sequence of values). mu is the population mean, tau the between-group sd and sigma the within-group sd. The latent group mean is marginalized out, so a group’s likelihood is the multivariate normal N(mu*1, sigma^2 I + tau^2 11^T) (computed in closed form). group_posterior / shrinkage give the partial-pooling estimates.

Parameters:
density(group)[source]

Return the probability density or mass at a single observation.

Concrete default: exponentiate log_density (the abstract method subclasses must provide). Leaves with a cheaper closed form may override this.

Return type:

float

log_density(group)[source]

Marginal log-likelihood of one group (latent group mean integrated out).

Return type:

float

seq_log_density(x)[source]

Return vectorized log-density values for sequence-encoded observations.

Return type:

ndarray

group_posterior(ybar, n)[source]

Posterior (mean, sd) of a group’s true mean given its sample mean ybar and size n.

The shrinkage estimate mu + shrink*(ybar - mu) with shrink = tau^2/(tau^2 + sigma^2/n).

Parameters:
Return type:

tuple[float, float]

shrinkage(n)[source]

The shrinkage weight for a size-n group (0 = full pooling to mu, 1 = its own mean).

Parameters:

n (int)

Return type:

float

sampler(seed=None)[source]

Return a sampler for drawing observations from this distribution.

Parameters:

seed (int | None)

Return type:

HierarchicalNormalSampler

estimator(pseudo_count=None)[source]

Return an estimator for fitting this distribution from data.

Parameters:

pseudo_count (float | None)

Return type:

HierarchicalNormalEstimator

dist_to_encoder()[source]

Return the data encoder used by this distribution for vectorized methods.

Return type:

HierarchicalNormalDataEncoder

class HierarchicalNormalEstimator(max_iter=500, tol=1e-9, name=None, keys=None)[source]

Bases: ParameterEstimator

Empirical-Bayes estimator: fits (mu, tau, sigma) by EM over the latent group means.

Parameters:
accumulator_factory()[source]
Return type:

StatisticAccumulatorFactory

estimate(nobs, suff_stat)[source]
Return type:

HierarchicalNormalDistribution