Type at least 2 letters. Enter opens the first result, Esc closes.

    learn.mohebi.ai

    Gaussian process regression

    Put data points on a plane and watch a Gaussian process fit them. See its uncertainty grow far from the data, change its beliefs by changing the kernel, and tune the kernel by maximizing the evidence.

    A Gaussian process (GP) is a probability distribution over functions. Before we see data, it describes which functions we find plausible: smooth or rough, repeating or not, flat or with a trend. This belief is set by one function, the kernel k(x,x′)k(x, x'). After we see data, Bayes' rule gives the posterior: the functions that agree with both the belief and the data. A GP gives more than one curve. It gives a mean prediction and an honest error bar at every xx.

    In the playground you add data points with a tap and see four things live:

    1. The playground #

    Interactive figure: loading…

    Tap empty space to add a point, tap a point to remove it, drag a point to move it. Blue: the posterior mean and the 95% band. Aqua, violet and magenta: three posterior samples. Orange, dashed: the true function of the example data. Press Clear to see the prior: what the GP believes before any data. Under the figure, the evidence log⁡p(y∣X,θ)\log p(\mathbf y \mid X, \theta) and its three terms. The map shows the evidence over two hyperparameters (the orange dot is the current point, × is the best point of the map); click it to move there. Gradient ascent climbs the evidence step by step (its path is drawn on the map); Grid search jumps to the best point of the map.

    2. Try this #

    1. From prior to posterior. Press Clear. The band is the same everywhere: ±1.96 σf\pm 1.96\,\sigma_f. Now add one point near (0,1)(0, 1). Question: how wide is the band at x=0x = 0, at x=1x = 1 and at x=2x = 2? What to see: at the point the band shrinks to about ±0.2\pm 0.2 (the noise σn=0.1\sigma_n = 0.1 is all that is left). At x=1x = 1 the standard deviation is still 0.80.8. At x=2x = 2 it is 0.990.99, so the band is almost the prior band again. One point teaches the GP only about its neighbourhood, and the size of the neighbourhood is the length scale ℓ=1\ell = 1.
    2. The length scale. Pick 5 points and move ℓ\ell from 0.30.3 to 33. Question: what happens between the points, for example at x=2x = 2? Which value does the evidence prefer? What to see: with ℓ=0.3\ell = 0.3 the mean returns to 00 between the points and the band is as wide as the prior: the points are too far apart to say anything about each other. With ℓ=3\ell = 3 the curve is stiff and the band is thin everywhere, but the evidence drops from about −5.9-5.9 to about −20-20: such a confident, smooth curve explains these points badly. Now press Gradient ascent. It ends near ℓ=0.35\ell = 0.35 with log⁡p≈−5.4\log p \approx -5.4 (mostly by making σf\sigma_f smaller), and it may say that the evidence is almost flat there. It is: every ℓ\ell below about 0.40.4 gives almost the same evidence. Five points far apart cannot tell these length scales apart. Here the evidence rules out long length scales, but not short ones.
    3. Two explanations of noisy data. Pick noisy (30 points, true noise 0.250.25) and press Gradient ascent. Set Band for to f(x)f(x) and then to yy. Then move the σn\sigma_n slider all the way to the left (σn=0.01\sigma_n = 0.01) and the ℓ\ell slider to about 0.150.15, and press Gradient ascent again. Question: do both runs end at the same place? What to see: the first run climbs from log⁡p≈−20.4\log p \approx -20.4 to −10.2-10.2 in about 35 steps and ends near ℓ=1.0\ell = 1.0, σn=0.19\sigma_n = 0.19: a smooth function plus noise (the true noise is 0.250.25; 30 points give only a rough estimate). There, the band for ff misses 7 of the 30 points, and the band for y=f(x)+εy = f(x) + \varepsilon contains all of them. The second run ends at ℓ≈0.36\ell \approx 0.36, σn=0.01\sigma_n = 0.01 (the lower limit), log⁡p≈−14.6\log p \approx -14.6: a wiggly function that passes through every point. Both are local maxima of the evidence. The data prefer the first by about 4.4 nats, a likelihood ratio of about e4.4≈80e^{4.4} \approx 80.
    4. Kernels are beliefs: extrapolation. Pick periodic. The data stop near x=0.4x = 0.4. Choose the RBF kernel and press Gradient ascent. Then pick periodic under Try again (this resets the hyperparameters and selects the periodic kernel) and press Gradient ascent. Question: what does each model predict for xx between 22 and 55? What to see: the RBF model ends near ℓ=0.18\ell = 0.18 with log⁡p≈−18.2\log p \approx -18.2. To the right of the data its mean falls back to 00 and its band becomes the prior band: it knows nothing there. The periodic model finds the period p≈1.60p \approx 1.60 (the true one) with log⁡p≈0.35\log p \approx 0.35, and it continues the pattern to x=5x = 5 with a thin band. The evidence prefers it by about 18 nats. Both runs say "not fully converged". More presses raise log⁡p\log p only a little: plain gradient ascent is slow on the flat ridge that is left.
    5. A local maximum and grid search. Pick trend + season: a straight trend plus a pattern with period 1.51.5, with the Sum kernel and a wrong start p=2p = 2. Press Gradient ascent, then Grid search, then Gradient ascent again. Question: where does each step end? What to see: the first run ends at p≈3.0p \approx 3.0 with log⁡p≈0.2\log p \approx 0.2 (press again if it says "not fully converged"; then it stops at a local maximum). This is a real local maximum: a pattern that repeats every 1.51.5 also repeats every 33. Grid search tries all 36×2836 \times 28 values of (p,σn)(p, \sigma_n) on the map and jumps to p≈1.45p \approx 1.45; the second gradient ascent climbs to p≈1.48p \approx 1.48 with log⁡p≈6.8\log p \approx 6.8. Now switch to Linear and to RBF. The linear model continues the trend but not the season; the RBF model continues neither.
    6. A jump breaks the belief. Pick step: a function that jumps at x=0.5x = 0.5, with noise 0.060.06. Press Gradient ascent with RBF and then with Matérn 3/2. Question: what noise level do the models choose? What to see: RBF ends at σn≈0.43\sigma_n \approx 0.43 and Matérn 3/2 at σn≈0.37\sigma_n \approx 0.37, six to seven times the true noise. Both kernels believe that the function is equally smooth everywhere (they are stationary), so the best they can do is a long length scale plus a lot of "noise" that absorbs the jump. The rougher Matérn kernel explains the data a little better (log⁡p≈−17.6\log p \approx -17.6 against −18.1-18.1).

    3. Kernels are prior beliefs #

    A GP with mean 00 and kernel kk is written f∼GP(0,k)f \sim \mathcal{GP}(0, k). It means: for any finite set of inputs x1,…,xnx_1, \dots, x_n, the vector of function values is Gaussian,

    (f(x1),…,f(xn))∼N(0,K),Kij=k(xi,xj).\big(f(x_1), \dots, f(x_n)\big) \sim \mathcal N(0, K), \qquad K_{ij} = k(x_i, x_j).

    So the kernel is a covariance function: k(x,x′)k(x, x') is the covariance of f(x)f(x) and f(x′)f(x'). If k(x,x′)k(x, x') is large, the values at xx and x′x' move together; if it is near 00, they are independent. Every choice of kernel is a belief about the function. The matrix KK must be positive semi-definite for every set of inputs, so not every function of two variables is a kernel.

    Interactive figure: loading…

    Switch kernels, move the sliders and drag the marker x0x_0. Left: five random functions from the prior (colours) and the 95% band (grey). Below: the kernel k(x0,x)k(x_0, x), the covariance between the value at the marker and the value at xx. Right: the covariance matrix of the function values on a grid of 64 points. Notice how ℓ\ell sets the width of the bump in k(x0,x)k(x_0, x) and the speed of the wiggles; how the periodic kernel has bumps again at x0±px_0 \pm p; and how the matrix of the linear kernel is not constant along its diagonals.

    The kernels of the playground (r=∣x−x′∣r = |x - x'|):

    Kernel k(x,x′)k(x, x') Belief about ff
    RBF (squared exponential) σf2exp⁡ ⁣(−r2/2ℓ2)\sigma_f^2 \exp\!\big(-r^2 / 2\ell^2\big) very smooth: all derivatives exist; changes on a scale ℓ\ell
    Matérn 3/2 σf2(1+3 r/ℓ)exp⁡ ⁣(−3 r/ℓ)\sigma_f^2 \big(1 + \sqrt3\,r/\ell\big) \exp\!\big(-\sqrt3\,r/\ell\big) rougher: one derivative, not two
    Periodic σf2exp⁡ ⁣(−2sin⁡2(πr/p)/ℓ2)\sigma_f^2 \exp\!\big(-2\sin^2(\pi r / p) / \ell^2\big) repeats exactly with period pp
    Linear σf2(1+xx′)\sigma_f^2 (1 + x x') straight lines a+bxa + bx with a,b∼N(0,σf2)a, b \sim \mathcal N(0, \sigma_f^2)
    Sum kper+σlin2(1+xx′)k_{\text{per}} + \sigma_{\text{lin}}^2 (1 + x x') a periodic pattern plus an independent trend
    Quick check

    The prior uses the RBF kernel with ℓ=1\ell = 1 and σf=1.5\sigma_f = 1.5. You observe 10 points, all in [−1,1][-1, 1]. What does the posterior say at x=50x = 50?

    4. The math in short #

    The posterior #

    We observe yi=f(xi)+εiy_i = f(x_i) + \varepsilon_i with independent noise εi∼N(0,σn2)\varepsilon_i \sim \mathcal N(0, \sigma_n^2). Write K=k(X,X)K = k(X, X) for the n×nn \times n matrix of the data inputs, Ky=K+σn2IK_y = K + \sigma_n^2 I, and k∗=k(X,x∗)k_* = k(X, x_*) for the vector of covariances between the data and a new input x∗x_*. Under the prior, y\mathbf y and f(x∗)f(x_*) are jointly Gaussian:

    (yf(x∗))∼N ⁣(0,  (Kyk∗k∗⊤k(x∗,x∗))).\begin{pmatrix} \mathbf y \\ f(x_*) \end{pmatrix} \sim \mathcal N\!\left(0,\; \begin{pmatrix} K_y & k_* \\ k_*^\top & k(x_*, x_*) \end{pmatrix}\right).

    Conditioning a Gaussian on part of its vector (a Schur complement) gives the posterior, again Gaussian:

    μ(x∗)=k∗⊤Ky−1y,σ2(x∗)=k(x∗,x∗)−k∗⊤Ky−1k∗.\mu(x_*) = k_*^\top K_y^{-1} \mathbf y, \qquad \sigma^2(x_*) = k(x_*, x_*) - k_*^\top K_y^{-1} k_* .

    Computing it. Never form Ky−1K_y^{-1}. Factor once with the Cholesky decomposition Ky=LL⊤K_y = LL^\top, then use triangular solves:

    α=L−⊤(L−1y),v=L−1k∗,μ(x∗)=k∗⊤α,σ2(x∗)=k(x∗,x∗)−v⊤v.\alpha = L^{-\top}\big(L^{-1}\mathbf y\big), \qquad v = L^{-1} k_*, \qquad \mu(x_*) = k_*^\top \alpha, \qquad \sigma^2(x_*) = k(x_*, x_*) - v^\top v .

    The evidence and how to tune the kernel #

    The hyperparameters θ=(ℓ,σf,σn,… )\theta = (\ell, \sigma_f, \sigma_n, \dots) are chosen by maximizing the log marginal likelihood: the log probability of the observed y\mathbf y when ff is integrated out. Since y∼N(0,Ky)\mathbf y \sim \mathcal N(0, K_y),

    log⁡p(y∣X,θ)=−12 y⊤Ky−1y⏟data fit  −  12log⁡det⁡Ky⏟complexity penalty  −  n2log⁡2π⏟constant,log⁡det⁡Ky=2∑ilog⁡Lii.\log p(\mathbf y \mid X, \theta) = \underbrace{-\tfrac12\, \mathbf y^\top K_y^{-1} \mathbf y}_{\text{data fit}} \;\underbrace{-\;\tfrac12 \log\det K_y}_{\text{complexity penalty}} \;\underbrace{-\;\tfrac n2 \log 2\pi}_{\text{constant}}, \qquad \log\det K_y = 2\sum_i \log L_{ii} .

    The two terms pull in opposite directions. A very short length scale lets ff pass through every point, so the data-fit term is good. But then KyK_y is close to (σf2+σn2)I(\sigma_f^2 + \sigma_n^2) I: the model spreads its probability over a huge set of wiggly functions, log⁡det⁡Ky\log\det K_y is large, and the penalty is large. A very long length scale is the opposite. The evidence picks the simplest model that explains the data: an automatic form of Occam's razor. This is why the evidence in experiment 2 rejects ℓ=3\ell = 3, and why it can have several local maxima (experiment 3).

    The gradient has a closed form. With α=Ky−1y\alpha = K_y^{-1}\mathbf y and using dlog⁡det⁡K=tr⁡(K−1dK)d\log\det K = \operatorname{tr}(K^{-1} dK):

    ∂∂θjlog⁡p(y∣X,θ)=12tr⁡ ⁣((αα⊤−Ky−1)∂Ky∂θj).\frac{\partial}{\partial \theta_j} \log p(\mathbf y \mid X, \theta) = \tfrac12 \operatorname{tr}\!\Big( \big(\alpha\alpha^\top - K_y^{-1}\big) \frac{\partial K_y}{\partial \theta_j} \Big).

    The playground optimizes u=log⁡θu = \log\theta (so every hyperparameter stays positive and all of them move on the same scale) with plain gradient ascent and a simple line search: u←u+η ∇ulog⁡pu \leftarrow u + \eta\, \nabla_u \log p. A step is kept only if the evidence increases; otherwise η\eta is made smaller and the step is tried again. After a good step η\eta grows by a factor 1.51.5, and no log value moves more than 0.250.25 in one step. Each hyperparameter stays inside its slider range. The run stops when the evidence rises by less than 10−410^{-4} in 50 steps; a test with the second derivatives (the Hessian) then says whether this is a maximum or an almost flat ridge. Plain gradient ascent is slow when the evidence is much more curved in one direction than in another. For the periodic kernel, the evidence is very sharp in pp and flat in ℓ\ell, so it can need several presses. Gradient ascent finds only a local maximum near the start. Grid search evaluates the evidence at all 36×2836 \times 28 points of the map (log-spaced values of two hyperparameters, the others fixed) and takes the best one: slow, but it cannot be trapped. Libraries such as scikit-learn and GPyTorch use L-BFGS or Adam with several random restarts.

    Quick check

    Gradient ascent from a very short length scale ends at a curve that passes through every noisy point, with σn\sigma_n at its lower limit. Which term of the evidence makes this solution worse than a smooth curve with σn≈0.2\sigma_n \approx 0.2?

    5. The cost: O(n3)O(n^3) #

    The Cholesky factorization of the n×nn \times n matrix KyK_y needs about n3/3n^3/3 floating-point operations, and the matrix needs n2n^2 numbers of memory. After that, the mean at a new point costs O(n)O(n) and the variance O(n2)O(n^2). Every new value of the hyperparameters needs a new factorization, so each step of gradient ascent costs O(n3)O(n^3), and a grid search costs (number of grid points) × O(n3)\times\, O(n^3).

    Interactive figure: loading…

    Press Measure on this device. It times the Cholesky factorization on your own computer or phone for growing nn. Blue: the measured times. Dashed: a line of slope 3 through the largest measurement. On log–log axes, time ∝n3\propto n^3 is a straight line of slope 3. The table extrapolates: what takes a fraction of a second for n=1000n = 1000 takes years for n=106n = 10^6, and the matrix alone needs 8 TB.

    This is why exact GPs are used for up to about 10410^4 points. For larger data sets there are approximations:

    Quick check

    An exact GP with n=5000n = 5000 points needs 2 seconds for one Cholesky factorization on your laptop. About how long does it need with n=10 000n = 10\,000, and how much memory does KyK_y need then (8 bytes per entry)?