diff --git a/GPy/likelihoods/ep.py b/GPy/likelihoods/ep.py index 4fedd66b..cfa00500 100644 --- a/GPy/likelihoods/ep.py +++ b/GPy/likelihoods/ep.py @@ -19,7 +19,6 @@ class EP(likelihood): self.num_data, self.output_dim = self.data.shape self.is_heteroscedastic = True self.num_params = 0 - self._transf_data = self.noise_model._preprocess_values(data) #Initial values - Likelihood approximation parameters: #p(y|f) = t(f|tau_tilde,v_tilde) @@ -134,7 +133,7 @@ class EP(likelihood): self.tau_[i] = 1./Sigma[i,i] - self.eta*self.tau_tilde[i] self.v_[i] = mu[i]/Sigma[i,i] - self.eta*self.v_tilde[i] #Marginal moments - self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i]) + self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i]) #Site parameters update Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma[i,i]) Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma[i,i]) @@ -233,7 +232,7 @@ class EP(likelihood): self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i] self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i] #Marginal moments - self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i]) + self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i]) #Site parameters update Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i]) Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i]) @@ -336,7 +335,7 @@ class EP(likelihood): self.tau_[i] = 1./Sigma_diag[i] - self.eta*self.tau_tilde[i] self.v_[i] = mu[i]/Sigma_diag[i] - self.eta*self.v_tilde[i] #Marginal moments - self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self._transf_data[i],self.tau_[i],self.v_[i]) + self.Z_hat[i], mu_hat[i], sigma2_hat[i] = self.noise_model.moments_match(self.data[i],self.tau_[i],self.v_[i]) #Site parameters update Delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i]) Delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i]) diff --git a/GPy/likelihoods/noise_models/bernoulli_noise.py b/GPy/likelihoods/noise_models/bernoulli_noise.py index 1d27d48b..5a11ba37 100644 --- a/GPy/likelihoods/noise_models/bernoulli_noise.py +++ b/GPy/likelihoods/noise_models/bernoulli_noise.py @@ -45,18 +45,24 @@ class Bernoulli(NoiseDistribution): :param tau_i: precision of the cavity distribution (float) :param v_i: mean/variance of the cavity distribution (float) """ + if data_i == 1: + sign = 1. + elif data_i == 0: + sign = -1 + else: + raise ValueError("bad value for Bernouilli observation (0,1)") if isinstance(self.gp_link,gp_transformations.Probit): - z = data_i*v_i/np.sqrt(tau_i**2 + tau_i) + z = sign*v_i/np.sqrt(tau_i**2 + tau_i) Z_hat = std_norm_cdf(z) phi = std_norm_pdf(z) - mu_hat = v_i/tau_i + data_i*phi/(Z_hat*np.sqrt(tau_i**2 + tau_i)) + mu_hat = v_i/tau_i + sign*phi/(Z_hat*np.sqrt(tau_i**2 + tau_i)) sigma2_hat = 1./tau_i - (phi/((tau_i**2+tau_i)*Z_hat))*(z+phi/Z_hat) elif isinstance(self.gp_link,gp_transformations.Heaviside): - a = data_i*v_i/np.sqrt(tau_i) + a = sign*v_i/np.sqrt(tau_i) Z_hat = std_norm_cdf(a) N = std_norm_pdf(a) - mu_hat = v_i/tau_i + data_i*N/Z_hat/np.sqrt(tau_i) + mu_hat = v_i/tau_i + sign*N/Z_hat/np.sqrt(tau_i) sigma2_hat = (1. - a*N/Z_hat - np.square(N/Z_hat))/tau_i if np.any(np.isnan([Z_hat, mu_hat, sigma2_hat])): stop @@ -97,7 +103,7 @@ class Bernoulli(NoiseDistribution): .. Note: Each y_i must be in {0,1} """ - assert np.asarray(link_f).shape == np.asarray(y).shape + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape objective = (link_f**y) * ((1.-link_f)**(1.-y)) return np.exp(np.sum(np.log(objective))) @@ -116,7 +122,7 @@ class Bernoulli(NoiseDistribution): :returns: log likelihood evaluated at points link(f) :rtype: float """ - assert np.asarray(link_f).shape == np.asarray(y).shape + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape #objective = y*np.log(link_f) + (1.-y)*np.log(link_f) objective = np.where(y==1, np.log(link_f), np.log(1-link_f)) return np.sum(objective) @@ -136,7 +142,7 @@ class Bernoulli(NoiseDistribution): :returns: gradient of log likelihood evaluated at points link(f) :rtype: Nx1 array """ - assert np.asarray(link_f).shape == np.asarray(y).shape + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape grad = (y/link_f) - (1.-y)/(1-link_f) return grad @@ -161,7 +167,7 @@ class Bernoulli(NoiseDistribution): Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) """ - assert np.asarray(link_f).shape == np.asarray(y).shape + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape d2logpdf_dlink2 = -y/(link_f**2) - (1-y)/((1-link_f)**2) return d2logpdf_dlink2 @@ -180,7 +186,7 @@ class Bernoulli(NoiseDistribution): :returns: third derivative of log likelihood evaluated at points link(f) :rtype: Nx1 array """ - assert np.asarray(link_f).shape == np.asarray(y).shape + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape d3logpdf_dlink3 = 2*(y/(link_f**3) - (1-y)/((1-link_f)**3)) return d3logpdf_dlink3