Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Spatiotemporal Hawkes (ETAS-style) — From Scratch and With NumPyro

Open In Colab

Self-exciting spatiotemporal point processes — Hawkes processes — model events that trigger further events. The conditional intensity given the history Ht\mathcal H_t takes the ETAS-style form

λ∗(s,t)=μ+∑ti<tα βe−β(t−ti) N(s;si,σ2I).\lambda^*(s, t) = \mu + \sum_{t_i < t} \alpha\, \beta e^{-\beta(t - t_i)}\, \mathcal{N}(s; s_i, \sigma^2 I).

Each past event ii leaves a Gaussian-shaped “aftershock cloud” in space and an exponential decay in time. The branching ratio is α\alpha (sub-critical when α<1\alpha < 1 — the spatial and temporal kernels each integrate to 1, so the dimensional check works out).

This notebook walks through the operator, sampler, and a NumPyro fit that recovers μ,α,β,σ\mu, \alpha, \beta, \sigma from a single realisation.

Setup

/home/azureuser/localfiles/xtremax/.venv/bin/python: No module named pip
Note: you may need to restart the kernel to use updated packages.
/home/azureuser/localfiles/xtremax/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

1. From scratch — sample a sub-critical Hawkes realisation

Sampled 100 events (sub-critical α=0.4 < 1).
<Figure size 600x500 with 2 Axes>

Notice the clusters: events are not uniformly scattered in space-time, even though μ\mu alone is constant. The excitation kernel concentrates aftershock-like sequences near each “parent” event.

Conditional intensity at a query

<Figure size 700x350 with 1 Axes>

Closed-form log-likelihood

stpp_hawkes_log_prob evaluates ∑ilog⁡λ∗(si,ti)−Λ\sum_i \log \lambda^*(s_i, t_i) - \Lambda in O(n²) over the events. The compensator Λ\Lambda uses the analytic axis-wise erf-CDF for the spatial Gaussian when boundary_correction=True.

log L = -257.481

2. With NumPyro — recover (μ, α, β, σ)

Use weakly-informative priors that respect positivity and sub-criticality. NUTS works fine here because the closed-form compensator gives exact gradients.

   mu: posterior mean = 0.141, 95% CI = [0.101, 0.187], true = 0.2
alpha: posterior mean = 0.356, 95% CI = [0.153, 0.583], true = 0.4
 beta: posterior mean = 1.622, 95% CI = [0.744, 3.027], true = 1.5
sigma: posterior mean = 0.530, 95% CI = [0.358, 0.731], true = 0.6
<Figure size 1400x320 with 4 Axes>

A single realisation is enough to localise μ,α,β,σ\mu, \alpha, \beta, \sigma when the slab is large relative to the kernel bandwidth. Expect σ\sigma to be the most poorly identified — bandwidth and amplitude trade off when the cluster count is small.