CategoricalProbability
Probability Maps as First-Class Arrows
A sensor feeds a filter feeds a controller, and every handoff is a distribution. Markov kernels make each step a composable arrow, and Wasserstein distance measures how far apart two beliefs really sit.
§0The Big Idea
A sensor hands a noisy estimate to a filter, the filter hands a belief to a controller, and every handoff along the way is a distribution rather than a value.
The pipeline begs to be treated like function composition, and it can be: each stochastic step is a Markov kernel — an arrow X → Dist(Y) you compose like any other — and distributions carry a principled distance, Wasserstein, so “how far apart are these two beliefs?” has an actual answer. That buys clean plumbing for stochastic systems and a robust way to compare what a model expects against what a sensor reports.
§1Three Foundational Concepts
Giry Monad
A monad on measurable spaces sending each space X to the space of probability measures on X. The unit turns a point into a point mass; multiplication flattens a distribution over distributions into one distribution. Its Kleisli category has Markov kernels as morphisms — stochastic programs you can compose.
Markov Categories
A diagrammatic axiomatization of probability in which conditioning, disintegration, and conditional independence become algebraic laws — general enough that results like the Kolmogorov zero–one law admit purely diagrammatic proofs.
Kantorovich Monad
On complete metric spaces, the probability monad carries the Wasserstein distance, and the whole structure is generated by finite samples: distributions arise as limits of empirical ones. The bridge between sampling code and measure theory.
§2Why This Matters Practically
Compositional Pipelines
X → Dist(Y). Compose kernels instead of juggling PDFs. In the sheaf-fusion picture of the companion note, these kernels are the plumbing that connects local beliefs to transport costs.Robustness Knobs
Sample ↔ Measure Sanity
§3Runnable Example: Compare Beliefs
A minimal example showing how to compute the Wasserstein distance between two belief snapshots. Use this number to regularize a controller (e.g., add λ·W₁ to your cost) or to gate model switching.
import numpy as np
from scipy.stats import wasserstein_distance
# Two belief snapshots, each a bag of samples
a = np.array([0.1, 0.2, 0.2, 0.8])
b = np.array([0.15, 0.25, 0.7])
# Compute Wasserstein-1 distance
w1 = wasserstein_distance(a, b)
print("W1 =", w1) # lower = closer beliefs
# Use in a controller cost function
# (the helpers below come from your own stack)
def augmented_cost(state, action, lambda_reg=0.1):
base_cost = compute_base_cost(state, action)
predicted_belief = predict_belief(state, action)
observed_belief = get_observation()
# Robustness penalty
belief_mismatch = wasserstein_distance(
predicted_belief,
observed_belief
)
return base_cost + lambda_reg * belief_mismatch§3.1Kernel Composition Pattern
Build stochastic pipelines by composing Markov kernels. Each arrow transforms distributions through a stochastic step.
class MarkovKernel:
"""A stochastic map X -> Dist(Y)"""
def __init__(self, transition_fn):
self.transition = transition_fn
def __call__(self, x):
"""Apply kernel to a point, get distribution"""
return self.transition(x)
def pushforward(self, dist_x):
"""Apply kernel to a distribution (bind)"""
return flatten([self(x) for x in dist_x.samples])
def compose(self, other):
"""Kleisli composition: (f >=> g)(x) = bind(f(x), g)"""
def composed(x):
intermediate = self(x)
return other.pushforward(intermediate)
return MarkovKernel(composed)
# Build a sensor-state-controller pipeline
sensor_to_latent = MarkovKernel(sensor_model)
latent_to_action = MarkovKernel(policy)
# Compose into end-to-end pipeline
sensor_to_action = sensor_to_latent.compose(latent_to_action)§4Minimal Mental Model
- Unit: Wrap a value into a degenerate distribution (Dirac delta). This is how deterministic values enter the stochastic world.
- Map / Pushforward: Transform a distribution through a deterministic function. If f: X → Y and μ is a distribution on X, the pushforward f#μ is a distribution on Y: sample from μ, then apply f.
- Bind (>>=): Run a stochastic step that returns a new distribution, then flatten. This is kernel composition — the essential plumbing operation.
§4.1Connection to Sheaf Fusion
Alongside the sheaf-fusion picture in the companion note on topos-theoretic probability, categorical probability supplies:
- Clean glue between local beliefs, via kernel composition
- Transport costs via built-in Wasserstein metrics
- Structural reasoning — conditional independence expressed as an algebraic law in a Markov category
§5Further Reading
Giry (1982), A Categorical Approach to Probability Theory
The paper that made distributions a monad, with Markov kernels as the morphisms of its Kleisli category.
Fritz (2020), A Synthetic Approach to Markov Kernels
Markov categories in full: algebraic laws for conditioning, disintegration, and conditional independence, with classical theorems reproved diagrammatically.
Fritz & Perrone (2019), A Probability Monad as the Colimit of Spaces of Finite Samples
The Kantorovich monad: Wasserstein structure generated by finite empirical distributions.
- Giry 1982Michèle Giry, A Categorical Approach to Probability Theory (Springer Lecture Notes in Mathematics 915)
- Fritz 2020Tobias Fritz, A Synthetic Approach to Markov Kernels, Conditional Independence and Theorems on Sufficient Statistics (Advances in Mathematics 370)
- Fritz & Perrone 2019Tobias Fritz & Paolo Perrone, A Probability Monad as the Colimit of Spaces of Finite Samples (Theory and Applications of Categories 34)
- Cho & Jacobs 2019Kenta Cho & Bart Jacobs, Disintegration and Bayesian Inversion via String Diagrams (Mathematical Structures in Computer Science 29)