mixle.stats.rankings.paired_comparison module

Paired-comparison models beyond plain Bradley-Terry: Gaussian pairwise and ties.

Three canonical models that complete the pairwise-comparison family:

  • ThurstoneMostellerDistribution – the Gaussian (probit) pairwise model P(i beats j) = Phi((mu_i - mu_j) / sqrt(2)); the pairwise peer of ThurstoneDistribution and the Gaussian counterpart of BradleyTerryDistribution. Observation: (winner, loser).

  • DavidsonDistribution – Bradley-Terry with ties (Davidson 1970): a draw has probability nu * sqrt(w_i w_j) / (w_i + w_j + nu sqrt(w_i w_j)). Observation: (i, j, outcome) with outcome in {0: i wins, 1: j wins, 2: tie}.

  • RaoKupperDistribution – Bradley-Terry with ties via a threshold nu >= 1 (Rao-Kupper 1967): P(i beats j) = w_i / (w_i + nu w_j). Same (i, j, outcome) observation.

All three treat the compared pair as a uniform draw over the C(K, 2) unordered pairs, making them proper distributions over (canonicalized) comparison outcomes. Worths/utilities are identified up to a shift and stored mean-zero. Fitting maximizes the comparison log-likelihood from the win/tie count matrices (the sufficient statistic).

class ThurstoneMostellerDistribution(mu, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Gaussian/probit paired-comparison model P(i beats j) = Phi((mu_i - mu_j) / sqrt(2)).

Parameters:
  • mu (Sequence[float] | np.ndarray)

  • name (str | None)

  • keys (str | None)

classmethod compute_capabilities()[source]
density(x)[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.

Parameters:

x (tuple[int, int])

Return type:

float

log_density(x)[source]

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

Parameters:

x (tuple[int, int])

Return type:

float

seq_log_density(x)[source]

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

Parameters:

x (ndarray)

Return type:

ndarray

sampler(seed=None)[source]

Return a sampler for drawing observations from this distribution.

Parameters:

seed (int | None)

Return type:

ThurstoneMostellerSampler

estimator(pseudo_count=None)[source]

Return an estimator for fitting this distribution from data.

Parameters:

pseudo_count (float | None)

Return type:

ThurstoneMostellerEstimator

dist_to_encoder()[source]

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

Return type:

PairDataEncoder

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

Bases: DistributionSampler

Parameters:
  • dist (ThurstoneMostellerDistribution)

  • 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:

tuple[int, int] | list[tuple[int, int]]

class ThurstoneMostellerEstimator(dim, name=None, keys=None)[source]

Bases: ParameterEstimator

mu_i - mu_j = sqrt(2) Phi^{-1}(P(i beats j)) from the win-count matrix (least squares).

Parameters:
  • dim (int)

  • name (str | None)

  • keys (str | None)

accumulator_factory()[source]
Return type:

PairWinAccumulatorFactory

estimate(nobs, suff_stat)[source]
Parameters:

nobs (float | None)

Return type:

ThurstoneMostellerDistribution

class PairWinAccumulator(dim, keys=None)[source]

Bases: SequenceEncodableStatisticAccumulator

Win-count matrix wins[i, j] for (winner, loser) pair data.

Parameters:
update(x, weight, estimate)[source]
Parameters:
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]
Return type:

PairWinAccumulator

value()[source]
from_value(x)[source]
Return type:

PairWinAccumulator

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:

PairDataEncoder

class PairWinAccumulatorFactory(dim, keys=None)[source]

Bases: StatisticAccumulatorFactory

Parameters:
make()[source]
Return type:

PairWinAccumulator

class PairDataEncoder(dim=None)[source]

Bases: DataSequenceEncoder

Encode (winner, loser) pairs into an (N, 2) integer array.

Parameters:

dim (int | None)

seq_encode(x)[source]

Encode the iid observation sequence x for vectorized evaluation.

Parameters:

x (Sequence[tuple[int, int]])

Return type:

ndarray

class DavidsonDistribution(log_w, nu=1.0, name=None, keys=None)[source]

Bases: _BaseTieDistribution

Bradley-Terry with ties (Davidson 1970); tie mass nu sqrt(w_i w_j).

Parameters:
estimator(pseudo_count=None)[source]

Return an estimator for fitting this distribution from data.

Parameters:

pseudo_count (float | None)

class DavidsonEstimator(dim, name=None, keys=None)[source]

Bases: ParameterEstimator

Maximum-likelihood Davidson worths and tie parameter (L-BFGS on the count matrices).

Parameters:
  • dim (int)

  • name (str | None)

  • keys (str | None)

accumulator_factory()[source]
Return type:

_TieAccumulatorFactory

estimate(nobs, suff_stat)[source]
Parameters:

nobs (float | None)

Return type:

DavidsonDistribution

class RaoKupperDistribution(log_w, nu=1.5, name=None, keys=None)[source]

Bases: _BaseTieDistribution

Bradley-Terry with ties via a threshold nu >= 1 (Rao-Kupper 1967).

Parameters:
estimator(pseudo_count=None)[source]

Return an estimator for fitting this distribution from data.

Parameters:

pseudo_count (float | None)

class RaoKupperEstimator(dim, name=None, keys=None)[source]

Bases: ParameterEstimator

Maximum-likelihood Rao-Kupper worths and threshold (L-BFGS on the count matrices).

Parameters:
  • dim (int)

  • name (str | None)

  • keys (str | None)

accumulator_factory()[source]
Return type:

_TieAccumulatorFactory

estimate(nobs, suff_stat)[source]
Parameters:

nobs (float | None)

Return type:

RaoKupperDistribution