Got most of laplace approximation working

This commit is contained in:
Alan Saul 2013-03-13 17:55:41 +00:00
parent ad2c266c65
commit 3f114aa020
9 changed files with 124 additions and 45 deletions

View file

@ -1,8 +1,14 @@
import nump as np
import numpy as np
import scipy as sp
import GPy
from GPy.util.linalg import jitchol
from functools import partial
from GPy.likelihoods.likelihood import likelihood
from GPy.util.linalg import pdinv,mdot
class Laplace(GPy.likelihoods.likelihood):
class Laplace(likelihood):
"""Laplace approximation to a posterior"""
def __init__(self,data,likelihood_function):
@ -23,8 +29,6 @@ class Laplace(GPy.likelihoods.likelihood):
:likelihood_function: @todo
"""
GPy.likelihoods.likelihood.__init__(self)
self.data = data
self.likelihood_function = likelihood_function
@ -38,7 +42,7 @@ class Laplace(GPy.likelihoods.likelihood):
GPy expects a likelihood to be gaussian, so need to caluclate the points Y^{squiggle} and Z^{squiggle}
that makes the posterior match that found by a laplace approximation to a non-gaussian likelihood
"""
raise NotImplementedError
z_hat = N(f_hat|f_hat, hess_hat) / self.height_unnormalised
def fit_full(self, K):
"""
@ -46,9 +50,38 @@ class Laplace(GPy.likelihoods.likelihood):
For nomenclature see Rasmussen & Williams 2006
:K: Covariance matrix
"""
self.f = np.zeros(self.N)
f = np.zeros((self.N, 1))
print K.shape
print f.shape
print self.data.shape
(Ki, _, _, log_Kdet) = pdinv(K)
obj_constant = (0.5 * log_Kdet) - ((0.5 * self.N) * np.log(2*np.pi))
#Find \hat(f) using a newton raphson optimizer for example
#TODO: Add newton-raphson as subclass of optimizer class
#FIXME: Can we get rid of this horrible reshaping?
def obj(f):
f = f[:, None]
res = -1 * (self.likelihood_function.link_function(self.data, f) - 0.5 * mdot(f.T, (Ki, f)) + obj_constant)
return float(res)
def obj_grad(f):
f = f[:, None]
res = -1 * (self.likelihood_function.link_grad(self.data, f) - mdot(Ki, f))
return np.squeeze(res)
def obj_hess(f):
f = f[:, None]
res = -1 * (np.diag(self.likelihood_function.link_hess(self.data, f)) - Ki)
return np.squeeze(res)
self.f_hat = sp.optimize.fmin_ncg(obj, f, fprime=obj_grad, fhess=obj_hess)
#At this point get the hessian matrix
self.hess_hat = obj_hess(f_hat)
#Need to add the constant as we previously were trying to avoid computing it (seems like a small overhead though...)
self.height_unnormalised = obj(f_hat) #FIXME: Is it -1?
return _compute_GP_variables()