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.

A Gaussian-process primer — and richer spatial features

From a lon/lat interpolator to an ARD GP that weighs elevation, distance-to-coast and slope

Abstract

A Gaussian process is a prior over smooth functions — the natural way to say the extreme-value parameters vary smoothly across space. We warm up by using a GP to interpolate each station’s mean annual maximum from its (lon, lat), with calibrated uncertainty. Then we ask what a station really “knows”: we derive physical covariates — elevation, distance to the coast and terrain slope — and let an ARD (automatic relevance determination) GP decide, through one lengthscale per feature, which of them actually drive the extremes.

Keywords:Gaussian processautomatic relevance determinationspatial covariateselevationdistance to coast

A Gaussian-process primer (with pyrox)

A Gaussian process (GP) is a prior over smooth functions: nearby inputs get correlated outputs, with the correlation set by a kernel. It is the natural way to say “the extreme-value parameters vary smoothly across space”.

As a warm-up, forget extremes for a moment and just use a GP to interpolate a spatial field: regress each station’s mean annual maximum onto its (lon, lat), and predict a smooth surface with uncertainty. We use pyrox.gp: a Matern kernel, a GPPrior, fit its hyperparameters by SVI, then condition on the data and predict on a grid. Then we go beyond (lon, lat) and give the GP physical features to work with.

/Users/eman/code_projects/research_notebook/projects/spatial_extremes/.venv/lib/python3.12/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
source: REAL | stations 107
fitted kernel: variance=0.85, lengthscale=0.91, noise=0.44

Condition the fitted GP on the stations and predict on a regular grid over Iberia. (We learn the observation noise: with it fixed too small the GP is forced to interpolate every station and the lengthscale collapses toward zero — a spiky, overfit surface. Learning it recovers an honest regional lengthscale.)

<Figure size 1300x500 with 4 Axes>

The GP gives a smooth interpolated surface and a calibrated uncertainty that grows away from stations — all from just two inputs, (lon, lat). But a station “knows” more than where it sits. The rest of the notebook hands the GP physical covariates and lets it decide which ones matter.

Beyond lon/lat: physical spatial features

Longitude and latitude are only proxies for what actually shapes a station’s summer extremes. Three physical covariates carry real signal:

  • elevation — temperature falls with height (the lapse rate, ≈ 6.5 °C/km);

  • distance to the coast — the sea moderates extremes, so inland stations run hotter and more variable;

  • terrain slope — local relief, a proxy for sheltered valleys vs. exposed ground.

These are not in the CDS archive (which stores only lon/lat), so we derive them once from public geodata — a DEM (OpenTopoData) for elevation and slope, the Natural Earth coastline for distance — and cache a small table. The notebook only reads that cache (scripts/build_features.py builds it), so rendering never touches the network.

feature table: (107, 5)
       elevation  dist_coast_km  slope_deg
count      107.0          107.0      107.0
mean       366.2          106.8        2.0
std        377.5          113.2        2.8
min          0.0            0.0        0.0
25%         26.5            3.3        0.4
50%        242.0           60.7        1.1
75%        648.5          183.5        2.6
max       1758.0          348.1       20.7
<Figure size 1500x420 with 6 Axes>

A quick look before modelling — the Pearson correlation of each feature with the per-station mean annual maximum. Some of these will surprise us, which is exactly why we let the GP weigh the features rather than guessing.

corr(feature, mean annual max):
  longitude (°E)           r = -0.04
  latitude (°N)            r = -0.43
  elevation (m)            r = +0.03
  distance to coast (km)   r = +0.24
  terrain slope (°)        r = -0.25

The correlations hold a surprise: latitude carries the strongest signal (the north–south gradient), while raw elevation barely correlates with the mean annual maximum. That is confounding, not a non-effect — the lowest-elevation stations are a mix of cool, sea-moderated coastal sites and the hottest inland valleys, so elevation’s influence is masked marginally even though the highest mountains are plainly the coolest (the 1758 m station tops out near 29 °C). A multi-feature model is exactly what untangles this.

ARD: one lengthscale per feature

pyrox’s Matérn is isotropic — a single lengthscale shared by every input. Automatic Relevance Determination (ARD) gives each input its own lengthscale: a short lengthscale means the function changes quickly along that feature (it matters), a long one means the GP barely uses it. We implement ARD by scaling each standardised feature by a learnable per-dimension lengthscale and feeding the result to the isotropic kernel — so the fitted scales themselves are the relevance read-out. As above, we learn the noise: without it the GP overfits the noisiest feature (slope) with a vanishing lengthscale and mis-reports its relevance.

fitted ARD lengthscales (short = relevant):
  longitude (°E)           ℓ =  0.78   relevance 1/ℓ = 1.27
  latitude (°N)            ℓ =  0.34   relevance 1/ℓ = 2.93
  elevation (m)            ℓ =  1.21   relevance 1/ℓ = 0.83
  distance to coast (km)   ℓ =  1.15   relevance 1/ℓ = 0.87
  terrain slope (°)        ℓ =  3.02   relevance 1/ℓ = 0.33
<Figure size 650x340 with 1 Axes>

Does it predict better?

Relevance is suggestive; the honest test is out-of-sample accuracy. We compare leave-one-out (LOO) RMSE of the plain (lon, lat) GP against the feature-rich ARD GP, using the closed-form GP-LOO identity (no refitting):   μ^−i=yi−[K−1y]i/[K−1]ii\;\hat\mu_{-i} = y_i - [K^{-1}y]_i / [K^{-1}]_{ii}.

LOO RMSE — lon/lat GP      : 2.56 °C
LOO RMSE — ARD feature GP  : 2.70 °C
=> features change LOO error by -6%

A fuller metric: the Cholesky transform

ARD scales each feature independently — a diagonal input transform, axis aligned. The tinygp library offers a more general option, transforms.Cholesky: a full lower-triangular linear map LL applied to the inputs, so the kernel measures a Mahalanobis distance ∥L(x−x′)∥\lVert L(x-x')\rVert. Off-diagonal entries let the GP rotate and mix features (e.g. a “low and coastal” direction) rather than only rescale axes. ARD is the special case where LL is diagonal.

pyrox has no transform API, but the idea is one line — feed the isotropic Matérn the transformed inputs XL⊤X L^{\top} with a learned lower-triangular LL. It has D(D+1)/2D(D{+}1)/2 parameters instead of ARD’s DD; the question is whether that extra freedom helps or overfits on ~100 stations.

leave-one-out RMSE, simplest to richest:
  lon/lat GP         : 2.56 °C   (3 params)
  ARD diagonal metric: 2.70 °C   (7 params)
  Cholesky full metric: 2.74 °C  (17 params)
<Figure size 480x400 with 2 Axes>

Takeaway

Two (lon, lat) coordinates already interpolate the mean-annual-max field well, and — the honest result — richer inputs do not beat them here. Leave-one-out RMSE rises as we add flexibility:

modelinputsparamsLOO RMSE
(lon, lat) GP232.56 °C
ARD (diagonal metric)572.70 °C
Cholesky (full metric)5172.74 °C

With a dense network every held-out station has near neighbours, so coordinates already carry the smooth field; elevation and coastline are largely redundant with location for interpolation, and the Cholesky transform’s extra feature-mixing parameters only overfit ~100 stations. More capacity, no better generalisation — the bias–variance trade-off in one table.

What the features still buy is diagnosis and reach, not a lower interpolation error:

  • ARD as a relevance read-out. The fitted lengthscales rank latitude first (the north–south gradient), longitude / distance-to-coast / elevation in the middle, and terrain slope last — the GP rightly distrusts a noisy, local feature once the observation noise is learned. (Fixed-noise fits invert this, overfitting slope with a vanishing lengthscale.)

  • Extrapolation and covariates. Where stations are sparse a (lon, lat) GP reverts to the prior mean, while elevation and coast distance still inform the field — which is why the spatial-GEV capstones can take them as covariates on μ(s)\mu(s) rather than leaning on coordinates alone.

Next: instead of interpolating a precomputed summary, we put a GP inside the GEV model so the location parameter μ(s)\mu(s) is a latent spatial field learned jointly with the tail — and these same covariates can drive it.