mixle.stats.univariate.discrete.negative_binomial module

Create, estimate, enumerate, and sample from a negative binomial distribution.

The parameterization is the number of failures X before r successes, with success probability p:

P(X=x) = Gamma(x+r) / (Gamma(r) Gamma(x+1)) * p**r * (1-p)**x, x = 0, 1, 2, …

The dispersion r has no closed-form MLE; the estimator recovers it by a 1-D numerical solve of the digamma score equation (with p profiled out), then p follows in closed form. Pass estimate_r=False to hold r fixed instead.

Reference: Johnson, Kemp & Kotz, Univariate Discrete Distributions (3rd ed., Wiley, 2005).

class NegativeBinomialDistribution(r, p, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Negative binomial distribution over non-negative integer counts.

Parameters:
classmethod compute_capabilities()[source]
classmethod compute_declaration()[source]
static backend_legacy_sufficient_statistics(x, params, engine)[source]

Return per-row negative-binomial sufficient statistics in accumulator order.

The accumulator’s NegativeBinomialAccumulator.value() returns (count, sum, histogram); the third row stat carries the per-row counts so the declaration’s kind="histogram" reducer can fold them into the weighted count histogram the dispersion (r) solve needs.

Parameters:
Return type:

tuple[Any, …]

static exp_family_sufficient_statistics(x, engine)[source]

Return the NegativeBinomial sufficient statistic T(x) = (x,) (r fixed).

Parameters:
Return type:

tuple[Any, …]

static exp_family_natural_parameters(params, engine)[source]

Return the NegativeBinomial natural parameter eta = log(1 - p) (r fixed).

Parameters:
Return type:

tuple[Any, …]

static exp_family_log_partition(params, engine)[source]

Return the NegativeBinomial log partition A = -r * log(p) (r fixed).

Parameters:
Return type:

Any

static exp_family_base_measure_from_params(x, params, engine)[source]

Return the NegativeBinomial base measure log h(x) = lgamma(x+r) - lgamma(r) - log(x!).

The base measure carries the binomial-coefficient term and depends on the fixed shape r; invalid (non-integer / negative) counts are mapped to -inf.

Parameters:
Return type:

Any

density(x)[source]

Return the probability density or mass at a single observation.

Parameters:

x (int)

Return type:

float

log_density(x)[source]

Return the log-density or log-mass at a single observation.

Parameters:

x (int)

Return type:

float

seq_log_density(x)[source]

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

Parameters:

x (tuple[ndarray, ndarray])

Return type:

ndarray

static backend_log_density_from_params(vals, log_fact, r, p, engine)[source]

Engine-neutral negative-binomial log-density from explicit parameters.

Parameters:
Return type:

Any

backend_seq_log_density(x, engine)[source]

Engine-neutral vectorized log-density for encoded data.

Parameters:
Return type:

Any

classmethod backend_stacked_params(dists, engine)[source]

Return stacked negative-binomial parameters for a homogeneous mixture kernel.

Parameters:
  • dists (Sequence[NegativeBinomialDistribution])

  • engine (Any)

Return type:

dict[str, Any]

classmethod backend_stacked_log_density(x, params, engine)[source]

Return an (n, k) matrix of negative-binomial log densities.

Parameters:
Return type:

Any

to_fisher(**kwargs)[source]

Return the NegativeBinomial’s count-family Fisher view.

mean()[source]

Mean E[X] (failures before r successes): r(1-p)/p.

Return type:

float

variance()[source]

Variance Var[X]: r(1-p)/p^2.

Return type:

float

cdf(x)[source]

Cumulative distribution function P(X <= x) = I_p(r, floor(x)+1).

Parameters:

x (float)

Return type:

float

quantile(q)[source]

Inverse CDF F^{-1}(q) (via scipy nbinom).

Parameters:

q (float)

Return type:

float

sampler(seed=None)[source]

Return a sampler for drawing observations from this distribution.

Parameters:

seed (int | None)

Return type:

NegativeBinomialSampler

estimator(pseudo_count=None)[source]

Return an estimator for fitting this distribution from data.

Parameters:

pseudo_count (float | None)

Return type:

NegativeBinomialEstimator

dist_to_encoder()[source]

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

Return type:

NegativeBinomialDataEncoder

enumerator()[source]

Return an enumerator over the distribution support when available.

Return type:

NegativeBinomialEnumerator

class NegativeBinomialEnumerator(dist)[source]

Bases: DistributionEnumerator

Enumerate the infinite support in descending probability order.

Parameters:

dist (NegativeBinomialDistribution)

class NegativeBinomialSampler(dist, seed=None)[source]

Bases: DistributionSampler

Draw iid negative binomial observations.

Parameters:
  • dist (NegativeBinomialDistribution)

  • seed (int | None)

sample(size=None)[source]

Draw observations.

Combinator samplers (mixture/sequence/…) accept batched. With batched=True (the default) each child stream is drawn in one vectorized call instead of a per-draw Python loop – far faster. Because every child sampler owns an independent RandomState, batching consumes each stream in the same order as the loop, so the draws are identical to the legacy path. batched=False forces that legacy per-draw loop as a guaranteed- stable reference. Leaf samplers are already vectorized and ignore the flag.

Parameters:

size (int | None)

Return type:

int | ndarray

class NegativeBinomialAccumulator(name=None, keys=None)[source]

Bases: SequenceEncodableStatisticAccumulator

Accumulate weighted count and sum statistics plus the count histogram.

The dispersion r has no finite-dimensional sufficient statistic: its MLE needs sum_i w_i digamma(x_i + r), which cannot be reduced to count/sum. We therefore accumulate the weighted histogram {x: weight} so NegativeBinomialEstimator.estimate() can solve the score equation for r.

Parameters:
  • name (str | None)

  • keys (str | None)

update(x, weight, estimate)[source]
Parameters:
  • x (int)

  • weight (float)

  • estimate (NegativeBinomialDistribution | None)

Return type:

None

initialize(x, weight, rng)[source]
Parameters:
Return type:

None

seq_update(x, weights, estimate)[source]
Parameters:
Return type:

None

seq_initialize(x, weights, rng)[source]
Parameters:
Return type:

None

combine(suff_stat)[source]
Parameters:

suff_stat (tuple[float, float, dict[int, float]])

Return type:

NegativeBinomialAccumulator

value()[source]
Return type:

tuple[float, float, dict[int, float]]

from_value(x)[source]
Parameters:

x (tuple[float, float, dict[int, float]])

Return type:

NegativeBinomialAccumulator

key_merge(stats_dict)[source]

Pool this accumulator’s statistics into stats_dict under its merge key.

The structural default implements the common single-key pattern: store the accumulator under self.keys the first time the key is seen, else combine into the one already there. Accumulators with several named keys (e.g. an HMM’s init/trans/state keys) or a non-accumulator stats payload override this. A keys of None (the default) is a no-op.

Parameters:

stats_dict (dict[str, Any])

Return type:

None

key_replace(stats_dict)[source]

Replace this accumulator’s statistics from the pooled stats_dict entry (see key_merge).

Parameters:

stats_dict (dict[str, Any])

Return type:

None

acc_to_encoder()[source]
Return type:

NegativeBinomialDataEncoder

class NegativeBinomialAccumulatorFactory(name=None, keys=None)[source]

Bases: StatisticAccumulatorFactory

Factory for NegativeBinomialAccumulator.

Parameters:
  • name (str | None)

  • keys (str | None)

make()[source]
Return type:

NegativeBinomialAccumulator

class NegativeBinomialEstimator(r=1.0, pseudo_count=None, suff_stat=None, estimate_r=True, threshold=1.0e-8, name=None, keys=None)[source]

Bases: ParameterEstimator

Estimate r and p for a negative binomial distribution.

By default the dispersion r is recovered by a 1-D solve of the digamma score equation (p profiled out), then p follows in closed form. Pass estimate_r=False to hold r fixed at the constructor value (the historical geometric/fixed-shape M-step). The r argument is the initial value / fallback when estimate_r=True.

Parameters:
accumulator_factory()[source]
Return type:

NegativeBinomialAccumulatorFactory

resident_accumulation_supported()[source]

Dispersion estimation needs the full count histogram, not fixed-width resident stats.

Return type:

bool

static estimate_dispersion(histogram, r_init, threshold)[source]

Solve the negative-binomial dispersion MLE from a weighted count histogram.

With p profiled to its MLE p = r / (r + xbar), the score for r is

g(r) = sum_k h(k) [digamma(k + r) - digamma(r)] - N * log(1 + xbar / r),

which is strictly decreasing and crosses zero exactly when the data are over-dispersed (sample variance > mean). Under equi/under-dispersion the MLE runs off to the Poisson limit, so r is capped at _MAX_NB_SHAPE.

Parameters:
Return type:

float

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

NegativeBinomialDistribution

class NegativeBinomialDataEncoder[source]

Bases: DataSequenceEncoder

Encode count observations with precomputed log-factorials.

seq_encode(x)[source]

Encode the iid observation sequence x for vectorized evaluation.

Parameters:

x (Sequence[int])

Return type:

tuple[ndarray, ndarray]