import numpy as np
import drisk as drCombining Distributions with Mixtures
Weighted blends of univariate distributions
Overview
A UvMixture represents a weighted blend of univariate distributions. This is useful when one process has distinct regimes. For example, most delivery times might follow a bounded PERT estimate, while a smaller share of outcomes come from a long-tailed delay process.
Define component distributions
quick_delivery = dr.PERT.elicit(
min=1,
mode=1.1,
max=8,
name="Quick delivery",
)
typical_delivery = dr.PERT.elicit(
min=6,
mode=9,
max=14,
name="Typical delivery",
)
delayed_delivery = dr.LogNormal.elicit(
lower=14,
upper=21,
confidence=0.8,
name="Delayed delivery",
)Create the mixture
delivery_mixture = dr.UvMixture.elicit(
components=[quick_delivery, typical_delivery, delayed_delivery],
weights=[1, 3, 1],
name="Delivery time with delays",
)
delivery_mixtureUvMixture(dist_type='uv_mixture', name='Delivery time with delays', elicitation_params={'weights': (1, 3, 1)}, params={}, components=(PERT(dist_type='pert', name='Quick delivery', elicitation_params={'min': 1, 'mode': 1.1, 'max': 8, 'concentration': 4.0}, params={'min': 1.0, 'max': 8.0, 'alpha': 1.0571428571428572, 'beta': 4.942857142857143, 'mode': 1.1, 'concentration': 4.0}), PERT(dist_type='pert', name='Typical delivery', elicitation_params={'min': 6, 'mode': 9, 'max': 14, 'concentration': 4.0}, params={'min': 6.0, 'max': 14.0, 'alpha': 2.5, 'beta': 3.5, 'mode': 9.0, 'concentration': 4.0}), LogNormal(dist_type='lognormal', name='Delayed delivery', elicitation_params={'lower': 14, 'upper': 21, 'confidence': 0.8}, params={'mu': 2.8417898836693407, 'sigma': 0.15819305247224313})), weights=(0.2, 0.6, 0.2))
The weights are normalized during construction, so they can be provided as proportions or relative frequencies.
delivery_mixture.weights(0.2, 0.6, 0.2)
Sample and plot the mixture
Mixtures support direct sampling plus PDF/CDF evaluation.
mixture_samples = delivery_mixture.sample(size=10_000, seed=123)
np.percentile(mixture_samples, [10, 50, 90, 99])array([ 1.97953541, 9.16634637, 16.84419091, 22.14657182])
delivery_mixture.plot(color="seagreen")
Because a generic mixture usually has no simple inverse CDF, UvMixture.ppf(...) is not implemented. That also means mixtures are not currently usable as copula marginals, since the copula sampler maps correlated uniform values through each marginal’s ppf.