{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Prior distributions\n", "\n", "One important aspect of Bayesian inference has not yet been discussed in this tutorial: [prior distributions](https://en.wikipedia.org/wiki/Prior_probability). In Bayesian statistics, one has to provide probability (density) values for every possible parameter value *before* taking into account the data at hand. This prior distribution thus reflects all *prior* knowledge of the system that is to be investigated. In the case that no prior knowledge is available, a *non-informative* prior in the form of the so-called [Jeffreys prior](https://en.wikipedia.org/wiki/Jeffreys_prior) allows to minimize the effect of the prior on the results. The next two sub-sections discuss how one can set custom prior distributions for the parameters of the observation model and for hyper-parameters in a hyper-study or change-point study." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-04-27T19:17:29.386451Z", "iopub.status.busy": "2026-04-27T19:17:29.386019Z", "iopub.status.idle": "2026-04-27T19:17:30.357735Z", "shell.execute_reply": "2026-04-27T19:17:30.357178Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "+ Created new study.\n", "+ Successfully imported example data.\n" ] } ], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt # plotting\n", "plt.style.use('seaborn-v0_8-whitegrid') # plot styling\n", "\n", "import numpy as np\n", "import bayesloop as bl\n", "\n", "# prepare study for coal mining data\n", "S = bl.Study()\n", "S.load_example_data()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Parameter prior\n", "\n", "*bayesloop* employs a forward-backward algorithm that is based on [Hidden Markov models](http://www.cs.sjsu.edu/~stamp/RUA/HMM.pdf). This inference algorithm iteratively produces a parameter distribution for each time step, but it has to start these iterations from a specified probability distribution - the parameter prior. All built-in observation models already have a predefined prior, stored in the attribute `prior`. Here, the prior distribution is stored as a Python function that takes as many arguments as there are parameters in the observation model. The prior distributions can be looked up directly within `observation_models.py`. For the `Poisson` model discussed in this tutorial, the default prior distribution is defined in a method called `jeffreys` as\n", "```\n", "def jeffreys(x):\n", " return np.sqrt(1. / x)\n", "```\n", "corresponding to the non-informative Jeffreys prior, $p(\\lambda) \\propto 1/\\sqrt{\\lambda}$. *bayesloop* can also attempt to derive this type of prior for symbolic user-defined observation models; see the [custom observation model tutorial](customobservationmodels.ipynb).\n", "\n", "### Prior functions and arrays\n", "\n", "To change the predefined prior of a given observation model, one can add the keyword argument `prior` when defining an observation model. There are different ways of defining a parameter prior in *bayesloop*: If `prior=None` is set, *bayesloop* will assign equal probability to all parameter values, resulting in a uniform prior distribution within the specified parameter boundaries. One can also directly supply a NumPy array with prior probability (density) values. The shape of the array must match the shape of the parameter grid! Another way to define a custom prior is to provide a function that takes exactly as many arguments as there are parameters in the defined observation model. *bayesloop* will then evaluate the function for all parameter values and assign the corresponding probability values.\n", "\n", "