This is a homework assignment. I need a hint in the right direction and a couple explanations as things are not very clear to me. What is the predictive distribution? How do I draw from it? The notation is quite confusing for me as I'm missing the big picture right now.
Task: Generate new data from $f(x)=sin(2\pi x)$ where $x\in[0,1]$ and add Gaussian noise with a standard deviation of $\beta^{-1/2}=0.3$ to the data points generated. Explore data sets of various size. Consider a model of consisting of 1 constant function $\phi_0$ and 9 Gaussian radial basis functions with identical width $s$ and means $\mu_j$ equally distributed between $0$ and $1$. Explore different widths of for the basis functions. Plot an analog of Bishop page 157 figure 1 by computing the predictive distribution given the following information:
Consider a target variable $t$ given by a deterministic function
$$y(\mathbf{x},\mathbf{w})=\mathbf{w}^T\phi(\mathbf{x})$$
depending on input $\mathbf{x}$ and parameters $\mathbf{w}$ with additive gaussian noise so that $t=y(\mathbf{x}, \mathbf{w}) + \epsilon$, where $\epsilon$ is a zero mean Gaussian random variable with precision parameter $\beta$.
This can also be written as
$$p(t|\mathbf{x},\mathbf{w}, \beta)=\mathcal{N}(t|y(\mathbf{x},\mathbf{w}),\beta^{-1}).$$
Choosing a Gaussian prior
$$p(\mathbf{w}|\alpha)=\mathcal{N}(\mathbf{w}|\mathbf{0},\alpha^{-1}\mathbf{I})$$
the predictive distribution is also Gaussian and given by
$$p(t|\mathbf{x},\mathbf{t},\mathbf{X},\alpha,\beta)=\mathcal{N}(t|\mathbf{m}_N^T\phi(\mathbf{x}),\sigma_N^2(\mathbf{x}))$$
with mean
$$\mathbf{m}_N=\beta\mathbf{S}_N\mathbf{\Phi}^T\mathbf{t}$$
and variance
$$\sigma_N^2(\mathbf{x})=\frac{1}{\beta}+\phi(\mathbf{x})^T\mathbf{S}_N\phi(\mathbf{x}),$$
where the Matrix $\mathbf{S}_N$ is defined as
$$\mathbf{S}_N^{-1}=\alpha\mathbf{I}+\beta\mathbf{\Phi}^T\mathbf{\Phi},$$
the vector of basis functions is given as
$$\phi(\mathbf{x}_n)=(\phi_0(\mathbf{x}_n),\phi_1(\mathbf{x}_n),\ldots,\phi_{M-1}(\mathbf{x}_n))^T,$$
the matrix of basis functions given by
$$\mathbf{\Phi}=\left( \begin{array}{rrrr} \phi_0(\mathbf{x}_1) & \phi_1(\mathbf{x}_1) & \cdots & \phi_{M-1}(\mathbf{x}_1) \\ \phi_0(\mathbf{x}_2) & \phi_1(\mathbf{x}_2) & \cdots & \phi_{M-1}(\mathbf{x}_2) \\ \vdots & \vdots & \ddots & \vdots \\ \phi_0(\mathbf{x}_N) & \phi_1(\mathbf{x}_N) & \cdots & \phi_{M-1}(\mathbf{x}_N) \\ \end{array}\right)$$
with the vectors of input training data $\mathbf{X}=\{\mathbf{x_1}, \mathbf{x_2},\ldots,\mathbf{x_N}\}$ and corresponding output training values $\mathbf{t}=\{t_1,\ldots,t_n\}$ and the value t to be predicted for a new input $\mathbf{x}$.
Code: This is what I've got so far. As asked, I'm drawing random samples from the sin function and adding noise. Also, I've already defined the radial function. What should I do next?
from math import sin, pi, exp, e
from random import random, gauss
import matplotlib.pyplot as plt
import numpy as np
from typing import List
AMOUNT_RBA = 10 # amount of radial basis functions
ALPHA = 1 # what is this?
BETA = 1 # what is this?
def gen_data_point() -> int:
rand = random()
noise = gauss(0, 0.3**2)
return rand, sin(2 * pi * rand) + noise
def radial_basis(j: int, x: int, amount=9) -> int:
s = 1 # parameter to play with
mu_j = (j-1)/(amount-1) # spreads the mean evenly over [0,1]
numerator = (x-mu_j)**2
denumerator = 2*(s**2)
phi = e**(-numerator/denumerator)
return phi
def radial_basis_null():
return 1 # constant factor
def vector_basis_funtions(x: int):
phi_0 = radial_basis_null()
phis = [radial_basis(i, x) for i in range(1, AMOUNT_RBA)]
basis_func_vector = np.matrix([phi_0] + phis)
return basis_func_vector.T
# print(np.concatenate((basis_func_vector, basis_func_vector)).T)
def matrix_basis_functions(xs: int):
# initalize matrix with the needed dimensions
n, m = len(xs), AMOUNT_RBA
Phi = np.zeros([n, m])
# add row to matrix for every x
for i, x in enumerate(xs):
Phi[i] = vector_basis_funtions(x).T
return Phi
def S_N(xs: List[int]):
identity_matrix = np.identity(AMOUNT_RBA)
Phi = matrix_basis_functions(xs)
S_N = ALPHA*identity_matrix + BETA*Phi.T*Phi
return np.linalg.inv(S_N)
def var_N(x: int, xs: List[int]):
precision = 1/BETA
var = vector_basis_funtions(x).T * S_N(xs) * vector_basis_funtions(x)
return precision + var
def mean_N():
pass
# print(S_N(list(range(10))))
xs = list(range(10))
print(var_N(xs[0],xs))