├── docs ├── .nojekyll ├── audios │ ├── beta.mp3 │ ├── rice.mp3 │ ├── wald.mp3 │ ├── cauchy.mp3 │ ├── gamma.mp3 │ ├── gumbel.mp3 │ ├── hurdle.mp3 │ ├── moyal.mp3 │ ├── normal.mp3 │ ├── pareto.mp3 │ ├── bernoulli.mp3 │ ├── binomial.mp3 │ ├── censored.mp3 │ ├── dirichlet.mp3 │ ├── geometric.mp3 │ ├── laplace.mp3 │ ├── logistic.mp3 │ ├── lognormal.mp3 │ ├── mixture.mp3 │ ├── poisson.mp3 │ ├── studentt.mp3 │ ├── truncated.mp3 │ ├── uniform.mp3 │ ├── vonmises.mp3 │ ├── weibull.mp3 │ ├── betascaled.mp3 │ ├── categorical.mp3 │ ├── chisquared.mp3 │ ├── exgaussian.mp3 │ ├── exponential.mp3 │ ├── halfcauchy.mp3 │ ├── halfnormal.mp3 │ ├── kumaraswamy.mp3 │ ├── logitnormal.mp3 │ ├── loglogistic.mp3 │ ├── skewnormal.mp3 │ ├── triangular.mp3 │ ├── betabinomial.mp3 │ ├── halfstudentt.mp3 │ ├── hypergeometric.mp3 │ ├── inversegamma.mp3 │ ├── skewstudentt.mp3 │ ├── discreteuniform.mp3 │ ├── discreteweibull.mp3 │ ├── negativebinomial.mp3 │ ├── truncatednormal.mp3 │ ├── asymmetriclaplace.mp3 │ ├── multivariatenormal.mp3 │ ├── zeroinflatedpoisson.mp3 │ ├── zeroinflatedbinomial.mp3 │ └── zeroinflatednegativebinomial.mp3 ├── logos │ ├── PreliZ.eps │ ├── PreliZ.jpg │ ├── PreliZ.png │ ├── favicon.ico │ ├── PreliZ_fav.eps │ ├── PreliZ_fav.jpg │ ├── PreliZ_fav.png │ ├── PreliZ_flat.jpg │ ├── PreliZ_flat.png │ ├── PreliZ_white.png │ ├── PreliZ_flat_white.jpg │ └── PreliZ_flat_white.png ├── examples │ ├── img │ │ ├── ppa.gif │ │ ├── ppa.png │ │ ├── roulette.gif │ │ ├── beta_bounds.png │ │ ├── quartile_int.gif │ │ ├── global_settings.png │ │ ├── work_with_dist.png │ │ ├── predictive_explorer.png │ │ ├── direct_elicitation_1D.png │ │ └── direct_elicitation_ND.png │ └── gallery │ │ ├── direct_elicitation_ND.md │ │ └── global_settings.md ├── _static │ └── custom.css ├── changelog.rst ├── distributions │ ├── img │ │ ├── Beta.png │ │ ├── Gamma.png │ │ ├── Moyal.png │ │ ├── Rice.png │ │ ├── Wald.png │ │ ├── Binomial.png │ │ ├── Cauchy.png │ │ ├── Censored.png │ │ ├── Gumbel.png │ │ ├── Hurdle.png │ │ ├── Laplace.png │ │ ├── Logistic.png │ │ ├── Mixture.png │ │ ├── MvNormal.png │ │ ├── Normal.png │ │ ├── Pareto.png │ │ ├── Poisson.png │ │ ├── StudentT.png │ │ ├── Uniform.png │ │ ├── VonMises.png │ │ ├── Weibull.png │ │ ├── Bernoulli.png │ │ ├── BetaScaled.png │ │ ├── ChiSquared.png │ │ ├── Dirichlet.png │ │ ├── ExGaussian.png │ │ ├── Geometric.png │ │ ├── HalfCauchy.png │ │ ├── HalfNormal.png │ │ ├── LogNormal.png │ │ ├── SkewNormal.png │ │ ├── Triangular.png │ │ ├── Truncated.png │ │ ├── BetaBinomial.png │ │ ├── Categorical.png │ │ ├── Exponential.png │ │ ├── HalfStudentT.png │ │ ├── InverseGamma.png │ │ ├── Kumaraswamy.png │ │ ├── LogLogistic.png │ │ ├── LogitNormal.png │ │ ├── SkewStudentT.png │ │ ├── DiscreteUniform.png │ │ ├── DiscreteWeibull.png │ │ ├── HyperGeometric.png │ │ ├── TruncatedNormal.png │ │ ├── AsymmetricLaplace.png │ │ ├── NegativeBinomial.png │ │ ├── ZeroInflatedBinomial.png │ │ ├── ZeroInflatedPoisson.png │ │ ├── ScaledInverseChiSquared.png │ │ └── ZeroInflatedNegativeBinomial.png │ └── gallery │ │ ├── scaledinversechisquared.md │ │ ├── categorical.md │ │ ├── kumaraswamy.md │ │ ├── halfcauchy.md │ │ ├── binomial.md │ │ ├── discrete_uniform.md │ │ ├── weibull.md │ │ ├── poisson.md │ │ ├── gumbel.md │ │ ├── pareto.md │ │ ├── vonmises.md │ │ ├── geometric.md │ │ ├── mixture.md │ │ ├── hypergeometric.md │ │ ├── betabinomial.md │ │ ├── chisquared.md │ │ ├── discrete_weibull.md │ │ ├── moyal.md │ │ ├── bernoulli.md │ │ ├── laplace.md │ │ ├── log_logistic.md │ │ ├── zeroinflatedpoisson.md │ │ ├── exgaussian.md │ │ ├── censored.md │ │ ├── logistic.md │ │ └── truncated.md ├── ppls.rst ├── predictive.rst ├── unidimensional.rst ├── multidimensional.rst ├── api_reference.rst ├── contributing.rst ├── citing.rst ├── get_cover_gallery_multivariate.py ├── Makefile ├── make.bat ├── installation.rst ├── pronunciation.py ├── gallery_examples.rst └── index.rst ├── preliz ├── internal │ ├── __init__.py │ ├── predictive_helper.py │ └── citations.py ├── tests │ ├── test_ppa.py │ ├── test_roulette.py │ ├── test_quartile_int.py │ ├── test_predictive_explorer.py │ ├── test_distributions_helper.py │ ├── test_internals.py │ ├── test_citation.py │ ├── test_dirichlet_mode.py │ ├── test_combine.py │ ├── test_helper.py │ ├── test_optimization.py │ ├── test_combine_roulette.py │ ├── quartile_int.ipynb │ ├── test_posterior_to_prior.py │ ├── test_censored.py │ ├── test_matching.py │ ├── check_inside_notebook.ipynb │ ├── test_ppe.py │ ├── test_hurdle.py │ ├── test_special.py │ ├── test_non_scipy.py │ ├── test_truncated.py │ └── test_mixture.py ├── multidimensional │ ├── __init__.py │ └── dirichlet_mode.py ├── ppls │ └── __init__.py ├── predictive │ ├── __init__.py │ └── predictive_explorer.py ├── unidimensional │ ├── __init__.py │ ├── combine.py │ ├── combine_roulette.py │ └── mle.py ├── __init__.py └── styles │ └── preliz-doc.mplstyle ├── paper └── figures │ ├── figure_1.png │ ├── figure_2.png │ ├── figure_3.png │ └── figure_4.png ├── audios └── scaledinversechisquared.mp3 ├── environment.yml ├── requirements-dev.txt ├── requirements-docs.txt ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ ├── bug_report.md │ └── usage-question.md ├── workflows │ ├── post-release.yml │ ├── publish-to-test-pypi.yml │ └── test.yml └── pull_request_template.md ├── environment-docs.yml ├── environment-dev.yml ├── CONTRIBUTING.md ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── .gitignore └── pyproject.toml /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /preliz/internal/__init__.py: -------------------------------------------------------------------------------- 1 | """utility functions for internal use.""" 2 | -------------------------------------------------------------------------------- /docs/audios/beta.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/beta.mp3 -------------------------------------------------------------------------------- /docs/audios/rice.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/rice.mp3 -------------------------------------------------------------------------------- /docs/audios/wald.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/wald.mp3 -------------------------------------------------------------------------------- /docs/audios/cauchy.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/cauchy.mp3 -------------------------------------------------------------------------------- /docs/audios/gamma.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/gamma.mp3 -------------------------------------------------------------------------------- /docs/audios/gumbel.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/gumbel.mp3 -------------------------------------------------------------------------------- /docs/audios/hurdle.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/hurdle.mp3 -------------------------------------------------------------------------------- /docs/audios/moyal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/moyal.mp3 -------------------------------------------------------------------------------- /docs/audios/normal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/normal.mp3 -------------------------------------------------------------------------------- /docs/audios/pareto.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/pareto.mp3 -------------------------------------------------------------------------------- /docs/logos/PreliZ.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ.eps -------------------------------------------------------------------------------- /docs/logos/PreliZ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ.jpg -------------------------------------------------------------------------------- /docs/logos/PreliZ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ.png -------------------------------------------------------------------------------- /docs/logos/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/favicon.ico -------------------------------------------------------------------------------- /docs/audios/bernoulli.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/bernoulli.mp3 -------------------------------------------------------------------------------- /docs/audios/binomial.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/binomial.mp3 -------------------------------------------------------------------------------- /docs/audios/censored.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/censored.mp3 -------------------------------------------------------------------------------- /docs/audios/dirichlet.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/dirichlet.mp3 -------------------------------------------------------------------------------- /docs/audios/geometric.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/geometric.mp3 -------------------------------------------------------------------------------- /docs/audios/laplace.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/laplace.mp3 -------------------------------------------------------------------------------- /docs/audios/logistic.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/logistic.mp3 -------------------------------------------------------------------------------- /docs/audios/lognormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/lognormal.mp3 -------------------------------------------------------------------------------- /docs/audios/mixture.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/mixture.mp3 -------------------------------------------------------------------------------- /docs/audios/poisson.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/poisson.mp3 -------------------------------------------------------------------------------- /docs/audios/studentt.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/studentt.mp3 -------------------------------------------------------------------------------- /docs/audios/truncated.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/truncated.mp3 -------------------------------------------------------------------------------- /docs/audios/uniform.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/uniform.mp3 -------------------------------------------------------------------------------- /docs/audios/vonmises.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/vonmises.mp3 -------------------------------------------------------------------------------- /docs/audios/weibull.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/weibull.mp3 -------------------------------------------------------------------------------- /docs/examples/img/ppa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/ppa.gif -------------------------------------------------------------------------------- /docs/examples/img/ppa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/ppa.png -------------------------------------------------------------------------------- /docs/logos/PreliZ_fav.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_fav.eps -------------------------------------------------------------------------------- /docs/logos/PreliZ_fav.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_fav.jpg -------------------------------------------------------------------------------- /docs/logos/PreliZ_fav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_fav.png -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | .jupyter-widgets-disconnected::before { 2 | content: none !important; 3 | } 4 | -------------------------------------------------------------------------------- /docs/audios/betascaled.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/betascaled.mp3 -------------------------------------------------------------------------------- /docs/audios/categorical.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/categorical.mp3 -------------------------------------------------------------------------------- /docs/audios/chisquared.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/chisquared.mp3 -------------------------------------------------------------------------------- /docs/audios/exgaussian.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/exgaussian.mp3 -------------------------------------------------------------------------------- /docs/audios/exponential.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/exponential.mp3 -------------------------------------------------------------------------------- /docs/audios/halfcauchy.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/halfcauchy.mp3 -------------------------------------------------------------------------------- /docs/audios/halfnormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/halfnormal.mp3 -------------------------------------------------------------------------------- /docs/audios/kumaraswamy.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/kumaraswamy.mp3 -------------------------------------------------------------------------------- /docs/audios/logitnormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/logitnormal.mp3 -------------------------------------------------------------------------------- /docs/audios/loglogistic.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/loglogistic.mp3 -------------------------------------------------------------------------------- /docs/audios/skewnormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/skewnormal.mp3 -------------------------------------------------------------------------------- /docs/audios/triangular.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/triangular.mp3 -------------------------------------------------------------------------------- /docs/logos/PreliZ_flat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_flat.jpg -------------------------------------------------------------------------------- /docs/logos/PreliZ_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_flat.png -------------------------------------------------------------------------------- /docs/logos/PreliZ_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_white.png -------------------------------------------------------------------------------- /paper/figures/figure_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/paper/figures/figure_1.png -------------------------------------------------------------------------------- /paper/figures/figure_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/paper/figures/figure_2.png -------------------------------------------------------------------------------- /paper/figures/figure_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/paper/figures/figure_3.png -------------------------------------------------------------------------------- /paper/figures/figure_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/paper/figures/figure_4.png -------------------------------------------------------------------------------- /docs/audios/betabinomial.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/betabinomial.mp3 -------------------------------------------------------------------------------- /docs/audios/halfstudentt.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/halfstudentt.mp3 -------------------------------------------------------------------------------- /docs/audios/hypergeometric.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/hypergeometric.mp3 -------------------------------------------------------------------------------- /docs/audios/inversegamma.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/inversegamma.mp3 -------------------------------------------------------------------------------- /docs/audios/skewstudentt.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/skewstudentt.mp3 -------------------------------------------------------------------------------- /docs/examples/img/roulette.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/roulette.gif -------------------------------------------------------------------------------- /docs/audios/discreteuniform.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/discreteuniform.mp3 -------------------------------------------------------------------------------- /docs/audios/discreteweibull.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/discreteweibull.mp3 -------------------------------------------------------------------------------- /docs/audios/negativebinomial.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/negativebinomial.mp3 -------------------------------------------------------------------------------- /docs/audios/truncatednormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/truncatednormal.mp3 -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ********* 3 | 4 | .. include:: ../CHANGELOG.md 5 | :parser: myst_parser.sphinx_ -------------------------------------------------------------------------------- /docs/distributions/img/Beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Beta.png -------------------------------------------------------------------------------- /docs/distributions/img/Gamma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Gamma.png -------------------------------------------------------------------------------- /docs/distributions/img/Moyal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Moyal.png -------------------------------------------------------------------------------- /docs/distributions/img/Rice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Rice.png -------------------------------------------------------------------------------- /docs/distributions/img/Wald.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Wald.png -------------------------------------------------------------------------------- /docs/logos/PreliZ_flat_white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_flat_white.jpg -------------------------------------------------------------------------------- /docs/logos/PreliZ_flat_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/logos/PreliZ_flat_white.png -------------------------------------------------------------------------------- /audios/scaledinversechisquared.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/audios/scaledinversechisquared.mp3 -------------------------------------------------------------------------------- /docs/audios/asymmetriclaplace.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/asymmetriclaplace.mp3 -------------------------------------------------------------------------------- /docs/audios/multivariatenormal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/multivariatenormal.mp3 -------------------------------------------------------------------------------- /docs/audios/zeroinflatedpoisson.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/zeroinflatedpoisson.mp3 -------------------------------------------------------------------------------- /docs/distributions/img/Binomial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Binomial.png -------------------------------------------------------------------------------- /docs/distributions/img/Cauchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Cauchy.png -------------------------------------------------------------------------------- /docs/distributions/img/Censored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Censored.png -------------------------------------------------------------------------------- /docs/distributions/img/Gumbel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Gumbel.png -------------------------------------------------------------------------------- /docs/distributions/img/Hurdle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Hurdle.png -------------------------------------------------------------------------------- /docs/distributions/img/Laplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Laplace.png -------------------------------------------------------------------------------- /docs/distributions/img/Logistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Logistic.png -------------------------------------------------------------------------------- /docs/distributions/img/Mixture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Mixture.png -------------------------------------------------------------------------------- /docs/distributions/img/MvNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/MvNormal.png -------------------------------------------------------------------------------- /docs/distributions/img/Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Normal.png -------------------------------------------------------------------------------- /docs/distributions/img/Pareto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Pareto.png -------------------------------------------------------------------------------- /docs/distributions/img/Poisson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Poisson.png -------------------------------------------------------------------------------- /docs/distributions/img/StudentT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/StudentT.png -------------------------------------------------------------------------------- /docs/distributions/img/Uniform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Uniform.png -------------------------------------------------------------------------------- /docs/distributions/img/VonMises.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/VonMises.png -------------------------------------------------------------------------------- /docs/distributions/img/Weibull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Weibull.png -------------------------------------------------------------------------------- /docs/examples/img/beta_bounds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/beta_bounds.png -------------------------------------------------------------------------------- /docs/examples/img/quartile_int.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/quartile_int.gif -------------------------------------------------------------------------------- /docs/audios/zeroinflatedbinomial.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/zeroinflatedbinomial.mp3 -------------------------------------------------------------------------------- /docs/distributions/img/Bernoulli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Bernoulli.png -------------------------------------------------------------------------------- /docs/distributions/img/BetaScaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/BetaScaled.png -------------------------------------------------------------------------------- /docs/distributions/img/ChiSquared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ChiSquared.png -------------------------------------------------------------------------------- /docs/distributions/img/Dirichlet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Dirichlet.png -------------------------------------------------------------------------------- /docs/distributions/img/ExGaussian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ExGaussian.png -------------------------------------------------------------------------------- /docs/distributions/img/Geometric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Geometric.png -------------------------------------------------------------------------------- /docs/distributions/img/HalfCauchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/HalfCauchy.png -------------------------------------------------------------------------------- /docs/distributions/img/HalfNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/HalfNormal.png -------------------------------------------------------------------------------- /docs/distributions/img/LogNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/LogNormal.png -------------------------------------------------------------------------------- /docs/distributions/img/SkewNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/SkewNormal.png -------------------------------------------------------------------------------- /docs/distributions/img/Triangular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Triangular.png -------------------------------------------------------------------------------- /docs/distributions/img/Truncated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Truncated.png -------------------------------------------------------------------------------- /docs/examples/img/global_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/global_settings.png -------------------------------------------------------------------------------- /docs/examples/img/work_with_dist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/work_with_dist.png -------------------------------------------------------------------------------- /docs/distributions/img/BetaBinomial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/BetaBinomial.png -------------------------------------------------------------------------------- /docs/distributions/img/Categorical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Categorical.png -------------------------------------------------------------------------------- /docs/distributions/img/Exponential.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Exponential.png -------------------------------------------------------------------------------- /docs/distributions/img/HalfStudentT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/HalfStudentT.png -------------------------------------------------------------------------------- /docs/distributions/img/InverseGamma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/InverseGamma.png -------------------------------------------------------------------------------- /docs/distributions/img/Kumaraswamy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/Kumaraswamy.png -------------------------------------------------------------------------------- /docs/distributions/img/LogLogistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/LogLogistic.png -------------------------------------------------------------------------------- /docs/distributions/img/LogitNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/LogitNormal.png -------------------------------------------------------------------------------- /docs/distributions/img/SkewStudentT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/SkewStudentT.png -------------------------------------------------------------------------------- /preliz/tests/test_ppa.py: -------------------------------------------------------------------------------- 1 | from test_helper import run_notebook 2 | 3 | 4 | def test_ppa(): 5 | run_notebook("ppa.ipynb") 6 | -------------------------------------------------------------------------------- /docs/distributions/img/DiscreteUniform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/DiscreteUniform.png -------------------------------------------------------------------------------- /docs/distributions/img/DiscreteWeibull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/DiscreteWeibull.png -------------------------------------------------------------------------------- /docs/distributions/img/HyperGeometric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/HyperGeometric.png -------------------------------------------------------------------------------- /docs/distributions/img/TruncatedNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/TruncatedNormal.png -------------------------------------------------------------------------------- /docs/examples/img/predictive_explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/predictive_explorer.png -------------------------------------------------------------------------------- /docs/audios/zeroinflatednegativebinomial.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/audios/zeroinflatednegativebinomial.mp3 -------------------------------------------------------------------------------- /docs/distributions/img/AsymmetricLaplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/AsymmetricLaplace.png -------------------------------------------------------------------------------- /docs/distributions/img/NegativeBinomial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/NegativeBinomial.png -------------------------------------------------------------------------------- /docs/examples/img/direct_elicitation_1D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/direct_elicitation_1D.png -------------------------------------------------------------------------------- /docs/examples/img/direct_elicitation_ND.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/examples/img/direct_elicitation_ND.png -------------------------------------------------------------------------------- /preliz/multidimensional/__init__.py: -------------------------------------------------------------------------------- 1 | from preliz.multidimensional.dirichlet_mode import dirichlet_mode 2 | 3 | __all__ = ["dirichlet_mode"] 4 | -------------------------------------------------------------------------------- /docs/distributions/img/ZeroInflatedBinomial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ZeroInflatedBinomial.png -------------------------------------------------------------------------------- /docs/distributions/img/ZeroInflatedPoisson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ZeroInflatedPoisson.png -------------------------------------------------------------------------------- /preliz/tests/test_roulette.py: -------------------------------------------------------------------------------- 1 | from test_helper import run_notebook 2 | 3 | 4 | def test_roulette(): 5 | run_notebook("roulette.ipynb") 6 | -------------------------------------------------------------------------------- /docs/distributions/img/ScaledInverseChiSquared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ScaledInverseChiSquared.png -------------------------------------------------------------------------------- /preliz/tests/test_quartile_int.py: -------------------------------------------------------------------------------- 1 | from test_helper import run_notebook 2 | 3 | 4 | def test_quartile_int(): 5 | run_notebook("quartile_int.ipynb") 6 | -------------------------------------------------------------------------------- /docs/distributions/img/ZeroInflatedNegativeBinomial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arviz-devs/preliz/HEAD/docs/distributions/img/ZeroInflatedNegativeBinomial.png -------------------------------------------------------------------------------- /preliz/tests/test_predictive_explorer.py: -------------------------------------------------------------------------------- 1 | from test_helper import run_notebook 2 | 3 | 4 | def test_predictive_explorer(): 5 | run_notebook("predictive_explorer.ipynb") 6 | -------------------------------------------------------------------------------- /docs/ppls.rst: -------------------------------------------------------------------------------- 1 | Probabilistic programming languages 2 | ************* 3 | 4 | 5 | :mod:`preliz.ppls` 6 | ====================================== 7 | 8 | .. automodule:: preliz.ppls 9 | :members: 10 | -------------------------------------------------------------------------------- /preliz/ppls/__init__.py: -------------------------------------------------------------------------------- 1 | """Functions for interacting with probabilistic programming languages.""" 2 | 3 | from preliz.ppls.pymc_io import from_prior, from_pymc 4 | 5 | __all__ = ["from_pymc", "from_prior"] 6 | -------------------------------------------------------------------------------- /docs/predictive.rst: -------------------------------------------------------------------------------- 1 | Predictive Elicitation 2 | ************* 3 | 4 | 5 | :mod:`preliz.predictive` 6 | ====================================== 7 | 8 | .. automodule:: preliz.predictive 9 | :members: 10 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: preliz 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - python >= 3.11 7 | - matplotlib>=3.8 8 | - numba>=0.60 9 | - numpy>=2.0 10 | - scipy>=1.12 11 | -------------------------------------------------------------------------------- /docs/unidimensional.rst: -------------------------------------------------------------------------------- 1 | Unidimensional 2 | ************* 3 | 4 | 5 | :mod:`preliz.unidimensional` 6 | ====================================== 7 | 8 | .. automodule:: preliz.unidimensional 9 | :members: 10 | -------------------------------------------------------------------------------- /docs/multidimensional.rst: -------------------------------------------------------------------------------- 1 | Multidimensional 2 | ************* 3 | 4 | 5 | :mod:`preliz.multidimensional` 6 | ====================================== 7 | 8 | .. automodule:: preliz.multidimensional 9 | :members: 10 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | click 2 | pytest-cov>=2.6.1 3 | pytest>=4.4.0 4 | pre-commit>=2.19 5 | ipytest 6 | nbconvert 7 | nbformat 8 | lxml 9 | ipykernel 10 | pandas 11 | pymc>=5.24.0 12 | bambi>=0.13.0 13 | pymc-extras 14 | ruff -------------------------------------------------------------------------------- /requirements-docs.txt: -------------------------------------------------------------------------------- 1 | pydata-sphinx-theme>=0.6.3 2 | myst-nb 3 | sphinx>=4 4 | sphinx-copybutton 5 | sphinx_tabs 6 | sphinx-design 7 | jupyter-sphinx 8 | ipympl 9 | pymc 10 | bambi 11 | pymc-extras 12 | sphinxcontrib-bibtex -------------------------------------------------------------------------------- /preliz/predictive/__init__.py: -------------------------------------------------------------------------------- 1 | from preliz.predictive.ppa import ppa 2 | from preliz.predictive.ppe import ppe 3 | from preliz.predictive.predictive_explorer import predictive_explorer 4 | 5 | __all__ = ["ppa", "ppe", "predictive_explorer"] 6 | -------------------------------------------------------------------------------- /docs/api_reference.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ************* 3 | 4 | This reference provides detailed documentation for user functions in the current release of PreliZ. 5 | 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | 10 | unidimensional 11 | multidimensional 12 | predictive 13 | ppls 14 | distributions -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | We welcome contributions from interested individuals or groups! For information about contributing to PreliZ check out our instructions, policies, and guidelines `here `_. 4 | 5 | See the `GitHub contributor page `_. 6 | -------------------------------------------------------------------------------- /preliz/tests/test_distributions_helper.py: -------------------------------------------------------------------------------- 1 | from preliz.internal.distribution_helper import process_extra 2 | 3 | 4 | def test_process_extra(): 5 | ref0 = {"TruncatedNormal": {"lower": -3, "upper": 3}} 6 | ref1 = {"StudentT": {"nu": 3.4}, "Normal": {"mu": 3.0}} 7 | 8 | assert process_extra("TruncatedNormal(lower=-3, upper=3)") == ref0 9 | assert process_extra("StudentT(nu=3.4),Normal(mu=3)") == ref1 10 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | fail_fast: true 2 | 3 | repos: 4 | - repo: https://github.com/astral-sh/ruff-pre-commit 5 | rev: v0.14.1 6 | hooks: 7 | - id: ruff 8 | args: [ --fix, --exit-non-zero-on-fix ] 9 | - id: ruff-format 10 | types_or: [ python, pyi ] 11 | - repo: https://github.com/MarcoGorelli/madforhooks 12 | rev: 0.4.1 13 | hooks: 14 | - id: no-print-statements 15 | -------------------------------------------------------------------------------- /preliz/tests/test_internals.py: -------------------------------------------------------------------------------- 1 | from test_helper import run_notebook 2 | 3 | from preliz.internal.plot_helper import check_inside_notebook 4 | 5 | 6 | def test_check_inside_notebook_not(capsys): 7 | check_inside_notebook() 8 | captured = capsys.readouterr() 9 | assert "RuntimeError" in captured.out 10 | 11 | 12 | def test_check_inside_notebook_yes(): 13 | run_notebook("check_inside_notebook.ipynb") 14 | -------------------------------------------------------------------------------- /preliz/tests/test_citation.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | import preliz as pz 4 | 5 | 6 | @pytest.mark.parametrize( 7 | "methods, filepath, format_type", 8 | [ 9 | (None, None, "bibtex"), 10 | ([pz.Roulette, pz.dirichlet_mode], None, "bibtex"), 11 | (["all", None, "bibtex"]), 12 | ], 13 | ) 14 | def test_citations(methods, filepath, format_type): 15 | pz.citations(methods, filepath, format_type) 16 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | version: 2 4 | 5 | build: 6 | os: ubuntu-22.04 7 | tools: 8 | python: "3.11" 9 | 10 | sphinx: 11 | configuration: docs/conf.py 12 | 13 | python: 14 | install: 15 | - requirements: requirements-docs.txt 16 | - method: pip 17 | path: . 18 | extra_requirements: 19 | - full 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Tell us about it 11 | 12 | The more specific the better. 13 | 14 | ## Thoughts on implementation 15 | 16 | Not required, but if you have thoughts on how to implement the feature, that can be helpful! In case there are academic references, we welcome those here too. 17 | -------------------------------------------------------------------------------- /environment-docs.yml: -------------------------------------------------------------------------------- 1 | name: preliz-docs 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - python >= 3.11 7 | - matplotlib>=3.8 8 | - numba>=0.60 9 | - numpy>=2.0 10 | - scipy>=1.12 11 | - nbclient>=0.2 12 | - ipywidgets 13 | - ipympl 14 | - jupyterlab 15 | - notebook 16 | - pydata-sphinx-theme>=0.6.3 17 | - myst-nb 18 | - sphinx>=4 19 | - sphinx-copybutton 20 | - sphinx-tabs 21 | - sphinxcontrib-bibtex 22 | - jupyter-sphinx 23 | - pymc>=5.24.0 24 | - bambi>=0.13.0 25 | -------------------------------------------------------------------------------- /.github/workflows/post-release.yml: -------------------------------------------------------------------------------- 1 | name: Post-release 2 | on: 3 | release: 4 | types: [published, released] 5 | workflow_dispatch: 6 | 7 | jobs: 8 | changelog: 9 | name: Update changelog 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | ref: main 15 | - uses: rhysd/changelog-from-release/action@v3 16 | with: 17 | file: CHANGELOG.md 18 | github_token: ${{ secrets.GITHUB_TOKEN }} 19 | commit_summary_template: 'update changelog for %s changes' 20 | -------------------------------------------------------------------------------- /environment-dev.yml: -------------------------------------------------------------------------------- 1 | name: preliz-dev 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - python >= 3.11 7 | - pip 8 | - matplotlib>=3.9 9 | - numba>=0.62 10 | - numpy>=2.0 11 | - scipy>=1.12 12 | - nbclient>=0.2 13 | - ipywidgets 14 | - ipympl 15 | - jupyterlab 16 | - notebook 17 | - click 18 | - pytest-cov>=2.6.1 19 | - pytest>=4.4.0 20 | - pre-commit>=2.19 21 | - nbconvert 22 | - nbformat 23 | - ruff 24 | - ipykernel 25 | - pymc>=5.24.0 26 | - bambi>=0.13.0 27 | - pip: 28 | - lxml 29 | - ipytest 30 | -------------------------------------------------------------------------------- /docs/citing.rst: -------------------------------------------------------------------------------- 1 | How to Cite 2 | =========== 3 | 4 | If you find PreliZ useful in your work we kindly request that you cite the following paper: 5 | 6 | :: 7 | 8 | @article{Icazatti_2023, 9 | author = {Icazatti, Alejandro and Abril-Pla, Oriol and Klami, Arto and Martin, Osvaldo A}, 10 | doi = {10.21105/joss.05499}, 11 | journal = {Journal of Open Source Software}, 12 | month = sep, 13 | number = {89}, 14 | pages = {5499}, 15 | title = {{PreliZ: A tool-box for prior elicitation}}, 16 | url = {https://joss.theoj.org/papers/10.21105/joss.05499}, 17 | volume = {8}, 18 | year = {2023} 19 | } 20 | -------------------------------------------------------------------------------- /preliz/unidimensional/__init__.py: -------------------------------------------------------------------------------- 1 | from preliz.unidimensional.combine import combine 2 | from preliz.unidimensional.combine_roulette import combine_roulette 3 | from preliz.unidimensional.matching import match_moments, match_quantiles 4 | from preliz.unidimensional.maxent import maxent 5 | from preliz.unidimensional.mle import mle 6 | from preliz.unidimensional.quartile import quartile 7 | from preliz.unidimensional.quartile_int import QuartileInt 8 | from preliz.unidimensional.roulette import Roulette 9 | 10 | __all__ = [ 11 | "combine", 12 | "combine_roulette", 13 | "match_moments", 14 | "match_quantiles", 15 | "maxent", 16 | "mle", 17 | "quartile", 18 | "QuartileInt", 19 | "Roulette", 20 | ] 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior. Ideally a self-contained snippet of code, or link to a notebook or external code. Please include screenshots/images produced with PreliZ here, or the stack trace including `preliz` code to help. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Additional context** 20 | Versions of `preliz` and other libraries used, operating system used, and anything else that may be useful. 21 | -------------------------------------------------------------------------------- /docs/get_cover_gallery_multivariate.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | from preliz import Dirichlet, MvNormal, style 5 | 6 | style.use("preliz-doc") 7 | 8 | w = 1834 / 300 9 | h = 1234 / 300 10 | 11 | mu = [0.0, 0] 12 | sigma = np.array([[1, 1], [1, 1.5]]) 13 | _, ax = plt.subplots() 14 | ax = MvNormal(mu, sigma).plot_pdf(marginals=False, legend=False, ax=ax) 15 | ax.set_xticks([]) 16 | ax.set_yticks([]) 17 | ax.spines[["left", "bottom"]].set_visible(False) 18 | plt.savefig("distributions/img/MvNormal.png") 19 | 20 | _, ax = plt.subplots(figsize=(w, h)) 21 | ax = Dirichlet([5, 5, 5]).plot_pdf(marginals=False, legend=None, ax=ax) 22 | ax.get_lines()[0].set_alpha(0) 23 | ax.set_xticks([]) 24 | ax.set_yticks([]) 25 | ax.spines[["left", "bottom"]].set_visible(False) 26 | plt.savefig("distributions/img/Dirichlet.png") 27 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = # "-W" treats warnings as errors 6 | SPHINXBUILD ?= sphinx-multiversion 7 | SOURCEDIR = . 8 | BUILDDIR ?= _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | clean: 17 | rm -rf $(BUILDDIR)/* 18 | 19 | # For local build 20 | local: 21 | sphinx-build "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 22 | 23 | # Catch-all target: route all unknown targets to Sphinx using the new 24 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 25 | %: Makefile 26 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/usage-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Usage Question 3 | about: General questions about PreliZ usage 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Short Description 11 | 12 | Let us know what you're trying to do and we can point you in the right direction. Screenshots/plots or stack traces that include `preliz` are particularly helpful. 13 | 14 | ## Code Example or link 15 | 16 | Please provide a minimal, self-contained, and reproducible example demonstrating what you're trying to do. Ideally, it will be a code snippet, a link to a notebook, or a link to code that can be run on another user's computer. 17 | 18 | Also include the PreliZ version and the version of any other relevant packages. 19 | 20 | ## Relevant documentation or public examples 21 | 22 | Please provide documentation, public examples, or any additional information which may be relevant to your question 23 | -------------------------------------------------------------------------------- /preliz/tests/test_dirichlet_mode.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | 4 | from preliz import dirichlet_mode 5 | 6 | 7 | def test_dirichlet_mode(): 8 | _, dist = dirichlet_mode([0.22, 0.22, 0.32, 0.22], 0.99, bound=0.02) 9 | for alpha, expected in zip(dist.alpha, [675, 675, 981.37, 675.0]): 10 | assert np.isclose(alpha, expected, atol=0.01) 11 | 12 | 13 | def test_invalid_mass(): 14 | with pytest.raises(ValueError): 15 | dirichlet_mode([0.22, 0.22, 0.32, 0.22], 1.1, bound=0.02) 16 | 17 | 18 | def test_invalid_mode(): 19 | with pytest.raises(ValueError): 20 | dirichlet_mode([-0.2, 0.22, 0.32, 1.22], 0.99, bound=0.02) 21 | 22 | 23 | def test_plot_beta_mode(): 24 | _, _ = dirichlet_mode( 25 | mode=[0.22, 0.22, 0.32, 0.22], 26 | mass=0.99, 27 | bound=0.02, 28 | plot=True, 29 | plot_kwargs={"pointinterval": True}, 30 | ) 31 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /preliz/tests/test_combine.py: -------------------------------------------------------------------------------- 1 | from preliz.distributions import Gamma, Normal 2 | from preliz.unidimensional.combine import combine 3 | 4 | 5 | def test_combine(): 6 | # Create some sample distributions 7 | distributions = [Normal(0, 1), Gamma(2, 1)] 8 | 9 | # Call the combine function 10 | fit_dists, ax = combine(distributions, rng=413) 11 | 12 | assert [dist.__class__.__name__ for dist in fit_dists[:2]] == ["StudentT", "Normal"] 13 | assert [dist.is_frozen for dist in fit_dists] == [True, True, False, False] 14 | 15 | fit_dists, ax = combine(distributions, weights=[0, 1], rng=None, plot=0) 16 | 17 | assert [dist.__class__.__name__ for dist in fit_dists[:2]] == ["Gamma", "LogNormal"] 18 | assert [dist.is_frozen for dist in fit_dists] == [True, True, True, True] 19 | assert ax is None 20 | 21 | fit_dists, _ = combine(distributions, dist_names=["Moyal"]) 22 | assert len(fit_dists) == 1 23 | assert fit_dists[0].__class__.__name__ == "Moyal" 24 | -------------------------------------------------------------------------------- /docs/distributions/gallery/scaledinversechisquared.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Scaled Inverse Chi-Squared Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Non-Negative](../../gallery_tags.rst#non-negative), 16 | 17 | The Scaled Inverse chi-squared (Scale-Inv-$\chi^2$) is a continuous probability distribution characterized by two parameters, $\nu$, usually called degrees of freedom, and $\tau^2$, a scale parameter. 18 | 19 | More to come... 20 | 21 | ## References 22 | 23 | - [Wikipedia - Scaled Inverse Chi-squared distribution](https://en.wikipedia.org/wiki/Scaled_inverse_chi-squared_distribution) 24 | 25 | -------------------------------------------------------------------------------- /preliz/tests/test_helper.py: -------------------------------------------------------------------------------- 1 | from os import path 2 | 3 | import nbformat 4 | from nbconvert.preprocessors import ExecutePreprocessor 5 | 6 | 7 | def run_notebook(notebook): 8 | current_dir = path.dirname(path.realpath(__file__)) 9 | file_path = path.join(current_dir, notebook) 10 | 11 | with open(file_path, encoding="utf-8") as inb_f: 12 | inb = nbformat.read(inb_f, as_version=4) 13 | 14 | exec_pre = ExecutePreprocessor(timeout=600, kernel_name="python3") 15 | 16 | try: 17 | exec_pre.preprocess(inb, {"metadata": {"path": current_dir}}) 18 | except Exception as e: 19 | raise RuntimeError(f"Notebook execution failed: {e}") from e 20 | 21 | for cell in inb.cells: 22 | if cell.cell_type == "code" and "outputs" in cell: 23 | for output in cell.outputs: 24 | try: 25 | if "FAILED" in output.text: 26 | raise RuntimeError(f"Error in notebook cell:\n{output.text}") 27 | except AttributeError: 28 | pass 29 | -------------------------------------------------------------------------------- /preliz/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | PreliZ. 3 | 4 | Exploring and eliciting probability distributions 5 | """ 6 | 7 | from os import path as os_path 8 | 9 | from matplotlib import rcParams as mpl_rcParams 10 | from matplotlib import style 11 | 12 | from preliz.distributions import * 13 | from preliz.distributions.plot import plot 14 | from preliz.predictive import * 15 | from preliz.ppls import * 16 | from preliz.unidimensional import * 17 | from preliz.multidimensional import * 18 | from preliz.internal.rcparams import rc_context, rcParams 19 | from preliz.internal.citations import citations 20 | 21 | 22 | __version__ = "0.23.0" 23 | 24 | 25 | # Allow legend outside plot in maxent to be included in the saved figure 26 | mpl_rcParams["savefig.bbox"] = "tight" 27 | 28 | 29 | # add PreliZ's styles to matplotlib's styles 30 | _preliz_style_path = os_path.join(os_path.dirname(__file__), "styles") 31 | style.core.USER_LIBRARY_PATHS.append(_preliz_style_path) 32 | style.core.reload_library() 33 | 34 | # clean namespace 35 | del os_path, mpl_rcParams, _preliz_style_path 36 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | PreliZ is tested on Python 3.11+. And depends on matplotlib, numba, NumPy, and SciPy. See `pyproject.toml `_ for version information. 5 | 6 | 7 | For the latest release, you can install PreliZ either using pip or conda-forge: 8 | 9 | Using pip 10 | --------- 11 | 12 | .. code-block:: bash 13 | 14 | pip install preliz 15 | 16 | To make use of the interactive features, you can install the optional dependencies: 17 | 18 | .. tabs:: 19 | 20 | .. tab:: JupyterLab 21 | .. code-block:: bash 22 | 23 | pip install "preliz[full,lab]" 24 | 25 | .. tab:: Jupyter Notebook 26 | .. code-block:: bash 27 | 28 | pip install "preliz[full,notebook]" 29 | 30 | Using conda-forge 31 | ----------------- 32 | 33 | .. code-block:: bash 34 | 35 | conda install -c conda-forge preliz 36 | 37 | 38 | Development version 39 | ------------------- 40 | 41 | The latest development version can be installed from the main branch using pip: 42 | 43 | .. code-block:: bash 44 | 45 | pip install git+https://github.com/arviz-devs/preliz.git 46 | -------------------------------------------------------------------------------- /preliz/tests/test_optimization.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_almost_equal 4 | 5 | from preliz.distributions import ( 6 | Beta, 7 | Exponential, 8 | Geometric, 9 | HalfNormal, 10 | Laplace, 11 | Normal, 12 | Poisson, 13 | StudentT, 14 | Weibull, 15 | ) 16 | from preliz.internal.optimization import find_ppf 17 | 18 | 19 | @pytest.mark.parametrize( 20 | "p_dist, p_params", 21 | [ 22 | (Beta, {"alpha": 2, "beta": 5}), 23 | (Exponential, {"scale": 3.7}), 24 | (HalfNormal, {"sigma": 2}), 25 | (Laplace, {"mu": 2.5, "b": 4}), 26 | (Normal, {"mu": 0, "sigma": 2}), 27 | (StudentT, {"nu": 5, "mu": 0, "sigma": 2}), 28 | (Weibull, {"alpha": 5.0, "beta": 2.0}), 29 | (Geometric, {"p": 0.4}), 30 | (Poisson, {"mu": 3.5}), 31 | ], 32 | ) 33 | def test_find_ppf(p_dist, p_params): 34 | preliz_dist = p_dist(**p_params) 35 | x_vals = np.linspace(0.001, 0.999, 10) 36 | actual_ppf = preliz_dist.ppf(x_vals) 37 | expected_ppf = find_ppf(preliz_dist, x_vals) 38 | assert_almost_equal(actual_ppf, expected_ppf, decimal=4) 39 | -------------------------------------------------------------------------------- /.github/workflows/publish-to-test-pypi.yml: -------------------------------------------------------------------------------- 1 | name: Publish tagged releases to PyPI and TestPyPI 2 | 3 | on: 4 | release: 5 | types: 6 | - created 7 | 8 | jobs: 9 | build-n-publish: 10 | name: Build and publish Python distributions to PyPI and TestPyPI 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Set up Python 3.11 15 | uses: actions/setup-python@v5 16 | with: 17 | python-version: "3.11" 18 | 19 | - name: Install pypa/build 20 | run: >- 21 | python -m 22 | pip install 23 | build 24 | --user 25 | - name: Build a binary wheel and a source tarball 26 | run: >- 27 | python -m 28 | build 29 | --sdist 30 | --wheel 31 | --outdir dist/ 32 | 33 | - name: Publish distribution to Test PyPI 34 | uses: pypa/gh-action-pypi-publish@release/v1 35 | with: 36 | password: ${{ secrets.TEST_PYPI_API_TOKEN }} 37 | repository_url: https://test.pypi.org/legacy/ 38 | 39 | - name: Publish distribution to PyPI 40 | if: startsWith(github.ref, 'refs/tags') 41 | uses: pypa/gh-action-pypi-publish@release/v1 42 | with: 43 | password: ${{ secrets.PYPI_API_TOKEN }} 44 | -------------------------------------------------------------------------------- /docs/examples/gallery/direct_elicitation_ND.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Direct Elicitation in ND 13 | 14 | ```{jupyter-execute} 15 | 16 | import preliz as pz 17 | ``` 18 | 19 | ```{jupyter-execute} 20 | 21 | pz.style.use("preliz-doc") 22 | ``` 23 | 24 | ## Dirichlet mode 25 | 26 | `dirichlet_mode` returns a Dirichlet distribution where the marginals have the specified mode and mass and their masses 27 | lie within the range mode ± bound. 28 | 29 | The mode of a Dirichlet is defined as: 30 | 31 | $$x_i = \frac{\alpha_i - 1}{\alpha_0 - K}, \qquad \alpha_i > 1$$ 32 | 33 | where $K$ is the number of categories (the length of the vector $\alpha$), and $\alpha_0 = \sum_{i=1}^K\alpha_i$ 34 | 35 | ```{jupyter-execute} 36 | 37 | ax, dist = pz.dirichlet_mode([1/3, 1/3, 1/3], bound=0.2) 38 | ``` 39 | 40 | When the dimension of the Dirichlet is 3 we can also plot the joint pdf 41 | 42 | ```{jupyter-execute} 43 | 44 | dist.plot_pdf(marginals=False); 45 | ``` 46 | 47 | ```{jupyter-execute} 48 | 49 | ax, dist = pz.dirichlet_mode([0.2, 0.3, 0.5], bound=0.1) 50 | ``` 51 | 52 | ```{jupyter-execute} 53 | 54 | dist.plot_pdf(marginals=False); 55 | ``` 56 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PreliZ 2 | This document outlines only the most common contributions. 3 | Please see the [Contributing guide](https://arviz-devs.github.io/arviz/contributing/index.html) 4 | on our documentation for a better view of how can you contribute to PreliZ. 5 | We welcome a wide range of contributions, not only code! 6 | 7 | ## Reporting issues 8 | If you encounter any bug or incorrect behaviour while using PreliZ, 9 | please report an issue to our [issue tracker](https://github.com/arviz-devs/preliz/issues). 10 | Please include any supporting information, in particular the version of 11 | PreliZ that you are using. 12 | The issue tracker has several templates available to help in writing the issue 13 | and including useful supporting information. 14 | 15 | ## Contributing code 16 | Thanks for your interest in contributing code to PreliZ! 17 | 18 | * If this is your first time contributing to a project on GitHub, please read through our step by step guide to contributing to PreliZ 19 | * If you have contributed to other projects on GitHub you can go straight to our [development workflow]() 20 | 21 | ### Adding new features 22 | If you are interested in adding a new feature to PreliZ, 23 | first submit an issue using the "Feature Request" label for the community 24 | to discuss its place and implementation within PreliZ. 25 | -------------------------------------------------------------------------------- /preliz/tests/test_combine_roulette.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from numpy.testing import assert_almost_equal 3 | 4 | from preliz import combine_roulette 5 | from preliz.distributions import BetaScaled, LogNormal, StudentT 6 | 7 | response0 = ( 8 | [1.5, 2.5, 3.5], 9 | [0.32142857142857145, 0.35714285714285715, 0.32142857142857145], 10 | 28, 11 | 0, 12 | 10, 13 | 10, 14 | 11, 15 | ) 16 | response1 = ( 17 | [7.5, 8.5, 9.5], 18 | [0.32142857142857145, 0.35714285714285715, 0.32142857142857145], 19 | 28, 20 | 0, 21 | 10, 22 | 10, 23 | 11, 24 | ) 25 | response2 = ([9.5], [1], 10, 0, 10, 10, 11) 26 | response3 = ([9.5], [1], 10, 0, 10, 10, 14) 27 | 28 | 29 | @pytest.mark.parametrize( 30 | "responses, weights, dist_names, params, result", 31 | [ 32 | ([response0, response1], [0.5, 0.5], None, None, BetaScaled(1.2, 1, 0, 10)), 33 | ( 34 | [response0, response1], 35 | [0.5, 0.5], 36 | ["Beta", "StudentT"], 37 | "TruncatedNormal(lower=0), StudentT(nu=1000)", 38 | StudentT(1000, 5.5, 3.1), 39 | ), 40 | ([response0, response2], [1, 1], None, None, LogNormal(1.1, 0.6)), 41 | ], 42 | ) 43 | def test_combine_roulette(responses, weights, dist_names, params, result): 44 | dist = combine_roulette(responses, weights, dist_names, params) 45 | assert_almost_equal(dist.params, result.params, decimal=1) 46 | 47 | 48 | def test_combine_roulette_error(): 49 | with pytest.raises(ValueError): 50 | combine_roulette([response0, response3]) 51 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: "1.2.0" 2 | authors: 3 | - family-names: Icazatti 4 | given-names: Alejandro 5 | orcid: "https://orcid.org/0000-0003-1491-7330" 6 | - family-names: Abril-Pla 7 | given-names: Oriol 8 | orcid: "https://orcid.org/0000-0002-1847-9481" 9 | - family-names: Klami 10 | given-names: Arto 11 | orcid: "https://orcid.org/0000-0002-7950-1355" 12 | - family-names: Martin 13 | given-names: Osvaldo A 14 | orcid: "https://orcid.org/0000-0001-7419-8978" 15 | contact: 16 | - family-names: Martin 17 | given-names: Osvaldo A 18 | orcid: "https://orcid.org/0000-0001-7419-8978" 19 | doi: 10.5281/zenodo.8368516 20 | message: If you use this software, please cite our article in the 21 | Journal of Open Source Software. 22 | preferred-citation: 23 | authors: 24 | - family-names: Icazatti 25 | given-names: Alejandro 26 | orcid: "https://orcid.org/0000-0003-1491-7330" 27 | - family-names: Abril-Pla 28 | given-names: Oriol 29 | orcid: "https://orcid.org/0000-0002-1847-9481" 30 | - family-names: Klami 31 | given-names: Arto 32 | orcid: "https://orcid.org/0000-0002-7950-1355" 33 | - family-names: Martin 34 | given-names: Osvaldo A 35 | orcid: "https://orcid.org/0000-0001-7419-8978" 36 | date-published: 2023-09-22 37 | doi: 10.21105/joss.05499 38 | issn: 2475-9066 39 | issue: 89 40 | journal: Journal of Open Source Software 41 | publisher: 42 | name: Open Journals 43 | start: 5499 44 | title: "PreliZ: A tool-box for prior elicitation" 45 | type: article 46 | url: "https://joss.theoj.org/papers/10.21105/joss.05499" 47 | volume: 8 48 | title: "PreliZ: A tool-box for prior elicitation" 49 | -------------------------------------------------------------------------------- /preliz/tests/quartile_int.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "81849101", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "%matplotlib widget\n", 11 | "import ipytest\n", 12 | "import pytest\n", 13 | "\n", 14 | "ipytest.autoconfig()\n", 15 | "\n", 16 | "from preliz import QuartileInt" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "id": "1630c205", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "%%ipytest\n", 27 | "\n", 28 | "@pytest.mark.parametrize(\"q1, q2, q3, dist_names, figsize\", [\n", 29 | " (1, 2, 3, None, None), # Test default behavior\n", 30 | " (-1, 2, 3, [\"Poisson\", \"Normal\"], None), # Test custom list of distributions\n", 31 | " (-1, 2, 3, None, (10, 8)), # Test custom figsize\n", 32 | "])\n", 33 | "def test_quartile_int(q1, q2, q3, dist_names, figsize):\n", 34 | " QuartileInt(q1, q2, q3, dist_names, figsize)" 35 | ] 36 | } 37 | ], 38 | "metadata": { 39 | "kernelspec": { 40 | "display_name": "test", 41 | "language": "python", 42 | "name": "python3" 43 | }, 44 | "language_info": { 45 | "codemirror_mode": { 46 | "name": "ipython", 47 | "version": 3 48 | }, 49 | "file_extension": ".py", 50 | "mimetype": "text/x-python", 51 | "name": "python", 52 | "nbconvert_exporter": "python", 53 | "pygments_lexer": "ipython3", 54 | "version": "3.9.0" 55 | }, 56 | "vscode": { 57 | "interpreter": { 58 | "hash": "5b344a7d0839c309585d2ae27435157813d3b4ade1fa431f12bd272ea9135317" 59 | } 60 | } 61 | }, 62 | "nbformat": 4, 63 | "nbformat_minor": 5 64 | } 65 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - "docs/**" 9 | pull_request: 10 | paths-ignore: 11 | - "docs/**" 12 | 13 | jobs: 14 | test: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | python-version: ["3.11", "3.12", "3.13"] 19 | 20 | name: Set up Python ${{ matrix.python-version }} 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: conda-incubator/setup-miniconda@v3 28 | with: 29 | channels: conda-forge, defaults 30 | channel-priority: true 31 | python-version: ${{ matrix.python-version }} 32 | auto-update-conda: true 33 | 34 | - name: Install preliz 35 | shell: bash -l {0} 36 | run: | 37 | conda install pip 38 | pip install -r requirements-dev.txt 39 | pip install ".[full]" 40 | python --version 41 | conda list 42 | pip freeze 43 | - name: Run linters 44 | shell: bash -l {0} 45 | run: | 46 | echo "Checking code style with ruff..." 47 | ruff check preliz/ 48 | - name: Run tests 49 | shell: bash -l {0} 50 | run: | 51 | python -m pytest -vv --cov=preliz --cov-report=term --cov-report=xml preliz/tests 52 | env: 53 | PYTHON_VERSION: ${{ matrix.python-version }} 54 | 55 | - name: Upload coverage to Codecov 56 | uses: codecov/codecov-action@v5 57 | with: 58 | env_vars: OS,PYTHON 59 | name: codecov-umbrella 60 | fail_ci_if_error: false 61 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 14 | 15 | ## Checklist 16 | 17 | 18 | - [ ] Code style is correct (follows ruff guidelines) 19 | - [ ] Includes new or updated tests to cover the new feature 20 | - [ ] New features are properly documented (with an example if appropriate) 21 | - [ ] Includes a sample plot to visually illustrate the changes (only for plot-related functions) 22 | 23 | 34 | -------------------------------------------------------------------------------- /preliz/internal/predictive_helper.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from preliz.internal.distribution_helper import get_distributions 4 | from preliz.internal.plot_helper import repr_to_matplotlib 5 | from preliz.unidimensional import mle 6 | 7 | 8 | def back_fitting_ppa(model, subset, new_families=True): 9 | """Use MLE to fit a subset of the prior samples to the marginal prior distributions.""" 10 | string = "Your selection is consistent with the priors (original families):\n" 11 | 12 | for name, dist in model.items(): 13 | dist._fit_mle(subset[name]) 14 | string += f"{name} = {repr_to_matplotlib(dist)}\n" 15 | 16 | if new_families: 17 | string += "\nYour selection is consistent with the priors (new families):\n" 18 | 19 | # We should store this in a central place 20 | # So we use the same families for other functions 21 | common_cont = ["Gamma", "Exponential"] 22 | common_disc = ["Poisson", "NegativeBinomial"] 23 | for name, dist in model.items(): 24 | if dist.kind == "continuous": 25 | distributions = get_distributions(set([dist.__class__.__name__] + common_cont)) 26 | elif dist.kind == "discrete": 27 | distributions = get_distributions(set([dist.__class__.__name__] + common_disc)) 28 | idx, _ = mle(distributions, subset[name], plot=False) 29 | string += f"{name} = {repr_to_matplotlib(distributions[idx[0]])}\n" 30 | 31 | return string, np.concatenate([dist.params for dist in model.values()]) 32 | 33 | 34 | def select_prior_samples(selected, prior_samples, model): 35 | """Given a selected set of prior predictive samples pick the corresponding prior samples.""" 36 | subsample = {rv: prior_samples[rv][selected] for rv in model.keys()} 37 | 38 | return subsample 39 | -------------------------------------------------------------------------------- /preliz/tests/test_posterior_to_prior.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | from preliz.distributions import Gamma, LogNormal, Normal 4 | from preliz.ppls.agnostic import posterior_to_prior 5 | 6 | SEED = 2945 7 | 8 | data = Normal(0, 1).rvs(200, random_state=SEED) 9 | 10 | try: 11 | import pymc as pm 12 | 13 | with pm.Model() as model: 14 | a = pm.Normal("a", mu=0, sigma=1) 15 | b = pm.HalfNormal("b", sigma=[1, 1], shape=2) 16 | y = pm.Normal("y", mu=a, sigma=b[0], observed=data) 17 | idata = pm.sample(tune=200, draws=500, random_seed=SEED) 18 | except ImportError: 19 | pass 20 | 21 | 22 | def test_p2p_pymc(): 23 | posterior_to_prior(model, idata) 24 | assert 'Gamma\x1b[0m("b", alpha=' in posterior_to_prior(model, idata, new_families="auto") 25 | posterior_to_prior(model, idata, new_families=[LogNormal()]) 26 | assert 'Gamma\x1b[0m("b", mu=' in posterior_to_prior( 27 | model, idata, new_families={"b": [Gamma(mu=0)]} 28 | ) 29 | 30 | 31 | try: 32 | import bambi as bmb 33 | 34 | bmb_data = pd.DataFrame( 35 | { 36 | "y": Normal(0, 1).rvs(117, random_state=SEED + 1), 37 | "x": Normal(0, 1).rvs(117, random_state=SEED + 2), 38 | "x1": Normal(0, 1).rvs(117, random_state=SEED + 3), 39 | } 40 | ) 41 | bmb_prior = {"Intercept": bmb.Prior("Normal", mu=0, sigma=1)} 42 | bmb_model = bmb.Model("y ~ x + x1", bmb_data, priors=bmb_prior) 43 | bmb_idata = bmb_model.fit(tune=200, draws=200, random_seed=SEED) 44 | except ImportError: 45 | pass 46 | 47 | 48 | def test_p2p_bambi(): 49 | posterior_to_prior(bmb_model, bmb_idata) 50 | posterior_to_prior(bmb_model, bmb_idata, new_families="auto") 51 | posterior_to_prior(bmb_model, bmb_idata, new_families=[LogNormal()]) 52 | assert 'Normal\x1b[0m", mu=' in posterior_to_prior( 53 | bmb_model, bmb_idata, new_families={"Intercept": [Normal(mu=1, sigma=1)]} 54 | ) 55 | -------------------------------------------------------------------------------- /docs/pronunciation.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from gtts import gTTS 4 | 5 | # List of terms to generate audio files for 6 | names = { 7 | "en": [ 8 | "AsymmetricLaplace", 9 | "Censored", 10 | "ExGaussian", 11 | "Exponential", 12 | "HalfCauchy", 13 | "HalfNormal", 14 | "HalfStudentT", 15 | "Hurdle", 16 | "InverseGamma", 17 | "Logistic", 18 | "LogLogistic", 19 | "LogitNormal", 20 | "LogNormal", 21 | "Mixture", 22 | "Normal", 23 | "Rice", 24 | "SkewNormal", 25 | "SkewStudentT", 26 | "StudentT", 27 | "Triangular", 28 | "Truncated", 29 | "TruncatedNormal", 30 | "Uniform", 31 | "Binomial", 32 | "Categorical", 33 | "DiscreteUniform", 34 | "Geometric", 35 | "HyperGeometric", 36 | "NegativeBinomial", 37 | "ZeroInflatedBinomial", 38 | "ZeroInflatedNegativeBinomial", 39 | "MultivariateNormal", 40 | ], 41 | "de": ["Bernoulli", "DiscreteWeibull", "Gumbel", "VonMises", "Wald", "Weibull"], 42 | "el": [ 43 | ("Beta", "βήτα"), 44 | ("Betascaled", "βήταscaled"), 45 | ("BetaBinomial", "βήταsBinomial"), 46 | ("Gamma", "γάμμα"), 47 | ("chisquared", "χι-squared"), 48 | ("ScaledInverseChiSquared", "scaled inverse χι-squared"), 49 | ], 50 | "fr": ["Cauchy", "Dirichlet", "Laplace", "Poisson", "ZeroInflatedPoisson"], 51 | "it": ["pareto"], 52 | "hi": ["Kumaraswamy"], 53 | "es": ["Moyal"], 54 | } 55 | 56 | 57 | output_dir = "audios" 58 | os.makedirs(output_dir, exist_ok=True) 59 | 60 | for lang, terms in names.items(): 61 | for term in terms: 62 | if lang == "el": 63 | file, name = term 64 | else: 65 | file = name = term 66 | 67 | tts = gTTS(text=name, lang=lang) 68 | tts.save(f"{output_dir}/{file.lower()}.mp3") 69 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # PreliZ Community Code of Conduct 2 | 3 | PreliZ adopts the NumFOCUS Code of Conduct directly. In other words, we 4 | expect our community to treat others with kindness and understanding. 5 | 6 | 7 | # THE SHORT VERSION 8 | Be kind to others. Do not insult or put down others. 9 | Behave professionally. Remember that harassment and sexist, racist, 10 | or exclusionary jokes are not appropriate. 11 | 12 | All communication should be appropriate for a professional audience 13 | including people of many different backgrounds. Sexual language and 14 | imagery are not appropriate. 15 | 16 | PreliZ is dedicated to providing a harassment-free community for everyone, 17 | regardless of gender, sexual orientation, gender identity, and 18 | expression, disability, physical appearance, body size, race, 19 | or religion. We do not tolerate harassment of community members 20 | in any form. 21 | 22 | Thank you for helping make this a welcoming, friendly community for all. 23 | 24 | 25 | # How to Submit a Report 26 | If you feel that there has been a Code of Conduct violation an anonymous 27 | reporting form is available. 28 | **If you feel your safety is in jeopardy or the situation is an 29 | emergency, we urge you to contact local law enforcement before making 30 | a report. (In the U.S., dial 911.)** 31 | 32 | We are committed to promptly addressing any reported issues. 33 | If you have experienced or witnessed behavior that violates this 34 | Code of Conduct, please complete the form below to 35 | make a report. 36 | 37 | **REPORTING FORM:** https://numfocus.typeform.com/to/ynjGdT 38 | 39 | Reports are sent to the NumFOCUS Code of Conduct Enforcement Team 40 | (see below). 41 | 42 | You can view the Privacy Policy and Terms of Service for TypeForm here. 43 | The NumFOCUS Privacy Policy is here: 44 | https://www.numfocus.org/privacy-policy 45 | 46 | 47 | # Full Code of Conduct 48 | The full text of the NumFOCUS/PreliZ Code of Conduct can be found on 49 | NumFOCUS's website 50 | https://numfocus.org/code-of-conduct 51 | -------------------------------------------------------------------------------- /docs/examples/gallery/global_settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Global Settings 12 | 13 | ```{jupyter-execute} 14 | 15 | import preliz as pz 16 | ``` 17 | 18 | Some of the PreliZ default values are regulated by `preliz.rcParams`, a class similar to a dictionary storing key-value pairs inspired by the one in matplotlib and ArviZ. It is similar to a dictionary and not a dictionary though because all keys are fixed, and each key has associated a validation function to help prevent setting nonsensical defaults. 19 | 20 | ## Preliz Configuration File 21 | 22 | The `rcParams` class is generated and populated at import time. PreliZ checks several locations for a file named `prelizrc` and, if found, prefers those settings over the library ones. 23 | 24 | The locations checked are the following: 25 | 26 | 1. Current working directory, {func}`os.getcwd` 27 | 2. Location indicated by {envvar}`PRELIZ_DATA` environment variable 28 | 3. The third and last location checked is OS dependent: 29 | - On Linux: `$XDG_CONFIG_HOME/preliz` if exists, otherwise `~/.config/preliz/` 30 | - Elsewhere: `~/.preliz/` 31 | 32 | The file is a simple text file with a structure similar to the following: 33 | 34 | ```text 35 | stats.ci_kind : eti 36 | stats.ci_prob : 0.89 37 | ``` 38 | 39 | All available keys are listed below. The `prelizrc` file can have any subset of the keys, it isn't necessary to include them all. For those keys without a user defined default, the library one is used. 40 | 41 | To find out the current settings, you can use: 42 | 43 | ```{jupyter-execute} 44 | 45 | pz.rcParams 46 | ``` 47 | 48 | ## Context manager 49 | 50 | A context manager is also available to temporarily change the default settings. 51 | 52 | ```{jupyter-execute} 53 | 54 | with pz.rc_context({"plots.show_plot": False}): 55 | pz.maxent(pz.Normal()) 56 | ``` 57 | 58 | The context manager accepts a dictionary, a file path, or both. 59 | -------------------------------------------------------------------------------- /preliz/internal/citations.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | 5 | def citations(methods=None, filepath=None, format_type="bibtex"): 6 | """ 7 | Generate references associated with the methods. 8 | 9 | Parameters 10 | ---------- 11 | methods : str or list, optional 12 | Specifies the PreliZ methods or classes for which to display references. 13 | Use `"all"` to show references for all available methods/classes. 14 | Defaults to `None`, which displays PreliZ references. 15 | 16 | filepath : str or a file-like object 17 | Specifies the location to save the file. 18 | If ``None``, the result is returned as a string. 19 | 20 | format_type : str 21 | Specifies in which type the references will be displayed. 22 | Currently, only "bibtex" is supported. 23 | Defaults to ``bibtex``. 24 | 25 | """ 26 | ref_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "reference.bib") 27 | with open(ref_path, encoding="utf-8") as fr: 28 | content = fr.read() 29 | if methods == "all": 30 | keys = set(re.findall(r"@.*?\{(.*?),", content)) 31 | elif methods is None: 32 | keys = {"PreliZ", "Icazatti2023"} 33 | else: 34 | keys = set() 35 | for method in methods: 36 | matches = set(re.findall(r":(?:cite|footcite):[tp]:`(.*?)`", method.__doc__)) 37 | keys.update(matches) 38 | if format_type == "bibtex": 39 | cite_text = _citation_bibtex(content, keys) 40 | if filepath: 41 | with open(filepath, "w") as fw: 42 | fw.write(cite_text) 43 | else: 44 | return cite_text 45 | else: 46 | raise ValueError("Invalid value for format_type. Use 'bibtex'.") 47 | 48 | 49 | def _citation_bibtex(content, keys): 50 | """Extract and return references in BibTeX format.""" 51 | extracted_refs = [] 52 | for key in keys: 53 | match = re.search(rf"(@\w+\{{\s*{key}\s*,.*?\n\}})", content, re.DOTALL) 54 | extracted_refs.append(match.group(1)) 55 | return "\n".join(extracted_refs) 56 | -------------------------------------------------------------------------------- /preliz/tests/test_censored.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_almost_equal 4 | from scipy.stats import kurtosis, skew 5 | 6 | from preliz.distributions import Censored, Normal, Poisson 7 | 8 | 9 | @pytest.mark.parametrize( 10 | "dist, lower, upper", 11 | [ 12 | (Normal(0, 2), -2, 2), 13 | (Poisson(3.5), 1, 6), 14 | ], 15 | ) 16 | def test_censored(dist, lower, upper): 17 | cen_dist = Censored(dist, lower, upper) 18 | cen_dist_inf = Censored(dist, -np.inf, np.inf) 19 | 20 | x_vals = cen_dist.rvs(1000000, random_state=1) 21 | assert_almost_equal(np.mean(x_vals == lower), dist.cdf(lower), decimal=2) 22 | if dist.kind == "discrete": 23 | assert_almost_equal(np.mean(x_vals == upper), 1 - dist.cdf(upper - 1), decimal=2) 24 | else: 25 | assert_almost_equal(np.mean(x_vals == upper), 1 - dist.cdf(upper), decimal=2) 26 | 27 | x_inside = x_vals[(x_vals > lower) & (x_vals < upper)] 28 | assert_almost_equal(dist.logpdf(x_inside), cen_dist.logpdf(x_inside)) 29 | assert_almost_equal(dist.cdf(x_inside), cen_dist.cdf(x_inside)) 30 | 31 | assert_almost_equal(dist.cdf(x_inside), cen_dist.cdf(x_inside)) 32 | 33 | assert_almost_equal(cen_dist.median(), dist.median()) 34 | assert_almost_equal(x_vals.mean(), cen_dist.mean(), decimal=1) 35 | assert_almost_equal(x_vals.var(), cen_dist.var(), decimal=1) 36 | assert_almost_equal(skew(x_vals), cen_dist.skewness(), decimal=0) 37 | assert_almost_equal(kurtosis(x_vals), cen_dist.kurtosis(), decimal=0) 38 | 39 | actual_mean = dist.mean() 40 | expected_mean = cen_dist_inf.mean() 41 | assert_almost_equal(actual_mean, expected_mean, decimal=2) 42 | 43 | actual_var = dist.var() 44 | expected_var = cen_dist_inf.var() 45 | assert_almost_equal(actual_var, expected_var, decimal=2) 46 | 47 | actual_entropy = dist.entropy() 48 | expected_entropy = cen_dist_inf.entropy() 49 | assert_almost_equal(actual_entropy, expected_entropy, decimal=1) 50 | 51 | c_l, c_u = cen_dist.hdi() 52 | d_l, d_u = dist.hdi() 53 | assert c_l >= d_l 54 | assert c_u <= d_u 55 | assert_almost_equal(cen_dist_inf.hdi(), dist.hdi()) 56 | -------------------------------------------------------------------------------- /preliz/tests/test_matching.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | 4 | import preliz as pz 5 | from preliz.unidimensional.matching import match_moments, match_quantiles 6 | 7 | 8 | @pytest.fixture 9 | def normal_dist(): 10 | return pz.Normal(15, 1) 11 | 12 | 13 | @pytest.fixture 14 | def gamma_dist(): 15 | return pz.Gamma() 16 | 17 | 18 | def test_match_moments_basic(normal_dist, gamma_dist): 19 | match_moments(normal_dist, gamma_dist) 20 | assert np.isclose(gamma_dist.mean(), normal_dist.mean(), atol=1e-2) 21 | assert np.isclose(gamma_dist.std(), normal_dist.std(), atol=1e-2) 22 | 23 | 24 | def test_match_moments_custom_moments(normal_dist, gamma_dist): 25 | match_moments(normal_dist, gamma_dist, moments="mdk") 26 | assert np.isclose(gamma_dist.mean(), normal_dist.mean(), atol=1e-2) 27 | assert np.isclose(gamma_dist.std(), normal_dist.std(), atol=1e-2) 28 | 29 | 30 | def test_match_moments_invalid_moments(normal_dist, gamma_dist): 31 | with pytest.raises(ValueError): 32 | match_moments(pz.Cauchy(), gamma_dist) 33 | 34 | with pytest.raises(ValueError): 35 | match_moments(normal_dist, pz.Cauchy()) 36 | 37 | 38 | def test_match_quantiles_basic(normal_dist, gamma_dist): 39 | match_quantiles(normal_dist, gamma_dist) 40 | q = np.array([0.25, 0.5, 0.5]) 41 | assert np.allclose(gamma_dist.ppf(q), normal_dist.ppf(q), atol=1e-2) 42 | 43 | 44 | def test_match_quantiles_custom_quantiles(normal_dist): 45 | to_dist = pz.StudentT(nu=5) 46 | quantiles = [0.1, 0.5, 0.9] 47 | match_quantiles(normal_dist, to_dist, quantiles=quantiles) 48 | assert np.allclose(to_dist.ppf(quantiles), normal_dist.ppf(quantiles), atol=1e-2) 49 | 50 | 51 | def test_match_quantiles_invalid_quantiles(normal_dist): 52 | to_dist = pz.Gamma() 53 | with pytest.raises(ValueError): 54 | match_quantiles(normal_dist, to_dist, quantiles=[-0.1, 1.1]) 55 | 56 | 57 | def test_match_moments_plot(normal_dist, gamma_dist): 58 | result = match_moments(normal_dist, gamma_dist, plot=True) 59 | assert isinstance(result, tuple) 60 | assert hasattr(result[0], "mean") 61 | assert hasattr(result[1], "plot") 62 | 63 | 64 | def test_match_quantiles_plot(normal_dist, gamma_dist): 65 | result = match_quantiles(normal_dist, gamma_dist, plot=True) 66 | assert isinstance(result, tuple) 67 | assert hasattr(result[0], "mean") 68 | assert hasattr(result[1], "plot") 69 | -------------------------------------------------------------------------------- /preliz/tests/check_inside_notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "81849101", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import ipytest\n", 11 | "import pytest\n", 12 | "\n", 13 | "ipytest.autoconfig()\n", 14 | "import sys\n", 15 | "\n", 16 | "from preliz.internal.plot_helper import check_inside_notebook" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "id": "1630c205", 23 | "metadata": {}, 24 | "outputs": [ 25 | { 26 | "name": "stdout", 27 | "output_type": "stream", 28 | "text": [ 29 | "\u001b[32m.\u001b[0m\u001b[32m [100%]\u001b[0m\n", 30 | "\u001b[32m\u001b[32m\u001b[1m1 passed\u001b[0m\u001b[32m in 0.01s\u001b[0m\u001b[0m\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "%%ipytest\n", 36 | "\n", 37 | "def test_ok(capsys):\n", 38 | " check_inside_notebook()\n", 39 | " captured = capsys.readouterr()\n", 40 | " assert \"\" == captured.out" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 3, 46 | "id": "843a0c94", 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "\u001b[32m.\u001b[0m\u001b[32m [100%]\u001b[0m\n", 54 | "\u001b[32m\u001b[32m\u001b[1m1 passed\u001b[0m\u001b[32m in 0.01s\u001b[0m\u001b[0m\n" 55 | ] 56 | } 57 | ], 58 | "source": [ 59 | "%%ipytest\n", 60 | "\n", 61 | "def test_widget_fail(capsys):\n", 62 | " check_inside_notebook(need_widget=True)\n", 63 | " captured = capsys.readouterr()\n", 64 | " assert \"widget\" in captured.out\n" 65 | ] 66 | } 67 | ], 68 | "metadata": { 69 | "kernelspec": { 70 | "display_name": "preliz", 71 | "language": "python", 72 | "name": "python3" 73 | }, 74 | "language_info": { 75 | "codemirror_mode": { 76 | "name": "ipython", 77 | "version": 3 78 | }, 79 | "file_extension": ".py", 80 | "mimetype": "text/x-python", 81 | "name": "python", 82 | "nbconvert_exporter": "python", 83 | "pygments_lexer": "ipython3", 84 | "version": "3.11.8" 85 | } 86 | }, 87 | "nbformat": 4, 88 | "nbformat_minor": 5 89 | } 90 | -------------------------------------------------------------------------------- /docs/distributions/gallery/categorical.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Categorical Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Categorical distribution is the most general discrete distribution and is parameterized by a vector $p$ where each element $p_i$ specifies the probabilities of each possible outcome. 18 | 19 | ## Key properties and parameters 20 | 21 | ```{eval-rst} 22 | ======== =================================== 23 | Support :math:`x \in \{0, 1, \ldots, |p|-1\}` 24 | ======== =================================== 25 | ``` 26 | 27 | **Parameters:** 28 | 29 | - $p$ : (array) Probabilities of each category, $p_i \geq 0$ and $\sum_i p_i = 1$. 30 | 31 | ### Probability Density Function (PDF) 32 | 33 | $$ 34 | f(x) = p_x 35 | $$ 36 | 37 | ```{code-cell} 38 | --- 39 | tags: [remove-input] 40 | mystnb: 41 | image: 42 | alt: Categorical Distribution PDF 43 | --- 44 | 45 | from preliz import Categorical, style 46 | style.use('preliz-doc') 47 | ps = [[0.1, 0.6, 0.3], [0.3, 0.1, 0.1, 0.5]] 48 | for p in ps: 49 | Categorical(p).plot_pdf() 50 | ``` 51 | 52 | ### Cumulative Distribution Function (CDF) 53 | 54 | $$ 55 | F(x \mid p) = \begin{cases} 56 | 0 & \text{if } x < 0 \\ 57 | \sum_{i=0}^{x} p_i & \text{if } 0 \leq x < |p| \\ 58 | 1 & \text{if } x \geq |p| 59 | \end{cases} 60 | $$ 61 | 62 | where $p$ is the array of probabilities for each category. 63 | 64 | ```{code-cell} 65 | --- 66 | tags: [remove-input] 67 | mystnb: 68 | image: 69 | alt: Categorical Distribution CDF 70 | --- 71 | 72 | for p in ps: 73 | Categorical(p).plot_cdf() 74 | ``` 75 | 76 | ```{seealso} 77 | :class: seealso 78 | 79 | **Related Distributions:** 80 | 81 | - [Bernoulli](bernoulli.md) - The Categorical distribution is a generalization of the Bernoulli distribution to more than two outcomes. 82 | - [Discrete Uniform](discrete_uniform.md) - A special case of the Categorical distribution where all outcomes have equal probability. 83 | ``` 84 | 85 | ## References 86 | 87 | - [Wikipedia - Categorical Distribution](https://en.wikipedia.org/wiki/Categorical_distribution) -------------------------------------------------------------------------------- /preliz/tests/test_ppe.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | try: 4 | import pymc as pm 5 | except ImportError: 6 | pass 7 | import pytest 8 | from numpy.testing import assert_allclose 9 | 10 | import preliz as pz 11 | 12 | rng = np.random.default_rng(1241) 13 | 14 | 15 | @pytest.mark.parametrize( 16 | "params", 17 | [ 18 | { 19 | "mu_x": 0, 20 | "sigma_x": 10, 21 | "sigma_z": 10, 22 | "target": pz.Normal(mu=174, sigma=20), 23 | "X": rng.normal(0, 10, 120), 24 | "new_x": 174, 25 | "new_z": 2.9, 26 | }, 27 | { 28 | "mu_x": [0, 1], 29 | "sigma_x": [10, 10], 30 | "sigma_z": 10, 31 | "target": pz.Normal(mu=174, sigma=20), 32 | "X": rng.normal(0, 10, 120), 33 | "new_x": [174, 174], 34 | "new_z": 2.9, 35 | }, 36 | { 37 | "mu_x": 0, 38 | "sigma_x": 10, 39 | "sigma_z": 10, 40 | "target": [(pz.Normal(mu=174, sigma=20), 0.5), (pz.Normal(mu=176, sigma=19.5), 0.5)], 41 | "X": rng.normal(0, 10, 120), 42 | "new_x": 175, 43 | "new_z": 2.9, 44 | }, 45 | { 46 | "mu_x": [0, 1], 47 | "sigma_x": 10, 48 | "sigma_z": 10, 49 | "target": [ 50 | (pz.Normal(mu=174, sigma=20), 0.5), 51 | (pz.Normal(mu=176, sigma=19.5), 0.4), 52 | (pz.StudentT(mu=174, sigma=20, nu=3), 0.1), 53 | ], 54 | "X": rng.normal(0, 10, 120), 55 | "new_x": [175, 175], 56 | "new_z": 3, 57 | }, 58 | ], 59 | ) 60 | def test_ppe(params): 61 | Y = np.zeros_like(params["X"]) 62 | target = params.pop("target") 63 | with pm.Model() as model: 64 | x = pm.Normal("x", shape=1 if isinstance(params["mu_x"], int) else 2) 65 | z = pm.HalfNormal("z") 66 | x_idx = ( 67 | x if np.asarray(params["mu_x"]).size == 1 else x[np.repeat(np.arange(2), Y.size / 2)] 68 | ) 69 | pm.Normal("y", x_idx, z, observed=Y) 70 | 71 | new_prior = pz.ppe(model, target).replace("\x1b[1m", "").replace("\x1b[0m", "") 72 | exec_context = {} 73 | exec(new_prior, globals(), exec_context) 74 | model = exec_context.get("model") 75 | initial = model.initial_point() 76 | assert_allclose(initial["x"], params["new_x"]) 77 | assert_allclose(initial["z_log__"], params["new_z"], atol=0.1) 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | _build 74 | jupyter_execute 75 | docs/examples/*.png 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # Lint cache 135 | .ruff_cache/ 136 | -------------------------------------------------------------------------------- /preliz/tests/test_hurdle.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_almost_equal 4 | 5 | from preliz.distributions import ( 6 | Gamma, 7 | Hurdle, 8 | LogNormal, 9 | NegativeBinomial, 10 | Normal, 11 | Poisson, 12 | Truncated, 13 | ) 14 | from preliz.internal.distribution_helper import eps 15 | 16 | 17 | @pytest.mark.parametrize( 18 | "dist", 19 | [ 20 | (Gamma(3, 5)), 21 | (LogNormal(0, 0.5)), 22 | (Normal(0, 2)), 23 | (Poisson(3.5)), 24 | (NegativeBinomial(3, 5)), 25 | ], 26 | ) 27 | def test_hurdle_vs_truncated(dist): 28 | if dist.kind == "discrete": 29 | lower = 1 30 | else: 31 | lower = eps 32 | 33 | hurdle_dist = Hurdle(dist, 1) 34 | base_dist = Truncated(dist, lower=lower, upper=np.inf) 35 | 36 | rng = np.random.default_rng(1) 37 | actual_rvs = hurdle_dist.rvs(100_000, random_state=rng) 38 | expected_rvs = base_dist.rvs(100_000, random_state=rng) 39 | assert_almost_equal(actual_rvs.mean(), expected_rvs.mean(), decimal=2) 40 | assert_almost_equal(actual_rvs.var(), expected_rvs.var(), decimal=2) 41 | 42 | assert_almost_equal(hurdle_dist.mean(), base_dist.mean(), decimal=2) 43 | assert_almost_equal(hurdle_dist.var(), base_dist.var(), decimal=3) 44 | assert_almost_equal(hurdle_dist.std(), base_dist.std(), decimal=4) 45 | assert_almost_equal(hurdle_dist.entropy(), base_dist.entropy()) 46 | 47 | few_rvs = hurdle_dist.rvs(20, random_state=rng) 48 | assert_almost_equal(hurdle_dist.pdf(few_rvs), base_dist.pdf(few_rvs)) 49 | assert_almost_equal(hurdle_dist.cdf(few_rvs), base_dist.cdf(few_rvs)) 50 | assert_almost_equal(hurdle_dist.logpdf(few_rvs), base_dist.logpdf(few_rvs)) 51 | assert_almost_equal(hurdle_dist._neg_logpdf(few_rvs), base_dist._neg_logpdf(few_rvs)) 52 | x_vals = [-1, 0, 0.25, 0.5, 0.75, 1, 2] 53 | assert_almost_equal(hurdle_dist.ppf(x_vals), base_dist.ppf(x_vals)) 54 | 55 | 56 | @pytest.mark.parametrize( 57 | "dist", 58 | [ 59 | (Gamma(3, 5)), 60 | (LogNormal(0, 0.5)), 61 | (Normal(0, 2)), 62 | (Poisson(3.5)), 63 | (NegativeBinomial(3, 5)), 64 | ], 65 | ) 66 | def test_hurdle_vs_random(dist): 67 | hurdle_dist = Hurdle(dist, psi=0.7) 68 | 69 | rng = np.random.default_rng(1) 70 | rvs = hurdle_dist.rvs(500_000, random_state=rng) 71 | 72 | assert_almost_equal(hurdle_dist.mean(), rvs.mean(), decimal=2) 73 | assert_almost_equal(hurdle_dist.var(), rvs.var(), decimal=0) 74 | assert_almost_equal(hurdle_dist.std(), rvs.std(), decimal=0) 75 | -------------------------------------------------------------------------------- /preliz/tests/test_special.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numpy.testing import assert_almost_equal 3 | from scipy import special as sc_special 4 | 5 | from preliz.internal import special as pz_special 6 | 7 | 8 | def test_erf(): 9 | x = np.linspace(-2, 2, 100) 10 | assert_almost_equal(sc_special.erf(x), pz_special.erf(x)) 11 | 12 | 13 | def test_inv_erf(): 14 | x = np.linspace(-0.9, 0.9, 100) 15 | assert_almost_equal(sc_special.erfinv(x), pz_special.erfinv(x)) 16 | 17 | 18 | def test_beta(): 19 | a = np.linspace(0, 10, 100) 20 | b = np.linspace(0, 10, 100) 21 | assert_almost_equal(sc_special.beta(a, b), pz_special.beta(a, b)) 22 | 23 | 24 | def test_betaln(): 25 | a = np.linspace(0, 10, 100) 26 | b = np.linspace(0, 10, 100) 27 | assert_almost_equal(sc_special.betaln(a, b), pz_special.betaln(a, b)) 28 | 29 | 30 | def test_betainc(): 31 | x = np.linspace(0, 1, 100) 32 | a = np.linspace(0, 10, 100) 33 | b = np.linspace(0, 10, 100) 34 | assert_almost_equal(sc_special.betainc(a, b, x), pz_special.betainc(a, b, x)) 35 | 36 | 37 | def test_betaincinv(): 38 | x = np.linspace(0, 1, 100) 39 | a = np.linspace(0, 10, 100) 40 | b = np.linspace(0, 10, 100) 41 | # in scipy < 1.12 this matches to at least 1e-7 42 | # in scipy >= 1.12 this matches to 1e-5 43 | assert_almost_equal(sc_special.betaincinv(a, b, x), pz_special.betaincinv(a, b, x)) 44 | 45 | 46 | def test_gammaln(): 47 | x = np.linspace(0.1, 10, 100) 48 | assert_almost_equal(sc_special.gammaln(x), pz_special.gammaln(x)) 49 | 50 | 51 | def test_gamma(): 52 | x = np.linspace(0.1, 10, 100) 53 | assert_almost_equal(sc_special.gamma(x), pz_special.gamma(x)) 54 | 55 | 56 | def test_digamma(): 57 | x = np.linspace(0.1, 10, 100) 58 | assert_almost_equal(sc_special.digamma(x), pz_special.digamma(x)) 59 | 60 | 61 | def test_logit(): 62 | x = np.linspace(-0.1, 1.1, 100) 63 | assert_almost_equal(sc_special.logit(x), pz_special.logit(x)) 64 | 65 | 66 | def test_expit(): 67 | x = np.linspace(-20, 10, 500) 68 | assert_almost_equal(sc_special.expit(x), pz_special.expit(x)) 69 | 70 | 71 | def test_xlogy(): 72 | x = np.linspace(0, 10, 10) 73 | y = np.linspace(0, 10, 10) 74 | assert_almost_equal(sc_special.xlogy(x, y), pz_special.xlogy(x, y)) 75 | 76 | 77 | def test_xlog1py(): 78 | x = np.linspace(0, 10, 10) 79 | y = np.linspace(0, 10, 10) 80 | assert_almost_equal(sc_special.xlog1py(x, y), pz_special.xlog1py(x, y)) 81 | 82 | 83 | def test_xlogx(): 84 | x = np.linspace(0.0, 10, 10) 85 | assert_almost_equal(pz_special.xlogy(x, x), pz_special.xlogx(x)) 86 | -------------------------------------------------------------------------------- /preliz/tests/test_non_scipy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numpy.testing import assert_almost_equal 3 | from scipy import integrate 4 | from scipy.stats import kurtosis, skew 5 | 6 | from preliz.distributions import Categorical, DiscreteWeibull, ScaledInverseChiSquared 7 | 8 | 9 | def test_categorical(): 10 | p = [0.2, 0.5, 0.3] 11 | q = [0.2, 0.7, 1] 12 | dist = Categorical(p) 13 | assert dist.p.sum() == 1.0 14 | assert all(dist.pdf([0, 1, 2]) == p) 15 | assert all(dist.cdf([0, 1, 2]) == np.cumsum(p)) 16 | assert all(dist.cdf(dist.ppf(q)) == q) 17 | 18 | 19 | def test_disc_weibull_vs_random(): 20 | dist = DiscreteWeibull(0.7, 0.9) 21 | 22 | rng = np.random.default_rng(1) 23 | rvs = dist.rvs(500_000, random_state=rng) 24 | 25 | assert_almost_equal(dist.mean(), rvs.mean(), decimal=2) 26 | assert_almost_equal(dist.median(), np.median(rvs), decimal=2) 27 | assert_almost_equal(dist.var(), rvs.var(), decimal=1) 28 | assert_almost_equal(dist.std(), rvs.std(), decimal=1) 29 | assert_almost_equal(dist.skewness(), skew(rvs), decimal=1) 30 | assert_almost_equal(dist.kurtosis(), kurtosis(rvs), decimal=0) 31 | 32 | q = np.linspace(0.1, 0.9, 10) 33 | assert_almost_equal(dist.ppf(q), np.quantile(rvs, q), decimal=2) 34 | 35 | for x in np.arange(6): 36 | assert_almost_equal(dist.pdf(x), np.mean(rvs == x), decimal=2) 37 | assert_almost_equal(dist.cdf(x), np.sum(dist.pdf(np.arange(x + 1))), decimal=2) 38 | assert_almost_equal(dist.cdf(x), np.sum(np.exp(dist.logpdf(np.arange(x + 1)))), decimal=2) 39 | assert_almost_equal(dist.cdf(x), np.mean(rvs <= x), decimal=2) 40 | 41 | 42 | def test_scaled_inverse_chi2(): 43 | dist = ScaledInverseChiSquared(15, 1) 44 | 45 | rng = np.random.default_rng(1) 46 | rvs = dist.rvs(500_000, random_state=rng) 47 | 48 | assert_almost_equal(dist.mean(), rvs.mean(), decimal=2) 49 | assert_almost_equal(dist.median(), np.median(rvs), decimal=2) 50 | assert_almost_equal(dist.var(), rvs.var(), decimal=1) 51 | assert_almost_equal(dist.std(), rvs.std(), decimal=1) 52 | assert_almost_equal(dist.skewness(), skew(rvs), decimal=0) 53 | assert_almost_equal(dist.kurtosis(), kurtosis(rvs), decimal=0) 54 | 55 | q = np.linspace(0.1, 0.9, 10) 56 | assert_almost_equal(dist.ppf(q), np.quantile(rvs, q), decimal=2) 57 | assert_almost_equal(dist.cdf(dist.ppf(q)), q, decimal=2) 58 | 59 | for x in np.arange(6): 60 | assert_almost_equal(dist.cdf(x), np.mean(rvs <= x), decimal=2) 61 | 62 | assert_almost_equal(integrate.quad(dist.pdf, 0.1, 50)[0], 1, decimal=5) 63 | 64 | for x in np.linspace(0.2, 10, 5): 65 | val, _ = integrate.quad(dist.pdf, 0, x) 66 | assert_almost_equal(val, dist.cdf(x)) 67 | -------------------------------------------------------------------------------- /preliz/tests/test_truncated.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numpy.testing import assert_almost_equal 3 | 4 | from preliz.distributions import Normal, Truncated, TruncatedNormal 5 | 6 | 7 | def test_truncated(): 8 | custom_truncnorm_dist = Truncated(Normal(0, 2), -1, np.inf) 9 | genera_truncnorm_dist = TruncatedNormal(0, 2, -1, np.inf) 10 | 11 | rng = np.random.default_rng(1) 12 | actual_rvs = custom_truncnorm_dist.rvs(20, random_state=rng) 13 | rng = np.random.default_rng(1) 14 | expected_rvs = genera_truncnorm_dist.rvs(20, random_state=rng) 15 | assert_almost_equal(actual_rvs, expected_rvs) 16 | 17 | actual_pdf = custom_truncnorm_dist.pdf(actual_rvs) 18 | expected_pdf = genera_truncnorm_dist.pdf(actual_rvs) 19 | assert_almost_equal(actual_pdf, expected_pdf, decimal=4) 20 | 21 | support = custom_truncnorm_dist.support 22 | cdf_vals = np.concatenate([actual_rvs, support, [support[0] - 1], [support[1] + 1]]) 23 | 24 | actual_cdf = custom_truncnorm_dist.cdf(cdf_vals) 25 | expected_cdf = genera_truncnorm_dist.cdf(cdf_vals) 26 | assert_almost_equal(actual_cdf, expected_cdf, decimal=6) 27 | 28 | x_vals = [-1, 0, 0.25, 0.5, 0.75, 1, 2] 29 | actual_ppf = custom_truncnorm_dist.ppf(x_vals) 30 | expected_ppf = genera_truncnorm_dist.ppf(x_vals) 31 | assert_almost_equal(actual_ppf, expected_ppf) 32 | 33 | actual_logpdf = custom_truncnorm_dist.logpdf(actual_rvs) 34 | expected_logpdf = genera_truncnorm_dist.logpdf(actual_rvs) 35 | assert_almost_equal(actual_logpdf, expected_logpdf) 36 | 37 | actual_neg_logpdf = custom_truncnorm_dist._neg_logpdf(actual_rvs) 38 | expected_neg_logpdf = -expected_logpdf.sum() 39 | assert_almost_equal(actual_neg_logpdf, expected_neg_logpdf) 40 | 41 | actual_median = custom_truncnorm_dist.median() 42 | expected_median = genera_truncnorm_dist.median() 43 | assert_almost_equal(actual_median, expected_median) 44 | 45 | actual_mean = custom_truncnorm_dist.mean() 46 | expected_mean = genera_truncnorm_dist.mean() 47 | assert_almost_equal(actual_mean, expected_mean, decimal=2) 48 | 49 | actual_var = custom_truncnorm_dist.var() 50 | expected_var = genera_truncnorm_dist.var() 51 | assert_almost_equal(actual_var, expected_var, decimal=2) 52 | 53 | actual_skew = custom_truncnorm_dist.skewness() 54 | expected_skew = genera_truncnorm_dist.skewness() 55 | assert_almost_equal(actual_skew, expected_skew, decimal=2) 56 | 57 | actual_kurt = custom_truncnorm_dist.kurtosis() 58 | expected_kurt = genera_truncnorm_dist.kurtosis() 59 | assert_almost_equal(actual_kurt, expected_kurt, decimal=1) 60 | 61 | actual_entropy = custom_truncnorm_dist.entropy() 62 | expected_entropy = genera_truncnorm_dist.entropy() 63 | assert_almost_equal(actual_entropy, expected_entropy, decimal=2) 64 | -------------------------------------------------------------------------------- /docs/distributions/gallery/kumaraswamy.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Kumaraswamy Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Kumaraswamy distribution is a continuous probability distribution bounded between 0 and 1. It is characterized by two positive shape parameters: $a$ and $b$. 18 | 19 | The Kumaraswamy distribution is a flexible distribution that can adopt a wide range of shapes, including uniform, U-shape, exponential-like, and many others, always restricted to the unit interval [0, 1]. 20 | 21 | ## Key properties and parameters: 22 | 23 | ```{eval-rst} 24 | ======== ============================================================== 25 | Support :math:`x \in (0, 1)` 26 | Mean :math:`b B(1 + \tfrac{1}{a}, b)` 27 | Variance :math:`b B(1 + \tfrac{2}{a}, b) - (b B(1 + \tfrac{1}{a}, b))^2` 28 | ======== ============================================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $a$ : (float) First shape parameter, $a > 0$. 34 | - $b$ : (float) Second shape parameter, $b > 0$. 35 | 36 | ### Probability Density Function (PDF) 37 | 38 | $$ 39 | f(x|a, b) = a b x^{a-1} (1 - x^{a})^{b-1} 40 | $$ 41 | 42 | ```{code-cell} 43 | --- 44 | tags: [remove-input] 45 | mystnb: image 46 | --- 47 | import matplotlib.pyplot as plt 48 | 49 | from preliz import Kumaraswamy, style 50 | style.use('preliz-doc') 51 | 52 | a_s = [.5, 5., 1., 1., 2., 2.] 53 | b_s = [.5, 1., 1., 3., 2., 5.] 54 | 55 | for a, b in zip(a_s, b_s): 56 | ax = Kumaraswamy(a, b).plot_pdf() 57 | ax.set_ylim(0, 3.) 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x|a, b) = 1 - (1 - x^{a})^{b} 64 | $$ 65 | 66 | ```{code-cell} 67 | --- 68 | tags: [remove-input] 69 | mystnb: image 70 | --- 71 | for a, b in zip(a_s, b_s): 72 | ax = Kumaraswamy(a, b).plot_cdf() 73 | ``` 74 | 75 | ```{seealso} 76 | :class: seealso 77 | 78 | **Common Alternatives:** 79 | 80 | - [Beta](beta.md) - The Kumaraswamy distribution is similar to the Beta distribution, but with closed-form expressions for its probability density function, cumulative distribution function and quantile function. 81 | 82 | **Related Distributions:** 83 | 84 | - [Uniform](uniform.md) - The Uniform distribution on the interval [0, 1] is a special case of the Kumaraswamy distribution with $a = b = 1$. 85 | ``` 86 | 87 | ## References 88 | 89 | - [Wikipedia - Kumaraswamy distribution](https://en.wikipedia.org/wiki/Kumaraswamy_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/halfcauchy.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Half-Cauchy Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Non-Negative](../../gallery_tags.rst#non-negative), [Asymmetric](../../gallery_tags.rst#asymmetric), [Heavy-tailed](../../gallery_tags.rst#heavy-tailed) 16 | 17 | The Half-Cauchy distribution is a continuous probability distribution that is derived from the Cauchy distribution but is restricted to only positive values. It is characterized by a single scale parameter ($\beta$), which determines the width of the distribution. Similar to the Cauchy distribution, the Half-Cauchy distribution has undefined mean and variance, making it an example of a "pathological" distribution with heavy tails. 18 | 19 | In Bayesian statistics, the Half-Cauchy distribution is often used as a prior for scale parameters. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in [0, \infty)` 26 | Mean undefined 27 | Variance undefined 28 | ======== ========================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\beta$ : (float) Scale parameter, $\beta > 0$. 34 | 35 | ### Probability Density Function (PDF) 36 | 37 | $$ 38 | f(x|\beta) = \frac{2}{\pi \beta \left[1 + \left(\frac{x}{\beta}\right)^2\right]} 39 | $$ 40 | 41 | ```{code-cell} 42 | --- 43 | tags: [remove-input] 44 | mystnb: image 45 | --- 46 | from preliz import HalfCauchy, style 47 | style.use('preliz-doc') 48 | betas = [0.5, 1, 2] 49 | for beta in betas: 50 | HalfCauchy(beta).plot_pdf(support=(0, 5)) 51 | ``` 52 | 53 | ## Cumulative Distribution Function (CDF): 54 | 55 | $$ 56 | F(x|\beta) = \frac{2}{\pi} \arctan\left(\frac{x}{\beta}\right) 57 | $$ 58 | 59 | ```{code-cell} 60 | --- 61 | tags: [remove-input] 62 | mystnb: image 63 | --- 64 | for beta in betas: 65 | HalfCauchy(beta).plot_cdf(support=(0, 5)) 66 | ``` 67 | 68 | ```{seealso} 69 | :class: seealso 70 | 71 | **Common Alternatives:** 72 | 73 | - [Half-Student's t](halfstudentt.md) - The Half-Cauchy distribution is a special case of the Half-Student's t-distribution with $\nu=1$. 74 | - [Half-Normal](halfnormal.md) - A distribution that considers only the positive half of the normal distribution. 75 | 76 | **Related Distributions:** 77 | 78 | - [Cauchy](cauchy.md) - The Cauchy distribution is the parent distribution from which the Half-Cauchy is derived. 79 | ``` 80 | ## References 81 | 82 | - [Wikipedia - Cauchy](https://en.wikipedia.org/wiki/Cauchy_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/binomial.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Binomial Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Binomial distribution is a discrete probability distribution that describes the number of successes in a fixed number $n$ of independent Bernoulli trials (yes/no experiments), each with the same probability of success $p$. 18 | 19 | ## Key properties and parameters 20 | 21 | ```{eval-rst} 22 | ======== ================================================================= 23 | Support :math:`x \in \{0, 1, \ldots, n\}` 24 | Mean :math:`n p` 25 | Variance :math:`n p (1-p)` 26 | ======== ================================================================= 27 | ``` 28 | 29 | **Parameters:** 30 | 31 | - $n$ : (int) Number of Bernoulli trials, $n \geq 0$. 32 | - $p$ : (float) Probability of success in each trial, $0 \leq p \leq 1$. 33 | 34 | ### Probability Mass Function (PMF) 35 | 36 | $$ 37 | f(x \mid n, p) = \binom{n}{x} p^x (1-p)^{n-x} 38 | $$ 39 | 40 | ```{code-cell} 41 | --- 42 | tags: [remove-input] 43 | mystnb: 44 | image: 45 | alt: Binomial Distribution PMF 46 | --- 47 | 48 | from preliz import Binomial, style 49 | style.use('preliz-doc') 50 | ns = [5, 10, 10] 51 | ps = [0.5, 0.5, 0.7] 52 | for n, p in zip(ns, ps): 53 | Binomial(n, p).plot_pdf() 54 | ``` 55 | 56 | ### Cumulative Distribution Function (CDF) 57 | 58 | $$ 59 | F(k \mid n, p) = I_{1 - p}(n - \lfloor x \rfloor, \lfloor x \rfloor + 1) 60 | $$ 61 | 62 | ```{code-cell} 63 | --- 64 | tags: [remove-input] 65 | mystnb: 66 | image: 67 | alt: Binomial Distribution CDF 68 | --- 69 | 70 | for n, p in zip(ns, ps): 71 | Binomial(n, p).plot_cdf() 72 | ``` 73 | 74 | where $I_{1 - p}(a, b)$ is the [regularized incomplete beta function](https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function). 75 | 76 | ```{seealso} 77 | :class: seealso 78 | 79 | **Common Alternatives:** 80 | 81 | - [Bernoulli Distribution](bernoulli.md) - For a single trial, i.e., $n=1$, the Binomial distribution reduces to the Bernoulli distribution. 82 | 83 | **Related Distributions:** 84 | 85 | - [Beta-Binomial Distribution](betabinomial.md) - Generalization of the Binomial distribution with a Beta distribution for the probability of success. 86 | - [Hypergeometric Distribution](hypergeometric.md) - Distribution of the number of successes in a sample drawn without replacement. 87 | ``` 88 | 89 | ## References 90 | 91 | - [Wikipedia - Binomial Distribution](https://en.wikipedia.org/wiki/Binomial_distribution) -------------------------------------------------------------------------------- /preliz/tests/test_mixture.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytest 3 | from numpy.testing import assert_almost_equal 4 | from scipy.stats import kurtosis, skew 5 | 6 | from preliz.distributions import Mixture, Normal, Poisson 7 | 8 | 9 | @pytest.mark.parametrize( 10 | "dist0, dist1, weights", 11 | [ 12 | (Normal(-1.5, 1), Normal(1, 0.5), [0.6, 0.4]), 13 | (Poisson(4), Poisson(1.5), [0.5, 0.5]), 14 | ], 15 | ) 16 | def test_mixture(dist0, dist1, weights): 17 | mix_dist = Mixture([dist0, dist1], weights=weights) 18 | s_s = (np.array(weights) * 10000).astype(int) 19 | mix_samples = np.concatenate([dist0.rvs(s_s[0]), dist1.rvs(s_s[1])]) 20 | 21 | assert_almost_equal(mix_dist.mean(), mix_samples.mean(), decimal=1) 22 | assert_almost_equal(mix_dist.var(), mix_samples.var(), decimal=0) 23 | assert_almost_equal(skew(mix_samples), mix_dist.skewness(), decimal=1) 24 | assert_almost_equal(kurtosis(mix_samples), mix_dist.kurtosis(), decimal=0) 25 | assert_almost_equal(mix_dist.median(), np.median(mix_samples), decimal=1) 26 | assert_almost_equal(mix_dist.std(), mix_samples.std(), decimal=1) 27 | assert_almost_equal(mix_dist.rvs(10000).mean(), mix_samples.mean(), decimal=1) 28 | 29 | # x_vals = cen_dist.rvs(1000000, random_state=1) 30 | # assert_almost_equal(np.mean(x_vals == lower), dist.cdf(lower), decimal=2) 31 | # if dist.kind == "discrete": 32 | # assert_almost_equal(np.mean(x_vals == upper), 1 - dist.cdf(upper - 1), decimal=2) 33 | # else: 34 | # assert_almost_equal(np.mean(x_vals == upper), 1 - dist.cdf(upper), decimal=2) 35 | 36 | # x_inside = x_vals[(x_vals > lower) & (x_vals < upper)] 37 | # assert_almost_equal(dist.logpdf(x_inside), cen_dist.logpdf(x_inside)) 38 | # assert_almost_equal(dist.cdf(x_inside), cen_dist.cdf(x_inside)) 39 | 40 | # assert_almost_equal(dist.cdf(x_inside), cen_dist.cdf(x_inside)) 41 | 42 | # assert_almost_equal(cen_dist.median(), dist.median()) 43 | # assert_almost_equal(x_vals.mean(), cen_dist.mean(), decimal=1) 44 | # assert_almost_equal(x_vals.var(), cen_dist.var(), decimal=1) 45 | # assert_almost_equal(skew(x_vals), cen_dist.skewness(), decimal=0) 46 | # assert_almost_equal(kurtosis(x_vals), cen_dist.kurtosis(), decimal=0) 47 | 48 | # actual_mean = dist.mean() 49 | # expected_mean = cen_dist_inf.mean() 50 | # assert_almost_equal(actual_mean, expected_mean, decimal=2) 51 | 52 | # actual_var = dist.var() 53 | # expected_var = cen_dist_inf.var() 54 | # assert_almost_equal(actual_var, expected_var, decimal=2) 55 | 56 | # actual_entropy = dist.entropy() 57 | # expected_entropy = cen_dist_inf.entropy() 58 | # assert_almost_equal(actual_entropy, expected_entropy, decimal=1) 59 | 60 | # c_l, c_u = cen_dist.hdi() 61 | # d_l, d_u = dist.hdi() 62 | # assert c_l >= d_l 63 | # assert c_u <= d_u 64 | # assert_almost_equal(cen_dist_inf.hdi(), dist.hdi()) 65 | -------------------------------------------------------------------------------- /docs/distributions/gallery/discrete_uniform.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Discrete Uniform Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Discrete Uniform distribution is a probability distribution where each integer value between `lower` and `upper` (inclusive) has the same probability. This distribution is characterized by two parameters: `lower` and `upper`, defining the range of integers. 18 | 19 | A simple example of the Discrete Uniform distribution is rolling a fair six-sided die, where each face has an equal probability of 1/6. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ============================================================ 25 | Support :math:`x \in \{ \text{lower}, \text{lower} + 1, \ldots, \text{upper} \}` 26 | Mean :math:`\dfrac{\text{lower} + \text{upper}}{2}` 27 | Variance :math:`\dfrac{(\text{upper} - \text{lower} + 1)^2 - 1}{12}` 28 | ======== ============================================================ 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - `lower` : (int) Lower bound of the distribution. 34 | - `upper` : (int) Upper bound of the distribution, $\text{upper} \geq \text{lower}$. 35 | 36 | ### Probability Mass Function (PMF) 37 | 38 | $$ 39 | f(x \mid lower, upper) = \frac{1}{upper-lower+1} 40 | $$ 41 | 42 | ```{code-cell} 43 | --- 44 | tags: [remove-input] 45 | mystnb: 46 | image: 47 | alt: Discrete Uniform Distribution PMF 48 | --- 49 | 50 | from preliz import DiscreteUniform, style 51 | style.use('preliz-doc') 52 | ls = [1, -2] 53 | us = [6, 2] 54 | for l, u in zip(ls, us): 55 | DiscreteUniform(l, u).plot_pdf() 56 | ``` 57 | 58 | ### Cumulative Distribution Function (CDF) 59 | 60 | $$ 61 | F(x \mid lower, upper) = = \frac{x - lower + 1}{upper - lower + 1} 62 | $$ 63 | 64 | ```{code-cell} 65 | --- 66 | tags: [remove-input] 67 | mystnb: 68 | image: 69 | alt: Discrete Uniform Distribution CDF 70 | --- 71 | 72 | for l, u in zip(ls, us): 73 | DiscreteUniform(l, u).plot_cdf() 74 | ``` 75 | 76 | ```{seealso} 77 | :class: seealso 78 | 79 | **Common Alternatives:** 80 | 81 | - [Categorical](categorical.md) - The Discrete Uniform distribution is a special case of the Categorical distribution where all elements of $p$ are equal. 82 | 83 | **Related Distributions:** 84 | 85 | - [Uniform](uniform.md) - The continuous version of the Discrete Uniform distribution. 86 | ``` 87 | 88 | ## References 89 | 90 | - [Wikipedia - Discrete Uniform Distribution](https://en.wikipedia.org/wiki/Discrete_uniform_distribution) -------------------------------------------------------------------------------- /preliz/multidimensional/dirichlet_mode.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | import numpy as np 4 | 5 | from preliz.distributions import Beta, Dirichlet 6 | from preliz.internal.optimization import optimize_dirichlet_mode 7 | from preliz.internal.rcparams import rcParams 8 | 9 | 10 | def dirichlet_mode(mode, mass=None, bound=0.01, plot=None, plot_kwargs=None, ax=None): 11 | """ 12 | Elicitate a Dirichlet distribution with a given mode and mass. 13 | 14 | Computes a Dirichlet distribution where the marginals have the specified mode 15 | and mass and their masses lie within the range mode ± bound 16 | (Adapted from :footcite:t:`Michael2017`). 17 | 18 | Parameters 19 | ---------- 20 | mode : list 21 | Mode of the Dirichlet distribution. 22 | mass : float 23 | Probability mass between within mode +- bounds. Defaults to None, 24 | which results in the value of rcParams["stats.ci_prob"] being used. 25 | bound : float 26 | Defines upper and lower bounds for the mass as mode +- bound. Defaults to 0.01. 27 | plot : bool 28 | Whether to plot the distribution. Defaults to True. 29 | plot_kwargs : dict 30 | Dictionary passed to the method ``plot_pdf()``. 31 | ax : matplotlib axes 32 | 33 | Returns 34 | ------- 35 | ax : matplotlib axes 36 | dist : Preliz Dirichlet distribution. 37 | Dirichlet distribution with fitted parameters alpha for the given mass and intervals. 38 | 39 | References 40 | ---------- 41 | 42 | .. footbibliography:: 43 | 44 | """ 45 | if mass is None: 46 | mass = rcParams["stats.ci_prob"] 47 | 48 | if plot is None: 49 | plot = rcParams["plots.show_plot"] 50 | 51 | if not 0 < mass <= 1: 52 | raise ValueError("mass should be larger than 0 and smaller or equal to 1") 53 | 54 | if not all(i > 0 for i in mode): 55 | raise ValueError("mode should be larger than 0") 56 | 57 | if not abs(sum(mode) - 1) < 0.0001: 58 | warnings.warn("The mode should sum to 1, normalising mode to sum to 1") 59 | sum_mode = sum(mode) 60 | mode = [i / sum_mode for i in mode] 61 | 62 | if plot_kwargs is None: 63 | plot_kwargs = {} 64 | 65 | lower_bounds = np.clip(np.array(mode) - bound, 0, 1) 66 | target_mass = (1 - mass) / 2 67 | _dist = Beta() 68 | 69 | _, alpha = optimize_dirichlet_mode(lower_bounds, mode, target_mass, _dist) 70 | 71 | alpha_np = np.array(alpha) 72 | calculated_mode = (alpha_np - 1) / (alpha_np.sum() - len(alpha_np)) 73 | 74 | if np.any((np.array(mode) - calculated_mode) > 0.01): 75 | warnings.warn( 76 | f"The requested mode {mode} is different from the calculated mode {calculated_mode}." 77 | ) 78 | 79 | dirichlet_distribution = Dirichlet(alpha) 80 | 81 | if plot: 82 | ax = dirichlet_distribution.plot_pdf(**plot_kwargs, ax=ax) 83 | 84 | return ax, dirichlet_distribution 85 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["flit_core >=3.4,<4"] 3 | build-backend = "flit_core.buildapi" 4 | 5 | [project] 6 | name = "preliz" 7 | readme = "README.md" 8 | requires-python = ">=3.11" 9 | license = {file = "LICENSE"} 10 | authors = [ 11 | {name = "ArviZ team", email = "arviz.devs@gmail.com"} 12 | ] 13 | classifiers = [ 14 | "Development Status :: 3 - Alpha", 15 | "Intended Audience :: Science/Research", 16 | "Intended Audience :: Education", 17 | "License :: OSI Approved :: Apache Software License", 18 | "Operating System :: OS Independent", 19 | "Programming Language :: Python", 20 | "Programming Language :: Python :: 3", 21 | "Programming Language :: Python :: 3.11", 22 | "Programming Language :: Python :: 3.12", 23 | "Programming Language :: Python :: 3.13", 24 | ] 25 | dynamic = ["version"] 26 | description = "Exploring and eliciting probability distributions." 27 | dependencies = [ 28 | "arviz_stats>=0.6.0", 29 | "matplotlib>=3.9", 30 | "numba>=0.62", 31 | "numpy>=2.0", 32 | "scipy>=1.12" 33 | ] 34 | 35 | [tool.flit.module] 36 | name = "preliz" 37 | 38 | [project.urls] 39 | source = "https://github.com/arviz-devs/preliz" 40 | tracker = "https://github.com/arviz-devs/preliz/issues" 41 | documentation = "https://preliz.readthedocs.io" 42 | funding = "https://opencollective.com/arviz" 43 | 44 | [project.optional-dependencies] 45 | full = [ 46 | "nbclient>=0.2", 47 | "ipywidgets", 48 | "ipympl", 49 | ] 50 | lab = ["jupyterlab"] 51 | notebook = ["notebook"] 52 | 53 | 54 | [tool.isort] 55 | profile = "black" 56 | include_trailing_comma = true 57 | use_parentheses = true 58 | multi_line_output = 3 59 | line_length = 100 60 | 61 | [tool.pydocstyle] 62 | convention = "numpy" 63 | 64 | [tool.pytest.ini_options] 65 | testpaths = [ 66 | "tests", 67 | ] 68 | 69 | [tool.ruff] 70 | line-length = 100 71 | 72 | [tool.ruff.lint] 73 | select = [ 74 | "F", # Pyflakes 75 | "E", # Pycodestyle 76 | "W", # Pycodestyle 77 | "D", # pydocstyle 78 | "NPY", # numpy specific rules 79 | "UP", # pyupgrade 80 | "I", # isort 81 | "PL", # Pylint 82 | "TID", # Absolute imports 83 | ] 84 | ignore = [ 85 | "PLR0912", # too many branches 86 | "PLR0913", # too many arguments 87 | "PLR2004", # magic value comparison 88 | "PLR0915", # too many statements 89 | "PLC0415", # import outside of top level 90 | "PLR0911", # too many return statements 91 | "D1" # Missing docstring 92 | 93 | ] 94 | 95 | [tool.ruff.lint.per-file-ignores] 96 | "docs/source/**/*.ipynb" = ["D", "E", "F", "I", "NPY", "PL", "TID", "UP", "W"] 97 | "preliz/__init__.py" = ["I", "F401", "E402", "F403"] 98 | "preliz/tests/**/*" = ["D", "PLR2004", "TID252"] 99 | "preliz/tests/**/*.ipynb" = ["E", "F"] 100 | 101 | [tool.ruff.lint.pydocstyle] 102 | convention = "numpy" 103 | 104 | [tool.ruff.lint.flake8-tidy-imports] 105 | ban-relative-imports = "all" # Disallow all relative imports. 106 | 107 | [tool.ruff.format] 108 | docstring-code-format = false 109 | -------------------------------------------------------------------------------- /docs/distributions/gallery/weibull.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Weibull Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Asymmetric](../../gallery_tags.rst#asymmetric), [Non-Negative](../../gallery_tags.rst#non-negative), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The Weibull distribution is a continuous probability distribution that models the "waiting time" until an event occurs. It has two parameters: the shape parameter $\alpha$ and the scale parameter $\beta$. 18 | 19 | This distribution is widely used in fields like engineering, survival analysis, and material science. If $\alpha > 1$, the event becomes more likely as time passes, making it useful for modeling aging or wear-out processes. If $\alpha < 1$, the event is more likely at the beginning and decreases over time. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in [0, \infty)` 26 | Mean :math:`\beta \Gamma(1 + \frac{1}{\alpha})` 27 | Variance :math:`\beta^2 \Gamma(1 + \frac{2}{\alpha} - \mu^2/\beta^2)` 28 | ======== ==================================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\alpha > 0$: Shape parameter 34 | - $\beta > 0$: Scale parameter 35 | 36 | ### Probability Density Function (PDF) 37 | 38 | $$ 39 | f(x \mid \alpha, \beta) = \frac{\alpha x^{\alpha - 1} \exp(-(\frac{x}{\beta})^{\alpha})}{\beta^\alpha} 40 | $$ 41 | 42 | ```{code-cell} 43 | --- 44 | tags: [remove-input] 45 | mystnb: 46 | image: 47 | alt: Weibull Distribution PDF 48 | --- 49 | 50 | from preliz import Weibull, style 51 | style.use('preliz-doc') 52 | alphas = [1., 2., 5., 5.] 53 | betas = [1., 1., 1., 2.] 54 | for alpha, beta in zip(alphas, betas): 55 | Weibull(alpha, beta).plot_pdf(support=(0, 5)) 56 | ``` 57 | 58 | ### Cumulative Distribution Function (CDF) 59 | 60 | $$ 61 | F(x \mid \alpha, \beta) = 1 - \exp(-(\frac{x}{\beta})^{\alpha}) 62 | $$ 63 | 64 | ```{code-cell} 65 | --- 66 | tags: [remove-input] 67 | mystnb: 68 | image: 69 | alt: Weibull Distribution CDF 70 | --- 71 | 72 | for alpha, beta in zip(alphas, betas): 73 | Weibull(alpha, beta).plot_cdf(support=(0, 5)) 74 | ``` 75 | 76 | ```{seealso} 77 | :class: seealso 78 | 79 | **Common Alternatives:** 80 | 81 | - [Exponential](exponential.md) - The Exponential distribution is a special case of the Weibull distribution with the shape parameter $\alpha = 1$. 82 | 83 | **Related Distributions:** 84 | 85 | - [Gumbel](gumbel.md) - If a random variable follows a Weibull distribution, the logarithm of the random variable follows a Gumbel distribution. 86 | ``` 87 | 88 | ## References 89 | 90 | - [Wikipedia - Weibull Distribution](https://en.wikipedia.org/wiki/Weibull_distribution) -------------------------------------------------------------------------------- /preliz/unidimensional/combine.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from preliz.internal.distribution_helper import get_distributions 4 | from preliz.unidimensional.mle import mle 5 | 6 | 7 | def combine( 8 | distributions, 9 | weights=None, 10 | dist_names=None, 11 | sample_size=10_000, 12 | rng=0, 13 | plot=1, 14 | plot_kwargs=None, 15 | ax=None, 16 | ): 17 | """ 18 | Combine a set of distributions into a single one. 19 | 20 | Fit a weighted sample from ``distributions`` into the distributions listed in ``dist_names`. 21 | The fit is done using maximum likelihood estimation, and the best match is plotted. 22 | Notice that the result is NOT a Mixture distribution, but a single distribution 23 | that best fits the weighted sample. 24 | 25 | Parameters 26 | ---------- 27 | distributions : List of PreliZ distributions 28 | These are the distributions that we want to combine. Typically, these have been 29 | elicited from different individuals or instances. 30 | weights : array-like, optional 31 | Weights for each distribution. Defaults to None, i.e. equal weights. 32 | The sum of the weights must be equal to 1, otherwise it will be normalized. 33 | dist_names: list 34 | List of distributions to fit the weighted sample. 35 | Defaults to ``["Normal", "Gamma", "LogNormal", "StudentT"]``. 36 | sample_size : int 37 | Number of total samples to generate for the fit. 38 | rng : int or numpy.random.Generator, optional 39 | Random number generator or seed. Defaults to ``0``. 40 | plot : int 41 | Number of distributions to plots. Defaults to ``1`` (i.e. plot the best match) 42 | If larger than the number of passed distributions it will plot all of them. 43 | Use ``0`` or ``False`` to disable plotting. 44 | plot_kwargs : dict 45 | Dictionary passed to the method ``plot_pdf()``. 46 | ax : matplotlib axes 47 | 48 | Returns 49 | ------- 50 | fitted_distributions : list of PreliZ distributions. 51 | The distributions that best fit the weighted sample. Sorted from best to worst match. 52 | axes : matplotlib axes 53 | """ 54 | if rng is None: 55 | rng = np.random.default_rng() 56 | else: 57 | rng = np.random.default_rng(rng) 58 | 59 | if weights is None: 60 | weights = np.full(len(distributions), 1 / len(distributions)) 61 | else: 62 | weights = np.array(weights, dtype=float) 63 | 64 | if np.any(weights < 0): 65 | raise ValueError("The weights must be positive.") 66 | 67 | weights /= weights.sum() 68 | 69 | n_size = (sample_size * weights).astype(int) 70 | 71 | if dist_names is None: 72 | dist_names = ["Normal", "Gamma", "LogNormal", "StudentT"] 73 | 74 | sample = [] 75 | for dist, n in zip(distributions, n_size): 76 | sample.append(dist.rvs(n, random_state=rng)) 77 | 78 | distributions = get_distributions(dist_names) 79 | 80 | idx, ax = mle(distributions, np.concatenate(sample), plot=plot, plot_kwargs=plot_kwargs, ax=ax) 81 | 82 | return np.array(distributions)[idx], ax 83 | -------------------------------------------------------------------------------- /docs/distributions/gallery/poisson.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Poisson Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Non-Negative](../../gallery_tags.rst#non-negative) 16 | 17 | The Poisson distribution is a discrete probability distribution that expresses the probability of a given number of events occurring in a fixed interval of time (or space) if these events occur with a known constant mean rate and independently of the time since the last event. 18 | 19 | ## Key properties and parameters 20 | 21 | ```{eval-rst} 22 | ======== ========================== 23 | Support :math:`x \in \mathbb{N}_0` 24 | Mean :math:`\mu` 25 | Variance :math:`\mu` 26 | ======== ========================== 27 | ``` 28 | 29 | **Parameters:** 30 | 31 | - $\mu$ : (float) The mean rate of events, $\mu > 0$. 32 | 33 | ### Probability Density Function (PDF) 34 | 35 | $$ 36 | f(x \mid \mu) = \frac{e^{-\mu}\mu^x}{x!} 37 | $$ 38 | 39 | ```{code-cell} 40 | --- 41 | tags: [remove-input] 42 | mystnb: 43 | image: 44 | alt: Poisson Distribution PDF 45 | --- 46 | 47 | 48 | from preliz import Poisson, style 49 | style.use('preliz-doc') 50 | for mu in [0.5, 3, 8]: 51 | Poisson(mu).plot_pdf(); 52 | ``` 53 | 54 | ### Cumulative Distribution Function (CDF) 55 | 56 | $$ 57 | F(x \mid \mu) = \frac{\Gamma(x + 1, \mu)}{x!} 58 | $$ 59 | 60 | where $\Gamma(x + 1, \mu)$ is the [upper incomplete gamma function](https://en.wikipedia.org/wiki/Incomplete_gamma_function). 61 | 62 | ```{code-cell} 63 | --- 64 | tags: [remove-input] 65 | mystnb: 66 | image: 67 | alt: Poisson Distribution CDF 68 | --- 69 | 70 | for mu in [0.5, 3, 8]: 71 | Poisson(mu).plot_cdf(); 72 | ``` 73 | 74 | ```{seealso} 75 | :class: seealso 76 | 77 | **Common Alternatives:** 78 | 79 | - [NegativeBinomial](negativebinomial.md) - The Negative Binomial is often used as an alternative the Poisson when the variance is greater than the mean (overdispersed data). 80 | - [ZeroInflatedPoisson](zeroinflatedpoisson.md) - The Zero-Inflated Poisson is used when there is an excess of zero counts in the data. 81 | - [HurdlePoisson](hurdle.md) - The Hurdle Poisson is used when there is an excess of zero counts in the data. 82 | 83 | **Related Distributions:** 84 | 85 | - [Binomial](binomial.md) - The Poisson distribution can be derived as a limiting case to the binomial distribution as the number of trials goes to infinity and the expected number of successes remains fixed. See [law of rare events](https://en.wikipedia.org/wiki/Poisson_distribution#law_of_rare_events). 86 | - [Normal](normal.md) - For sufficiently large values of $\mu$, the normal distribution with mean $\mu$ and standard deviation \sqrt{\mu} can be a good approximation to the Poisson. 87 | ``` 88 | 89 | ## References 90 | 91 | - [Wikipedia - Poisson](https://en.wikipedia.org/wiki/Poisson_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/gumbel.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Gumbel Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Gumbel distribution, also known as the type-I Generalized Extreme Value (GEV) distribution, is a continuous probability distribution that describes the distribution of the maximum (or minimum) of a number of samples of various different random variables, particularly the exponential and normal distributions. It is characterized by two parameters: the location parameter $\mu$ and the scale parameter $\beta$. 18 | 19 | The Gumbel distribution is commonly used in the fields of hydrology, meteorology, and environmental science to model extreme events such as floods, earthquakes, and wind speeds. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in (-\infty, \infty)` 26 | Mean :math:`\mu + \beta \gamma`, where :math:`\gamma` is the `Euler-Mascheroni constant `_ 27 | Variance :math:`\frac{\pi^2}{6} \beta^2` 28 | ======== ========================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\mu$ : (float) Location parameter. 34 | - $\beta$ : (float) Scale parameter. 35 | 36 | ### Probability Density Function (PDF) 37 | 38 | $$ 39 | f(x|\mu, \beta) = \frac{1}{\beta} e^{-(z + e^{-z})} 40 | $$ 41 | 42 | where $z = \frac{x - \mu}{\beta}$. 43 | 44 | ```{code-cell} 45 | --- 46 | tags: [remove-input] 47 | mystnb: 48 | image: 49 | alt: Gumbel Distribution PDF 50 | --- 51 | 52 | from preliz import Gumbel, style 53 | style.use('preliz-doc') 54 | mus = [0., 4., -1.] 55 | betas = [1., 2., 4.] 56 | for mu, beta in zip(mus, betas): 57 | Gumbel(mu, beta).plot_pdf(support=(-10,20)) 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x|\mu, \beta) = e^{-e^{-z}} 64 | $$ 65 | 66 | where $z = \frac{x - \mu}{\beta}$. 67 | 68 | ```{code-cell} 69 | --- 70 | tags: [remove-input] 71 | mystnb: 72 | image: 73 | alt: Gumbel Distribution CDF 74 | --- 75 | 76 | for mu, beta in zip(mus, betas): 77 | Gumbel(mu, beta).plot_cdf(support=(-10,20)) 78 | ``` 79 | 80 | ```{seealso} 81 | :class: seealso 82 | 83 | **Related Distributions:** 84 | 85 | - [Weibull Distribution](weibull) - If a random variable follows a Weibull distribution, the logarithm of the random variable follows a Gumbel distribution. 86 | - [Exponential Distribution](exponential) - The maximum of a number of exponentially distributed random variables follows a Gumbel distribution and the exponential distribution is a special case of the Weibull distribution. 87 | ``` 88 | 89 | ## References 90 | 91 | - [Wikipedia - Gumbel Distribution](https://en.wikipedia.org/wiki/Gumbel_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/pareto.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Pareto Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Asymmetric](../../gallery_tags.rst#asymmetric), [Non-Negative](../../gallery_tags.rst#non-negative), [Heavy-tailed](../../gallery_tags.rst#heavy-tailed) 16 | 17 | The Pareto distribution is a continuous probability distribution, known for following a power-law and having a heavy right tail. It is defined by two parameters: the scale parameter $m$ and the shape parameter $\alpha$. 18 | 19 | It was originally used to describe the distribution of wealth in society where a small proportion of the population holds a large proportion of the wealth (the "80-20 rule"). It has since been used in various fields to describe a wide range of phenomena where events get rarer at greater magnitudes. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | 25 | ======== ========================================== 26 | Support :math:`x \in [m, \infty)` 27 | Mean :math:`\frac{\alpha m}{\alpha - 1}` for :math:`\alpha > 1` 28 | Variance :math:`\frac{m^2 \alpha}{(\alpha - 1)^2 (\alpha - 2)}` for :math:`\alpha > 2` 29 | ======== ========================================== 30 | ``` 31 | 32 | **Parameters:** 33 | 34 | - $m$ : (float) Scale parameter, $m > 0$. 35 | - $\alpha$ : (float) Shape parameter, $\alpha > 1$. 36 | 37 | ### Probability Density Function (PDF) 38 | 39 | $$ 40 | f(x|\alpha, m) = \frac{\alpha m^\alpha}{x^{\alpha + 1}} 41 | $$ 42 | 43 | ```{code-cell} 44 | --- 45 | tags: [remove-input] 46 | mystnb: 47 | image: 48 | alt: Pareto Distribution PDF 49 | --- 50 | 51 | from preliz import Pareto, style 52 | style.use('preliz-doc') 53 | alphas = [1., 5., 5.] 54 | ms = [1., 1., 2.] 55 | for alpha, m in zip(alphas, ms): 56 | Pareto(alpha, m).plot_pdf(support=(0,4)) 57 | ``` 58 | 59 | ### Cumulative Distribution Function (CDF) 60 | 61 | $$ 62 | F(x|\alpha, m) = 1 - \left(\frac{m}{x}\right)^\alpha 63 | $$ 64 | 65 | ```{code-cell} 66 | --- 67 | tags: [remove-input] 68 | mystnb: 69 | image: 70 | alt: Pareto Distribution CDF 71 | --- 72 | 73 | for alpha, m in zip(alphas, ms): 74 | Pareto(alpha, m).plot_cdf(support=(0,4)) 75 | ``` 76 | 77 | ```{seealso} 78 | :class: seealso 79 | 80 | **Related Distributions:** 81 | 82 | - [Exponential Distribution](exponential.md) - If X is Pareto distributed, with scale parameter $m$, and shape parameter $\alpha$, then $Y = log(X/m)$ is exponentially distributed with rate parameter $\lambda = \alpha$. 83 | - [Log-Normal Distribution](log_normal.md) - Also used for modeling positive, skewed data with long tails. The log-normal distribution allows for more flexibility in shaping the tail behavior compared to the Pareto distribution. 84 | ``` 85 | 86 | ## References 87 | 88 | - [Wikipedia - Pareto Distribution](https://en.wikipedia.org/wiki/Pareto_distribution) -------------------------------------------------------------------------------- /preliz/unidimensional/combine_roulette.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from preliz.internal.distribution_helper import get_distributions, process_extra 4 | from preliz.internal.optimization import fit_to_epdf 5 | 6 | 7 | def combine_roulette(responses, weights=None, dist_names=None, params=None): 8 | """ 9 | Combine multiple elicited distributions into a single distribution. 10 | 11 | Parameters 12 | ---------- 13 | responses : list of tuples 14 | Typically, each tuple comes from the ``.inputs`` attribute of a ``Roulette`` object and 15 | represents a single elicited distribution. 16 | weights : array-like, optional 17 | Weights for each elicited distribution. Defaults to None, i.e. equal weights. 18 | The sum of the weights must be equal to 1, otherwise it will be normalized. 19 | dist_names: list 20 | List of distributions names to be used in the elicitation. 21 | Defaults to ["Normal", "BetaScaled", "Gamma", "LogNormal", "StudentT"]. 22 | params : str, optional 23 | Extra parameters to be passed to the distributions. The format is a string with the 24 | PreliZ's distribution name followed by the argument to fix. 25 | For example: "TruncatedNormal(lower=0), StudentT(nu=8)". 26 | 27 | Returns 28 | ------- 29 | PreliZ distribution 30 | """ 31 | if params is not None: 32 | extra_pros = process_extra(params) 33 | else: 34 | extra_pros = [] 35 | 36 | if weights is None: 37 | weights = np.full(len(responses), 1 / len(responses)) 38 | else: 39 | weights = np.array(weights, dtype=float) 40 | 41 | if np.any(weights < 0): 42 | raise ValueError("The weights must be positive.") 43 | 44 | weights /= weights.sum() 45 | 46 | if not all(records[3:] == responses[0][3:] for records in responses): 47 | raise ValueError( 48 | "To combine single elicitation instances, the grid should be the same for all of them." 49 | ) 50 | 51 | if dist_names is None: 52 | dist_names = ["Normal", "BetaScaled", "Gamma", "LogNormal", "StudentT"] 53 | 54 | new_pdf = {} 55 | for records, weight in zip(responses, weights): 56 | chips = records[2] 57 | for x_i, pdf_i in zip(records[0], records[1]): 58 | if x_i in new_pdf: 59 | new_pdf[x_i] += pdf_i * weight * chips 60 | else: 61 | new_pdf[x_i] = pdf_i * weight * chips 62 | 63 | total = sum(new_pdf.values()) 64 | mean = 0 65 | for x_i, pdf_i in new_pdf.items(): 66 | val = pdf_i / total 67 | mean += x_i * val 68 | new_pdf[x_i] = val 69 | 70 | var = 0 71 | for x_i, pdf_i in new_pdf.items(): 72 | var += pdf_i * (x_i - mean) ** 2 73 | std = var**0.5 74 | 75 | # Assuming all the elicited distributions have the same x_min and x_max 76 | x_min = responses[0][3] 77 | x_max = responses[0][4] 78 | 79 | fitted_dist = fit_to_epdf( 80 | get_distributions(dist_names), 81 | list(new_pdf.keys()), 82 | list(new_pdf.values()), 83 | mean, 84 | std, 85 | x_min, 86 | x_max, 87 | extra_pros, 88 | ) 89 | 90 | return fitted_dist 91 | -------------------------------------------------------------------------------- /docs/distributions/gallery/vonmises.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Von Mises Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Symmetric](../../gallery_tags.rst#symmetric) 16 | 17 | The Von Mises distribution is a continuous probability distribution on the unit circle. It is characterized by two parameters: $\mu$ and $\kappa$, which are the mean direction and concentration parameter, respectively. 18 | 19 | The Von Mises distribution is the circular analogue of the normal distribution, and it is used to model circular data, such as wind directions, compass bearings, or angles. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in (-\pi, \pi)` 26 | Mean :math:`\mu` 27 | Variance :math:`1 - I_1(\kappa) / I_0(\kappa)` 28 | ======== ========================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\mu$ : (float) Mean direction, $-\pi \leq \mu \leq \pi$. 34 | - $\kappa$ : (float) Concentration parameter, $\kappa \geq 0$. 35 | 36 | ### Probability Density Function (PDF) 37 | 38 | $$ 39 | f(x|\mu, \kappa) = \frac{e^{\kappa \cos(x - \mu)}}{2\pi I_0(\kappa)} 40 | $$ 41 | 42 | where $I_0(\kappa)$ is the [modified Bessel function of the first kind](https://en.wikipedia.org/wiki/Bessel_function#Modified_Bessel_functions:_I%CE%B1,_K%CE%B1). 43 | 44 | ```{code-cell} 45 | --- 46 | tags: [remove-input] 47 | mystnb: 48 | image: 49 | alt: Von Mises Distribution PDF 50 | --- 51 | import numpy as np 52 | 53 | from preliz import style, VonMises 54 | style.use('preliz-doc') 55 | mus = [0., 0., 0., -2.5] 56 | kappas = [.01, 0.5, 4., 2.] 57 | for mu, kappa in zip(mus, kappas): 58 | VonMises(mu, kappa).plot_pdf(support=(-np.pi,np.pi)) 59 | ``` 60 | 61 | ### Cumulative Distribution Function (CDF) 62 | 63 | The Von Mises distribution does not have an analytical expression for the CDF. However, it can be evaluated numerically by integrating the PDF in the interval $(-\pi, x)$: 64 | 65 | $$ 66 | F(x|\mu, \kappa) = \frac{1}{2\pi I_0(\kappa)} \int_{-\pi}^{x} e^{\kappa \cos(t - \mu)} dt 67 | $$ 68 | 69 | ```{code-cell} 70 | --- 71 | tags: [remove-input] 72 | mystnb: 73 | image: 74 | alt: Von Mises Distribution CDF 75 | --- 76 | 77 | for mu, kappa in zip(mus, kappas): 78 | VonMises(mu, kappa).plot_cdf(support=(-np.pi,np.pi)) 79 | ``` 80 | 81 | ```{seealso} 82 | :class: seealso 83 | 84 | **Related Distributions:** 85 | 86 | - [Normal Distribution](normal.md) - When $\kappa \to \infty$, the Von Mises distribution approximates the normal distribution. 87 | - [Uniform Distribution](uniform.md) - When $\kappa = 0$, the Von Mises distribution converges to the uniform distribution in the interval $(-\pi, \pi)$. 88 | ``` 89 | 90 | ## References 91 | 92 | - [Wikipedia - Von Mises distribution](https://en.wikipedia.org/wiki/Von_Mises_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/geometric.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Geometric Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Non-Negative](../../gallery_tags.rst#non-negative), [Asymmetric](../../gallery_tags.rst#asymmetric) 16 | 17 | The Geometric distribution is a discrete probability distribution used to model the number of Bernoulli trials required to achieve the first success. The distribution has a single parameter, $p$ ($0 < p \leq 1$), representing the probability of success in each Bernoulli trial. 18 | 19 | The geometric distribution is memoryless, meaning that the probability of success on the next trial is independent of past outcomes. This property makes it useful in scenarios such as modeling the time until the first occurrence of an event in reliability engineering, quality control, and queuing theory. It is particularly effective for analyzing discrete data patterns where each trial is independent and identically distributed. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ============================= 25 | Support :math:`x \in \mathbb{N}_{>0}` 26 | Mean :math:`\dfrac{1}{p}` 27 | Variance :math:`\dfrac{1 - p}{p^2}` 28 | ======== ============================= 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $p$ : (float) Probability of success in each Bernoulli trial, $0 < p \leq 1$. 34 | 35 | ### Probability Mass Function (PMF) 36 | 37 | $$ 38 | f(x \mid p) = p(1-p)^{x-1} 39 | $$ 40 | 41 | ```{code-cell} 42 | --- 43 | tags: [remove-input] 44 | mystnb: 45 | image: 46 | alt: Geometric Distribution PMF 47 | --- 48 | 49 | from preliz import Geometric, style 50 | style.use('preliz-doc') 51 | for p in [0.1, 0.25, 0.75]: 52 | Geometric(p).plot_pdf(support=(1,10)) 53 | ``` 54 | 55 | ### Cumulative Distribution Function (CDF) 56 | 57 | $$ 58 | F(x \mid p) = 1 - (1-p)^x 59 | $$ 60 | 61 | ```{code-cell} 62 | --- 63 | tags: [remove-input] 64 | mystnb: 65 | image: 66 | alt: Geometric Distribution CDF 67 | --- 68 | 69 | for p in [0.1, 0.25, 0.75]: 70 | Geometric(p).plot_cdf(support=(1,10)) 71 | ``` 72 | 73 | ```{seealso} 74 | :class: seealso 75 | 76 | **Common Alternatives:** 77 | 78 | - [Discrete Weibull Distribution](discrete_weibull.md) - The Geometric distribution is a special case of the Discrete Weibull distribution with shape parameter $\beta=1$. 79 | 80 | **Related Distributions:** 81 | 82 | - [Exponential Distribution](exponential.md) - Continuous analog of the Geometric distribution, used to model the time between events in a Poisson process. 83 | - [Negative Binomial Distribution](negativebinomial.md) - The geometric distribution (on $\{ 0, 1, 2, 3, \dots \}$) is a special case of the negative binomial distribution, with $\text{Geom}(p)=\text{NB}(1, p)$. 84 | ``` 85 | 86 | ## References 87 | 88 | - [Wikipedia - Geometric Distribution](https://en.wikipedia.org/wiki/Geometric_distribution) -------------------------------------------------------------------------------- /docs/gallery_examples.rst: -------------------------------------------------------------------------------- 1 | Examples Gallery 2 | ================ 3 | 4 | The examples in this section showcase the flexibility and capabilities of PreliZ for working with distributions and eliciting probability distributions. Some methods are more automatic than others but some level of interactivity and visual inspection is expected as you should be the final judge. 5 | 6 | Distribution Guide and Settings 7 | ------------------------------- 8 | 9 | This section is where you’ll learn how to define, manipulate, and visualize distributions directly. 10 | 11 | .. grid:: 1 2 3 3 12 | :gutter: 2 2 3 3 13 | 14 | .. grid-item-card:: 15 | :link: ./examples/gallery/working_with_distributions.html 16 | :text-align: center 17 | :shadow: none 18 | :class-card: example-gallery 19 | 20 | .. image:: examples/img/work_with_dist.png 21 | :alt: Working with Distributions 22 | 23 | +++ 24 | Working with Distributions 25 | 26 | .. grid-item-card:: 27 | :link: ./examples/gallery/global_settings.html 28 | :text-align: center 29 | :shadow: none 30 | :class-card: example-gallery 31 | 32 | .. image:: examples/img/global_settings.png 33 | :alt: Global Settings 34 | 35 | +++ 36 | Global Settings 37 | 38 | Direct Elicitation 39 | ------------------ 40 | 41 | Direct Elicitation demonstrates how to interactively elicit a probability distribution. 42 | 43 | .. grid:: 1 2 3 3 44 | :gutter: 2 2 3 3 45 | 46 | .. grid-item-card:: 47 | :link: ./examples/gallery/direct_elicitation_1D.html 48 | :text-align: center 49 | :shadow: none 50 | :class-card: example-gallery 51 | 52 | .. image:: examples/img/direct_elicitation_1D.png 53 | :alt: Direct Elicitation in 1D 54 | 55 | +++ 56 | Direct Elicitation in 1D 57 | 58 | .. grid-item-card:: 59 | :link: ./examples/gallery/direct_elicitation_ND.html 60 | :text-align: center 61 | :shadow: none 62 | :class-card: example-gallery 63 | 64 | .. image:: examples/img/direct_elicitation_ND.png 65 | :alt: Direct Elicitation in ND 66 | 67 | +++ 68 | Direct Elicitation in ND 69 | 70 | 71 | Predictive Elicitation 72 | ---------------------- 73 | 74 | This section illustrates how PreliZ can be used to perform elicitation on the observed space, instead of the parameters space like in the previous examples. In all these examples, the prior predictive distribution is key. 75 | 76 | .. grid:: 1 2 3 3 77 | :gutter: 2 2 3 3 78 | 79 | .. grid-item-card:: 80 | :link: ./examples/gallery/predictive_explorer.html 81 | :text-align: center 82 | :shadow: none 83 | :class-card: example-gallery 84 | 85 | .. image:: examples/img/predictive_explorer.png 86 | :alt: Predictive Explorer 87 | 88 | +++ 89 | Predictive Explorer 90 | 91 | .. grid-item-card:: 92 | :link: ./examples/gallery/ppa.html 93 | :text-align: center 94 | :shadow: none 95 | :class-card: example-gallery 96 | 97 | .. image:: examples/img/ppa.png 98 | :alt: ppa 99 | 100 | +++ 101 | Prior predictive assistant 102 | -------------------------------------------------------------------------------- /docs/distributions/gallery/mixture.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | (Mixture_gallery)= 12 | # Mixture Distribution 13 | 14 | 15 | 16 | [Modifier](../../gallery_tags.rst#modifier) 17 | 18 | This is not a distribution per se, but a modifier of univariate distributions. 19 | 20 | A mixture distribution is a probability distribution that results from the combination of two or more univariate distributions. The resulting distribution is a weighted sum of the component distributions. 21 | 22 | Mixture distributions are widely used whenever a single, simple distribution cannot adequately capture the complexity of a dataset. For example, in modeling the distribution of incomes across a population with distinct socioeconomic groups, mixtures can represent each subgroup’s unique income pattern. 23 | 24 | ## Key properties and parameters 25 | 26 | **Parameters:** 27 | 28 | - `dists` : (list of Univariate PreliZ distributions) Components of the mixture. They should be all discrete or all continuous. 29 | - `weights` : (list of floats) List of weights for each distribution. Weights must be larger or equal to 0 and their sum must be positive. If the weights do not sum up to 1, they will be normalized. 30 | 31 | ### Probability Density Function (PDF) 32 | 33 | Given a list of base distributions with cumulative distribution functions (CDFs) and probability density/mass functions (PDFs/PMFs). The pdf of a Mixture distribution is: 34 | 35 | $$ 36 | f(x) = \sum_{i=1}^n \, w_i \, p_i(x) 37 | $$ 38 | 39 | where $w_i$ is the weight of the $i$-th distribution and $p_i(x)$ is the PDF/PMF of the $i$-th distribution. 40 | 41 | ```{code-cell} 42 | --- 43 | tags: [remove-input] 44 | mystnb: 45 | image: 46 | alt: Mixture Distribution PDF 47 | --- 48 | 49 | from preliz import Normal, Mixture, style 50 | style.use('preliz-doc') 51 | 52 | Mixture([Normal(0, 0.5), Normal(2, 0.5)], [0.2, 0.8]).plot_pdf() 53 | Normal(0, 0.5).plot_pdf(alpha=0.5) 54 | Normal(2, 0.5).plot_pdf(alpha=0.5); 55 | ``` 56 | 57 | ### Cumulative Distribution Function (CDF) 58 | 59 | The cumulative distribution function (CDF) of a Mixture distribution is the sum of the CDFs of the component distributions. 60 | 61 | $$ 62 | F(x) = \sum_{i=1}^n \, w_i \, P_i(x) 63 | $$ 64 | 65 | where $w_i$ is the weight of the $i$-th distribution and $P_i(x)$ is the CDF of the $i$-th distribution. 66 | 67 | ```{code-cell} 68 | --- 69 | tags: [remove-input] 70 | mystnb: 71 | image: 72 | alt: Mixture Distribution CDF 73 | --- 74 | 75 | Mixture([Normal(0, 0.5), Normal(2, 0.5)], [0.2, 0.8]).plot_cdf() 76 | Normal(0, 0.5).plot_cdf(alpha=0.5) 77 | Normal(2, 0.5).plot_cdf(alpha=0.5); 78 | ``` 79 | 80 | ```{seealso} 81 | :class: seealso 82 | 83 | **Related Distributions:** 84 | 85 | - [Hurdle](hurdle.md) - A modifier that combines a point mass at zero with a separate distribution for positive outcomes. 86 | ``` 87 | 88 | ## References 89 | 90 | - Wikipedia - [Mixture distribution](https://en.wikipedia.org/wiki/Mixture_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/hypergeometric.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Hypergeometric Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Hypergeometric distribution is a discrete probability distribution used to model the number of successes in a sequence of $n$ draws, taken whithout replacement, from a finite population of size $N$ containing $K$ successful individuals. The distribution is defined by three parameters: $N$, $K$, and $n$. 18 | 19 | This distribution is particularly useful for sampling without replacement, where the probability of success changes with each draw. Common applications include calculating probabilities in games of chance like lottery draws or poker, auditing elections to detect irregularities, and assessing over-representation in statistical tests such as Fisher's exact test. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ============================= 25 | Support :math:`x \in \left[\max(0, n - N + k), \min(k, n)\right]` 26 | Mean :math:`\dfrac{nk}{N}` 27 | Variance :math:`\dfrac{(N-n)nk(N-k)}{(N-1)N^2}` 28 | ======== ============================= 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $N$ : (int) Population size. $N > 0$. 34 | - $K$ : (int) Number of successful individuals in the population. $0 \leq K \leq N$. 35 | - $n$ : (int) Number of samples drawn from the population. $0 \leq n \leq N$. 36 | 37 | ### Probability Mass Function (PMF) 38 | 39 | $$ 40 | f(x \mid N, K, n) = \frac{\binom{k}{x} \binom{N-K}{n-x}}{\binom{N}{n}} 41 | $$ 42 | 43 | ```{code-cell} 44 | --- 45 | tags: [remove-input] 46 | mystnb: 47 | image: 48 | alt: Hypergeometric Distribution PMF 49 | --- 50 | 51 | from preliz import HyperGeometric, style 52 | style.use('preliz-doc') 53 | N = 50 54 | k = 10 55 | for n in [20, 25]: 56 | HyperGeometric(N, k, n).plot_pdf(support=(1,15)) 57 | ``` 58 | 59 | ### Cumulative Distribution Function (CDF) 60 | 61 | $$ 62 | F(x \mid N, K, n) = 1 - \frac{\binom{n}{k+1} \binom{N-n}{K-k-1}}{\binom{N}{K}} \, {}_3F_2 \left[ 63 | \begin{array}{c} 64 | 1, \, k+1-K, \, k+1-n \\ 65 | k+2, \, N+k+2-K-n 66 | \end{array} 67 | ; 1 \right] 68 | $$ 69 | 70 | where ${}_pF_q$ is the [generalized hypergeometric function](https://en.wikipedia.org/wiki/Generalized_hypergeometric_function). 71 | 72 | ```{code-cell} 73 | --- 74 | tags: [remove-input] 75 | mystnb: 76 | image: 77 | alt: Hypergeometric Distribution CDF 78 | --- 79 | 80 | for n in [20, 25]: 81 | HyperGeometric(N, k, n).plot_cdf(support=(1,15)) 82 | ``` 83 | 84 | ```{seealso} 85 | :class: seealso 86 | 87 | **Related Distributions:** 88 | 89 | - [Binomial Distribution](binomial.md) - The Hypergeometric distribution converges to the Binomial distribution as the population size $N$ approaches infinity. 90 | ``` 91 | 92 | ## References 93 | 94 | - [Wikipedia - Hypergeometric Distribution](https://en.wikipedia.org/wiki/Hypergeometric_distribution) 95 | 96 | -------------------------------------------------------------------------------- /docs/distributions/gallery/betabinomial.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Beta-Binomial Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Beta-Binomial distribution is a discrete probability distribution derived from the Binomial distribution, with its probability of success in each trial governed by a Beta distribution. This distribution is characterized by three parameters: $\alpha$, $\beta$, and $n$, where $\alpha$ and $\beta$ are the shape parameters of the Beta distribution and $n$ is the number of trials in the Binomial distribution. 18 | 19 | ## Key properties and parameters 20 | 21 | ```{eval-rst} 22 | ======== ================================================================= 23 | Support :math:`x \in \{0, 1, \ldots, n\}` 24 | Mean :math:`n \dfrac{\alpha}{\alpha + \beta}` 25 | Variance :math:`\dfrac{n \alpha \beta (\alpha+\beta+n)}{(\alpha+\beta)^2 (\alpha+\beta+1)}` 26 | ======== ================================================================= 27 | ``` 28 | 29 | **Parameters:** 30 | 31 | - $\alpha$ : (float) Shape parameter of the Beta distribution, $\alpha > 0$. 32 | - $\beta$ : (float) Shape parameter of the Beta distribution, $\beta > 0$. 33 | - $n$ : (int) Number of trials in the Binomial distribution, $n \geq 0$. 34 | 35 | ### Probability Mass Function (PMF) 36 | 37 | $$ 38 | f(x \mid \alpha, \beta, n) = \binom{n}{x} \frac{B(x + \alpha, n - x + \beta)}{B(\alpha, \beta)} 39 | $$ 40 | 41 | where $B$ is the [Beta function](https://en.wikipedia.org/wiki/Beta_function) and $\binom{n}{x}$ is the [binomial coefficient](https://en.wikipedia.org/wiki/Binomial_coefficient). 42 | 43 | ```{code-cell} 44 | --- 45 | tags: [remove-input] 46 | mystnb: 47 | image: 48 | alt: Beta-Binomial Distribution PMF 49 | --- 50 | 51 | from preliz import BetaBinomial, style 52 | style.use('preliz-doc') 53 | alphas = [0.5, 1, 2.3] 54 | betas = [0.5, 1, 2] 55 | n = 10 56 | for a, b in zip(alphas, betas): 57 | BetaBinomial(a, b, n).plot_pdf() 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x \mid \alpha, \beta, n) = 64 | \begin{cases} 65 | 0, & x < 0 \\ 66 | \sum_{k=0}^{x} \binom{n}{k} \frac{B(k + \alpha, n - k + \beta)}{B(\alpha, \beta)}, & 0 \leq x < n \\ 67 | 1, & x \geq n 68 | \end{cases} 69 | $$ 70 | 71 | ```{code-cell} 72 | --- 73 | tags: [remove-input] 74 | mystnb: 75 | image: 76 | alt: Beta-Binomial Distribution CDF 77 | --- 78 | 79 | for a, b in zip(alphas, betas): 80 | BetaBinomial(a, b, n).plot_cdf() 81 | ``` 82 | 83 | ```{seealso} 84 | :class: seealso 85 | 86 | **Related Distributions:** 87 | 88 | - [Binomial](binomial.md) - The Beta-Binomial distribution is a compound distribution derived from the Binomial distribution. 89 | - [Beta](beta.md) - The Beta-Binomial distribution is a compound distribution parameterized by the Beta distribution. 90 | ``` 91 | 92 | ## References 93 | 94 | - [Wikipedia - Beta-Binomial](https://en.wikipedia.org/wiki/Beta-binomial_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/chisquared.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Chi-Squared Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Non-Negative](../../gallery_tags.rst#non-negative), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The chi-squared (also chi-square or $\chi^2$) is a continuous probability distribution characterized by a single parameter, $\nu$, usually called degrees of freedom. This distribution emerges from the sum of the squares of $\nu$ independent standard normal random variables. 18 | 19 | The chi-squared distribution is widely used in many statistical tests, for hypothesis testing and constructing confidence intervals. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in [0, \infty)` 26 | Mean :math:`\nu` 27 | Variance :math:`2\nu` 28 | ======== ========================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\nu$ : (float) Degrees of freedom, $\nu > 0$. 34 | 35 | ### Probability Density Function (PDF) 36 | 37 | $$ 38 | f(x|\nu) = \frac{1}{2^{\nu/2}\Gamma(\nu/2)} x^{\nu/2 - 1} e^{-x/2} 39 | $$ 40 | 41 | where $\Gamma$ is the [gamma function](https://en.wikipedia.org/wiki/Gamma_function). 42 | 43 | ```{code-cell} 44 | --- 45 | tags: [remove-input] 46 | mystnb: 47 | image: 48 | alt: Chi-Squared Distribution PDF 49 | --- 50 | 51 | import numpy as np 52 | 53 | from preliz import ChiSquared, style 54 | style.use('preliz-doc') 55 | nus = [1, 3, 9] 56 | 57 | for nu in nus: 58 | ax = ChiSquared(nu).plot_pdf(support=(np.finfo(float).eps, 20)) 59 | ax.set_ylim(0, 0.6) 60 | ``` 61 | 62 | ### Cumulative Distribution Function (CDF) 63 | 64 | $$ 65 | F(x|\nu) = \frac{1}{\Gamma(\nu/2)} \gamma(\nu/2, x/2) 66 | $$ 67 | 68 | where $\gamma$ is the [lower incomplete gamma function](https://en.wikipedia.org/wiki/Incomplete_gamma_function). 69 | 70 | ```{code-cell} 71 | --- 72 | tags: [remove-input] 73 | mystnb: 74 | image: 75 | alt: Chi-Squared Distribution CDF 76 | --- 77 | 78 | for nu in nus: 79 | ChiSquared(nu).plot_cdf(support=(0, 20)) 80 | ``` 81 | 82 | ```{seealso} 83 | :class: seealso 84 | 85 | **Common Alternatives:** 86 | 87 | - [Gamma](gamma.md) - The chi-squared distribution is a special case of the gamma distribution with the shape parameter $\alpha = \nu/2$ and the scale parameter $\beta = 1/2$. 88 | 89 | **Related Distributions:** 90 | 91 | - [Normal](normal.md) - By definition, the chi-squared distribution is the sum of the squares of $\nu$ independent standard normal random variables. 92 | - [Exponential](exponential.md) - A chi-squared distribution with 2 degrees of freedom is equivalent to an exponential distribution with the rate parameter $\lambda = 1/2$, because the exponential distribution is also a special case of the gamma distribution. 93 | ``` 94 | 95 | ## References 96 | 97 | - [Wikipedia - Chi-squared distribution](https://en.wikipedia.org/wiki/Chi-squared_distribution) 98 | 99 | -------------------------------------------------------------------------------- /docs/distributions/gallery/discrete_weibull.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Discrete Weibull Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded) 16 | 17 | The Discrete Weibull distribution is a discrete probability distribution used to model the number of trials until an event occurs. It is an analog of the continuous Weibull distribution, adapted for discrete settings. The distribution has two shape parameters: $q$ and $\beta$. The parameter $q$ ($0 < q < 1$) controls the overall probability decay across trials, with smaller values leading to faster decay. The parameter $\beta$ ($\beta > 0$) determines the specific shape of the distribution, influencing how probabilities change as the number of trials increases. 18 | 19 | The Discrete Weibull distribution is predominantly used in reliability engineering. It is particularly suitable for modeling failure data measured in discrete units, such as cycles or shocks. This distribution is a versatile tool for analyzing scenarios where event timing is counted in distinct intervals, making it especially valuable in fields that handle discrete data patterns and reliability analysis. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in \mathbb{N}_0` 26 | Mean :math:`\mu = \sum_{x = 1}^{\infty} q^{x^{\beta}}` 27 | Variance :math:`2 \sum_{x = 1}^{\infty} x q^{x^{\beta}} - \mu - \mu^2` 28 | ======== =============================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $q$ : (float) Probability of success in each trial, $0 < q < 1$. 34 | - $\beta$ : (float) Shape parameter, $\beta > 0$. 35 | 36 | ### Probability Mass Function (PMF) 37 | 38 | $$ 39 | f(x \mid q, \beta) = q^{x^{\beta}} - q^{(x + 1)^{\beta}} 40 | $$ 41 | 42 | ```{code-cell} 43 | --- 44 | tags: [remove-input] 45 | mystnb: 46 | image: 47 | alt: Discrete Weibull Distribution PMF 48 | --- 49 | 50 | from preliz import DiscreteWeibull, style 51 | style.use('preliz-doc') 52 | qs = [0.1, 0.9, 0.9] 53 | betas = [0.5, 0.5, 2] 54 | 55 | for q, beta in zip(qs, betas): 56 | DiscreteWeibull(q, beta).plot_pdf(support=(0, 10)) 57 | ``` 58 | 59 | ### Cumulative Distribution Function (CDF) 60 | 61 | $$ 62 | F(x \mid q, \beta) = 1 - q^{(x + 1)^{\beta}} 63 | $$ 64 | 65 | ```{code-cell} 66 | --- 67 | tags: [remove-input] 68 | mystnb: 69 | image: 70 | alt: Discrete Weibull Distribution CDF 71 | --- 72 | 73 | for q, beta in zip(qs, betas): 74 | DiscreteWeibull(q, beta).plot_cdf(support=(0, 10)) 75 | ``` 76 | 77 | ```{seealso} 78 | :class: seealso 79 | 80 | **Common Alternatives:** 81 | 82 | - [Geometric](geometric.md) - A special case of the Discrete Weibull distribution with $\beta = 1$. 83 | 84 | **Related Distributions:** 85 | 86 | - [Weibull](weibull.md) - The continuous analog of the Discrete Weibull distribution. 87 | ``` 88 | 89 | ## References 90 | 91 | - [Wikipedia - Discrete Weibull Distribution](https://en.wikipedia.org/wiki/Discrete_Weibull_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/moyal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Moyal Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Asymmetric](../../gallery_tags.rst#asymmetric), [Unbounded](../../gallery_tags.rst#unbounded), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The Moyal distribution is a continuous probability distribution that was proposed by the physicist J. E. Moyal in 1955 as an approximation to the [Landau distribution](https://en.wikipedia.org/wiki/Landau_distribution). The Moyal distribution is characterized by two parameters: the location parameter $\mu$ and the scale parameter $\sigma$. 18 | 19 | The Moyal distribution is used in high-energy physics to model the energy loss, and the number of ion pairs produced, by ionization for fast charged particles. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ============================================================== 25 | Support :math:`x \in (-\infty, \infty)` 26 | Mean :math:`\mu + \sigma\left(\gamma + \log 2\right)`, where 27 | :math:`\gamma` is the `Euler-Mascheroni constant `_ 28 | Variance :math:`\frac{\pi^{2}}{2}\sigma^{2}` 29 | ======== ============================================================== 30 | ``` 31 | 32 | **Parameters:** 33 | 34 | - $\mu$ (loc): The location parameter. 35 | - $\sigma$ (scale): The scale parameter. 36 | 37 | ### Probability Density Function (PDF) 38 | 39 | $$ 40 | f(x|\mu, \sigma) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{1}{2}\left(z + e^{-z}\right)} 41 | $$ 42 | 43 | where $z = \frac{x - \mu}{\sigma}$. 44 | 45 | ```{code-cell} 46 | --- 47 | tags: [remove-input] 48 | mystnb: image 49 | --- 50 | import matplotlib.pyplot as plt 51 | 52 | from preliz import Moyal, style 53 | style.use('preliz-doc') 54 | mus = [-1., 0., 4.] 55 | sigmas = [2., 1., 4.] 56 | for mu, sigma in zip(mus, sigmas): 57 | Moyal(mu, sigma).plot_pdf(support=(-10,20)) 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x; \mu, \sigma) = 1 - \text{erf}\left( \frac{e^{-z}}{\sqrt{2}} \right) 64 | $$ 65 | 66 | where [erf](https://en.wikipedia.org/wiki/Error_function) is the error function and $z = \frac{x - \mu}{\sigma}$. 67 | 68 | ```{code-cell} 69 | --- 70 | tags: [remove-input] 71 | mystnb: image 72 | --- 73 | for mu, sigma in zip(mus, sigmas): 74 | Moyal(mu, sigma).plot_cdf(support=(-10,20)) 75 | ``` 76 | 77 | ```{seealso} 78 | :class: seealso 79 | 80 | **Related Distributions:** 81 | 82 | - [Gamma](gamma.md) - The Moyal distribution is a transformation of the Gamma distribution. 83 | - [LogNormal](log_normal.md) - The LogNormal distribution is also used sometimes as an approximation to the Landau distribution. It is suitable for modeling positive and right-skewed data. 84 | ``` 85 | 86 | ## References 87 | 88 | - [SciPy Moyal Distribution](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.moyal.html) 89 | - [Wolfram Moyal Distribution](https://reference.wolfram.com/language/ref/MoyalDistribution.html) -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Exploring and eliciting probability distributions 2 | =================================================== 3 | 4 | |PyPI version| 5 | |Tests| 6 | |Coverage| 7 | |Ruff| 8 | |DOI| 9 | 10 | .. |PyPI version| image:: https://badge.fury.io/py/preliz.svg 11 | :target: https://badge.fury.io/py/preliz 12 | 13 | .. |Tests| image:: https://github.com/arviz-devs/preliz/actions/workflows/test.yml/badge.svg 14 | :target: https://github.com/arviz-devs/preliz 15 | 16 | .. |Coverage| image:: https://codecov.io/gh/arviz-devs/preliz/branch/main/graph/badge.svg?token=SLJIK2O4C5 17 | :target: https://codecov.io/gh/arviz-devs/preliz 18 | 19 | .. |Ruff| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json 20 | :target: https://github.com/astral-sh/ruff 21 | 22 | .. |DOI| image:: https://joss.theoj.org/papers/10.21105/joss.05499/status.svg 23 | :target: https://doi.org/10.21105/joss.05499 24 | 25 | 26 | Overview 27 | ======== 28 | 29 | Prior elicitation refers to the process of transforming the knowledge of a particular domain into well-defined probability distributions. 30 | Specifying useful priors is a central aspect of Bayesian statistics. PreliZ is a Python package aimed at helping practitioners choose prior 31 | distributions by offering a set of tools for the various facets of prior elicitation. It covers a range of methods, from unidimensional prior 32 | elicitation on the parameter space to predictive elicitation on the observed space. The goal is to be compatible with probabilistic programming 33 | languages (PPL) in the Python ecosystem like PyMC and PyStan, while remaining agnostic of any specific PPL. 34 | 35 | A good companion for PreliZ is `PriorDB `_, a database of prior distributions for Bayesian analysis. 36 | It is a community-driven project that aims to provide a comprehensive collection of prior distributions for a wide range of models and applications. 37 | 38 | **The Zen of PreliZ** 39 | 40 | * Being open source, community-driven, diverse and inclusive. 41 | * Avoid fully-automated solutions, keep the human in the loop. 42 | * Separate tasks between humans and computers, so users can retain control of important decisions while numerically demanding, error-prone or tedious tasks are automatized. 43 | * Prevent users to become overconfident in their own opinions. 44 | * Easily integrate with other tools. 45 | * Allow predictive elicitation. 46 | * Having a simple and intuitive interface suitable for non-specialists in order to minimize cognitive biases and heuristics. 47 | * Switching between different types of visualization such as kernel density estimates plots, quantile dotplots, histograms, etc. 48 | * Being agnostic of the underlying probabilistic programming language. 49 | * Being modular. 50 | 51 | .. toctree:: 52 | :maxdepth: 2 53 | :hidden: 54 | :caption: Getting Started 55 | 56 | Overview 57 | installation 58 | api_reference 59 | 60 | .. toctree:: 61 | :maxdepth: 2 62 | :hidden: 63 | :caption: Examples 64 | 65 | gallery_content 66 | gallery_examples 67 | 68 | .. toctree:: 69 | :maxdepth: 1 70 | :hidden: 71 | :caption: References 72 | 73 | citing 74 | contributing 75 | changelog 76 | 77 | Donations 78 | --------- 79 | 80 | PreliZ, as other ArviZ-devs projects, is a non-profit project under the NumFOCUS umbrella. If you want to support PreliZ financially, you can donate `here `_. -------------------------------------------------------------------------------- /docs/distributions/gallery/bernoulli.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Bernoulli Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Bounded](../../gallery_tags.rst#bounded), [Non-Negative](../../gallery_tags.rst#non-negative) 16 | 17 | The Bernoulli distribution is a discrete probability distribution. It can be thought of as a model for the set of possible outcomes of any single experiment that asks a yes–no question. More formally, it is a random variable which takes the value 1 with probability $p$ and the value 0 with probability $q = 1 − p$. 18 | 19 | ## Key properties and parameters 20 | 21 | ```{eval-rst} 22 | ======== ====================== 23 | Support :math:`x \in \{0, 1\}` 24 | Mean :math:`p` 25 | Variance :math:`p (1 - p)` 26 | ======== ====================== 27 | ``` 28 | 29 | **Parameters:** 30 | 31 | - $p$ : (float) Probability of success, $0 \leq p \leq 1$. 32 | - $\text{logit}(p)$ : (float) Alternative log odds for the probability success, $-\infty < \text{logit}(p) < \infty$. 33 | 34 | **Alternative parametrization** 35 | 36 | The Bernoulli distribution has 2 alternative parametrizations. In terms of $p$ or $\text{logit}(p)$. 37 | 38 | The link between the 2 alternatives is given by 39 | 40 | $$ 41 | \text{logit}(p) = \log(\frac{p}{1-p}) 42 | $$ 43 | 44 | 45 | ### Probability Mass Function (PMF) 46 | 47 | $$ 48 | f(x \mid p) = p^{x} (1-p)^{1-x} 49 | $$ 50 | 51 | ::::::{tab-set} 52 | :class: full-width 53 | 54 | :::::{tab-item} Parameters $p$ 55 | :sync: p 56 | ```{jupyter-execute} 57 | :hide-code: 58 | 59 | from preliz import Bernoulli, style 60 | style.use('preliz-doc') 61 | for p in [0.01, 0.5, 0.8]: 62 | Bernoulli(p).plot_pdf() 63 | ``` 64 | ::::: 65 | 66 | :::::{tab-item} Parameters $\text{logit}(p)$ 67 | :sync: logit_p 68 | 69 | ```{jupyter-execute} 70 | :hide-code: 71 | for logit_p in [-4.6, 0, 1.38]: 72 | Bernoulli(logit_p=logit_p).plot_pdf() 73 | ``` 74 | ::::: 75 | :::::: 76 | 77 | ### Cumulative Distribution Function (CDF) 78 | 79 | $$ 80 | F(x \mid p) = \begin{cases} 81 | 0 & \text{if } k < 0 \\ 82 | 1 - p & \text{if } 0 \leq k < 1 \\ 83 | 1 & \text{if } k \geq 1 84 | \end{cases} 85 | $$ 86 | 87 | ::::::{tab-set} 88 | :class: full-width 89 | 90 | :::::{tab-item} Parameters $p$ 91 | :sync: p 92 | 93 | ```{jupyter-execute} 94 | :hide-code: 95 | for p in [0.01, 0.5, 0.8]: 96 | Bernoulli(p).plot_cdf() 97 | ``` 98 | ::::: 99 | 100 | :::::{tab-item} Parameters $\text{logit}(p)$ 101 | :sync: logit_p 102 | 103 | ```{jupyter-execute} 104 | :hide-code: 105 | for logit_p in [-4.6, 0, 1.38]: 106 | Bernoulli(logit_p=logit_p).plot_cdf() 107 | ``` 108 | ::::: 109 | :::::: 110 | 111 | ```{seealso} 112 | :class: seealso 113 | 114 | **Related Distributions:** 115 | 116 | - [Binomial](binomial.md) - The Bernoulli distribution is a special case of the Binomial distribution with $N=1$. 117 | - [Categorical](categorical.md) - A generalization of the Bernoulli distribution to more than two outcomes. 118 | ``` 119 | 120 | ## References 121 | 122 | - [Wikipedia - Bernoulli](https://en.wikipedia.org/wiki/Bernoulli_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/laplace.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Laplace Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Symmetric](../../gallery_tags.rst#symmetric), [Unbounded](../../gallery_tags.rst#unbounded), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The Laplace or Laplacian distribution is a continuous probability distribution named after Pierre-Simon Laplace. It is also known as the double exponential distribution due to its shape: it consists of two exponential distributions of the same scale back to back about $x = \mu$. The difference between two independent identically distributed (i.i.d.) exponential random variables follows a Laplace distribution. 18 | 19 | The Laplace distribution is characterized by two parameters: the location parameter $\mu$ and the scale parameter $b$. 20 | 21 | The Laplace distribution is widely used due to its ability to model sharp peaks and heavy tails. In signal processing, it models coefficients in speech recognition and image compression. In regression analysis, the Lasso regression can be thought of as a Bayesian regression with a Laplacian prior for the coefficients, altought sparsity is better achieved with priors such as horseshoe instead of Laplace. It is also used in hydrology, finance, and other fields to model extreme events and outliers. 22 | 23 | ## Key properties and parameters 24 | 25 | ```{eval-rst} 26 | ======== ========================================== 27 | Support :math:`x \in \mathbb{R}` 28 | Mean :math:`\mu` 29 | Variance :math:`2b^2` 30 | ======== ========================================== 31 | ``` 32 | 33 | **Parameters:** 34 | 35 | - $\mu$ : (float) Location parameter. 36 | - $b$ : (float) Scale parameter, $b > 0$. 37 | 38 | ### Probability Density Function (PDF) 39 | 40 | $$ 41 | f(x|\mu, b) = \frac{1}{2b} \exp\left(-\frac{|x - \mu|}{b}\right) 42 | $$ 43 | 44 | ```{code-cell} 45 | --- 46 | tags: [remove-input] 47 | mystnb: image 48 | --- 49 | import matplotlib.pyplot as plt 50 | 51 | from preliz import Laplace, style 52 | style.use('preliz-doc') 53 | 54 | mus = [0., 0., 0., -5.] 55 | bs = [1., 2., 4., 4.] 56 | for mu, b in zip(mus, bs): 57 | Laplace(mu, b).plot_pdf(support=(-10,10)) 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x|\mu, b) = \begin{cases} 64 | \frac{1}{2} \exp\left(\frac{x - \mu}{b}\right) & \text{if } x < \mu \\ 65 | 1 - \frac{1}{2} \exp\left(-\frac{x - \mu}{b}\right) & \text{if } x \geq \mu 66 | \end{cases} 67 | $$ 68 | 69 | ```{code-cell} 70 | --- 71 | tags: [remove-input] 72 | mystnb: image 73 | --- 74 | import matplotlib.pyplot as plt 75 | 76 | for mu, b in zip(mus, bs): 77 | Laplace(mu, b).plot_cdf(support=(-10,10)) 78 | ``` 79 | 80 | ```{seealso} 81 | :class: seealso 82 | 83 | **Common Alternatives:** 84 | 85 | - [Asymmetric Laplace](asymmetric_laplace.md) - A generalization of the Laplace distribution with asymmetric tails. 86 | 87 | **Related Distributions:** 88 | 89 | - [Exponential](exponential.md) - The Laplace distribution is the difference between two i.i.d. exponential random variables. 90 | ``` 91 | 92 | ## References 93 | 94 | - [Wikipedia - Laplace Distribution](https://en.wikipedia.org/wiki/Laplace_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/log_logistic.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Log-Logistic Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Asymmetric](../../gallery_tags.rst#asymmetric), [Non-Negative](../../gallery_tags.rst#non-negative), [Extreme values](../../gallery_tags.rst#extreme-values), [Heavy-tailed](../../gallery_tags.rst#heavy-tailed) 16 | 17 | The log-logistic distribution, also known as the Fisk distribution, is a continuous probability distribution that is used to model non-negative random variables. It is characterized by two parameters: a scale parameter ($\alpha$), which is also the median of the distribution, and a shape parameter ($\beta$). The dispersion of the distribution decreases as $\beta$ increases. 18 | 19 | The log-logistic distribution is often used in survival analysis as a parametric model for events whose rate increases initially and decreases later, as, for example, mortality rate from cancer following diagnosis or treatment. It has been used in hydrology for modelling stream flow rates and precipitation. It is also used in reliability engineering to model the lifetime of components and systems. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================================================== 25 | Support :math:`x \in [0, \infty)` 26 | Mean :math:`{\alpha\,\pi/\beta \over \sin(\pi/\beta)}` if :math:`\beta>1`, else undefined 27 | Variance :math:`\alpha^2 \left(2b / \sin 2b -b^2 / \sin^2 b \right), \quad \beta>2` 28 | ======== ========================================================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\alpha$ : (float) Scale parameter, $\alpha > 0$. 34 | - $\beta$ : (float) Shape parameter, $\beta > 0$. 35 | 36 | ### Probability Density Function (PDF) 37 | 38 | $$ 39 | f(x|\alpha, \beta) = \frac{ (\beta/\alpha)(x/\alpha)^{\beta-1}}{\left( 1+(x/\alpha)^{\beta} \right)^2} 40 | $$ 41 | 42 | ```{code-cell} 43 | --- 44 | tags: [remove-input] 45 | mystnb: 46 | image: 47 | alt: Log-Logistic Distribution PDF 48 | --- 49 | 50 | import matplotlib.pyplot as plt 51 | 52 | from preliz import LogLogistic, style 53 | style.use('preliz-doc') 54 | alphas = [1, 1, 1, 1, 2] 55 | betas = [1, 2, 4, 8, 8] 56 | for alpha, beta in zip(alphas, betas): 57 | LogLogistic(alpha, beta).plot_pdf(support=(0, 6)) 58 | ``` 59 | 60 | ### Cumulative Distribution Function (CDF) 61 | 62 | $$ 63 | F(x|\alpha, \beta) = \frac{1}{1 + (x/\alpha)^{-\beta}} 64 | $$ 65 | 66 | ```{code-cell} 67 | --- 68 | tags: [remove-input] 69 | mystnb: 70 | image: 71 | alt: Log-Logistic Distribution CDF 72 | --- 73 | 74 | for alpha, beta in zip(alphas, betas): 75 | LogLogistic(alpha, beta).plot_cdf(support=(0, 6)) 76 | ``` 77 | 78 | ```{seealso} 79 | :class: seealso 80 | 81 | **Common Alternatives:** 82 | 83 | - [Log-Normal Distribution](log_normal.md) - The log-logistic distribution is similar to the log-normal distribution, but with heavier tails. 84 | 85 | **Related Distributions:** 86 | 87 | - [Logistic Distribution](logistic.md) - If a random variable $X$ is distributed as a log-logistic distribution, then its logarithm $\log(X)$ follows a logistic distribution. 88 | ``` 89 | 90 | ## References 91 | 92 | - [Wikipedia - Log-logistic distribution](https://en.wikipedia.org/wiki/Log-logistic_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/zeroinflatedpoisson.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Zero-Inflated Poisson Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Discrete](../../gallery_tags.rst#discrete), [Non-Negative](../../gallery_tags.rst#non-negative), [Zero-inflated](../../gallery_tags.rst#zero-inflated) 16 | 17 | The Zero-Inflated Poisson (ZIP) distribution is a discrete probability distribution used to model count data characterized by an excess of zeros. It combines two components: a standard Poisson distribution and an additional mechanism that increases the probability of observing zero outcomes. 18 | 19 | This distribution is particularly useful for scenarios where the data exhibit more zeros than what the Poisson model alone would predict. For example, in ecological studies, when researchers survey multiple habitats for a particular species, they often encounter many sites with zero observations (typically due to unsuitable habitat conditions) alongside a smaller number of sites where the species is observed in varying counts. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ================================ 25 | Support :math:`x \in \mathbb{N}_0` 26 | Mean :math:`\psi \mu` 27 | Variance :math:`\psi \mu (1+(1-\psi) \mu` 28 | ======== ================================ 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\psi$ : (float) Expected proportion of Poisson variates, $0 \leq \psi \leq 1$. 34 | - $\mu$ : (float) The mean rate of events of the Poisson component, $\mu > 0$. 35 | 36 | ### Probability Mass Function (PMF) 37 | 38 | $$ 39 | f(x \mid \psi, \mu) = \left\{ \begin{array}{l} 40 | (1-\psi) + \psi e^{-\mu}, \text{if } x = 0 \\ 41 | \psi \frac{e^{-\mu}\mu^x}{x!}, \text{if } x=1,2,3,\ldots 42 | \end{array} \right. 43 | $$ 44 | 45 | ```{code-cell} 46 | --- 47 | tags: [remove-input] 48 | mystnb: 49 | image: 50 | alt: Zero-Inflated Poisson Distribution PMF 51 | --- 52 | 53 | from preliz import ZeroInflatedPoisson, style 54 | style.use('preliz-doc') 55 | psis = [0.7, 0.4] 56 | mus = [8, 4] 57 | for psi, mu in zip(psis, mus): 58 | ZeroInflatedPoisson(psi, mu).plot_pdf() 59 | ``` 60 | 61 | ### Cumulative Distribution Function (CDF) 62 | 63 | $$ 64 | F(x \mid \psi, \mu) = \left\{ \begin{array}{l} 65 | (1-\psi) + \psi e^{-\mu}, \text{if } x = 0 \\ 66 | (1-\psi) + \psi \sum_{k=0}^x \frac{e^{-\mu}\mu^k}{k!}, \text{if } x=1,2,3,\ldots 67 | \end{array} \right. 68 | $$ 69 | 70 | ```{code-cell} 71 | --- 72 | tags: [remove-input] 73 | mystnb: 74 | image: 75 | alt: Zero-Inflated Poisson Distribution CDF 76 | --- 77 | 78 | for psi, mu in zip(psis, mus): 79 | ZeroInflatedPoisson(psi, mu).plot_cdf() 80 | ``` 81 | 82 | ```{seealso} 83 | 84 | **Common Alternatives:** 85 | 86 | - [Zero-Inflated Negative Binomial Distribution](zeroinflatednegativebinomial.md) - A distribution for overdispersed count data with excess zeros. 87 | - [Zero-Inflated Binomial Distribution](zeroinflatedbinomial.md) - A related distribution for count data with excess zeros. 88 | 89 | **Related Distributions:** 90 | 91 | - [Poisson Distribution](poisson.md) - A standard distribution for modeling count data. 92 | ``` 93 | 94 | ## References 95 | 96 | - [Wikipedia - Zero-Inflated Models](https://en.wikipedia.org/wiki/Zero-inflated_model) 97 | - [Wikipedia - Poisson Distribution](https://en.wikipedia.org/wiki/Poisson_distribution) -------------------------------------------------------------------------------- /preliz/styles/preliz-doc.mplstyle: -------------------------------------------------------------------------------- 1 | ## *************************************************************************** 2 | ## * FIGURE * 3 | ## *************************************************************************** 4 | 5 | figure.facecolor: white # broken white outside box 6 | figure.edgecolor: None # broken white outside box 7 | figure.titleweight: bold # weight of the figure title 8 | figure.titlesize: 18 9 | 10 | figure.figsize: 11.5, 5 11 | figure.dpi: 100.0 12 | figure.constrained_layout.use: True 13 | 14 | ## *************************************************************************** 15 | ## * FONT * 16 | ## *************************************************************************** 17 | 18 | font.style: normal 19 | font.variant: normal 20 | font.weight: normal 21 | font.stretch: normal 22 | 23 | text.color: .15 24 | 25 | ## *************************************************************************** 26 | ## * AXES * 27 | ## *************************************************************************** 28 | 29 | axes.facecolor: white 30 | axes.edgecolor: .33 # axes edge color 31 | axes.linewidth: 0.8 # edge line width 32 | 33 | axes.grid: False # do not show grid 34 | # axes.grid.axis: y # which axis the grid should apply to 35 | axes.grid.which: major # grid lines at {major, minor, both} ticks 36 | axes.axisbelow: True # keep grid layer in the back 37 | 38 | grid.color: .8 # grid color 39 | grid.linestyle: - # solid 40 | grid.linewidth: 0.8 # in points 41 | grid.alpha: 1.0 # transparency, between 0.0 and 1.0 42 | 43 | lines.solid_capstyle: round 44 | 45 | axes.spines.right: False # do not show right spine 46 | axes.spines.top: False # do not show top spine 47 | 48 | axes.titlesize: 16 49 | axes.titleweight: bold # font weight of title 50 | 51 | axes.labelsize: 14 52 | axes.labelcolor: .15 53 | axes.labelweight: normal # weight of the x and y labels 54 | 55 | # color-blind friendly cycle designed using https://colorcyclepicker.mpetroff.net/ 56 | # see preview and check for colorblindness here https://coolors.co/008b92-98d81a-f15c58-30c4f7-575352-be35f0-ba1802-7d1f77-efd6b4 57 | axes.prop_cycle: cycler(color=['008b92','98d81a','f15c58', '30c4f7', '575352', 'be35f0', 'ba1802', '7d1f77', 'efd6b4']) 58 | 59 | image.cmap: viridis 60 | 61 | ## *************************************************************************** 62 | ## * TICKS * 63 | ## *************************************************************************** 64 | 65 | xtick.labelsize: 14 66 | xtick.color: .15 67 | xtick.top: False 68 | xtick.bottom: True 69 | xtick.direction: out 70 | 71 | ytick.labelsize: 14 72 | ytick.color: .15 73 | ytick.left: True 74 | ytick.right: False 75 | ytick.direction: out 76 | 77 | ## *************************************************************************** 78 | ## * LEGEND * 79 | ## *************************************************************************** 80 | 81 | legend.framealpha: 0.5 82 | legend.frameon: False # do not draw on background patch 83 | legend.fancybox: False # do not round corners 84 | 85 | legend.numpoints: 1 86 | legend.scatterpoints: 1 87 | 88 | legend.fontsize: 14 -------------------------------------------------------------------------------- /docs/distributions/gallery/exgaussian.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Ex-Gaussian Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Asymmetric](../../gallery_tags.rst#asymmetric), [Unbounded](../../gallery_tags.rst#unbounded), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The Ex-Gaussian distribution (exponentially modified Gaussian distribution or EMG) is a continuous probability distribution that results from the convolution of a normal distribution and an exponential distribution. It is characterized by three parameters: $\mu$, $\sigma$, and $\nu$, which are the mean and standard deviation of the normal component, and the mean of the exponential component, respectively. It has a bell-shaped curve like the normal distribution, but with a positive skew due to the exponential component. 18 | 19 | The Ex-Gaussian distribution is commonly used to model reaction times in psychology. It is also used to model the shape of chromatographic peaks, the intermitotic times of cell division, cluster ion beams, and other phenomena. 20 | 21 | ## Key properties and parameters 22 | 23 | ```{eval-rst} 24 | ======== ========================================== 25 | Support :math:`x \in \mathbb{R}` 26 | Mean :math:`\mu + \nu` 27 | Variance :math:`\sigma^2 + \nu^2` 28 | ======== ========================================== 29 | ``` 30 | 31 | **Parameters:** 32 | 33 | - $\mu$ : (float) Mean of the normal component. 34 | - $\sigma$ : (float) Standard deviation of the normal component, $\sigma > 0$. 35 | - $\nu$ : (float) Mean of the exponential component, $\nu > 0$. 36 | 37 | ### Probability Density Function (PDF) 38 | 39 | $$ 40 | f(x \mid \mu, \sigma, \nu) = 41 | \frac{1}{\nu}\exp\left(\frac{\mu-x}{\nu}+\frac{\sigma^2}{2\nu^2}\right)\Phi\left(\frac{x-\mu}{\sigma}-\frac{\sigma}{\nu}\right) 42 | $$ 43 | 44 | where $\Phi$ is the [standard normal CDF](normal.md). 45 | 46 | ```{code-cell} 47 | --- 48 | tags: [remove-input] 49 | mystnb: 50 | image: 51 | alt: Ex-Gaussian Distribution PDF 52 | --- 53 | 54 | from preliz import ExGaussian, style 55 | style.use('preliz-doc') 56 | mus = [0., 0., -3.] 57 | sigmas = [1., 3., 1.] 58 | nus = [1., 1., 4.] 59 | for mu, sigma, nu in zip(mus, sigmas, nus): 60 | ExGaussian(mu, sigma, nu).plot_pdf(support=(-6,9)) 61 | ``` 62 | 63 | ### Cumulative Distribution Function (CDF) 64 | 65 | $$ 66 | F(x \mid \mu, \sigma, \nu) = 67 | \Phi(x, \mu, \sigma) 68 | - \frac{1}{2} \exp\left( \frac{1}{2\nu} \left(2\mu + \frac{\sigma^2}{\nu} - 2x\right) \right) \left(1 + \operatorname{erf}\left( \frac{x - \left(\mu + \frac{\sigma^2}{\nu}\right)}{\sigma \sqrt{2}} \right)\right) 69 | $$ 70 | 71 | where $\Phi$ is the CDF of a Gaussian distribution, $\text{erf}$ is the error function 72 | 73 | ```{code-cell} 74 | --- 75 | tags: [remove-input] 76 | mystnb: 77 | image: 78 | alt: Ex-Gaussian Distribution CDF 79 | --- 80 | 81 | for mu, sigma, nu in zip(mus, sigmas, nus): 82 | ExGaussian(mu, sigma, nu).plot_cdf(support=(-6,9)) 83 | ``` 84 | 85 | ```{seealso} 86 | :class: seealso 87 | 88 | **Related Distributions:** 89 | 90 | - [Normal](normal.md) - The Gaussian component of the Ex-Gaussian distribution. 91 | - [Exponential](exponential.md) - The exponential component of the Ex-Gaussian distribution. 92 | ``` 93 | 94 | ## References 95 | 96 | - [Wikipedia - Ex-Gaussian distribution](https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution) -------------------------------------------------------------------------------- /preliz/unidimensional/mle.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | import numpy as np 4 | 5 | from preliz.internal.distribution_helper import valid_distribution 6 | from preliz.internal.optimization import fit_to_sample 7 | from preliz.internal.rcparams import rcParams 8 | from preliz.ppls.pymc_io import if_pymc_get_preliz 9 | 10 | 11 | def mle( 12 | distributions, 13 | sample, 14 | plot=1, 15 | plot_kwargs=None, 16 | ax=None, 17 | ): 18 | """ 19 | Find the maximum likelihood distribution given a list of distributions and one sample. 20 | 21 | AIC with a correction for small sample sizes is used to compare the fits. 22 | (See :footcite:t:`Burnham2004`) 23 | 24 | Parameters 25 | ---------- 26 | distributions : list of PreliZ (or PyMC) distributions 27 | Instance of a distribution. Notice that the distributions will be 28 | updated inplace. If the distribution is from PyMC, it will be 29 | converted to a PreliZ distribution, use `.to_pymc()` to convert it back to PyMC. 30 | All parameters will be estimated from the data, no parameter can be fixed. 31 | For PreliZ distributions, pass uninitialized distributions. 32 | For some PyMC distributions, you may need to pass `np.nan` for parameters. 33 | sample : list or 1D array-like 34 | Data used to estimate the distribution parameters. 35 | plot : int 36 | Number of distributions to plots. Defaults to ``1`` (i.e. plot the best match) 37 | If larger than the number of passed distributions it will plot all of them. 38 | Use ``0`` or ``False`` to disable plotting. 39 | If you want to disable plotting globally you can also set 40 | ``rcParams["plots.show_plot"] = False``. 41 | plot_kwargs : dict 42 | Dictionary passed to the method ``plot_pdf()`` of ``distribution``. 43 | ax : matplotlib axes 44 | 45 | Returns 46 | ------- 47 | idx : array with the indexes to sort ``distributions`` from best to worst match 48 | axes : matplotlib axes 49 | 50 | Examples 51 | -------- 52 | Fit a Normal and a Gamma distribution to data sampled from a Moyal distribution. 53 | In "real life" instead of a sample from a known distribution you would have some observed data. 54 | 55 | .. plot:: 56 | :context: close-figs 57 | :include-source: true 58 | 59 | >>> import preliz as pz 60 | >>> pz.style.use('preliz-doc') 61 | >>> sample = pz.Moyal(1, 2).rvs(1000) # some random data 62 | >>> pz.mle([pz.Normal(), pz.Gamma()], sample) 63 | 64 | References 65 | ---------- 66 | 67 | .. footbibliography:: 68 | 69 | """ 70 | dists = [] 71 | for dist in distributions: 72 | dist_ = if_pymc_get_preliz(dist) 73 | valid_distribution(dist_) 74 | dists.append(dist_) 75 | 76 | sample = np.array(sample) 77 | x_min = sample.min() 78 | x_max = sample.max() 79 | 80 | fitted = fit_to_sample(dists, sample, x_min, x_max) 81 | 82 | plot = min(plot, len(dists)) 83 | 84 | idx = np.argsort(fitted.losses) 85 | 86 | if all(dist is None or not dist.is_frozen for dist in fitted.distributions): 87 | warnings.warn( 88 | """ 89 | No distribution was fitted. This is likely because the support of the 90 | distributions is incompatible with the sampled values.""" 91 | ) 92 | 93 | if plot and rcParams["plots.show_plot"]: 94 | plot_idx = idx[:plot] 95 | for dist in fitted.distributions[plot_idx]: 96 | if dist is not None and dist.is_frozen: 97 | ax = dist.plot_pdf(plot_kwargs) 98 | 99 | return idx, ax 100 | -------------------------------------------------------------------------------- /docs/distributions/gallery/censored.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | (Censored_gallery)= 12 | # Censored Distribution 13 | 14 | 15 | 16 | [Modifier](../../gallery_tags.rst#modifier) 17 | 18 | This is not a distribution per se, but a modifier of univariate distributions. 19 | 20 | A censored distribution arises when the observed data is limited to a certain range, and values outside this range are not recorded. For instance, in a study aiming to measure the impact of a drug on mortality rates it may be known that an individual's age at death is at least 75 years (but may be more). Such a situation could occur if the individual withdrew from the study at age 75, or if the individual is currently alive at the age of 75. Censoring can also happen when a value falls outside the range of a measuring instrument. For example, if a bathroom scale only measures up to 140 kg, and a 160-kg person is weighed, the observer would only know that the individual's weight is at least 140 kg. 21 | 22 | ## Key properties and parameters 23 | 24 | **Parameters:** 25 | 26 | - `dist` : (PreliZ distribution) Univariate distribution to be censored. 27 | - `lower` : (float, int, or `np.inf`) Lower (left) censoring point, `np.inf` indicates no lower censoring. 28 | - `upper` : (float, int, or `np.inf`) Upper (right) censoring point, `np.inf` indicates no upper censoring. 29 | 30 | ### Probability Density Function (PDF) 31 | 32 | Given a base distribution with cumulative distribution function (CDF) and probability density mass/function (PDF). The pdf of a Censored distribution is: 33 | 34 | $$ 35 | \begin{cases} 36 | 0 & \text{for } x < \text{lower}, \\ 37 | \text{CDF}(\text{lower}) & \text{for } x = \text{lower}, \\ 38 | \text{PDF}(x) & \text{for } \text{lower} < x < \text{upper}, \\ 39 | 1-\text{CDF}(\text{upper}) & \text {for } x = \text{upper}, \\ 40 | 0 & \text{for } x > \text{upper}, 41 | \end{cases} 42 | $$ 43 | 44 | where `lower` and `upper` are the lower and upper bounds of the censored distribution, respectively. 45 | 46 | ```{code-cell} 47 | --- 48 | tags: [remove-input] 49 | mystnb: 50 | image: 51 | alt: Censored Distribution PDF 52 | --- 53 | 54 | 55 | from preliz import Normal, Censored, style 56 | style.use('preliz-doc') 57 | Censored(Normal(0, 1), -1, 1).plot_pdf(support=(-4, 4)) 58 | Normal(0, 1).plot_pdf(alpha=0.5); 59 | ``` 60 | 61 | ### Cumulative Distribution Function (CDF) 62 | 63 | The given expression can be written mathematically as: 64 | 65 | $$ 66 | \begin{cases} 67 | 0 & \text{for } x < \text{lower}, \\ 68 | \text{CDF}(x) & \text{for } \text{lower} < x < \text{upper}, \\ 69 | 1 & \text{for } x > \text{upper}, 70 | \end{cases} 71 | $$ 72 | 73 | where `lower` and `upper` are the lower and upper bounds of the censored distribution, respectively. 74 | 75 | ```{code-cell} 76 | --- 77 | tags: [remove-input] 78 | mystnb: 79 | image: 80 | alt: Censored Distribution CDF 81 | --- 82 | 83 | Censored(Normal(0, 1), -1, 1).plot_cdf(support=(-4, 4)) 84 | Normal(0, 1).plot_cdf(alpha=0.5); 85 | ``` 86 | 87 | ```{seealso} 88 | :class: seealso 89 | 90 | 91 | **Related Distributions:** 92 | 93 | - [Truncated](truncated.md) - In a truncated distribution, values outside the range are not recorded, while in a censored distribution, they are set to the nearest bound. 94 | 95 | ``` 96 | 97 | ## References 98 | 99 | - Wikipedia - [Censored distribution](https://en.wikipedia.org/wiki/Censoring_(statistics)) 100 | -------------------------------------------------------------------------------- /docs/distributions/gallery/logistic.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Logistic Distribution 12 | 13 | 14 | 15 | [Univariate](../../gallery_tags.rst#univariate), [Continuous](../../gallery_tags.rst#continuous), [Symmetric](../../gallery_tags.rst#symmetric), [Unbounded](../../gallery_tags.rst#unbounded), [Light-tailed](../../gallery_tags.rst#light-tailed) 16 | 17 | The logistic distribution is a continuous probability distribution with a shape that resembles the normal distribution but with heavier tails. Thus, it is sometimes used as a replacement for the normal when heavier tails are needed. It is defined by two parameters: the mean ($\mu$) and the scale parameter ($s$). The mean determines the center of the distribution, while the scale parameter controls the width. 18 | 19 | Its cumulative distribution function is the [logistic function](https://en.wikipedia.org/wiki/Logistic_function), which is characterized by an S-shaped curve (sigmoid curve). It is particularly useful in modeling growth processes, such as population growth, where the rate of growth decreases as the population reaches its carrying capacity. 20 | 21 | A logistic regression model is typically characterized by a Bernoulli distribution for the likelihood and the logistic function as the inverse link function. However, logistic regression can also be [described](https://en.wikipedia.org/wiki/Logistic_distribution#Logistic_regression) as a latent variable model where the error term follows a logistic distribution. 22 | 23 | ## Key properties and parameters 24 | 25 | ```{eval-rst} 26 | ======== ========================================== 27 | Support :math:`x \in \mathbb{R}` 28 | Mean :math:`\mu` 29 | Variance :math:`\frac{\pi^2}{3}s^2` 30 | ======== ========================================== 31 | ``` 32 | 33 | **Parameters:** 34 | 35 | - $\mu$ : (float) Mean of the distribution. 36 | - $s$ : (float) Scale parameter, $s > 0$. 37 | 38 | ### Probability Density Function (PDF) 39 | 40 | $$ 41 | f(x \mid \mu, s) = 42 | \frac{e^{-(x-\mu)/s}}{s(1+e^{-(x-\mu)/s})^2} 43 | $$ 44 | 45 | ```{code-cell} 46 | --- 47 | tags: [remove-input] 48 | mystnb: 49 | image: 50 | alt: Logistic Distribution PDF 51 | --- 52 | 53 | import matplotlib.pyplot as plt 54 | 55 | from preliz import Logistic, style 56 | style.use('preliz-doc') 57 | mus = [0., 0., -2.] 58 | ss = [1., 2., .4] 59 | for mu, s in zip(mus, ss): 60 | Logistic(mu, s).plot_pdf(support=(-5,5)) 61 | ``` 62 | 63 | ### Cumulative Distribution Function (CDF) 64 | 65 | $$ 66 | F(x \mid \mu, s) = \frac{1}{1 + e^{-(x - \mu) / s}} 67 | $$ 68 | 69 | ```{code-cell} 70 | --- 71 | tags: [remove-input] 72 | mystnb: 73 | image: 74 | alt: Logistic Distribution CDF 75 | --- 76 | 77 | for mu, s in zip(mus, ss): 78 | Logistic(mu, s).plot_cdf(support=(-5,5)) 79 | ``` 80 | 81 | ```{seealso} 82 | :class: seealso 83 | 84 | **Common Alternatives:** 85 | 86 | - [Normal](normal.md) - Often used as an alternative to the logistic distribution when the tails are not of primary concern. 87 | - [Cauchy](cauchy.md) - Has much heavier tails than the logistic distribution, making it a robust alternative when outliers are a concern. 88 | - [Student's t](students_t.md) - A generalization of the normal distribution with heavier tails. 89 | 90 | **Related Distributions:** 91 | 92 | - [Log-logistic](log_logistic.md) - If a random variable is distributed as a logistic, then its exponential is distributed as a log-logistic distribution. 93 | ``` 94 | 95 | ## References 96 | 97 | - [Wikipedia - Logistic](https://en.wikipedia.org/wiki/Logistic_distribution) -------------------------------------------------------------------------------- /docs/distributions/gallery/truncated.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | # Truncated Distribution 12 | 13 | 14 | 15 | [Modifier](../../gallery_tags.rst#modifier) 16 | 17 | This is not a distribution per se, but a modifier of univariate distributions. 18 | 19 | Truncated distributions arise in cases where the ability to record, or even to know about, occurrences is limited to values which lie above or below a given threshold or within a specified range. For example, if the dates of birth of children in a school are examined, these would typically be subject to truncation relative to those of all children in the area given that the school accepts only children in a given age range on a specific date. There would be no information about how many children in the locality had dates of birth before or after the school's cutoff dates if only a direct approach to the school were used to obtain information. 20 | 21 | ## Key properties and parameters 22 | 23 | **Parameters:** 24 | 25 | - `dist` : (PreliZ distribution) Univariate distribution to be truncated. 26 | - `lower` : (float, int, or `np.inf`) Lower (left) truncation point, `np.inf` indicates no lower truncation. 27 | - `upper` : (float, int, or `np.inf`) Upper (right) truncation point, `np.inf` indicates no upper truncation. 28 | 29 | 30 | ### Probability Density Function (PDF) 31 | 32 | Given a base distribution with cumulative distribution function (CDF) and probability density mass/function (PDF). The pdf of a Truncated distribution is: 33 | 34 | $$ 35 | \begin{cases} 36 | 0 & \text{for } x < \text{lower}, \\ 37 | \frac{\text{PDF}(x)}{\text{CDF}(upper) - \text{CDF}(lower)} 38 | & \text{for } \text{lower} <= x <= \text{upper}, \\ 39 | 0 & \text{for } x > \text{upper}, 40 | \end{cases} 41 | $$ 42 | 43 | where `lower` and `upper` are the lower and upper bounds of the truncated distribution, respectively. 44 | 45 | 46 | ```{code-cell} 47 | --- 48 | tags: [remove-input] 49 | mystnb: 50 | image: 51 | alt: Truncated Distribution PDF 52 | --- 53 | 54 | 55 | from preliz import Gamma, Truncated, style 56 | style.use('preliz-doc') 57 | Truncated(Gamma(mu=2, sigma=1), 1, 4.5).plot_pdf() 58 | Gamma(mu=2, sigma=1).plot_pdf(); 59 | ``` 60 | 61 | ### Cumulative Distribution Function (CDF) 62 | 63 | The given expression can be written mathematically as: 64 | 65 | $$ 66 | \begin{cases} 67 | 0 & \text{if } x_i < \text{lower} \\ 68 | 1 & \text{if } x_i > \text{upper} \\ 69 | \frac{\text{CDF}(x_i) - \text{CDF}(\text{lower})}{\text{CDF}(\text{upper}) - \text{CDF}(\text{lower})} & \text{if } \text{lower} \leq x_i \leq \text{upper} 70 | \end{cases} 71 | $$ 72 | 73 | where `lower` and `upper` are the lower and upper bounds of the truncated distribution, respectively. 74 | 75 | ```{code-cell} 76 | --- 77 | tags: [remove-input] 78 | mystnb: 79 | image: 80 | alt: Trucated Distribution CDF 81 | --- 82 | 83 | Truncated(Gamma(mu=2, sigma=1), 1, 4.5).plot_cdf() 84 | Gamma(mu=2, sigma=1).plot_cdf(); 85 | ``` 86 | 87 | ```{seealso} 88 | :class: seealso 89 | 90 | **Related Distributions:** 91 | 92 | - [Censored](censored.md) - In a censored distribution, values outside the range are set to the nearest bound, while in a truncated distribution, they are not recorded. 93 | - [TruncatedNormal](truncated_normal.md) - A truncated normal distribution is a normal distribution that has been restricted to a specific range. 94 | 95 | ``` 96 | 97 | ## References 98 | 99 | - Wikipedia - [Truncated distribution](https://en.wikipedia.org/wiki/Truncated_distribution) 100 | -------------------------------------------------------------------------------- /preliz/predictive/predictive_explorer.py: -------------------------------------------------------------------------------- 1 | try: 2 | from IPython.display import display 3 | from ipywidgets import HBox, VBox, interactive_output 4 | except ImportError: 5 | pass 6 | from preliz.internal.plot_helper import get_textboxes 7 | from preliz.ppls.agnostic import ( 8 | inspect_source, 9 | parse_function_for_pred_textboxes, 10 | ppl_plot_decorator, 11 | ) 12 | 13 | 14 | def predictive_explorer( 15 | fmodel, 16 | samples=50, 17 | kind_plot="ecdf", 18 | references=None, 19 | plot_func=None, 20 | engine="auto", 21 | group="prior_predictive", 22 | var_name=None, 23 | stats_kwargs=None, 24 | ): 25 | """ 26 | Explore how changing parameters in the prior affects the prior predictive distribution. 27 | 28 | Use this function to interactively explore how a prior predictive distribution changes 29 | when the priors are changed. It also allows you to visualize how one prior changes when 30 | another prior is changed, this can be useful for prior that are not set independently, but 31 | are dependent on each other. 32 | 33 | Parameters 34 | ---------- 35 | fmodel : callable 36 | A function with a PreliZ model, a PyMC model, or a Bambi model. 37 | See examples section below for details 38 | samples : int, optional 39 | The number of samples to draw from the prior predictive distribution (default is 50). 40 | kind_plot : str, optional 41 | The type of plot to display. Defaults to "kde". Options are "hist" (histogram), 42 | "kde" (kernel density estimate), "ecdf" (empirical cumulative distribution function). 43 | references : int, float, list, tuple or dictionary 44 | Value(s) used as reference points representing prior knowledge. For example expected 45 | values or values that are considered extreme. Use a dictionary for labeled references. 46 | plot_func : function 47 | Custom matplotlib code. Defaults to None. ``kind_plot`` and ``references`` are ignored 48 | if ``plot_func`` is specified. 49 | engine : str, optional 50 | Library used to define the fmodel. Either `preliz`, `pymc` or `bambi`. Default is `auto`. 51 | The function will automatically select the appropriate library to use based on the fmodel 52 | provided. 53 | group : str, optional 54 | Which group to use. Ignored if the model is defined in `preliz`. 55 | Defaults to "prior_predictive". You can also pass "prior". 56 | var_name: str, optional 57 | The name of the variable to plot. Ignored if the model is defined in `preliz`. 58 | If "group=prior_predictive" it defaults to the first variable in `observed_RVs`. 59 | For "prior" it defaults to the last variable in `free_RVs`. 60 | stats_kwargs : dict, optional 61 | Additional keyword arguments to pass to the statistics function. 62 | Defaults to an empty dictionary. 63 | """ 64 | if stats_kwargs is None: 65 | stats_kwargs = {} 66 | source, signature, engine = inspect_source(fmodel) 67 | model = parse_function_for_pred_textboxes(source, signature, engine) 68 | textboxes = get_textboxes(signature, model, kind_plot) 69 | new_fmodel = ppl_plot_decorator( 70 | fmodel, samples, kind_plot, references, plot_func, engine, group, var_name, stats_kwargs 71 | ) 72 | out = interactive_output(new_fmodel, textboxes) 73 | default_names = [ 74 | "__kind__", 75 | "__set_xlim__", 76 | "__x_min__", 77 | "__x_max__", 78 | "__set_ylim__", 79 | "__y_min__", 80 | "__y_max__", 81 | "__resample__", 82 | ] 83 | default_controls = [textboxes[name] for name in default_names] 84 | params_controls = [v for k, v in textboxes.items() if k not in default_names] 85 | 86 | params_plot = VBox(params_controls + [out]) 87 | 88 | display(HBox([params_plot, VBox(default_controls)])) 89 | --------------------------------------------------------------------------------