Skip to content

Instantly share code, notes, and snippets.

@AustinRochford
Created November 5, 2021 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AustinRochford/8585e3b5d16768f5a1b710f4fb742ec2 to your computer and use it in GitHub Desktop.
Save AustinRochford/8585e3b5d16768f5a1b710f4fb742ec2 to your computer and use it in GitHub Desktop.
Efficiency of Various Parametrizations for Sampling from Latent Exchangeable Normal Random Variables in PyMC
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "389cf913-face-4458-b996-72d66b90cbb3",
"metadata": {},
"source": [
"For an upcoming analysis of the fighting skills of hockey players, I've fallen down a rabbit hole comparing several different parametrizations for estimating the covariance parameter of latent [exchangeable normal random variables](https://en.wikipedia.org/wiki/Exchangeable_random_variables) using [PyMC](https://docs.pymc.io/en/stable/). After working out which parameterization was most efficient for my model, I've decided that this derivation is interesting enough to merit its own post.\n",
"\n",
"<center>\n",
"<table>\n",
" <tr>\n",
" <td><img alt=\"Alice falling down a rabbit hole\" src=\"https://c.tenor.com/E14SgWRxUoMAAAAC/alice-rabbithole.gif\"></td>\n",
" <td><img alt=\"Bivariate normal distribution\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/57/Multivariate_Gaussian.png\" width=350></td>\n",
" <td><img alt=\"Philadelphia Flyers goalie punching Washington Capitals goalie\" src=\"http://www.trbimg.com/img-5b93e92c/turbine/ct-xpm-2013-11-01-chi-emery-starts-goalie-fight-in-flyers-loss-20131101\" width=350></td>\n",
" </tr>\n",
" <tr>\n",
" <td colspan=3><center>Alice in Wonderland, statistics, and hockey: three of my favorite things</center></td>\n",
" </tr>\n",
"</table>\n",
"</center>"
]
},
{
"cell_type": "markdown",
"id": "9c502bc2-0ad0-4a6b-8ef1-bd3c8e5f28f6",
"metadata": {},
"source": [
"## Exchangeable random variables\n",
"\n",
"Recall that a sequence of random variables $X_1, \\ldots, X_T$ is [exchangeable](https://en.wikipedia.org/wiki/Exchangeable_random_variables) if its joint distribution is invariant under permutations of the indicues. More concretely, this sequence is exchangeable if for every permutation of the indices (a bijective function $\\tau: \\{1, \\ldots T\\} \\to \\{1, \\ldots T\\}$), $X_1, \\ldots, X_T$ and $X_{\\tau(1)}, \\ldots, X_{\\tau(T)}$ have the same joint distribution.\n",
"\n",
"Exchangeabile variables arise in many situations, and most importantly for our situation, lead to interesting covariance/correlation structures. It is evident from the definition that exchangeable random variables must have the same mean and variance, so we define $\\mu = \\mathbb{E}(X_t)$ and $\\sigma^2 = \\mathbb{Var}(X_t)$. It is also evident that each pair has the same covariance, so we define the Pearson correlation coefficient\n",
"\n",
"$$\\rho = \\frac{\\mathbb{Cov}(X_s, X_t)}{\\sigma^2}.$$\n",
"\n",
"This post will focus on the sampling performance for estimating the posterior distribution of $\\rho$ using various mathematically equivalent parameterizations.\n",
"\n",
"Exchangeability imposes a restriction on how anticorrelated these random variables can be, as the following calculation shows. We know that variance must be nonnegative, so by the [bilinearity of covariance](https://en.wikipedia.org/wiki/Covariance#Covariance_of_linear_combinations)\n",
"\n",
"$$\n",
"\\begin{align}\n",
" 0\n",
" & \\leq \\mathbb{Var}\\left(\\sum_{t = 1}^T X_i\\right) \\\\\n",
" & = \\sum_{t = 1}^T \\mathbb{Var}(X_i) + 2 \\sum_{t = 1}^T \\sum_{s = 1}^t \\mathbb{Cov}(X_s, X_t) \\\\\n",
" & = T \\sigma^2 + T (T - 1) \\rho \\sigma^2 \\\\\n",
" & = (1 + (T - 1) \\rho) \\cdot T \\sigma^2.\n",
"\\end{align}\n",
"$$\n",
"\n",
"Since $T \\sigma^2 \\geq 0$ by definition, we must have\n",
"\n",
"$$1 + (T - 1) \\rho \\geq 0.$$\n",
"\n",
"Solving this inequality gives\n",
"\n",
"$$\\rho \\geq -\\frac{1}{T - 1},$$\n",
"\n",
"so exchangeable random variables cannot be too anticorrelated, and how anticorrelated they can be depends on the length of the sequence. In the limit $T \\to \\infty$, we see that an infinite sequence of exchangeable random variables must have nonnegative Pearson correlation.\n",
"\n",
"This constraint on the range of possible Pearson correlations for an exchangeable sequence is of particular interest for my hockey application as I want to examine the evidence that the latent fighting \"skill\" of players is uncorrelated across seasons. (The word \"skill\" appears in quotes here because if there is no season-over-season correlation, we are probably not modeling a true latent skill.)\n",
"\n",
"We will keep this constraint in mind as we explore the sampling efficiency of various parametrizations of latent exchangeable normal random variables in the following sections."
]
},
{
"cell_type": "markdown",
"id": "5d101733-d033-497d-bd6a-da13ed20bc3b",
"metadata": {},
"source": [
"## Generating the data\n",
"\n",
"For benchmarking purposes, we will simulate data sets drawn from a population based on latent normal parameters that are exchangeable. In order to focus on estimating the Pearson correlation, $\\rho$, we will assume all random variables have unit scale, $\\sigma = 1$. These calculations extend easily to the case of an abritrary scale.\n",
"\n",
"First we make the necessary Python imports and do some light housekeeping."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "b537677d-3058-4bff-905e-c76662863c1c",
"metadata": {},
"outputs": [],
"source": [
"from contextlib import contextmanager\n",
"from enum import Enum\n",
"from fastprogress.fastprogress import progress_bar\n",
"import json\n",
"import logging\n",
"from pathlib import Path\n",
"from toolz import compose, valmap"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1c7f8555-de8f-4ca4-bebc-3a1286f3b2ce",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"You are running the v4 development version of PyMC which currently still lacks key features. You probably want to use the stable v3 instead which you can either install via conda or find on the v3 GitHub branch: https://github.com/pymc-devs/pymc/tree/v3\n"
]
}
],
"source": [
"from aesara import tensor as at\n",
"import arviz as az\n",
"import matplotlib as mpl\n",
"from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import pymc as pm\n",
"import seaborn as sns\n",
"import sympy as sym"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bc8c6f18-c0b8-479a-9f28-7917f7b3b891",
"metadata": {},
"outputs": [],
"source": [
"FIG_WIDTH = 8\n",
"FIG_HEIGHT = 6\n",
"mpl.rcParams['figure.figsize'] = (FIG_WIDTH, FIG_HEIGHT)\n",
"\n",
"sns.set(color_codes=True)"
]
},
{
"cell_type": "markdown",
"id": "636c4acd-96e6-472f-acec-b9408723496c",
"metadata": {},
"source": [
"For the purposes of these simulations we will set $T = 4$, small enough so we can visualize covariance matrices using [SymPy](https://www.sympy.org/en/index.html), but large enough that I don't want to do the necessary calcuations by hand."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f8fe0454-a8cd-4328-bcfc-f58e4ca4e7fc",
"metadata": {},
"outputs": [],
"source": [
"T = 4"
]
},
{
"cell_type": "markdown",
"id": "99d465f8-ba98-43e1-91e3-5cbfeeb449eb",
"metadata": {},
"source": [
"We generate $K = 100$ random latent $T$-vectors from an exchangeable normal distribution with mean zero, unit scale, and Pearson correlation $\\rho$, so the covariance matrix is\n",
"\n",
"$$\n",
"\\Sigma_{\\rho}\n",
" = \\begin{pmatrix}\n",
" 1 & \\rho & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & 1 & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & 1 & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & \\rho & 1\n",
" \\end{pmatrix} \\in \\mathbb{R}^{T \\times T}\n",
"$$\n",
"\n",
"and $\\mathbf{\\mu}_1, \\ldots, \\mathbf{\\mu}_K \\sim N\\left(0, \\Sigma_{\\rho}\\right)$. For the moment we will use $\\rho = 0.5$."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0e76a91d-6939-4d84-9371-cc9ead85a08a",
"metadata": {},
"outputs": [],
"source": [
"RHO = 0.5\n",
"K = 100"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "06c45c84-cf38-4073-ad2e-bd3d03c7f3d5",
"metadata": {},
"outputs": [],
"source": [
"SEED = 123456789\n",
"\n",
"rng = np.random.default_rng(SEED)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "3be2550b-f528-4179-9494-9de8e93f16d3",
"metadata": {},
"outputs": [],
"source": [
"Sigma_rho = np.eye(T) + RHO * (1 - np.eye(T))\n",
"mu = rng.multivariate_normal(np.zeros(T), Sigma_rho, size=K)"
]
},
{
"cell_type": "markdown",
"id": "12fc15e5-68e8-45ed-8834-5f95d4da7252",
"metadata": {},
"source": [
"We see that these samples have the desired covariance structure (allowing for sampling noise on the order of $\\frac{1}{\\sqrt{K}} = 0.1$)."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "892b5832-b663-4b87-9ef7-320f6b58115b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1. , 0.43203461, 0.42611009, 0.52428711],\n",
" [0.43203461, 1. , 0.49784241, 0.52027976],\n",
" [0.42611009, 0.49784241, 1. , 0.48151274],\n",
" [0.52428711, 0.52027976, 0.48151274, 1. ]])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.corrcoef(mu, rowvar=False)"
]
},
{
"cell_type": "markdown",
"id": "f7a8f634-65e6-4534-859c-f9b394b4af80",
"metadata": {},
"source": [
"We now generate observations. Each of these $\\mathbf{\\mu}_k$ represent the latent mean of a group. We will generate $n_K = 20$ observations for group, $\\mathbf{x}_1, \\ldots, \\mathbf{x}_{K \\cdot n_K} \\in \\mathbb{R}^T$ with distribution $x_i \\sim N\\left(\\mathbf{\\mu}_{k(i)}, \\mathbb{I}_T\\right)$ where $k(i) = \\left\\lfloor \\frac{i}{n_K} \\right\\rfloor$ is the group of the $i$-th observation and $\\mathbb{I}_T$ is the T-dimensional identity matrix."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "8f0af28a-4474-4990-b0c5-dfecae063629",
"metadata": {},
"outputs": [],
"source": [
"n_K = 20\n",
"k_i = np.arange(K * n_K) // n_K"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "79106f10-d60f-4d89-94b9-adbb8eb308d6",
"metadata": {},
"outputs": [],
"source": [
"x = mu[k_i] + rng.normal(size=(K * n_K, T))"
]
},
{
"cell_type": "markdown",
"id": "3dc7361d-2896-40bb-8936-ff4d3a8f568e",
"metadata": {},
"source": [
"Calculating the covariance of $x_{i, s} = \\mu_{i, s} + \\varepsilon_{i, s}$ and $x_{i, t} = \\mu_{i, t} + \\varepsilon_{i, t}$, with $\\varepsilon_{i, t} \\sim N(0, 1)$ i.i.d as above, we get\n",
"\n",
"$$\n",
"\\begin{align}\n",
" \\mathbb{Cov}(x_{i, s}, x_{i, t})\n",
" & = \\mathbb{Cov}(\\mu_{i, s} + \\varepsilon_{i, s}, \\mu_{i, t} + \\varepsilon_{i, t}) \\\\\n",
" & = \\mathbb{Cov}(\\mu_{i, s}, \\mu_{i, t}) + \\mathbb{Cov}(\\varepsilon_{i, s}, \\varepsilon_{i, t}) \\\\\n",
" & = \\begin{cases}\n",
" \\sigma^2 + 1 & \\text{if } s = t \\\\\n",
" \\rho \\sigma^2 & \\text{if } s \\neq t\n",
" \\end{cases} \\\\\n",
" & = \\begin{cases}\n",
" 2 & \\text{if } s = t \\\\\n",
" 0.5 & \\text{if } s \\neq t\n",
" \\end{cases}.\n",
"\\end{align}\n",
"$$\n",
"\n",
"Therefore we get a Pearson correlation of\n",
"\n",
"$$\n",
"\\begin{align}\n",
" \\mathbb{Corr}(x_{i, s}, x_{i, t})\n",
" & = \\frac{\\mathbb{Cov}(x_{i, s}, x_{i, t})}{\\sqrt{\\mathbb{Cov}(x_{i, s}, x_{i, s})} \\cdot \\sqrt{\\mathbb{Cov}(x_{i, t}, x_{i, t})}} \\\\\n",
" & = \\frac{0.5}{\\sqrt{2} \\cdot \\sqrt{2}} \\\\\n",
" & = 0.25\n",
"\\end{align}\n",
"$$\n",
"\n",
"for $s \\neq t$.\n",
"\n",
"This correlation is borne out in our simulated data."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "f7361ad9-2663-4e92-b1c2-62abb34e946d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1. , 0.2343107 , 0.19670175, 0.24605147],\n",
" [0.2343107 , 1. , 0.22697497, 0.23203603],\n",
" [0.19670175, 0.22697497, 1. , 0.24862999],\n",
" [0.24605147, 0.23203603, 0.24862999, 1. ]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.corrcoef(x, rowvar=False)"
]
},
{
"cell_type": "markdown",
"id": "72fe97b0-e91f-4df9-9263-ad9ba1f61278",
"metadata": {},
"source": [
"In order to study the sampling performance of different parametrizations for a variety of values of $\\rho$, the following function that generates data as above given $\\rho$ will be useful."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "cfac7d46-5176-44d1-8c95-c77d4a27aa06",
"metadata": {},
"outputs": [],
"source": [
"def generate_data(rho, rng=None):\n",
" if rng is None:\n",
" rng = np.random.default_rng()\n",
" \n",
" Sigma_rho = np.eye(T) + rho * (1 - np.eye(T))\n",
" mu = rng.multivariate_normal(np.zeros(T), Sigma_rho, size=K)\n",
" \n",
" return mu[k_i] + rng.normal(size=(K * n_K, T))"
]
},
{
"cell_type": "markdown",
"id": "21a65e67-3ab3-4c2e-8526-8e0f4df9e721",
"metadata": {},
"source": [
"## Parametrizations for inference with exchangeble multivarial normal random variables\n",
"\n",
"For the rest of this post we will focus exclusively on the \n",
" \n",
"When we imported `pymc` we got the following warning:\n",
"\n",
"> `You are running the v4 development version of PyMC which currently still lacks key features. You probably want to use the stable v3 instead which you can either install via conda or find on the v3 GitHub branch: https://github.com/pymc-devs/pymc/tree/v3`\n",
"\n",
"One of the key features the development version of PyMC v4 lacks as of the commit that was installed in the Docker container I am composing this post on,"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "0a9e0f8b-6083-49ca-a40a-ed4fc3de9da1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"598dd9de2b818a58480071720a9f3da63177be89\n"
]
}
],
"source": [
"try:\n",
" pm_path = Path(pm.__path__[0])\n",
" dist_info_path, = pm_path.parent.glob(\"pymc-*.dist-info\")\n",
"\n",
" with open(dist_info_path / \"direct_url.json\", 'r') as src:\n",
" direct_url_data = json.load(src)\n",
"\n",
" print(direct_url_data[\"vcs_info\"][\"commit_id\"])\n",
"except:\n",
" print(\"Nothing to see here\")"
]
},
{
"cell_type": "markdown",
"id": "0c670757-138f-4bad-bfc7-0ceb3768c840",
"metadata": {},
"source": [
"is a working multivariate normal implementation. This lack is not a true problem as we can quickly implement a workaround sufficient for our situation that will be roughly in line with the eventual PyMC v4 implementation.\n",
"\n",
"### The Cholesky decomposition\n",
"\n",
"Recall that if $\\mathbf{\\mu} \\in \\mathbb{R}^T$ and $\\Sigma \\in \\mathbb{R}^{T \\times T}$ is a [positive definite](https://en.wikipedia.org/wiki/Positive-definite_matrix) covariance matrix and $\\mathbf{x} \\sim N(\\mathbf{\\mu}, \\Sigma)$ then the density of $\\mathbf{x}$ is\n",
"\n",
"$$\n",
"f\\left(\\mathbf{x}\\ | \\mathbf{\\mu}, \\Sigma\\right)\n",
" = (2 \\pi)^{-\\frac{T}{2}} \\cdot \\left|\\Sigma\\right|^{-\\frac{1}{2}} \\cdot \\exp \\left(-\\frac{(\\mathbf{x} - \\mathbf{\\mu})^{\\top} \\Sigma^{-1}(\\mathbf{x} - \\mathbf{\\mu})}{2}\\right).\n",
"$$\n",
"\n",
"The [quadratic form](https://en.wikipedia.org/wiki/Quadratic_form) $(\\mathbf{x} - \\mathbf{\\mu})^{\\top} \\Sigma^{-1}(\\mathbf{x} - \\mathbf{\\mu})$ is suggestive. If we can decompose the covariance matrix $\\Sigma = L L^{\\top}$ where $L$ is sufficiently nice, we can rewrite the quadratic form as\n",
"\n",
"$$\n",
"(\\mathbf{x} - \\mathbf{\\mu})^{\\top} \\Sigma^{-1}(\\mathbf{x} - \\mathbf{\\mu})\n",
" = (L^{-1} (\\mathbf{x} - \\mathbf{\\mu}))^{\\top} (L^{-1} (\\mathbf{x} - \\mathbf{\\mu})).\n",
"$$\n",
"\n",
"If, in particular, $L$ is lower diagonal, it is relatively easy to solve the linear system $L \\mathbf{z} = \\mathbf{x} - \\mathbf{\\mu}$ using [back subtitution](https://en.wikipedia.org/wiki/Triangular_matrix#Forward_and_back_substitution). The determinant in the density is also easy to calculate because $|\\Sigma|^{-\\frac{1}{2}} = |L|^{-1}$, and the determinant of a triangular matrix is just the product of its diagonal entries. Fortunately such a decomposition, the [Cholesky decomposition](https://en.wikipedia.org/wiki/Cholesky_decomposition), is well-known and has been extensively studied. Together with the Cholesky decomposition, the following fact gives an easy way to generate samples from a multivariate normal distribution with arbitrary covariance matrix.\n",
"\n",
"**Theorem** Let $\\mathbf{z} \\in \\mathbb{R}^n$ have components drawn from a standard normal distribution, $z_1, \\ldots z_n \\overset{\\text{i.i.d.}}{\\sim} N(0, 1)$. Let $A \\in \\mathbb{R}^{m \\times n}$. Then $A \\mathbf{z} \\in \\mathbb{R}^m$ has distribution $A \\mathbf{z} \\sim N(0, A^{\\top}A)$.\n",
"\n",
"Therefore if we want to generate samples from an $N(0, \\Sigma)$ distribution, we can calculate the Cholesky decomposition of the covariance matrix, $\\Sigma = L L^{\\top}$, generate samples $\\mathbf{z}_i \\sim N(0, \\mathbb{I})$ and multiply to get $L \\mathbf{z}_i \\sim N(0, \\Sigma)$.\n",
"\n",
"This post will compare two ways of calculating the Cholesky factorization of $\\Sigma$ in the case that the normal random variables are exchangeable with a third parametrization for cases where $\\rho \\geq 0$ through the lens of sampling efficiency using Hamiltonian Monte Carlo sampling implemented in PyMC."
]
},
{
"cell_type": "markdown",
"id": "de202f46-40d6-457f-9c85-acf9e55f8c8f",
"metadata": {},
"source": [
"### General Cholesky decomposition\n",
"\n",
"PyMC uses [Aesara](https://aesara.readthedocs.io/en/latest/index.html) as its underlying tensor computation/differentiation engine. Conveniently, Aesara implements a cholesky decomposition that PyMC then wraps in the function `pm.distributions.multivariate.cholesky` that can be applied to matrices of random variables.\n",
"\n",
"We begin with a uniform prior on our correlation coefficient in the permissible range $-\\frac{1}{T - 1} \\leq \\rho < 1$."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "e563901e-ee94-4419-8e5f-38c75bb6e3e2",
"metadata": {},
"outputs": [],
"source": [
"with pm.Model(rng_seeder=SEED) as gen_model:\n",
" ρ = pm.Uniform(\"ρ\", -1. / (T - 1), 1.)"
]
},
{
"cell_type": "markdown",
"id": "1c2ad4fa-a060-4f2d-a754-3d9a1390c725",
"metadata": {},
"source": [
"We then build the associated covariance matrix\n",
"\n",
"$$\n",
"\\Sigma_{\\rho}\n",
" = \\begin{pmatrix}\n",
" 1 & \\rho & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & 1 & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & 1 & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & \\rho & 1\n",
" \\end{pmatrix} \\in \\mathbb{R}^{T \\times T}\n",
"$$\n",
"\n",
"and compute its Cholesky decomposition."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "68e3c292-31f2-4a0e-aa95-d0e57b206d00",
"metadata": {},
"outputs": [],
"source": [
"def get_corr_mat(rho, n):\n",
" return np.eye(n) + rho * (1 - np.eye(n))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "deb144fa-3a7b-45db-8835-91c339e346e1",
"metadata": {},
"outputs": [],
"source": [
"with gen_model:\n",
" Σ_ρ = get_corr_mat(ρ, T)\n",
" L = pm.distributions.multivariate.cholesky(Σ_ρ)"
]
},
{
"cell_type": "markdown",
"id": "4b7f3e4d-f49c-4ee2-86fd-31e6d012f959",
"metadata": {},
"source": [
"Following the plan laid out in the theorem above, we then sample $\\mathbf{z}_1, \\ldots, \\mathbf{z}_K \\in \\mathbb{R}^T$ having standard normally distributed entries, and transform them to to $\\mathbf{\\mu}_k = L \\mathbf{z}_k \\sim N\\left(0, \\Sigma_{\\rho}\\right)$."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "4a644f69-5d13-4734-bdd9-ecc32ecb4a6a",
"metadata": {},
"outputs": [],
"source": [
"with gen_model:\n",
" z = pm.Normal(\"z\", 0., 1., shape=(K, T))\n",
" μ = z.dot(L.T)"
]
},
{
"cell_type": "markdown",
"id": "1ccfad77-8c27-4bf5-84d9-59e26efa64e8",
"metadata": {},
"source": [
"Finally we specify the likelihood of the observed data."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5f24b11f-0a1b-4374-ae83-a021a83be0c0",
"metadata": {},
"outputs": [],
"source": [
"with gen_model:\n",
" pm.Normal(\"obs\", μ[k_i], 1., observed=pm.Data(\"x\", x))"
]
},
{
"cell_type": "markdown",
"id": "1d315caf-e2f0-4e07-a5c1-338151476943",
"metadata": {},
"source": [
"We now sample from the model's posterior distribution."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "751ea5cf-16de-4a28-923b-e2eb9348876d",
"metadata": {},
"outputs": [],
"source": [
"CORES = 3\n",
"\n",
"SAMPLE_KWARGS = {\n",
" 'cores': CORES,\n",
" 'random_seed': [SEED + i for i in range(CORES)]\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "b0985d3b-fe62-4cdd-ac57-befd2a747cfd",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Auto-assigning NUTS sampler...\n",
"Initializing NUTS using jitter+adapt_diag...\n",
"Multiprocess sampling (3 chains in 3 jobs)\n",
"NUTS: [ρ, z]\n"
]
},
{
"data": {
"text/html": [
"\n",
" <div>\n",
" <style>\n",
" /* Turns off some styling */\n",
" progress {\n",
" /* gets rid of default border in Firefox and Opera. */\n",
" border: none;\n",
" /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
" background-size: auto;\n",
" }\n",
" .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
" background: #F44336;\n",
" }\n",
" </style>\n",
" <progress value='6000' class='' max='6000' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
" 100.00% [6000/6000 04:03<00:00 Sampling 3 chains, 0 divergences]\n",
" </div>\n",
" "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Sampling 3 chains for 1_000 tune and 1_000 draw iterations (3_000 + 3_000 draws total) took 245 seconds.\n",
"The number of effective samples is smaller than 25% for some parameters.\n"
]
}
],
"source": [
"with gen_model:\n",
" gen_trace = pm.sample(**SAMPLE_KWARGS)"
]
},
{
"cell_type": "markdown",
"id": "6da3adc4-f9be-44da-8969-54e4d7a87c08",
"metadata": {},
"source": [
"Note the warning about small effective sample size. Effective samples per second will be the key quantity to consider when we benchmark our parametrizations against each other.\n",
"\n",
"Plotting the posterior distribution of $\\rho$, we see that the true value of 0.5 is comfortably inside the high posterior density interval."
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "7fc954b2-12d9-4db2-95a9-1799017a6ae0",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"az.plot_posterior(gen_trace, var_names=\"ρ\", ref_val=0.5);"
]
},
{
"cell_type": "markdown",
"id": "6186d118-1b12-4fe2-9438-5a8d3774e1f3",
"metadata": {},
"source": [
"### Cholesky decomposition for excheangeable normal random variables\n",
"\n",
"One advantage of the previous parametrization is its generality; nowhere did we rely on the fact that the random variables were exchangeable. While pursuing my hockey fight research, I was curious if we can improve upon the sampling performance by taking advantage of the fact that exchangeable normal random variables lead to the highly structured covariance matrix\n",
"\n",
"$$\n",
"\\begin{align}\n",
" \\Sigma_{\\rho} = \\begin{pmatrix}\n",
" 1 & \\rho & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & 1 & \\cdots & \\rho & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & 1 & \\rho \\\\\n",
" \\rho & \\rho & \\cdots & \\rho & 1\n",
" \\end{pmatrix}.\n",
"\\end{align}\n",
"$$\n",
"\n",
"Therefore the question is, can we exploit this structure to come up with a simple (enough) closed form expression to facilitate faster sampling? The answer was not obvious to me, but I was hopeful. Prior to considering this question I had never calculated a Cholesky decomposition by hand, and I still have not. To avoid the tedious work of manual calculations, we can lean on [SymPy](https://www.sympy.org/en/index.html).\n",
"\n",
"Below we generate a matrix the $T \\times T$ covariance matrix for our situation (exchangeable normal random variables with unit scale and $T = 4$)."
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "34cb0988-6a02-4716-a794-1eea48d5a500",
"metadata": {},
"outputs": [],
"source": [
"def get_corr_mat_sympy(rho, n):\n",
" return sym.eye(n) + rho * (sym.ones(n, n) - sym.eye(n))"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "a1c84b5f-3e86-4365-824f-6816f42e50e7",
"metadata": {},
"outputs": [],
"source": [
"rho = sym.var(r\"\\rho\")"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "9da203b6-0893-4ab7-8cdf-ba66b48b8740",
"metadata": {},
"outputs": [],
"source": [
"Sigma_rho_sym = get_corr_mat_sympy(rho, T)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "5af9bd1b-c9e9-42fc-91ef-0d09c156d361",
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}1 & \\rho & \\rho & \\rho\\\\\\rho & 1 & \\rho & \\rho\\\\\\rho & \\rho & 1 & \\rho\\\\\\rho & \\rho & \\rho & 1\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[ 1, \\rho, \\rho, \\rho],\n",
"[\\rho, 1, \\rho, \\rho],\n",
"[\\rho, \\rho, 1, \\rho],\n",
"[\\rho, \\rho, \\rho, 1]])"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Sigma_rho_sym"
]
},
{
"cell_type": "markdown",
"id": "3e40b056-ab8b-4a45-80d7-0410cb20487a",
"metadata": {},
"source": [
"We can ask SymPy for this matrix's Cholesky decomposition and try to spot useful patterns."
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "582a3a7f-7a57-45af-ae3b-14cdbb851f37",
"metadata": {},
"outputs": [],
"source": [
"L_sym = Sigma_rho_sym.cholesky(hermitian=False)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "191ce6b1-0bae-4dc1-b165-4f66fdbe098e",
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}1 & 0 & 0 & 0\\\\\\rho & \\sqrt{1 - \\rho^{2}} & 0 & 0\\\\\\rho & \\frac{- \\rho^{2} + \\rho}{\\sqrt{1 - \\rho^{2}}} & \\sqrt{- \\rho^{2} + 1 - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}} & 0\\\\\\rho & \\frac{- \\rho^{2} + \\rho}{\\sqrt{1 - \\rho^{2}}} & \\frac{- \\rho^{2} + \\rho - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}}{\\sqrt{- \\rho^{2} + 1 - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}}} & \\sqrt{- \\rho^{2} + 1 - \\frac{\\left(- \\rho^{2} + \\rho - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}\\right)^{2}}{- \\rho^{2} + 1 - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}} - \\frac{\\left(- \\rho^{2} + \\rho\\right)^{2}}{1 - \\rho^{2}}}\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[ 1, 0, 0, 0],\n",
"[\\rho, sqrt(1 - \\rho**2), 0, 0],\n",
"[\\rho, (-\\rho**2 + \\rho)/sqrt(1 - \\rho**2), sqrt(-\\rho**2 + 1 - (-\\rho**2 + \\rho)**2/(1 - \\rho**2)), 0],\n",
"[\\rho, (-\\rho**2 + \\rho)/sqrt(1 - \\rho**2), (-\\rho**2 + \\rho - (-\\rho**2 + \\rho)**2/(1 - \\rho**2))/sqrt(-\\rho**2 + 1 - (-\\rho**2 + \\rho)**2/(1 - \\rho**2)), sqrt(-\\rho**2 + 1 - (-\\rho**2 + \\rho - (-\\rho**2 + \\rho)**2/(1 - \\rho**2))**2/(-\\rho**2 + 1 - (-\\rho**2 + \\rho)**2/(1 - \\rho**2)) - (-\\rho**2 + \\rho)**2/(1 - \\rho**2))]])"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"L_sym"
]
},
{
"cell_type": "markdown",
"id": "b179e961-4b28-4f15-81e5-8df50dc8227f",
"metadata": {},
"source": [
"One thing I notice immediately is that I am glad I did not calculate this by hand. Another important point to notice is that each column has at most two unique (nonzero) entries:\n",
"\n",
"1. the diagonal entry, and\n",
"2. the entry below the diagonal that is repeated to fill the rest of the column.\n",
"\n",
"For a $T \\times T$ covariance matrix, that means that there are only $2 T - 1$ unique entries to calculate, rather than $\\frac{T (T - 1)}{2}$, a significant reduction. I suspect, but also have not rigorously shown that these values can be calculated in less than the cubic [time required](https://en.wikipedia.org/wiki/Cholesky_decomposition#Computation) for the Cholesky decomposition of an arbitrary positive definite matrix.\n",
"\n",
"While there is a pattern here that we could manually implement, we can be lazy and use SymPy's [`lambdify`](https://docs.sympy.org/latest/modules/utilities/lambdify.html#sympy.utilities.lambdify.lambdify) and a small Aesara bookkeeping function to convert the SymPy computational graph for the above decomposition into an Aesara function that can be used in a PyMC model."
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "bc5c18fe-a58f-4ee0-a552-949cecf03d18",
"metadata": {},
"outputs": [],
"source": [
"def to_aesara(mat):\n",
" return at.stack(\n",
" [at.stack(row, axis=0) for row in mat],\n",
" axis=0\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "ef165ddf-0a29-4154-a3ee-ff7426f24eb4",
"metadata": {},
"outputs": [],
"source": [
"exch_chol = compose(to_aesara, sym.lambdify(rho, L_sym))"
]
},
{
"cell_type": "markdown",
"id": "82111d22-c625-42f3-ba77-4d56494eb986",
"metadata": {},
"source": [
"Except for the calculation of the Cholesky decomposition, every aspect of this model is the same as in the previous one."
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "bdc21ecf-c5da-4914-a895-be0abe8e065b",
"metadata": {},
"outputs": [],
"source": [
"with pm.Model(rng_seeder=SEED) as exch_model:\n",
" ρ = pm.Uniform(\"ρ\", -1. / (T - 1), 1.)\n",
" L = exch_chol(ρ)\n",
" \n",
" z = pm.Normal(\"z\", 0., 1., shape=(K, T))\n",
" μ = z.dot(L.T)\n",
" \n",
" pm.Normal(\"obs\", μ[k_i], 1., observed=pm.Data(\"x\", x))"
]
},
{
"cell_type": "markdown",
"id": "8acd33ef-d626-45c4-be36-9a6af62e65cc",
"metadata": {},
"source": [
"We now sample from this model's posterior distribution."
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "44a52e66-b779-4ec9-8734-44fa0488458d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Auto-assigning NUTS sampler...\n",
"Initializing NUTS using jitter+adapt_diag...\n",
"Multiprocess sampling (3 chains in 3 jobs)\n",
"NUTS: [ρ, z]\n"
]
},
{
"data": {
"text/html": [
"\n",
" <div>\n",
" <style>\n",
" /* Turns off some styling */\n",
" progress {\n",
" /* gets rid of default border in Firefox and Opera. */\n",
" border: none;\n",
" /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
" background-size: auto;\n",
" }\n",
" .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
" background: #F44336;\n",
" }\n",
" </style>\n",
" <progress value='6000' class='' max='6000' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
" 100.00% [6000/6000 00:25<00:00 Sampling 3 chains, 0 divergences]\n",
" </div>\n",
" "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Sampling 3 chains for 1_000 tune and 1_000 draw iterations (3_000 + 3_000 draws total) took 26 seconds.\n",
"The number of effective samples is smaller than 25% for some parameters.\n"
]
}
],
"source": [
"with exch_model:\n",
" exch_trace = pm.sample(**SAMPLE_KWARGS)"
]
},
{
"cell_type": "markdown",
"id": "549dedf2-d055-4693-95ea-bf2eb5bcc303",
"metadata": {},
"source": [
"This model sampled much more quickly than the previous one, but we still see the effective sample size warning.\n",
"\n",
"This model has done a very similar job of recovering the true correlation coefficient."
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "a17f72da-a4bb-4d0a-a608-3d74b188bd29",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"az.plot_posterior(exch_trace, var_names=\"ρ\", ref_val=0.5);"
]
},
{
"cell_type": "markdown",
"id": "e381e109-82d2-44db-9884-425045a561f5",
"metadata": {},
"source": [
"Now that we have two models that produce roughly equivalent estimates, we can compare their sampling efficiency."
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "2011f1d1-3f97-4be2-8135-b8bacee81ebd",
"metadata": {},
"outputs": [],
"source": [
"class ModelType(Enum):\n",
" GEN_CHOL = \"General Cholesky\"\n",
" EXCH_CHOL = \"Exchangeable Cholesky\"\n",
" TWO_STAGE = \"Two-stage\""
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "38675eac-1a95-42b2-9942-ed5aa76a9833",
"metadata": {},
"outputs": [],
"source": [
"half_traces = {\n",
" ModelType.GEN_CHOL: gen_trace,\n",
" ModelType.EXCH_CHOL: exch_trace\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "e4590989-8b7c-46c8-82fc-657165a1504d",
"metadata": {},
"outputs": [],
"source": [
"def get_ess_value(trace):\n",
" return (az.ess(trace, var_names=\"ρ\")\n",
" .to_array()\n",
" .values[0])\n",
"\n",
"def get_sampling_time(trace):\n",
" return (trace.sample_stats\n",
" .attrs\n",
" [\"sampling_time\"])\n",
"\n",
"def get_bench_df(traces):\n",
" df = pd.DataFrame.from_dict({\n",
" \"Effective sample size\": valmap(get_ess_value, traces),\n",
" \"Sampling time\": valmap(get_sampling_time, traces)\n",
" })\n",
" df[\"Effective samples per second\"] = df[\"Effective sample size\"] \\\n",
" / df[\"Sampling time\"]\n",
" df.index = df.index.map(lambda e: e.value)\n",
" \n",
" return df"
]
},
{
"cell_type": "markdown",
"id": "4f68c8a1-2fd2-410a-9e53-490cb2266161",
"metadata": {},
"source": [
"Here we have a benchmark comparing the effective sample size, sampling time, and effective samples per second for these two models."
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "388c5657-1df2-48e0-a7ee-0c4aefa7025c",
"metadata": {},
"outputs": [],
"source": [
"half_df = get_bench_df(half_traces)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "ce1db31e-d127-4b3f-9940-8e113fcd99fa",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Effective sample size</th>\n",
" <th>Sampling time</th>\n",
" <th>Effective samples per second</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>General Cholesky</th>\n",
" <td>518.860706</td>\n",
" <td>244.747165</td>\n",
" <td>2.119987</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Exchangeable Cholesky</th>\n",
" <td>530.852329</td>\n",
" <td>25.752860</td>\n",
" <td>20.613335</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Effective sample size Sampling time \\\n",
"General Cholesky 518.860706 244.747165 \n",
"Exchangeable Cholesky 530.852329 25.752860 \n",
"\n",
" Effective samples per second \n",
"General Cholesky 2.119987 \n",
"Exchangeable Cholesky 20.613335 "
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"half_df"
]
},
{
"cell_type": "markdown",
"id": "f3c78442-74ac-44a7-b6f8-d596b4f72145",
"metadata": {},
"source": [
"We see that these two models have produced essentially the same number of effective samples, but that the exchangeable model has produced this samples in a much shorter period of time than the general model, leading to a significantly higher effective samples per second."
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "a5cdebd1-e900-4ae3-9aaa-26cb5d458843",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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HowdO7baM12quQcNh44aNQpnzpzBnDlzsGvXLtjb26OoqAgXLlwwPzYBVBjye9Bj+ueff8bChQuRlZUFGxsb5OTk4Pbt23BxcQEADBs2DADg7u4OBwcHZGZmoqysDHZ2duazpsGDB5tHXVJTU5GcnIwFCxaY111WVoaffvoJ7dq1w4EDBxAXF4eysjLcuXOnwlla69at0bNnTwBAQEAAli9fjsLCwgrbfurUKaSlpWHSpEnmaeXl5cjJyUGLFi3M03gsWRZDsB7r1KkTbty4Yf7e1KeffhoHDhzA3/72N1y+fBnAvQdreHi4edjn9359sgDu/R7jr7/IIYTA1q1b4eHhUelyTZs2Nd+Oi4vDd999Z36SiomJMQ9TPUiLFi3g5uaGixcvol+/fpXO89sDQ6lUory83FybQlH9D3gKITB27FjMnz//vrapU6fCz88Pp0+fxsqVK+Hj44M33ngDANChQwecP38e169fNw89devWDUajEd999x3279+P2NjYatdPtVdaWopr166hefPmyM3NrdEyD3pML1iwACEhIRg0aBBMJhOeffZZlJSUVLvcgx5rQgg4OTnhwIED97WdP38ee/bswd///nc4OzsjLi4On3zySY3q/y1fX1+sW7euynl4LFkW3x1aj7Vp0wYDBw7EsmXLYDAYzNPv3Lljvu3n54ePPvoIxcXFAIDCwkIkJydX27efnx+2b99ufiLIy8vDzz//XOm8BoMBTk5OsLe3h8FgMP+qR3Vee+01rF27FmlpaeZpp06dwr///e8ql+vTpw9OnDiB27dvAwA++eQT9O3bt9JtOHDgADIzMwHc+6mtX18cpKSk4Mknn8TEiRPx4osv4tKlS+blnnnmGbz77rtYvHgxvv32W/P0KVOmYMGCBejatSt/rquOrFu3Ds888wx27tyJ8PBwZGZmolmzZtDpdPjoo4/M8+Xl5VXbl8FggLu7OwDg008/RWlpabXLtG3bFnfu3MF3330HADhy5Ij5DOipp56CnZ0d9u/fb54/OTkZhYWFKCgogL29PRwdHVFaWorPPvusQr83btzA+fPnAdx7Eenp6Wk+U/qVj48PTp06hWvXrpmnXbx4sdI6eSxZDs8E67k1a9Zg69atGDduHGxsbODg4ABXV1e8+uqrAIBXX30V7777LsaNGweFQgGFQoG5c+eiXbt2VfYbGhqK9evXIyAgAAqFAk2aNEFoaGilZ4ajRo3C0aNHMXz4cLi5uaF79+4VXmE/yMSJE2FnZ4fg4GAUFxdDqVSiY8eOWLx4sTl8K9O+fXssXLgQ06dPBwB4eHhgxYoV983Xo0cPvP7665g9ezaMRiPKysowZMgQdO7cGX/9619x9uxZNGnSBGq1GsuWLauwbIcOHRATE4PZs2dj+fLl8PX1xfDhw7FixQoEBQVVu230cIKDgyuciUVGRiIrKwvffvstYmNjYWtrizlz5mDBggX4+OOPsWHDBrz11lvQ6/VQKpXQ6/Xmx/yDLF26FK+99hrc3NzQs2dPODo6VluXWq3G22+/jYiICNjZ2aF3795o0aIFmjdvDhsbG8TExGD16tXYsWMHTCYTNBoN/vznP+O5557DF198gaFDh8LNzQ2dO3euEA6//gTc6tWroVQqKz3ba9OmDdavX48333wTxcXFKCsrQ7du3dClS5f75uWxZDn8FQmi/+f8+fOIiIhAXFxcjYaQqHEoLCw0n6WdOXMGISEhOHbsGJRKDpT9UQ3pWOKZIBHunRmfPn3a/HZ7kkdiYiI++ugjCCHMZ4YMwD+uoR1LPBMkIiJp8eUOERFJiyFIRETSYggSEZG0GIJERCQthiAREUnr/wAIh3oJs3LVHwAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 460.8x518.4 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(nrows=3, sharex=True,\n",
" figsize=(0.8 * FIG_WIDTH, 1.2 * FIG_HEIGHT))\n",
"\n",
"\n",
"(half_df[\"Effective sample size\"]\n",
" .plot.bar(ax=axes[0]));\n",
"(half_df[\"Sampling time\"]\n",
" .plot.bar(ax=axes[1]));\n",
"(half_df[\"Effective samples per second\"]\n",
" .plot.bar(ax=axes[2], rot=False));\n",
"\n",
"axes[1].set_ylabel(\"Seconds\");\n",
"\n",
"axes[0].set_title(\"Effective sample size\");\n",
"axes[1].set_title(\"Sampling time\");\n",
"axes[2].set_title(\"Effective samples per second\");\n",
"\n",
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"id": "0a76ca54-566b-4c08-8680-3b98fc35e454",
"metadata": {},
"source": [
"Effective samples per second is the metric by which we will ultimately judge our parametrizations."
]
},
{
"cell_type": "markdown",
"id": "9bb61219-b3af-4d7c-99bc-cd4bc4d8207c",
"metadata": {},
"source": [
"### Two-stage sampling for nonnegative correlations\n",
"\n",
"There is one more approach that is worth including in this comparison. If the correlation coefficient $\\rho \\geq 0$ we can produce samples with the desired covariance structure according to the following scheme.\n",
"\n",
"1. Sample $w_1, \\ldots z_K \\sim N(0, 1)$.\n",
"2. Sample $z_{k, t} \\sim N(0, 1)$ for $k = 1, \\ldots, K$ and $t = 1, \\ldots T$.\n",
"3. Set $\\mu_{k, t} = \\sqrt{\\rho} \\cdot w_k + \\sqrt{1 - \\rho} \\cdot z_{k, t}$.\n",
"\n",
"To see that these samples have the appropriate structure we calculate\n",
"\n",
"$$\n",
"\\begin{align}\n",
" \\mathbb{Cov}(\\mu_{k, s}, \\mu_{k, t})\n",
" & = \\mathbb{Cov}(\\sqrt{\\rho} \\cdot w_k + \\sqrt{1 - \\rho} \\cdot z_{k, s}, \\sqrt{\\rho} \\cdot w_k + \\sqrt{1 - \\rho} \\cdot z_{k, t}) \\\\\n",
" & = \\rho + (1 - \\rho) \\cdot \\mathbb{Cov}(z_{k, s}, z_{k, t})\n",
"\\end{align}\n",
"$$\n",
"\n",
"by independence. We have\n",
"\n",
"$$\n",
"\\mathbb{Cov}(z_{k, s}, z_{k, t}) = \\begin{cases}\n",
" 1 & \\text{if } s = t \\\\\n",
" 0 & \\text{if } s \\neq t\n",
"\\end{cases},\n",
"$$\n",
"\n",
"so\n",
"\n",
"$$\n",
"\\mathbb{Cov}(\\mu_{k, s}, \\mu_{k, t}) = \\begin{cases}\n",
" 1 & \\text{if } s = t \\\\\n",
" \\rho & \\text{if } s \\neq t\n",
"\\end{cases}.\n",
"$$\n",
"\n",
"It is clear from the $\\sqrt{\\rho}$ and $\\sqrt{1 - \\rho}$ terms why this sampling scheme requires $0 \\leq \\rho < 1$."
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "a3e4d4d0-566b-4761-8d7f-5e6fa34c4a5a",
"metadata": {},
"outputs": [],
"source": [
"with pm.Model(rng_seeder=SEED) as two_stage_model:\n",
" ρ = pm.Uniform(\"ρ\", 0., 1.)\n",
"\n",
" z = pm.Normal(\"z\", 0., 1., shape=(K, 1))\n",
" w = pm.Normal(\"w\", 0., 1., shape=(K, T))\n",
" μ = at.sqrt(ρ) * z + at.sqrt(1 - ρ) * w\n",
" \n",
" pm.Normal(\"y_obs\", μ[k_i], 1., observed=pm.Data(\"x\", x))"
]
},
{
"cell_type": "markdown",
"id": "4a678527-4760-4bba-933c-b4377ec2ef0a",
"metadata": {},
"source": [
"We now sample from this model's posterior distribution."
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "d1e7ce43-ddb9-4ea5-93f3-c63c965b115f",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Auto-assigning NUTS sampler...\n",
"Initializing NUTS using jitter+adapt_diag...\n",
"Multiprocess sampling (3 chains in 3 jobs)\n",
"NUTS: [ρ, z, w]\n"
]
},
{
"data": {
"text/html": [
"\n",
" <div>\n",
" <style>\n",
" /* Turns off some styling */\n",
" progress {\n",
" /* gets rid of default border in Firefox and Opera. */\n",
" border: none;\n",
" /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
" background-size: auto;\n",
" }\n",
" .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
" background: #F44336;\n",
" }\n",
" </style>\n",
" <progress value='6000' class='' max='6000' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
" 100.00% [6000/6000 01:03<00:00 Sampling 3 chains, 0 divergences]\n",
" </div>\n",
" "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Sampling 3 chains for 1_000 tune and 1_000 draw iterations (3_000 + 3_000 draws total) took 64 seconds.\n"
]
}
],
"source": [
"with two_stage_model:\n",
" half_traces[ModelType.TWO_STAGE] = pm.sample(**SAMPLE_KWARGS)"
]
},
{
"cell_type": "markdown",
"id": "dc46cfc7-ad25-477f-bb6d-9435e6c7d264",
"metadata": {},
"source": [
"Once again this model recovers the true correlation coefficient roughly as well as the others."
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "e45e35d4-7e0b-4096-97cb-2bf4efb03778",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"az.plot_posterior(half_traces[ModelType.TWO_STAGE],\n",
" var_names=\"ρ\", ref_val=0.5);"
]
},
{
"cell_type": "markdown",
"id": "a21f14a5-95cc-414c-9701-64534d7d849f",
"metadata": {},
"source": [
"Reevaluating our benchmarks with this model, we see that it samples slightly fewer effective samples per second than the exchangeable model, but is still significantly more efficient than the general model."
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "cebf9596-19d1-4c7c-a54a-9b74470b3202",
"metadata": {},
"outputs": [],
"source": [
"half_df = get_bench_df(half_traces)"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "2977fc1a-d6bc-480f-8888-2e4988369cf8",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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PPXUUygvL693u9qOsxACzs7ONV4rOn36NPbs2YN//etfcHFxwf79+/Hxxx83qP7fCwoKwtq1a+tch+OoedjZ2aFz5844cOAA3Nzc0LdvX+h0OjzyyCPS1HNdx3Pbtm04ePAggLvvY+jbty/27duH48ePIykpCdu3b8eePXvu2a6usVRXf3U9Zg8afkSiDh06dMCgQYOwdOlSGAwGafnt27elv4ODg/HBBx+grKwMAFBSUoL09PR69x0cHIzt27dLT4aFhYW4evVqjesaDAY4OzvD3t4eBoNB+lWN+rz66qtYs2YNsrKypGXHjh3Df//73zq369evH44cOYKbN28CAD7++GM8/fTTNd6HpKQk5OTkALj7U1e/vTjIyMjAY489hokTJ+KFF17Ajz/+KG3XtWtXvP3221i4cCG+//57afmUKVMQERGBHj16NMvPZa1duxZdu3bFzp07ERMTg5ycHLRp0wZ+fn744IMPpPUKCwvr3ZfBYJDecfrJJ5+goqKi3m06duyI27dv44cffgAAfPXVV9Kr6ccffxx2dnbYt2+ftH56ejpKSkpQXFwMe3t7ODk5oaKiAp9++mm1/V65cgWnT58GcPcFlI+Pj3Sm9JvAwEAcO3YMly5dkpadO3euxjo5jppHv379sHnzZvTr1w9qtRqPPPII9u7dK73Arut4zp49G0lJSUhKSkLfvn1x9epV2NvbY+TIkVi8eDH+93//FyaTSXoO+U1dY6lPnz44ePAg7ty5A5PJhM8//1xqq+sxe9DwTLAeq1evxtatWzFu3DjY2NjA0dER7u7ueOWVVwAAr7zyCt5++22MGzcOVlZWsLKywty5c+Ht7V3nfqOiorBu3TqEhITAysoKrVq1QlRUVI1nhs8//zwOHTqEkSNHwsPDA7169ap2llGbiRMnws7ODuHh4SgrK4O1tbX01vbfwrcmnTp1wvz58zF9+nQAgJeXF5YvX37Per1798brr7+O2bNnw2g0orKyEsOGDUO3bt3wz3/+EydPnkSrVq2gVquxdOnSatt27twZCQkJmD17NpYtW4agoCCMHDkSy5cvR1hYWL33rTHCw8OrnYnFxcUhNzcX33//PRITE2Fra4s5c+YgIiICH374IdavX48333wTWq0W1tbW0Gq10uNdm8WLF+PVV1+Fh4cHAgIC4OTkVG9darUaGzZsQGxsLOzs7NC3b1+0bdsWDg4OsLGxQUJCAlatWoUdO3bAZDLB1dUVf//73/HMM8/g888/x/Dhw+Hh4YFu3bpVC4fffn5s1apVsLa2rvFsr0OHDli3bh2WLFmCsrIyVFZWomfPnujevfs963IcNY9+/frhrbfeQt++fQEAffv2xZkzZ6THpKHHEwC+//577Ny5EyqVCiaTCW+++Sasra3Rr18/vP/++3juuecQEBCAyMjIWsfSoEGDcPbsWYSEhMDDwwNPPfUUfv31VwB1P2YPGv6KBFmM06dPIzY2Fvv372/QNFpLUFJSIp2lnThxApGRkTh8+DCsrTlJ82cpcRyZy2/j02QyYcmSJXB3d5emo1sKngmSRYiKisLx48eljxwoRWpqKj744AMIIaQzQwbgn6fUcWQuixYtwvXr11FWVoauXbvi5ZdflrukJsczQSIiUiy+5CQiIsViCBIRkWIxBImISLEYgkREpFgMQSIiUqz/D361gydhwrJDAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 460.8x518.4 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(nrows=3, sharex=True,\n",
" figsize=(0.8 * FIG_WIDTH, 1.2 * FIG_HEIGHT))\n",
"\n",
"(half_df[\"Effective sample size\"]\n",
" .plot.bar(ax=axes[0]));\n",
"(half_df[\"Sampling time\"]\n",
" .plot.bar(ax=axes[1]));\n",
"(half_df[\"Effective samples per second\"]\n",
" .plot.bar(ax=axes[2], rot=False));\n",
"\n",
"axes[1].set_ylabel(\"Seconds\");\n",
"\n",
"axes[0].set_title(\"Effective sample size\");\n",
"axes[1].set_title(\"Sampling time\");\n",
"axes[2].set_title(\"Effective samples per second\");\n",
"\n",
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"id": "44ca9211-5ccd-49e8-ae63-8d32b1ee544e",
"metadata": {},
"source": [
"Since the exchangeable model samples slightly more effective samples per second and can accomodate a wider range of correlation coefficients ($-\\frac{1}{T - 1} \\leq \\rho < 1$ versus $0 \\leq \\rho <1$) when compared to the two-stage model, we are inclined to prefer this parameterization."
]
},
{
"cell_type": "markdown",
"id": "776606ca-1109-416c-8155-93cec55cfdca",
"metadata": {},
"source": [
"## Benchmarking\n",
"\n",
"Before concluding that the exchangeable Cholesky parametrization is best for the hockey fight application, we will repeat the above exercise across a range of values of $\\rho$ of interest. We choose the left endpoint the interval, $-\\frac{1}{T - 1} \\leq \\rho < 1$, a few values around zero to see how these parametrizations behave in the neighborhood of zero, and a few larger positive values."
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "1a418b13-e957-491b-8091-b0833c158028",
"metadata": {},
"outputs": [],
"source": [
"RHOS = [-1 / (T - 1), -0.05, 0., 0.05, 0.5, 0.9]"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "80cf75d4-8b65-427e-824c-c6a7e9d9f581",
"metadata": {},
"outputs": [],
"source": [
"data = {RHO: x}\n",
"\n",
"for rho in RHOS:\n",
" if rho not in data:\n",
" data[rho] = generate_data(rho, rng=rng)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "914ae5a3-e99d-4bac-bf4a-492486a5bf64",
"metadata": {},
"outputs": [],
"source": [
"traces = {RHO: half_traces}"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "fce5f31c-9a69-41ab-ba08-e5ffcf00f92c",
"metadata": {},
"outputs": [],
"source": [
"def can_use_model(rho, name):\n",
" return rho >= 0 or name != ModelType.TWO_STAGE\n",
"\n",
"def sample_models(rho, x, models, *,\n",
" sample_kwargs=SAMPLE_KWARGS,\n",
" progressbar=True):\n",
" traces = {}\n",
" \n",
" for i, (name, model) in enumerate(models.items()):\n",
" if can_use_model(rho, name):\n",
" with model:\n",
" pm.set_data({\"x\": x})\n",
" traces[name] = pm.sample(progressbar=progressbar,\n",
" **sample_kwargs)\n",
" \n",
" return traces"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "c69026f5-cfb6-4c80-9f08-b296e602c6a2",
"metadata": {},
"outputs": [],
"source": [
"@contextmanager\n",
"def set_log_level(logger, level):\n",
" orig_level = logger.getEffectiveLevel()\n",
" \n",
" try:\n",
" logger.setLevel(level)\n",
" yield\n",
" finally:\n",
" logger.setLevel(orig_level)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "a0dfa9e9-736c-4f88-bb63-4acf3ef7afde",
"metadata": {},
"outputs": [],
"source": [
"models = {\n",
" ModelType.GEN_CHOL: gen_model,\n",
" ModelType.EXCH_CHOL: exch_model,\n",
" ModelType.TWO_STAGE: two_stage_model\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "474197c1-95b6-4937-95bc-9144c3834169",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" <div>\n",
" <style>\n",
" /* Turns off some styling */\n",
" progress {\n",
" /* gets rid of default border in Firefox and Opera. */\n",
" border: none;\n",
" /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
" background-size: auto;\n",
" }\n",
" .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
" background: #F44336;\n",
" }\n",
" </style>\n",
" <progress value='6' class='' max='6' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
" 100.00% [6/6 22:56<00:00 Sampling models for $\\rho = 0.90$]\n",
" </div>\n",
" "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pm_logger = logging.getLogger(\"pymc\")\n",
"\n",
"RHOS_prog = progress_bar(RHOS)\n",
"\n",
"with set_log_level(pm_logger, logging.CRITICAL):\n",
" for rho in RHOS_prog:\n",
" RHOS_prog.comment = f\"Sampling models for $\\\\rho = {rho:.2f}$\"\n",
"\n",
" if rho not in traces:\n",
" \n",
" traces[rho] = sample_models(rho, data[rho], models,\n",
" progressbar=False)"
]
},
{
"cell_type": "markdown",
"id": "88fa6105-3d7f-4684-a676-e6fac568de49",
"metadata": {},
"source": [
"From these traces, we can get a combined benchmark data frame."
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "d877cad3-574b-4d1e-b1f2-c3910e19ebd6",
"metadata": {},
"outputs": [],
"source": [
"def add_rho_level(rho, df):\n",
" return (df.assign(rho=rho)\n",
" .rename_axis(\"model\")\n",
" .set_index(\"rho\", append=True))"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "719dd6b6-5b7d-41f9-8aee-4ed69c944291",
"metadata": {},
"outputs": [],
"source": [
"bench_dfs = valmap(get_bench_df, traces)\n",
"bench_df = (\n",
" pd.concat((\n",
" add_rho_level(rho, rho_df) for rho, rho_df in bench_dfs.items()\n",
" ))\n",
" .sort_index(level=\"rho\")\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "103963c0-3e35-41cb-b3d1-8d3c3193c340",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th>Effective sample size</th>\n",
" <th>Sampling time</th>\n",
" <th>Effective samples per second</th>\n",
" </tr>\n",
" <tr>\n",
" <th>model</th>\n",
" <th>rho</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Exchangeable Cholesky</th>\n",
" <th>-0.333333</th>\n",
" <td>63.184842</td>\n",
" <td>24.983521</td>\n",
" <td>2.529061</td>\n",
" </tr>\n",
" <tr>\n",
" <th>General Cholesky</th>\n",
" <th>-0.333333</th>\n",
" <td>95.288883</td>\n",
" <td>243.715941</td>\n",
" <td>0.390983</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Exchangeable Cholesky</th>\n",
" <th>-0.050000</th>\n",
" <td>364.477740</td>\n",
" <td>23.676677</td>\n",
" <td>15.393957</td>\n",
" </tr>\n",
" <tr>\n",
" <th>General Cholesky</th>\n",
" <th>-0.050000</th>\n",
" <td>341.109837</td>\n",
" <td>180.427612</td>\n",
" <td>1.890563</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Exchangeable Cholesky</th>\n",
" <th>0.000000</th>\n",
" <td>371.375624</td>\n",
" <td>21.831124</td>\n",
" <td>17.011292</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Effective sample size Sampling time \\\n",
"model rho \n",
"Exchangeable Cholesky -0.333333 63.184842 24.983521 \n",
"General Cholesky -0.333333 95.288883 243.715941 \n",
"Exchangeable Cholesky -0.050000 364.477740 23.676677 \n",
"General Cholesky -0.050000 341.109837 180.427612 \n",
"Exchangeable Cholesky 0.000000 371.375624 21.831124 \n",
"\n",
" Effective samples per second \n",
"model rho \n",
"Exchangeable Cholesky -0.333333 2.529061 \n",
"General Cholesky -0.333333 0.390983 \n",
"Exchangeable Cholesky -0.050000 15.393957 \n",
"General Cholesky -0.050000 1.890563 \n",
"Exchangeable Cholesky 0.000000 17.011292 "
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bench_df.head()"
]
},
{
"cell_type": "markdown",
"id": "bef4cf90-33aa-4e9f-adfd-41a858535d61",
"metadata": {},
"source": [
"This analysis shows that, in every situation we have tested, the exchangeable Cholesky parameterization is preferable in terms of effective samples per second."
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "3932eac9-25e1-4b42-81c6-c0deebb95107",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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b29iY2NLulQRETGZEg/Bhg0b8uuvvxa4bu3atRfdLzg4mDVr1pRQVSIiIvrEGBERMTGFoIiImJZCUERETEshKCIipqUQFBER01IIioiIaSkERUTEtBSCIiJiWgpBERExLYWgiIiYVqlOpVSR+Fa34mH1LFYbeTnZpP2R46SKRESkqBSCV8jD6sm3s4YXq40WT78OKATNzBmzqoNmVhe5UgpBERdyxqzqcH5mdVAIihSV7gmKiIhpmfJMsJq3F16elVxdhoiIuJgpQ9DLsxKRT68sVhurZg10UjUiIuIquhwqIiKmVaZD8MCBAwwYMIBu3boxYMAADh486OqSRESkAinTITh58mQiIyPZvHkzkZGRREdHu7okERGpQMrsPcGUlBQSEhJYtmwZABEREUybNo3U1FT8/PwK1Ya7u9tF19XwrVLsGq3e/sVu41I1liRn9B80Bs7of42qhXs9X86VjGNFGoPy3H/QGJTUv4PLjYmbYRiGU47sZD/99BPjx49n/fr1jmU9e/Zk9uzZNGnSxIWViYhIRVGmL4eKiIiUpDIbgkFBQSQlJWGz2QCw2WwkJycTFBTk4spERKSiKLMh6O/vT0hICHFxcQDExcUREhJS6PuBIiIil1Nm7wkC7N+/n6ioKM6cOYO3tzexsbE0aNDA1WWJiEgFUaZDUEREpCSV2cuhIiIiJU0hKCIipqUQFBER01IIioiIaSkERUTEtBSCIiJiWgpBERExLYWgiIiYlkJQRERMSyEoIiKmpRAUERHTUgiKiIhpKQRFRMS0FIIiImJaCkGRcmrBggWMHTsWgOPHjxMaGorNZiuVY/fq1YudO3eWyrFESpKHqwsQKW927drFnDlz2LdvHxaLhQYNGjBx4kSaNm3qsppq167N7t27S6TtqKgoAgMDefLJJx3L1q9fXyLHEiltCkGRIsjIyOCRRx4hJiaGHj16kJuby65du7Bara4uTUSugC6HihTBgQMHAIiIiMBiseDl5UX79u257rrrADh8+DD33XcfrVu3pnXr1jz11FOcOXPGsX94eDivv/46vXv3plmzZkycOJFTp04xfPhwQkNDGTJkCH/88QcAR48epXHjxrzzzju0b9+e9u3b88YbbxRY15/b5uXlATB48GBefPFF7rnnHkJDQxk2bBipqamO7deuXUunTp1o3bo1CxcuJDw8nC+//PKCdt955x0+/vhjli5dSmhoKI888oijH39uv2DBAkaNGsXYsWMJDQ2ld+/eHDhwgFdffZW2bdvSsWNH/vOf/zjaTE9PZ+LEibRv354OHTowb968UruMK/JPCkGRIrj22muxWCyMHz+ezz//3BFYfzIMg4cffpgdO3awceNGTpw4wYIFC/JtEx8fz7Jly9i8eTNbt27lwQcfZMyYMezcuRO73c6bb76Zb/udO3cSHx/P0qVLWbJkSYFhVZC4uDiee+45vvrqK3Jzcx0B+ttvvzFlyhRmz57Njh07yMjIICkpqcA2BgwYQO/evXnggQfYvXs3ixcvLnC7rVu30qdPH7755htCQkJ44IEHsNvtbN++nZEjRxIdHe3Ydvz48Xh4eBAfH8/atWv54osvWLNmTaH6JOJsCkGRIqhatSqrVq3Czc2NZ599lrZt2/LII49w6tQpAK655hratWuH1WrFz8+PoUOH8s033+RrY9CgQdSoUYPAwEDCwsJo2rQp119/PVarla5du5KQkJBv+5EjR1K5cmUaN25M3759iYuLK1Stffv25dprr8XLy4vu3bvz888/A7Bp0yY6depEWFgYVquVUaNG4ebmVqxxCQsLo0OHDnh4eNC9e3fS0tJ46KGHqFSpEj179uTYsWOcOXOGU6dOsX37diZOnEjlypXx9/dnyJAhuscoLqN7giJFFBwczPPPPw/A/v37GTduHDNnzmTu3LmkpKQwffp0du3aRWZmJoZh4O3tnW//GjVqOL729PTM972Xlxdnz57Nt31QUJDj6zp16rB3795C1VmzZk3H11dddZWj3eTkZGrVqpVvnY+PT6HavBh/f3/H115eXvj6+mKxWBzfA5w9e5bk5GTy8vJo3769Y3u73Z6vjyKlSSEoUgzBwcH07duXd955B4AXXngBNzc3PvroI3x9ffnkk0+YOnVqsY6RmJhIcHAwcP6tEAEBAcVqLyAgwHFvEyArK4vTp09fdPviniX+Xa1atbBarXz99dd4eOjXj7ieLoeKFMH+/ft54403OHHiBHA+oOLi4rjpppsAyMzMpHLlynh7e5OUlMTrr79e7GMuWrSIc+fOsW/fPj744AN69uxZrPa6devGZ599xnfffUdOTg7z58/HMIyLbu/v78/Ro0eLdcw/BQQE0K5dO55//nkyMjKw2+0cPnyY//73v05pX6SoFIIi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S9VYkpzRf9AYOKP/Nao654++KxnHijQG5bn/oDEoqX8HlxsTN8MwLnxyRERExAT0sWkiImJaCkERETEthaCIiJiWQlBERExLISgiIqalEBQREdNSCIqIiGkpBEVExLQUgiIiYloKQRERMS2FoIiImJZCUERETEshKCIipqUQFBER01IIioiIaSkERUTEtBSCIiJiWgpBERExLYWgiIiYlkJQyrR58+bRunVr2rVrB8CWLVvo2LEjoaGhJCQkOO04u3btolu3bk5rryzZuXMnt9xyi6vLqFAaN27MoUOHXF2GOIGHqwsQcwsPD+fUqVNYLBbHsjvvvJPo6GgSExNZtmwZW7duxd/fH4DY2FieffZZunTpUqzjNm7cmPj4eK655hoAwsLC2Lx5c7HaFJHyRyEoLrd48WJuvvnmC5YfO3YMHx8fRwACHD9+nIYNG5ZmeVLC8vLy8PDQryJxDV0OlTLpyy+/ZNiwYSQnJxMaGsqYMWMIDQ3FZrPRp08fx5lgUlISjz/+OG3atCE8PJwVK1Y42rDZbCxevJguXboQGhpK3759SUxMZODAgQD06dOH0NBQNmzYkO+S4ZIlSxg1alS+eqZPn8706dMBSE9PZ+LEibRv354OHTowb948bDZbgf3Ys2cPffv2pXnz5tx8880899xzjnWjRo2iXbt2tGjRgoEDB7Jv3z7HuqioKGJiYhg+fDihoaHcc889nDx5khkzZtCyZUu6d++e73JweHg4r776Kj179qRly5ZMmDCB7OzsAmu61Jhdqt6/+3O8Fi9eTOvWrQkPD+ejjz5yrM/JySE2NpZbb72Vm2++mejoaLKysvLtu2TJEtq1a8eECRMuaP/QoUMMGjSIFi1a0Lp1a5544gnHuv379zN06FBatWpFt27d2LBhg2NdVlYWzz//PJ06daJFixbce++9juN++umn9OrVi7CwMAYPHsz+/fvzjd/SpUvp3bs3LVq04Iknnsg3fq+//jrt27enffv2vPfeewWOiZRThogLderUyfjiiy8KXPf1118bHTp0yLesUaNGxsGDBw3DMAybzWbceeedxoIFC4zs7Gzj8OHDRnh4uLF9+3bDMAzjtddeMyIiIoz9+/cbdrvd+Pnnn43U1NQL2vnnsY4ePWo0bdrUSE9PNwzDMPLy8ox27doZu3fvNgzDMEaMGGE8++yzRmZmpnHq1CnjrrvuMlavXl1gH/r37298+OGHhmEYRkZGhqMNwzCMNWvWGOnp6UZ2drYxffp04/bbb3esGz9+vNGqVSvjxx9/NLKysozBgwcbnTp1Mj788EMjLy/PmDt3rjFo0KB849irVy/j+PHjRlpamjFgwABj7ty5F/TtcmN2qXr/+bMJCQkxZs6caWRnZxs7d+40brrpJmP//v2GYRjG9OnTjYcffthIS0sz0tPTjYcfftiYM2dOvn1nzZplZGdnG+fOnbug/SeffNJYtGiRYbPZjKysLOObb74xDMMwMjMzjVtuucV47733jNzcXOOnn34yWrVqZezdu9cwDMOIiYkxBg0aZJw4ccLIy8szvv32WyM7O9v4/fffjZtuusn4z3/+Y+Tk5BhLliwxunTpYmRnZzvG76677jJOnDhhpKWlGd27dzdWrVplGIZhfP7550bbtm2NX3/91cjMzDTGjBlzwetHyi+dCYrLjRw5krCwMMd/7777bqH2+/HHH0lNTeWxxx7DarVSr149+vfv7zgzWLNmDaNHj6ZBgwa4ublx3XXX4evre9l269Spw/XXX88nn3wCwNdff42XlxfNmjXj1KlTbN++nYkTJ1K5cmX8/f0ZMmQI69evL7AtDw8PDh8+TGpqKlWqVKFZs2aOdf369aNq1apYrVYef/xxfvnlF9LT0x3ru3btyg033ICnpyddu3bF09OTO+64A4vFQs+ePfn555/zHWvgwIEEBQXh4+PDiBEjCqzpcmN2qXoLMnr0aKxWK61ataJjx45s3LgRwzBYs2YNEydOxMfHh6pVq/Lwww/nq8fd3Z1Ro0ZhtVrx8vIqcNyOHz9OcnIynp6ehIWFAbBt2zbq1KnDXXfdhYeHB02aNKFbt25s3rwZu93O+++/zzPPPENgYCAWi4XmzZtjtVrZsGEDHTt2pF27dlSqVIkHHniArKwsdu/e7Tjm4MGDCQwMxMfHh06dOjnGd+PGjfTt25dGjRpRuXJlHnvssUuOiZQvuhAvLrdw4cIC7wlezrFjx0hOTnb8goTzl0D//P7EiRNcffXVV1RTREQEcXFx3HHHHcTFxREREQGcvyeZl5dH+/btHdva7XaCgoIKbGfGjBnMnz+fHj16ULduXR577DE6deqEzWZj3rx5bNq0idTUVNzdz/89mpaWRrVq1QDy3Qv18vKiRo0a+b4/e/ZsvmP9vYbatWuTnJx8QT2XG7OL1VsQb29vKleufMExU1NTOXfuHH379nWsMwwDu93u+N7X1xdPT88C2wUYN24cL730Ev369aN69eoMHTqUfv36cezYMfbs2XNB/bfffjtpaWlkZ2dTr169C9pLTk6mdu3aju/d3d0JCgoiKSnJsaxmzZqOr6+66irH+CUnJ3PDDTc41tWpU+eidUv5oxCUcisoKIi6desSHx9f4PpatWpx+PBhGjVqVOS2e/ToQWxsLCdOnGDLli288847jjatVitff/11oR7mqF+/PnPnzsVutxMfH8+oUaPYuXMn8fHxfPrppyxbtoy6deuSnp5Oy5YtMQyjyLX+KTEx0fH18ePHCQgIuGCby43Zxer9e9j96cyZM5w9e9axLjExkYYNG+Lr64uXlxfr168nMDCwwOO4ubldsi81a9Z03IPdtWsXQ4cOpWXLlgQFBdGyZUuWLVt2wT52ux1PT0+OHDnCddddl29dQEAAe/fudXxvGAaJiYkXre+f+/5zbKXi0OVQKbeaNm1K1apVWbJkCVlZWdhsNvbu3cuePXsAuPvuu3nppZc4ePAghmHwyy+/kJaWBkCNGjU4cuTIRdv28/OjVatWTJgwgbp16xIcHAyc/4XYrl07nn/+eTIyMrDb7Rw+fJj//ve/Bbazbt06x5met7c3ABaLhczMTKxWK76+vpw7d465c+cWezxWrVrFiRMnOH36tOMhmX+63JhdrN6LWbBgATk5OezatYtt27bRvXt33N3dufvuu5k5cyYpKSnA+YdxduzYUei+bNy4kRMnTgBQvXp13NzccHd359Zbb+XgwYOsXbuW3NxccnNz2bNnD/v378fd3Z277rqL5557jqSkJGw2G7t37yYnJ4cePXrw+eef89VXX5Gbm8sbb7yB1WolNDT0srV0796dDz/8kN9++41z587x8ssvF7ofUvYpBMXlHnnkEUJDQx3/jRw5slD7WSwWXnnlFX755Rc6d+5MmzZtmDRpEhkZGQAMHTqUHj16MGzYMJo3b84zzzzjeOLvscceIyoqirCwsHxPF/5dREQEX375peNS6J9mzZpFbm6u40nMUaNGcfLkyQLb2LFjB7169SI0NJQZM2Ywb948x7292rVr06FDB3r16nXZe2+FERERwbBhw+jSpQv16tVjxIgRF2xzuTG7WL0FqVGjBt7e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\n",
"text/plain": [
"<Figure size 460.8x518.4 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, axes = plt.subplots(nrows=3, sharex=True,\n",
" figsize=(0.8 * FIG_WIDTH, 1.2 * FIG_HEIGHT))\n",
"\n",
"sns.barplot(\n",
" x=\"rho\", y=\"Effective sample size\",\n",
" data=bench_df.reset_index(),\n",
" hue=\"model\", ax=axes[0]\n",
");\n",
"sns.barplot(\n",
" x=\"rho\", y=\"Sampling time\",\n",
" data=bench_df.reset_index(),\n",
" hue=\"model\", ax=axes[1]\n",
");\n",
"sns.barplot(\n",
" x=\"rho\", y=\"Effective samples per second\",\n",
" data=bench_df.reset_index(),\n",
" hue=\"model\", ax=axes[2]\n",
");\n",
"\n",
"axes[0].set_xlabel(None);\n",
"axes[1].set_xlabel(None);\n",
"\n",
"axes[2].set_xticklabels([f\"{rho:.2f}\" for rho in RHOS]);\n",
"axes[2].set_xlabel(r\"$\\rho$\");\n",
"\n",
"axes[0].set_ylabel(None);\n",
"\n",
"axes[1].set_yscale('log');\n",
"axes[1].set_ylim(bottom=0.75);\n",
"axes[1].set_yticks([1, 10, 100]);\n",
"axes[1].set_ylabel(\"Seconds\");\n",
"\n",
"axes[2].set_ylabel(None);\n",
"\n",
"axes[0].set_title(\"Effective sample size\");\n",
"axes[1].set_title(\"Sampling time\");\n",
"axes[2].set_title(\"Effective samples per second\");\n",
"\n",
"axes[0].legend(loc=\"upper left\", title=\"Parameterization\");\n",
"axes[1].legend_.set(visible=False);\n",
"axes[2].legend_.set(visible=False);\n",
"\n",
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"id": "81cfc6c8-ab6e-426f-8d91-49ba4fe8a49e",
"metadata": {},
"source": [
"Interestingly, the exchangeable parameterization outperforms the two-stage sampling approach by a wider margin in the limit $\\rho \\searrow 0$.\n",
"\n",
"Of course if we wanted a really rigorous benchmark we would run inference in each of these situations many times to get a reliable average value and standard deviation for each of these metrics. I am unfortunately impatient, and collecting this data has already taken quite a while, so this evidence is sufficient for me to prefer the exchangeable Cholesky parameterization in my hockey fight analysis."
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "7e05638f-de04-4ecb-b308-51d5a1e3786c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Last updated: Fri Nov 05 2021\n",
"\n",
"Python implementation: CPython\n",
"Python version : 3.7.10\n",
"IPython version : 7.28.0\n",
"\n",
"json : 2.0.9\n",
"logging : 0.5.1.2\n",
"pymc : 4.0.0\n",
"sympy : 1.9\n",
"numpy : 1.19.5\n",
"aesara : 2.2.2\n",
"seaborn : 0.11.2\n",
"pandas : 1.3.3\n",
"matplotlib: 3.4.3\n",
"arviz : 0.11.4\n",
"\n"
]
}
],
"source": [
"%load_ext watermark\n",
"%watermark -n -u -v -iv"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.10"
},
"nikola": {
"title": "Efficiency of Various Parametrizations for Sampling from Latent Exchangeable Normal Random Variables in PyMC",
"slug": "exch-param-pymc",
"author": "Austin Rochford",
"date": "2021-11-05",
"tags": "Bayesian, PyMC"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment