{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(sampler_stats)=\n", "# Sampler Statistics\n", "\n", ":::{post} May 31, 2022\n", ":tags: diagnostics\n", ":category: beginner\n", ":author: Meenal Jhajharia, Christian Luhmann\n", ":::" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Running on PyMC v5.28.0+58.gf58491a3\n" ] } ], "source": [ "import arviz as az\n", "import matplotlib.pyplot as plt\n", "import pymc as pm\n", "\n", "print(f\"Running on PyMC v{pm.__version__}\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "az.style.use(\"arviz-variat\")\n", "plt.rcParams[\"figure.constrained_layout.use\"] = False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When checking for convergence or when debugging a badly behaving sampler, it is often helpful to take a closer look at what the sampler is doing. For this purpose some samplers export statistics for each generated sample.\n", "\n", "As a minimal example we sample from a standard normal distribution:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "model = pm.Model()\n", "with model:\n", " mu1 = pm.Normal(\"mu1\", mu=0, sigma=1, shape=10)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Multiprocess sampling (4 chains in 4 jobs)\n", "NUTS: [mu1]\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e859b236e88f458ca4908723a5b52c76", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n" ], "text/plain": [] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "Sampling 4 chains for 1_000 tune and 2_000 draw iterations (4_000 + 8_000 draws total) took 6 seconds.\n" ] } ], "source": [ "with model:\n", " step = pm.NUTS()\n", " idata = pm.sample(2000, tune=1000, init=None, step=step, chains=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- `Note`: NUTS provides the following statistics (these are internal statistics that the sampler uses, you don't need to do anything with them when using PyMC, to learn more about them, {class}`pymc.NUTS`." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<xarray.DataTree 'sample_stats'>\n",
"Group: /sample_stats\n",
" Dimensions: (chain: 4, draw: 2000)\n",
" Coordinates:\n",
" * chain (chain) int64 32B 0 1 2 3\n",
" * draw (draw) int64 16kB 0 1 2 3 4 ... 1996 1997 1998 1999\n",
" Data variables: (12/18)\n",
" acceptance_rate (chain, draw) float64 64kB 0.5117 0.8243 ... 0.6885\n",
" n_steps (chain, draw) float64 64kB 3.0 7.0 7.0 ... 7.0 7.0\n",
" max_energy_error (chain, draw) float64 64kB 0.9907 0.5716 ... 0.7114\n",
" divergences (chain, draw) int64 64kB 0 0 0 0 0 0 ... 0 0 0 0 0 0\n",
" index_in_trajectory (chain, draw) int64 64kB -3 -4 -5 -3 3 ... 2 3 -4 6 4\n",
" energy (chain, draw) float64 64kB 22.85 22.25 ... 17.12\n",
" ... ...\n",
" tree_depth (chain, draw) int64 64kB 2 3 3 3 3 3 ... 3 2 3 3 3 3\n",
" reached_max_treedepth (chain, draw) bool 8kB False False ... False False\n",
" step_size_bar (chain, draw) float64 64kB 0.8498 0.8498 ... 0.8669\n",
" lp (chain, draw) float64 64kB -16.29 -18.61 ... -11.36\n",
" perf_counter_diff (chain, draw) float64 64kB 0.0003056 ... 0.0003297\n",
" perf_counter_start (chain, draw) float64 64kB 37.75 37.75 ... 39.12\n",
" Attributes:\n",
" created_at: 2026-04-25T12:14:28.293981+00:00\n",
" creation_library: ArviZ\n",
" creation_library_version: 1.1.1dev0\n",
" creation_library_language: Python\n",
" inference_library: pymc\n",
" inference_library_version: 5.28.0+58.gf58491a3\n",
" sample_dims: ['chain', 'draw']\n",
" sampling_time: 5.952891111373901\n",
" tuning_steps: 1000<xarray.DataArray 'diverging' ()> Size: 8B\n",
"array(0)<xarray.DataArray 'accept' (chain: 4, accept_dim_0: 2)> Size: 64B\n",
"array([[ 3.75 , 153.17870672],\n",
" [ 3.75 , 734.08661568],\n",
" [ 3.75 , 127.786444 ],\n",
" [ 3.75 , 252.56104158]])\n",
"Coordinates:\n",
" * chain (chain) int64 32B 0 1 2 3\n",
" * accept_dim_0 (accept_dim_0) int64 16B 0 1