liveBook · Manning

Gaussian process

As explained in Machine Learning Algorithms in Depth

A Gaussian process is a collection of random variables such that every finite subset has a jointly Gaussian distribution, defining a probability distribution over functions.

A Gaussian process (GP) is a probability distribution over functions. For any finite choice of inputs x₁,…,xₙ, the function values (f(x₁),…,f(xₙ)) have a joint Gaussian distribution. A mean function μ(x) specifies their expected values; a positive-definite kernel κ(x,x′) specifies their covariance. Observed input–target pairs update this prior over functions to a posterior used for regression predictions. section 6.5 section 6.7

For training inputs X and test inputs X*, form K = κ(X,X), K* = κ(X,X*), and K** = κ(X*,X*). Under the noiseless-observation assumption, the joint Gaussian distribution of training and test outputs can be conditioned on observed targets y. Its posterior mean is μ(X*) + K*ᵀK⁻¹(y − μ(X)); its posterior covariance is K** − K*ᵀK⁻¹K*. The mean supplies predictions, while the covariance describes uncertainty across the chosen test points. These expressions use Gaussian conditioning rather than fitting one fixed function. section 6.5 section 6.6

A from-scratch regression implementation follows the covariance calculation:

  • Choose a mean function and kernel. One implementation uses a zero mean and a radial basis function kernel, exp(−‖x−z‖²/(2L²)), with length scale L. section 6.5
  • Evaluate the kernel on training–training, training–test, and test–test input pairs to construct K, K*, and K**. section 6.5
  • Condition the joint Gaussian on the observed targets to compute the posterior mean and covariance at test inputs. section 6.5

Continuous-value prediction

Predicting atmospheric CO₂ levels from measurements illustrates the regression task; the worked implementation assumes a sinusoidal model and uses a radial basis function kernel. Samples from the prior and posterior make the effect of conditioning on observations visible. section 6.0 section 6.5

A GP can also model an unknown performance function in Bayesian optimization. As evaluations accumulate, its posterior informs which continuous hyperparameters to try next: expected improvement or a GP upper confidence bound balances promising results against uncertainty. Applications include searches over support vector machine and random forest classifier settings. section 7.4.1

Listing 6.4 Gaussian process regression
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist

np.random.seed(42)

class GPreg:

 def __init__(self, X_train, y_train, X_test):        

     self.L = 1.0
     self.keps = 1e-8

     self.muFn = self.mean_func(X_test)
     self.Kfn = self.kernel_func(X_test, X_test) + 1e-15*np.eye(
      np.size(X_test))

     self.X_train = X_train
     self.y_train = y_train
     self.X_test = X_test

 def mean_func(self, x):
     muFn = np.zeros(len(x)).reshape(-1,1)
     return muFn

 def kernel_func(self, x, z):                
     sq_dist = cdist(x/self.L, z/self.L, 'euclidean')**2
     Kfn = 1.0 * np.exp(-sq_dist/2)
     return Kfn

 def compute_posterior(self):
     K = self.kernel_func(self.X_train, self.X_train)
     Ks = self.kernel_func(self.X_train, self.X_test) 
     Kss = self.kernel_func(self.X_test, self.X_test) + self
      .keps*np.eye(np.size(self.X_test))  
     Ki = np.linalg.inv(K) #1

     postMu = self.mean_func(self.X_test) + np.dot(np.transpose(Ks), 
      np.dot(Ki, (self.y_train - self.mean_func(self.X_train))))
     postCov = Kss - np.dot(np.transpose(Ks), np.dot(Ki, Ks))

     self.muFn = postMu
     self.Kfn = postCov            

     return None    

 def generate_plots(self, X, num_samples=3):
     plt.figure()
     for i in range(num_samples):
         fs = self.gauss_sample(1)
         plt.plot(X, fs, '-k')
         #plt.plot(self.X_train, self.y_train, 'xk')

     mu = self.muFn.ravel()
     S2 = np.diag(self.Kfn)
     plt.fill(np.concatenate([X, X[::-1]]), np.concatenate([mu – 
      2*np.sqrt(S2), (mu + 2*np.sqrt(S2))[::-1]]), alpha=0.2, fc='b')
     plt.show()    

 def gauss_sample(self, n):      #2
     A = np.linalg.cholesky(self.Kfn)
     Z = np.random.normal(loc=0, scale=1, size=(len(self.muFn),n))
     S = np.dot(A,Z) + self.muFn       #3
     return S    

def main():

    # generate noise-less training data
    X_train = np.array([-4, -3, -2, -1, 1])
    X_train = X_train.reshape(-1,1)
    y_train = np.sin(X_train)

    # generate  test data
    X_test = np.linspace(-5, 5, 50)
    X_test = X_test.reshape(-1,1)

    gp = GPreg(X_train, y_train, X_test)
    gp.generate_plots(X_test,3)   #4
    gp.compute_posterior()
    gp.generate_plots(X_test,3)   #5


if __name__ == "__main__":    
    main()

Inspect the regression implementation’s mean and kernel functions alongside its posterior computation. section 6.5

Figure 6.8 Gaussian process regression: Samples from the prior (left) and posterior (right)
figure

Compare sampled functions before and after observations update the prior. section 6.5

How Machine Learning Algorithms in Depth covers it

How deep it goes
Derives noiseless regression predictions by Gaussian conditioning and implements a radial basis function example from scratch.
Examples
Uses CO₂ prediction, prior-versus-posterior samples, and hyperparameter searches for support vector machines and random forests.
What it assumes
Assumes familiarity with multivariate Gaussians, matrix operations, and regression while defining the GP prior and its covariance construction.
What you can do after
Build it from scratch to compute regression posterior predictions, then evaluate/understand its role in Bayesian optimization.
How it connects
Links Gaussian conditioning, positive-definite kernels, Bayesian regression, and Bayesian optimization.

Also explained in

Compare how 3 books explain Gaussian process →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Machine Learning Algorithms in Depth. The section links point to the parts of the book it draws on.