mixle.stats.sequences.markov_chain module¶
Create, estimate, and sample from a Markov chain.
Defines the MarkovChainDistribution, MarkovChainDistributionSampler, MarkovChainDistributionAccumulatorFactory, MarkovChainDistributionAccumulator, MarkovChainDistributionEstimator, and the MarkovChainDistributionDataEncoder classes for use with mixle.
The assumed data type for the stats-space is T.
The density of Markov chain is given by for sequence of length n, x=[x[0],x[1],…,x[n-1]]
p_mat(x) = p_mat(x[0])*p_mat(x[1]|x[0])*…*p_mat(x[n-1]|x[n-2])*P_len(n)
where p_mat(x[i+1]|x[i]) is the transition probability, p_mat(x[0]) is the init-probability, and P_len(n) is given by the length distribution density.
Note if len(x) = 0, only log(P_len(0)) is returned.
- markov_chain_dirichlet_default_prior(states)[source]
Returns the default
(states, init_prior, row_priors)prior of unit-parameter Dirichlets.- Parameters:
states (Sequence[T]) – Ordered list of the S state values the priors range over.
- Returns:
Tuple
(list_of_states, DirichletDistribution, list_of_DirichletDistribution).
- stationary_distribution(transitions)[source]
Stationary distribution
piof a row-stochastic matrix (pi A = pi,sum pi = 1).Solved as the constrained least-squares system
[(I - A^T); 1^T] pi = [0; 1]so it is robust for reducible/near-singular chains (it returns one valid stationary distribution). The result is clipped to non-negative and renormalized.- Parameters:
transitions (np.ndarray) – a square row-stochastic transition matrix.
- Returns:
1-d numpy array of stationary probabilities (length = number of states).
- Return type:
- class MarkovChainDistribution(init_prob_map, transition_map, len_dist=NullDistribution(), default_value=0.0, name=None, prior=None)[source]
Bases:
SequenceEncodableProbabilityDistributionMarkov-chain distribution over finite-state sequences.
- Parameters:
- get_prior()[source]
Returns the conjugate prior in
(states, init_prior, row_priors)form (or None).
- set_prior(prior)[source]
Set the conjugate Dirichlet prior and precompute its digamma expectations.
With Dirichlet
init_priorand Dirichletrow_priors(each over the fixed orderedstates) this caches the digamma expectations E[ln p_k] = psi(alpha_k) - psi(sum alpha) used by expected_log_density and setshas_conj_prioraccordingly.prior=Noneleaves the distribution a plain point model.- Parameters:
prior –
(states, init_prior, row_priors)tuple or None.- Return type:
None
- expected_log_density(x)[source]
Variational E_q[log p(x)] under the Dirichlet priors over a state sequence.
Replaces the initial/transition log-probabilities with their digamma expectations E[ln p_k] = psi(alpha_k) - psi(sum alpha); the length term is added as in log_density(). Falls back to the plug-in log_density(x) when no conjugate prior is set.
- Parameters:
x (List[T]) – An observed Markov chain state sequence.
- Returns:
Expected log-density of the Markov chain at x.
- Return type:
- seq_expected_log_density(x)[source]
Vectorized expected_log_density() at sequence-encoded input x.
Falls back to seq_log_density(x) when no conjugate prior is set.
- compute_capabilities()[source]
- compute_declaration()[source]
- density(x)[source]
Return density of MarkovChainDistribution at observed sequence x.
Returns exponential of log_density(x). See log_density() for details.
- Parameters:
x (List[T]) – An observed Markov chain sequence of data type T.
- Returns:
Density of Markov chain at x.
- Return type:
- log_density(x)[source]
Return log-density of MarkovChainDistribution at observed sequence x.
Density of Markov chain is given by for sequence of length n, x=[x[0],x[1],…,x[n-1]]
p_mat(x) = p_mat(x[0])*p_mat(x[1]|x[0])*…*p_mat(x[n-1]|x[n-2])*P_len(n)
where p_mat(x[i+1]|x[i]) is the transition probability, p_mat(x[0]) is the init-probability, and P_len(n) is given by the length distribution density.
Note if len(x) = 0, only log(P_len(0)) is returned.
- Parameters:
x (List[T]) – An observed Markov chain sequence of data type T.
- Returns:
Log-density of Markov chain at x.
- Return type:
- seq_log_density(x)[source]
Vectorized evaluation of log_density of Markov Chain for an encoded sequence of observations x.
Computationally efficient implementation of log_density() for sequence encoded data x.
The arg value x is a Tuple of length 8 with entries:
x[0] (int): Number of total observations (number of Markov sequences). x[1] (ndarray[int]): Sequence index for initial state observations. x[2] (ndarray[int]): Sequence index for non-initial state observations in a sequence greater than len 1. x[3] (ndarray[int]): Numpy array of observations index in inv_key_map for initial states. x[4] (ndarray[int]): State-to-state index value of inv_key_map for initial state value. x[5] (ndarray[int]): State-to-state index value of inv_key_map for transition. x[6] (ndarray[T]): Maps integer index value to value in state-space (T). x[7] (Optional[T1]): Encoded sequence of lengths from len_encoder. None if no length distribution to be
estimated.
- backend_seq_log_density(x, engine)[source]
Engine-neutral vectorized log-density for encoded Markov-chain sequences.
- classmethod backend_stacked_params(dists, engine)[source]
Return stacked fixed-support Markov-chain parameters.
- classmethod backend_stacked_log_density(x, params, engine)[source]
Return an
(n, k)matrix of Markov-chain sequence log densities.
- classmethod backend_stacked_sufficient_statistics_with_estimator(x, weights, params, engine, estimator)[source]
Return per-component legacy
(initial_counts, transition_counts, length_stat)statistics.
- gradient_fit_state(engine, torch, leaves, recurse, tensor_param)[source]
Return distribution-owned state for fixed-support autograd fitting.
- sampler(seed=None)[source]
Create MarkovChainSampler from MarkovChainDistribution instance.
Raises exception if length distribution (len_dist) was not specified in initialization.
- Parameters:
seed (Optional[int]) – Used to set the seed of random number generator for sampling.
- Returns:
MarkovChainSampler object.
- Return type:
MarkovChainSampler
- estimator(pseudo_count=None)[source]
Create MarkovChainEstimator from instance of MarkovChainDistribution object.
- Parameters:
pseudo_count (Optional[float]) – Used to re-weight the sufficient statistics of MarkovChainDistribution.
- Returns:
MarkovChainEstimator object.
- Return type:
MarkovChainEstimator
- dist_to_encoder()[source]
Create MarkovChainDataEncoder object for encoding sequences of MarkovChainDistribution observations.
Note: len_encoder is passed as NullDataEncoder() if len_dist is not to be estimated.
- Returns:
MarkovChainDataEncoder object.
- Return type:
MarkovChainDataEncoder
- enumerator()[source]
Returns MarkovChainEnumerator iterating state sequences in descending probability order.
- Return type:
MarkovChainEnumerator
- quantized_count_index(quantizer, max_fine_bucket)[source]
Structural count index: a forward DP carrying a count histogram per (length, end-state).
log p(x) = log p_init(x0) + sum_i log p_trans(x_i|x_{i-1}) + log p(len). The forward recursion is lifted into the count semiring: alpha[t][s] is the histogram (over the fine bucket of accumulated log probability) of length-t prefixes ending in state s, with
alpha[1][s] = delta(bucket(log p_init(s)))andalpha[t+1][s'] = sum_s alpha[t][s].shift(bucket(log p_trans(s'|s))). Per length L the sequence histogram pools the end states and shifts by the length term; the total pools lengths. Sequences are unranked by choosing the end state, then walking the trellis backward choosing predecessors by count.- Parameters:
max_fine_bucket (int)
- class MarkovChainEnumerator(dist)[source]
Bases:
DistributionEnumerator- Parameters:
dist (MarkovChainDistribution)
- class MarkovChainSampler(dist, seed=None)[source]
Bases:
DistributionSampler- Parameters:
dist (MarkovChainDistribution)
seed (int | None)
- sample(size=None, *, batched=True)[source]
Draw iid samples from Markov chain distribution.
If size is None, sample N from len_sampler() and return a List[T] of length N, where T is the data type of the Markov chain. If size > 0, return a list of length size, containing List[T] data types.
With
batched=True(default) the state paths for the whole batch are drawn by looping over time and advancing all live chains at once through the transition matrix, instead of N x T scalar draws. This consumes the RNG in a different order than the legacy per-draw loop, so the draws are statistically equivalent but NOT byte-identical tobatched=False. Setbatched=Falseto reproduce the exact legacy output for a given seed.
- sample_paths(lengths)[source]
Vectorized batch of state paths, one per requested length.
Loops over time and advances all live chains at once through the transition matrix. The RNG consumption order differs from per-sequence
sample_seqcalls, so paths are statistically equivalent but not byte-identical. Used by HiddenMarkovSampler for batched state-path draws.
- sample_seq(size=None, v0=None, *, batched=False)[source]
Sample a Markov chain sequence of length ‘size’ conditioned on initial state ‘v0’.
If size is None, draw a sequence of length 1, returning as type T.
If size is not None, draw a sequence of length size, returning as type List[T].
If v0 is None, v0 is sampled from member variable ‘init_prob’.
This is the legacy per-step path (one
rng.choiceper transition); thebatchedflag is accepted for API symmetry but does not change behavior here. For vectorized batches of whole chains usesample_paths()orsample(..., batched=True).- Parameters:
- Returns:
T or List[T] depending on arg size.
- Return type:
T | list[T]
- class MarkovChainAccumulator(len_accumulator=NullAccumulator(), keys=None)[source]
Bases:
SequenceEncodableStatisticAccumulator- Parameters:
len_accumulator (SequenceEncodableStatisticAccumulator | None)
keys (str | None)
- update(x, weight, estimate)[source]
Update sufficient statistics of MarkovChainAccumulator with weighted observation.
Aggregates suff stats by checking initial state of sequence, and counting all transitions. Passes length of sequence x to len_accumulator.
- Parameters:
x (List[T])
weight (float) – Weight for observation.
estimate (Optional[MarkovChainDistribution]) – Previous estimate for MarkovChainDistribution or None.
- Returns:
None.
- Return type:
None
- initialize(x, weight, rng)[source]
- Initialize MarkovChainAccumulator with Markov chain observation x and random number generator rng passed
to len_accumulator.initialize().
- Parameters:
x (List[T]) – Single Markov chain observation.
weight (float) – Weight for observation.
rng (RandomState) – RandomState object for passing to len_accumulator.initialize().
- Returns:
None.
- Return type:
None
- seq_initialize(x, weights, rng)[source]
Vectorized initialization of MarkovChainAccumulator sufficient statistics from a sequence of encoded data x.
Note that this is the same as seq_update() for the transition and initial state updates. For len_accumulator, a call to seq_initialize() must be made.
- The arg value x is a Tuple of length 8 with entries:
x[0] (int): Number of total observations (number of Markov sequences). x[1] (ndarray[int]): Sequence index for initial state observations. x[2] (ndarray[int]): Sequence index for non-initial state observations in a sequence greater than len 1. x[3] (ndarray[int]): Numpy array of observations index in inv_key_map for initial states. x[4] (ndarray[int]): State-to-state index value of inv_key_map for initial state value. x[5] (ndarray[int]): State-to-state index value of inv_key_map for transition. x[6] (ndarray[T]): Maps integer index value to value in state-space (T). x[7] (Optional[T1]): Encoded sequence of lengths from len_encoder. None if no length distribution to be
estimated.
- Parameters:
- Returns:
None.
- Return type:
None
- seq_update(x, weights, estimate)[source]
Vectorized update of Markov chain sufficient statistics for a sequence encoded x.
Computationally efficient update of MarkovChainAccumulator object using vectorized numpy operations.
Note that estimate must be passed, as the ‘estimate’ argument of len_accumulator.seq_update() may require estimate parameter to not be None.
- The arg value x is a Tuple of length 8 with entries:
x[0] (int): Number of total observations (number of Markov sequences). x[1] (ndarray[int]): Sequence index for initial state observations. x[2] (ndarray[int]): Sequence index for non-initial state observations in a sequence greater than len 1. x[3] (ndarray[int]): Numpy array of observations index in inv_key_map for initial states. x[4] (ndarray[int]): State-to-state index value of inv_key_map for initial state value. x[5] (ndarray[int]): State-to-state index value of inv_key_map for transition. x[6] (ndarray[T]): Maps integer index value to value in state-space (T). x[7] (Optional[T1]): Encoded sequence of lengths from len_encoder. None if no length distribution to be
estimated.
- Parameters:
- Returns:
None.
- Return type:
None
- seq_update_engine(x, weights, estimate, engine)[source]
Engine-resident E-step: initial-state counts are reduced on the active engine and the transition weights are gathered on the engine before filling the sparse count maps; the length accumulator is routed through the engine. Matches seq_update.
- combine(suff_stat)[source]
Merge the sufficient statistics of arg suff_stat with MarkovChainAccumulator.
- Arg suff_stat is a Tuple of length three containing,
suff_stat[0] (Dict[T, float]): Maps initial state values to their corresponding counts. suff_stat[1] (Dict[T, Dict[T, List[float]]]): Maps state to state transition counts. suff_stat[2] (T1): Sufficient statistic value of length accumulator. (Assumed type T1).
- value()[source]
Returns Tuple of length three containing sufficient statistic member variables of MarkovChainAccumulator.
- from_value(x)[source]
Assign MarkovChainAccumulator sufficient statistics to value of x.
- Arg x is a Tuple of length three containing,
x[0] (Dict[T, float]): Maps initial state values to their corresponding counts. x[1] (Dict[T, Dict[T, List[float]]]): Maps state to state transition counts. x[2] (T1): Sufficient statistic value of length accumulator. (Assumed type T1).
- 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:
MarkovChainAccumulator
- key_merge(stats_dict)[source]
- Aggregate the sufficient statistics of MarkovChainAccumulator with member instance key in
stats_dict.
- Parameters:
stats_dict (Dict[str, MarkovChainAccumulator]) – Key of dict are the ‘keys’ for MarkovChainAccumulator that represent the same distribution.
- Returns:
None.
- Return type:
None
- key_replace(stats_dict)[source]
- Set MarkovChainAccumulator sufficient statistic member variables to the value of stats_dict with
matching keys.
Checks if member variable key is already in the stats_dict. If it is, set the accumulator to have same member variable sufficient statistics as MarkovChainAccumulators with matching keys.
- Parameters:
stats_dict (Dict[str, MarkovChainAccumulator]) – Maps member variable key to MarkovChainAccumulator with same key.
- Returns:
None.
- Return type:
None
- acc_to_encoder()[source]
Create MarkovChainDataEncoder object for encoding sequences of MarkovChainDistribution observations.
Note: len_encoder is passed as NullDataEncoder() if len_dist is not to be estimated.
- Returns:
MarkovChainDataEncoder object.
- Return type:
MarkovChainDataEncoder
- class MarkovChainAccumulatorFactory(len_factory=NullAccumulatorFactory(), keys=None)[source]
Bases:
StatisticAccumulatorFactory- Parameters:
len_factory (StatisticAccumulatorFactory)
keys (str | None)
- make()[source]
Returns MarkovChainAccumulator object for accumulating sufficient statistics of Markov chain.
- Return type:
MarkovChainAccumulator
- class MarkovChainEstimator(pseudo_count=None, levels=None, len_estimator=NullEstimator(), name=None, keys=None, prior=None)[source]
Bases:
ParameterEstimator- Parameters:
- accumulator_factory()[source]
Returns MarkovChainAccumulatorFactory for creating MarkovChainAccumulator.
- Return type:
MarkovChainAccumulatorFactory
- get_prior()[source]
Returns the conjugate prior in
(states, init_prior, row_priors)form (or None).
- set_prior(prior)[source]
Set the conjugate Dirichlet prior and flag whether it admits the conjugate update.
- Parameters:
prior –
(states, init_prior, row_priors)tuple or None; has_conj_prior is set when all priors are Dirichlet.- Return type:
None
- model_log_density(model)[source]
Log-density of the model’s probabilities under the Dirichlet priors.
Sums the Dirichlet log-densities of the initial-state probabilities and each transition row (floored at a tiny constant so MAP estimates that sit on the simplex boundary score finitely). Returns 0.0 without a conjugate prior.
- Parameters:
model (MarkovChainDistribution) – Model to score.
- Returns:
Prior log-density of the model parameters.
- Return type:
- estimate(nobs, suff_stat)[source]
Estimate MarkovChainDistribution from aggregated sufficient statistics from observed data.
- Arg suff_stat is a Tuple of length three containing,
suff_stat[0] (Dict[T, float]): Maps initial state values to their aggregated counts. suff_stat[1] (Dict[T, Dict[T, List[float]]]): Maps state to state transition counts. suff_stat[2] (T1): Sufficient statistic value of length accumulator. (Assumed type T1).
If member variable pseudo_count is set estimate1() is called to aggregated weighted sufficient statistics. Else estimate0() is called to obtain estimates for MarkovChainDistribution directly from arg ‘suff_stat’.
- estimate0(nobs, suff_stat)[source]
Estimate MarkovChainDistribution from aggregated sufficient statistics from observed data.
Maximum likelihood estimates for initial state probabilities, transition probabilities, and the length distribution are obtained directly from aggregated data in ‘suff_stat’.
- Arg suff_stat is a Tuple of length three containing,
suff_stat[0] (Dict[T, float]): Maps initial state values to their aggregated counts. suff_stat[1] (Dict[T, Dict[T, List[float]]]): Maps state to state transition counts. suff_stat[2] (T1): Sufficient statistic value of length accumulator. (Assumed type T1).
- estimate1(nobs, suff_stat)[source]
Estimate MarkovChainDistribution from aggregated sufficient statistics from observed data.
Maximum likelihood estimates for initial state probabilities, transition probabilities, and the length distribution are obtained by a weighted aggregation of sufficient statistics in ‘suff_stat’, and member variables of MarkovChainEstimator object.
- Arg suff_stat is a Tuple of length three containing,
suff_stat[0] (Dict[T, float]): Maps initial state values to their aggregated counts. suff_stat[1] (Dict[T, Dict[T, List[float]]]): Maps state to state transition counts. suff_stat[2] (T1): Sufficient statistic value of length accumulator. (Assumed type T1).
- class MarkovChainDataEncoder(len_encoder=NullDataEncoder())[source]
Bases:
DataSequenceEncoder- Parameters:
len_encoder (DataSequenceEncoder)
- seq_encode(x)[source]
Sequence encoding a sequence of iid Markov chain observations with data type T.
The returned value is (rv) is a Tuple of length 8 with entries:
rv[0] (int): Number of total observations (number of Markov sequences). rv[1] (ndarray[int]): Sequence index for initial state observations. rv[2] (ndarray[int]): Sequence index for non-initial state observations in a sequence greater than len 1. rv[3] (ndarray[int]): Numpy array of observations index in inv_key_map for initial states. rv[4] (ndarray[int]): State-to-state index value of inv_key_map for initial state value. rv[5] (ndarray[int]): State-to-state index value of inv_key_map for transition. rv[6] (ndarray[T]): Maps integer index value to value in state-space (T). rv[7] (Optional[T1]): Encoded sequence of lengths from len_encoder. None if no length distributon to be
estimated.