From bd1e98f564abc31ff61fc94e591f50f8089be8ad Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 22 May 2013 16:06:35 +0100 Subject: [PATCH] Implemented plot_latents as an external function in util --- GPy/models/Bayesian_GPLVM.py | 15 ++---- GPy/models/GPLVM.py | 76 ++---------------------------- GPy/util/plot_latent.py | 91 ++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 84 deletions(-) create mode 100644 GPy/util/plot_latent.py diff --git a/GPy/models/Bayesian_GPLVM.py b/GPy/models/Bayesian_GPLVM.py index e1e99af9..1e045a5a 100644 --- a/GPy/models/Bayesian_GPLVM.py +++ b/GPy/models/Bayesian_GPLVM.py @@ -14,6 +14,7 @@ import itertools from matplotlib.colors import colorConverter from matplotlib.figure import SubplotParams from GPy.inference.optimization import SCG +from GPy.util import plot_latent class Bayesian_GPLVM(sparse_GP, GPLVM): """ @@ -178,18 +179,8 @@ class Bayesian_GPLVM(sparse_GP, GPLVM): self.dbound_dZtheta = sparse_GP._log_likelihood_gradients(self) return np.hstack((self.dbound_dmuS.flatten(), self.dbound_dZtheta)) - def plot_latent(self, which_indices=None, *args, **kwargs): - - if which_indices is None: - try: - input_1, input_2 = np.argsort(self.input_sensitivity())[:2] - except: - raise ValueError, "cannot Atomatically determine which dimensions to plot, please pass 'which_indices'" - else: - input_1, input_2 = which_indices - ax = GPLVM.plot_latent(self, which_indices=[input_1, input_2], *args, **kwargs) - ax.plot(self.Z[:, input_1], self.Z[:, input_2], '^w') - return ax + def plot_latent(self, *args, **kwargs): + util.plot_latent_indices(self, *args, **kwargs) def do_test_latents(self, Y): """ diff --git a/GPy/models/GPLVM.py b/GPy/models/GPLVM.py index 2525ddf9..7445d0ab 100644 --- a/GPy/models/GPLVM.py +++ b/GPy/models/GPLVM.py @@ -11,6 +11,8 @@ from ..util.linalg import pdinv, PCA from GP import GP from ..likelihoods import Gaussian from .. import util +from GPy.util import plot_latent + class GPLVM(GP): """ @@ -60,75 +62,5 @@ class GPLVM(GP): mu, var, upper, lower = self.predict(Xnew) pb.plot(mu[:,0], mu[:,1],'k',linewidth=1.5) - def plot_latent(self, labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40): - """ - :param labels: a np.array of size self.N containing labels for the points (can be number, strings, etc) - :param resolution: the resolution of the grid on which to evaluate the predictive variance - """ - if ax is None: - ax = pb.gca() - util.plot.Tango.reset() - - if labels is None: - labels = np.ones(self.N) - if which_indices is None: - if self.Q==1: - input_1 = 0 - input_2 = None - if self.Q==2: - input_1, input_2 = 0,1 - else: - try: - input_1, input_2 = np.argsort(self.input_sensitivity())[:2] - except: - raise ValueError, "cannot Atomatically determine which dimensions to plot, please pass 'which_indices'" - else: - input_1, input_2 = which_indices - - #first, plot the output variance as a function of the latent space - Xtest, xx,yy,xmin,xmax = util.plot.x_frame2D(self.X[:,[input_1, input_2]],resolution=resolution) - Xtest_full = np.zeros((Xtest.shape[0], self.X.shape[1])) - Xtest_full[:, :2] = Xtest - mu, var, low, up = self.predict(Xtest_full) - var = var[:, :1] - ax.imshow(var.reshape(resolution, resolution).T, - extent=[xmin[0], xmax[0], xmin[1], xmax[1]], cmap=pb.cm.binary,interpolation='bilinear',origin='lower') - - # make sure labels are in order of input: - ulabels = [] - for lab in labels: - if not lab in ulabels: - ulabels.append(lab) - - for i, ul in enumerate(ulabels): - if type(ul) is np.string_: - this_label = ul - elif type(ul) is np.int64: - this_label = 'class %i'%ul - else: - this_label = 'class %i'%i - if len(marker) == len(ulabels): - m = marker[i] - else: - m = marker - - index = np.nonzero(labels==ul)[0] - if self.Q==1: - x = self.X[index,input_1] - y = np.zeros(index.size) - else: - x = self.X[index,input_1] - y = self.X[index,input_2] - ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) - - ax.set_xlabel('latent dimension %i'%input_1) - ax.set_ylabel('latent dimension %i'%input_2) - - if not np.all(labels==1.): - ax.legend(loc=0,numpoints=1) - - ax.set_xlim(xmin[0],xmax[0]) - ax.set_ylim(xmin[1],xmax[1]) - ax.grid(b=False) # remove the grid if present, it doesn't look good - ax.set_aspect('auto') # set a nice aspect ratio - return ax + def plot_latent(self, *args, **kwargs): + util.plot_latent.plot_latent(self, *args, **kwargs) \ No newline at end of file diff --git a/GPy/util/plot_latent.py b/GPy/util/plot_latent.py new file mode 100644 index 00000000..47896e48 --- /dev/null +++ b/GPy/util/plot_latent.py @@ -0,0 +1,91 @@ +import pylab as pb +import numpy as np +from .. import util + +def plot_latent(model, labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40): + """ + :param labels: a np.array of size model.N containing labels for the points (can be number, strings, etc) + :param resolution: the resolution of the grid on which to evaluate the predictive variance + """ + if ax is None: + ax = pb.gca() + util.plot.Tango.reset() + + if labels is None: + labels = np.ones(model.N) + if which_indices is None: + if model.Q==1: + input_1 = 0 + input_2 = None + if model.Q==2: + input_1, input_2 = 0,1 + else: + try: + input_1, input_2 = np.argsort(model.input_sensitivity())[:2] + except: + raise ValueError, "cannot Atomatically determine which dimensions to plot, please pass 'which_indices'" + else: + input_1, input_2 = which_indices + + #first, plot the output variance as a function of the latent space + Xtest, xx,yy,xmin,xmax = util.plot.x_frame2D(model.X[:,[input_1, input_2]],resolution=resolution) + Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) + Xtest_full[:, :2] = Xtest + mu, var, low, up = model.predict(Xtest_full) + var = var[:, :1] + ax.imshow(var.reshape(resolution, resolution).T, + extent=[xmin[0], xmax[0], xmin[1], xmax[1]], cmap=pb.cm.binary,interpolation='bilinear',origin='lower') + + # make sure labels are in order of input: + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i'%ul + else: + this_label = 'class %i'%i + if len(marker) == len(ulabels): + m = marker[i] + else: + m = marker + + index = np.nonzero(labels==ul)[0] + if model.Q==1: + x = model.X[index,input_1] + y = np.zeros(index.size) + else: + x = model.X[index,input_1] + y = model.X[index,input_2] + ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i'%input_1) + ax.set_ylabel('latent dimension %i'%input_2) + + if not np.all(labels==1.): + ax.legend(loc=0,numpoints=1) + + ax.set_xlim(xmin[0],xmax[0]) + ax.set_ylim(xmin[1],xmax[1]) + ax.grid(b=False) # remove the grid if present, it doesn't look good + ax.set_aspect('auto') # set a nice aspect ratio + return ax + + +def plot_latent_indices(model, which_indices=None, *args, **kwargs): + + if which_indices is None: + try: + input_1, input_2 = np.argsort(model.input_sensitivity())[:2] + except: + raise ValueError, "cannot Automatically determine which dimensions to plot, please pass 'which_indices'" + else: + input_1, input_2 = which_indices + ax = plot_latent(model, which_indices=[input_1, input_2], *args, **kwargs) + # TODO: Here test if there are inducing points... + ax.plot(model.Z[:, input_1], model.Z[:, input_2], '^w') + return ax \ No newline at end of file