replace np.int by int

This commit is contained in:
Martin Bubel 2023-10-16 21:20:17 +02:00
parent a6d78d79aa
commit 65af6ee35e
15 changed files with 3889 additions and 2375 deletions

View file

@ -5,13 +5,16 @@ from .kern import Kern
import numpy as np
from ...core.parameterization import Param
from paramz.transformations import Logexp
from ...util.config import config # for assesing whether to use cython
from ...util.config import config # for assesing whether to use cython
try:
from . import coregionalize_cython
use_coregionalize_cython = config.getboolean('cython', 'working')
use_coregionalize_cython = config.getboolean("cython", "working")
except ImportError:
print('warning in coregionalize: failed to import cython module: falling back to numpy')
print(
"warning in coregionalize: failed to import cython module: falling back to numpy"
)
use_coregionalize_cython = False
@ -43,22 +46,34 @@ class Coregionalize(Kern):
.. note: see coregionalization examples in GPy.examples.regression for some usage.
"""
def __init__(self, input_dim, output_dim, rank=1, W=None, kappa=None, active_dims=None, name='coregion'):
def __init__(
self,
input_dim,
output_dim,
rank=1,
W=None,
kappa=None,
active_dims=None,
name="coregion",
):
super(Coregionalize, self).__init__(input_dim, active_dims, name=name)
self.output_dim = output_dim
self.rank = rank
if self.rank>output_dim:
print("Warning: Unusual choice of rank, it should normally be less than the output_dim.")
if self.rank > output_dim:
print(
"Warning: Unusual choice of rank, it should normally be less than the output_dim."
)
if W is None:
W = 0.5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank)
W = 0.5 * np.random.randn(self.output_dim, self.rank) / np.sqrt(self.rank)
else:
assert W.shape==(self.output_dim, self.rank)
self.W = Param('W', W)
assert W.shape == (self.output_dim, self.rank)
self.W = Param("W", W)
if kappa is None:
kappa = 0.5*np.ones(self.output_dim)
kappa = 0.5 * np.ones(self.output_dim)
else:
assert kappa.shape==(self.output_dim, )
self.kappa = Param('kappa', kappa, Logexp())
assert kappa.shape == (self.output_dim,)
self.kappa = Param("kappa", kappa, Logexp())
self.link_parameters(self.W, self.kappa)
def parameters_changed(self):
@ -70,63 +85,69 @@ class Coregionalize(Kern):
else:
return self._K_numpy(X, X2)
def _K_numpy(self, X, X2=None):
index = np.asarray(X, dtype=np.int)
index = np.asarray(X, dtype=int)
if X2 is None:
return self.B[index,index.T]
return self.B[index, index.T]
else:
index2 = np.asarray(X2, dtype=np.int)
return self.B[index,index2.T]
index2 = np.asarray(X2, dtype=int)
return self.B[index, index2.T]
def _K_cython(self, X, X2=None):
if X2 is None:
return coregionalize_cython.K_symmetric(self.B, np.asarray(X, dtype=np.int64)[:,0])
return coregionalize_cython.K_asymmetric(self.B, np.asarray(X, dtype=np.int64)[:,0], np.asarray(X2, dtype=np.int64)[:,0])
return coregionalize_cython.K_symmetric(
self.B, np.asarray(X, dtype=np.int64)[:, 0]
)
return coregionalize_cython.K_asymmetric(
self.B,
np.asarray(X, dtype=np.int64)[:, 0],
np.asarray(X2, dtype=np.int64)[:, 0],
)
def Kdiag(self, X):
return np.diag(self.B)[np.asarray(X, dtype=np.int).flatten()]
return np.diag(self.B)[np.asarray(X, dtype=int).flatten()]
def update_gradients_full(self, dL_dK, X, X2=None):
index = np.asarray(X, dtype=np.int)
index = np.asarray(X, dtype=int)
if X2 is None:
index2 = index
else:
index2 = np.asarray(X2, dtype=np.int)
index2 = np.asarray(X2, dtype=int)
#attempt to use cython for a nasty double indexing loop: fall back to numpy
# attempt to use cython for a nasty double indexing loop: fall back to numpy
if use_coregionalize_cython:
dL_dK_small = self._gradient_reduce_cython(dL_dK, index, index2)
else:
dL_dK_small = self._gradient_reduce_numpy(dL_dK, index, index2)
dkappa = np.diag(dL_dK_small).copy()
dL_dK_small += dL_dK_small.T
dW = (self.W[:, None, :]*dL_dK_small[:, :, None]).sum(0)
dW = (self.W[:, None, :] * dL_dK_small[:, :, None]).sum(0)
self.W.gradient = dW
self.kappa.gradient = dkappa
def _gradient_reduce_numpy(self, dL_dK, index, index2):
index, index2 = index[:,0], index2[:,0]
index, index2 = index[:, 0], index2[:, 0]
dL_dK_small = np.zeros_like(self.B)
for i in range(self.output_dim):
tmp1 = dL_dK[index==i]
tmp1 = dL_dK[index == i]
for j in range(self.output_dim):
dL_dK_small[j,i] = tmp1[:,index2==j].sum()
dL_dK_small[j, i] = tmp1[:, index2 == j].sum()
return dL_dK_small
def _gradient_reduce_cython(self, dL_dK, index, index2):
index, index2 = np.int64(index[:,0]), np.int64(index2[:,0])
return coregionalize_cython.gradient_reduce(self.B.shape[0], dL_dK, index, index2)
index, index2 = np.int64(index[:, 0]), np.int64(index2[:, 0])
return coregionalize_cython.gradient_reduce(
self.B.shape[0], dL_dK, index, index2
)
def update_gradients_diag(self, dL_dKdiag, X):
index = np.asarray(X, dtype=np.int).flatten()
dL_dKdiag_small = np.array([dL_dKdiag[index==i].sum() for i in range(self.output_dim)])
self.W.gradient = 2.*self.W*dL_dKdiag_small[:, None]
index = np.asarray(X, dtype=int).flatten()
dL_dKdiag_small = np.array(
[dL_dKdiag[index == i].sum() for i in range(self.output_dim)]
)
self.W.gradient = 2.0 * self.W * dL_dKdiag_small[:, None]
self.kappa.gradient = dL_dKdiag_small
def gradients_X(self, dL_dK, X, X2=None):
@ -154,8 +175,8 @@ class Coregionalize(Kern):
@staticmethod
def _build_from_input_dict(kernel_class, input_dict):
useGPU = input_dict.pop('useGPU', None)
useGPU = input_dict.pop("useGPU", None)
# W and kappa must be converted back to numpy arrays
input_dict['W'] = np.array(input_dict['W'])
input_dict['kappa'] = np.array(input_dict['kappa'])
input_dict["W"] = np.array(input_dict["W"])
input_dict["kappa"] = np.array(input_dict["kappa"])
return Coregionalize(**input_dict)

View file

@ -8,6 +8,7 @@ from ...core.parameterization import Param
from paramz.transformations import Logexp
from paramz.caching import Cache_this
class EQ_ODE1(Kern):
"""
Covariance function for first order differential equation driven by an exponentiated quadratic covariance.
@ -33,23 +34,36 @@ class EQ_ODE1(Kern):
.. Note: see first order differential equation examples in GPy.examples.regression for some usage.
"""
def __init__(self, input_dim=2, output_dim=1, rank=1, W = None, lengthscale=None, decay=None, active_dims=None, name='eq_ode1'):
def __init__(
self,
input_dim=2,
output_dim=1,
rank=1,
W=None,
lengthscale=None,
decay=None,
active_dims=None,
name="eq_ode1",
):
assert input_dim == 2, "only defined for 1 input dims"
super(EQ_ODE1, self).__init__(input_dim=input_dim, active_dims=active_dims, name=name)
super(EQ_ODE1, self).__init__(
input_dim=input_dim, active_dims=active_dims, name=name
)
self.rank = rank
self.output_dim = output_dim
if lengthscale is None:
lengthscale = .5 + np.random.rand(self.rank)
lengthscale = 0.5 + np.random.rand(self.rank)
else:
lengthscale = np.asarray(lengthscale)
assert lengthscale.size in [1, self.rank], "Bad number of lengthscales"
if lengthscale.size != self.rank:
lengthscale = np.ones(self.rank)*lengthscale
lengthscale = np.ones(self.rank) * lengthscale
if W is None:
W = .5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank)
W = 0.5 * np.random.randn(self.output_dim, self.rank) / np.sqrt(self.rank)
else:
assert W.shape == (self.output_dim, self.rank)
@ -59,168 +73,181 @@ class EQ_ODE1(Kern):
decay = np.asarray(decay)
assert decay.size in [1, self.output_dim], "Bad number of decay"
if decay.size != self.output_dim:
decay = np.ones(self.output_dim)*decay
decay = np.ones(self.output_dim) * decay
# if kappa is None:
# self.kappa = np.ones(self.output_dim)
# else:
# kappa = np.asarray(kappa)
# assert kappa.size in [1, self.output_dim], "Bad number of kappa"
# if decay.size != self.output_dim:
# decay = np.ones(self.output_dim)*kappa
# if kappa is None:
# self.kappa = np.ones(self.output_dim)
# else:
# kappa = np.asarray(kappa)
# assert kappa.size in [1, self.output_dim], "Bad number of kappa"
# if decay.size != self.output_dim:
# decay = np.ones(self.output_dim)*kappa
#self.kappa = Param('kappa', kappa, Logexp())
#self.delay = Param('delay', delay, Logexp())
#self.is_normalized = True
#self.is_stationary = False
#self.gaussian_initial = False
# self.kappa = Param('kappa', kappa, Logexp())
# self.delay = Param('delay', delay, Logexp())
# self.is_normalized = True
# self.is_stationary = False
# self.gaussian_initial = False
self.lengthscale = Param('lengthscale', lengthscale, Logexp())
self.decay = Param('decay', decay, Logexp())
self.W = Param('W', W)
self.lengthscale = Param("lengthscale", lengthscale, Logexp())
self.decay = Param("decay", decay, Logexp())
self.W = Param("W", W)
self.link_parameters(self.lengthscale, self.decay, self.W)
@Cache_this(limit=3)
def K(self, X, X2=None):
#This way is not working, indexes are lost after using k._slice_X
#index = np.asarray(X, dtype=np.int)
#index = index.reshape(index.size,)
if hasattr(X, 'values'):
# This way is not working, indexes are lost after using k._slice_X
# index = np.asarray(X, dtype=int)
# index = index.reshape(index.size,)
if hasattr(X, "values"):
X = X.values
index = np.int_(np.round(X[:, 1]))
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
X_flag = index[0] >= self.output_dim
if X2 is None:
if X_flag:
#Calculate covariance function for the latent functions
# Calculate covariance function for the latent functions
index -= self.output_dim
return self._Kuu(X, index)
else:
raise NotImplementedError
else:
#This way is not working, indexes are lost after using k._slice_X
#index2 = np.asarray(X2, dtype=np.int)
#index2 = index2.reshape(index2.size,)
if hasattr(X2, 'values'):
# This way is not working, indexes are lost after using k._slice_X
# index2 = np.asarray(X2, dtype=int)
# index2 = index2.reshape(index2.size,)
if hasattr(X2, "values"):
X2 = X2.values
index2 = np.int_(np.round(X2[:, 1]))
index2 = index2.reshape(index2.size,)
index2 = index2.reshape(
index2.size,
)
X2_flag = index2[0] >= self.output_dim
#Calculate cross-covariance function
# Calculate cross-covariance function
if not X_flag and X2_flag:
index2 -= self.output_dim
return self._Kfu(X, index, X2, index2) #Kfu
return self._Kfu(X, index, X2, index2) # Kfu
elif X_flag and not X2_flag:
index -= self.output_dim
return self._Kfu(X2, index2, X, index).T #Kuf
return self._Kfu(X2, index2, X, index).T # Kuf
elif X_flag and X2_flag:
index -= self.output_dim
index2 -= self.output_dim
return self._Kusu(X, index, X2, index2) #Ku_s u
return self._Kusu(X, index, X2, index2) # Ku_s u
else:
raise NotImplementedError #Kf_s f
raise NotImplementedError # Kf_s f
#Calculate the covariance function for diag(Kff(X,X))
# Calculate the covariance function for diag(Kff(X,X))
def Kdiag(self, X):
if hasattr(X, 'values'):
if hasattr(X, "values"):
index = np.int_(np.round(X[:, 1].values))
else:
index = np.int_(np.round(X[:, 1]))
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
X_flag = index[0] >= self.output_dim
if X_flag: #Kuudiag
return np.ones(X[:,0].shape)
else: #Kffdiag
if X_flag: # Kuudiag
return np.ones(X[:, 0].shape)
else: # Kffdiag
kdiag = self._Kdiag(X)
return np.sum(kdiag, axis=1)
def _Kdiag(self, X):
#This way is not working, indexes are lost after using k._slice_X
#index = np.asarray(X, dtype=np.int)
#index = index.reshape(index.size,)
if hasattr(X, 'values'):
# This way is not working, indexes are lost after using k._slice_X
# index = np.asarray(X, dtype=int)
# index = index.reshape(index.size,)
if hasattr(X, "values"):
X = X.values
index = np.int_(X[:, 1])
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
#terms that move along t
# terms that move along t
t = X[:, 0].reshape(X.shape[0], 1)
d = np.unique(index) #Output Indexes
d = np.unique(index) # Output Indexes
B = self.decay.values[d]
S = self.W.values[d, :]
#Index transformation
# Index transformation
indd = np.arange(self.output_dim)
indd[d] = np.arange(d.size)
index = indd[index]
B = B.reshape(B.size, 1)
#Terms that move along q
# Terms that move along q
lq = self.lengthscale.values.reshape(1, self.rank)
S2 = S*S
kdiag = np.empty((t.size, ))
S2 = S * S
kdiag = np.empty((t.size,))
#Dx1 terms
c0 = (S2/B)*((.5*np.sqrt(np.pi))*lq)
# Dx1 terms
c0 = (S2 / B) * ((0.5 * np.sqrt(np.pi)) * lq)
#DxQ terms
nu = lq*(B*.5)
nu2 = nu*nu
#Nx1 terms
gamt = -2.*B
gamt = gamt[index]*t
# DxQ terms
nu = lq * (B * 0.5)
nu2 = nu * nu
# Nx1 terms
gamt = -2.0 * B
gamt = gamt[index] * t
#NxQ terms
t_lq = t/lq
# NxQ terms
t_lq = t / lq
# Upsilon Calculations
# Using wofz
#erfnu = erf(nu)
# erfnu = erf(nu)
upm = np.exp(nu2[index, :] + lnDifErf( nu[index, :] ,t_lq+nu[index,:] ))
upm[t[:, 0] == 0, :] = 0.
upm = np.exp(nu2[index, :] + lnDifErf(nu[index, :], t_lq + nu[index, :]))
upm[t[:, 0] == 0, :] = 0.0
upv = np.exp(
nu2[index, :] + gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :])
)
upv[t[:, 0] == 0, :] = 0.0
upv = np.exp(nu2[index, :] + gamt + lnDifErf( -t_lq+nu[index,:], nu[index, :] ) )
upv[t[:, 0] == 0, :] = 0.
#Covariance calculation
#kdiag = np.sum(c0[index, :]*(upm-upv), axis=1)
kdiag = c0[index, :]*(upm-upv)
# Covariance calculation
# kdiag = np.sum(c0[index, :]*(upm-upv), axis=1)
kdiag = c0[index, :] * (upm - upv)
return kdiag
def update_gradients_full(self, dL_dK, X, X2 = None):
#index = np.asarray(X, dtype=np.int)
#index = index.reshape(index.size,)
if hasattr(X, 'values'):
def update_gradients_full(self, dL_dK, X, X2=None):
# index = np.asarray(X, dtype=int)
# index = index.reshape(index.size,)
if hasattr(X, "values"):
X = X.values
self.decay.gradient = np.zeros(self.decay.shape)
self.W.gradient = np.zeros(self.W.shape)
self.lengthscale.gradient = np.zeros(self.lengthscale.shape)
index = np.int_(np.round(X[:, 1]))
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
X_flag = index[0] >= self.output_dim
if X2 is None:
if X_flag: #Kuu or Kmm
if X_flag: # Kuu or Kmm
index -= self.output_dim
tmp = dL_dK*self._gkuu_lq(X, index)
tmp = dL_dK * self._gkuu_lq(X, index)
for q in np.unique(index):
ind = np.where(index == q)
self.lengthscale.gradient[q] = tmp[np.ix_(ind[0], ind[0])].sum()
else:
raise NotImplementedError
else: #Kfu or Knm
#index2 = np.asarray(X2, dtype=np.int)
#index2 = index2.reshape(index2.size,)
if hasattr(X2, 'values'):
else: # Kfu or Knm
# index2 = np.asarray(X2, dtype=int)
# index2 = index2.reshape(index2.size,)
if hasattr(X2, "values"):
X2 = X2.values
index2 = np.int_(np.round(X2[:, 1]))
index2 = index2.reshape(index2.size,)
index2 = index2.reshape(
index2.size,
)
X2_flag = index2[0] >= self.output_dim
if not X_flag and X2_flag: #Kfu
if not X_flag and X2_flag: # Kfu
index2 -= self.output_dim
else: #Kuf
dL_dK = dL_dK.T #so we obtaing dL_Kfu
else: # Kuf
dL_dK = dL_dK.T # so we obtaing dL_Kfu
indtemp = index - self.output_dim
Xtemp = X
X = X2
@ -228,12 +255,12 @@ class EQ_ODE1(Kern):
index = index2
index2 = indtemp
glq, gSdq, gB = self._gkfu(X, index, X2, index2)
tmp = dL_dK*glq
tmp = dL_dK * glq
for q in np.unique(index2):
ind = np.where(index2 == q)
self.lengthscale.gradient[q] = tmp[:, ind].sum()
tmpB = dL_dK*gB
tmp = dL_dK*gSdq
tmpB = dL_dK * gB
tmp = dL_dK * gSdq
for d in np.unique(index):
ind = np.where(index == d)
self.decay.gradient[d] = tmpB[ind, :].sum()
@ -242,404 +269,459 @@ class EQ_ODE1(Kern):
self.W.gradient[d, q] = tmp[np.ix_(ind[0], ind2[0])].sum()
def update_gradients_diag(self, dL_dKdiag, X):
#index = np.asarray(X, dtype=np.int)
#index = index.reshape(index.size,)
if hasattr(X, 'values'):
# index = np.asarray(X, dtype=int)
# index = index.reshape(index.size,)
if hasattr(X, "values"):
X = X.values
self.decay.gradient = np.zeros(self.decay.shape)
self.W.gradient = np.zeros(self.W.shape)
self.lengthscale.gradient = np.zeros(self.lengthscale.shape)
index = np.int_(X[:, 1])
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
glq, gS, gB = self._gkdiag(X, index)
if dL_dKdiag.size == X.shape[0]:
dL_dKdiag = np.reshape(dL_dKdiag, (index.size, 1))
tmp = dL_dKdiag*glq
tmp = dL_dKdiag * glq
self.lengthscale.gradient = tmp.sum(0)
tmpB = dL_dKdiag*gB
tmp = dL_dKdiag*gS
tmpB = dL_dKdiag * gB
tmp = dL_dKdiag * gS
for d in np.unique(index):
ind = np.where(index == d)
self.decay.gradient[d] = tmpB[ind, :].sum()
self.W.gradient[d, :] = tmp[ind].sum(0)
def gradients_X(self, dL_dK, X, X2=None):
#index = np.asarray(X, dtype=np.int)
#index = index.reshape(index.size,)
if hasattr(X, 'values'):
# index = np.asarray(X, dtype=int)
# index = index.reshape(index.size,)
if hasattr(X, "values"):
X = X.values
index = np.int_(np.round(X[:, 1]))
index = index.reshape(index.size,)
index = index.reshape(
index.size,
)
X_flag = index[0] >= self.output_dim
#If input_dim == 1, use this
#gX = np.zeros((X.shape[0], 1))
#Cheat to allow gradient for input_dim==2
# If input_dim == 1, use this
# gX = np.zeros((X.shape[0], 1))
# Cheat to allow gradient for input_dim==2
gX = np.zeros(X.shape)
if X2 is None: #Kuu or Kmm
if X2 is None: # Kuu or Kmm
if X_flag:
index -= self.output_dim
gX[:, 0] = 2.*(dL_dK*self._gkuu_X(X, index)).sum(0)
gX[:, 0] = 2.0 * (dL_dK * self._gkuu_X(X, index)).sum(0)
return gX
else:
raise NotImplementedError
else: #Kuf or Kmn
#index2 = np.asarray(X2, dtype=np.int)
#index2 = index2.reshape(index2.size,)
if hasattr(X2, 'values'):
else: # Kuf or Kmn
# index2 = np.asarray(X2, dtype=int)
# index2 = index2.reshape(index2.size,)
if hasattr(X2, "values"):
X2 = X2.values
index2 = np.int_(np.round(X2[:, 1]))
index2 = index2.reshape(index2.size,)
index2 = index2.reshape(
index2.size,
)
X2_flag = index2[0] >= self.output_dim
if X_flag and not X2_flag: #gradient of Kuf(Z, X) wrt Z
if X_flag and not X2_flag: # gradient of Kuf(Z, X) wrt Z
index -= self.output_dim
gX[:, 0] = (dL_dK*self._gkfu_z(X2, index2, X, index).T).sum(1)
gX[:, 0] = (dL_dK * self._gkfu_z(X2, index2, X, index).T).sum(1)
return gX
else:
raise NotImplementedError
#---------------------------------------#
# ---------------------------------------#
# Helper functions #
#---------------------------------------#
# ---------------------------------------#
#Evaluation of squared exponential for LFM
# Evaluation of squared exponential for LFM
def _Kuu(self, X, index):
index = index.reshape(index.size,)
t = X[:, 0].reshape(X.shape[0],)
lq = self.lengthscale.values.reshape(self.rank,)
lq2 = lq*lq
#Covariance matrix initialization
index = index.reshape(
index.size,
)
t = X[:, 0].reshape(
X.shape[0],
)
lq = self.lengthscale.values.reshape(
self.rank,
)
lq2 = lq * lq
# Covariance matrix initialization
kuu = np.zeros((t.size, t.size))
#Assign 1. to diagonal terms
kuu[np.diag_indices(t.size)] = 1.
#Upper triangular indices
# Assign 1. to diagonal terms
kuu[np.diag_indices(t.size)] = 1.0
# Upper triangular indices
indtri1, indtri2 = np.triu_indices(t.size, 1)
#Block Diagonal indices among Upper Triangular indices
# Block Diagonal indices among Upper Triangular indices
ind = np.where(index[indtri1] == index[indtri2])
indr = indtri1[ind]
indc = indtri2[ind]
r = t[indr] - t[indc]
r2 = r*r
#Calculation of covariance function
kuu[indr, indc] = np.exp(-r2/lq2[index[indr]])
#Completion of lower triangular part
r2 = r * r
# Calculation of covariance function
kuu[indr, indc] = np.exp(-r2 / lq2[index[indr]])
# Completion of lower triangular part
kuu[indc, indr] = kuu[indr, indc]
return kuu
def _Kusu(self, X, index, X2, index2):
index = index.reshape(index.size,)
index2 = index2.reshape(index2.size,)
t = X[:, 0].reshape(X.shape[0],1)
t2 = X2[:, 0].reshape(1,X2.shape[0])
lq = self.lengthscale.values.reshape(self.rank,)
#Covariance matrix initialization
index = index.reshape(
index.size,
)
index2 = index2.reshape(
index2.size,
)
t = X[:, 0].reshape(X.shape[0], 1)
t2 = X2[:, 0].reshape(1, X2.shape[0])
lq = self.lengthscale.values.reshape(
self.rank,
)
# Covariance matrix initialization
kuu = np.zeros((t.size, t2.size))
for q in range(self.rank):
ind1 = index == q
ind2 = index2 == q
r = t[ind1]/lq[q] - t2[0,ind2]/lq[q]
r2 = r*r
#Calculation of covariance function
r = t[ind1] / lq[q] - t2[0, ind2] / lq[q]
r2 = r * r
# Calculation of covariance function
kuu[np.ix_(ind1, ind2)] = np.exp(-r2)
return kuu
#Evaluation of cross-covariance function
# Evaluation of cross-covariance function
def _Kfu(self, X, index, X2, index2):
#terms that move along t
# terms that move along t
t = X[:, 0].reshape(X.shape[0], 1)
d = np.unique(index) #Output Indexes
d = np.unique(index) # Output Indexes
B = self.decay.values[d]
S = self.W.values[d, :]
#Index transformation
# Index transformation
indd = np.arange(self.output_dim)
indd[d] = np.arange(d.size)
index = indd[index]
#Output related variables must be column-wise
# Output related variables must be column-wise
B = B.reshape(B.size, 1)
#Input related variables must be row-wise
# Input related variables must be row-wise
z = X2[:, 0].reshape(1, X2.shape[0])
lq = self.lengthscale.values.reshape((1, self.rank))
kfu = np.empty((t.size, z.size))
#DxQ terms
c0 = S*((.5*np.sqrt(np.pi))*lq)
nu = B*(.5*lq)
# DxQ terms
c0 = S * ((0.5 * np.sqrt(np.pi)) * lq)
nu = B * (0.5 * lq)
nu2 = nu**2
#1xM terms
z_lq = z/lq[0, index2]
#NxM terms
tz = t-z
tz_lq = tz/lq[0, index2]
# 1xM terms
z_lq = z / lq[0, index2]
# NxM terms
tz = t - z
tz_lq = tz / lq[0, index2]
# Upsilon Calculations
fullind = np.ix_(index, index2)
upsi = np.exp(nu2[fullind] - B[index]*tz + lnDifErf( -tz_lq + nu[fullind], z_lq+nu[fullind]))
upsi[t[:, 0] == 0, :] = 0.
#Covariance calculation
kfu = c0[fullind]*upsi
upsi = np.exp(
nu2[fullind]
- B[index] * tz
+ lnDifErf(-tz_lq + nu[fullind], z_lq + nu[fullind])
)
upsi[t[:, 0] == 0, :] = 0.0
# Covariance calculation
kfu = c0[fullind] * upsi
return kfu
#Gradient of Kuu wrt lengthscale
# Gradient of Kuu wrt lengthscale
def _gkuu_lq(self, X, index):
t = X[:, 0].reshape(X.shape[0],)
index = index.reshape(X.shape[0],)
lq = self.lengthscale.values.reshape(self.rank,)
lq2 = lq*lq
#Covariance matrix initialization
t = X[:, 0].reshape(
X.shape[0],
)
index = index.reshape(
X.shape[0],
)
lq = self.lengthscale.values.reshape(
self.rank,
)
lq2 = lq * lq
# Covariance matrix initialization
glq = np.zeros((t.size, t.size))
#Upper triangular indices
# Upper triangular indices
indtri1, indtri2 = np.triu_indices(t.size, 1)
#Block Diagonal indices among Upper Triangular indices
# Block Diagonal indices among Upper Triangular indices
ind = np.where(index[indtri1] == index[indtri2])
indr = indtri1[ind]
indc = indtri2[ind]
r = t[indr] - t[indc]
r2 = r*r
r2_lq2 = r2/lq2[index[indr]]
#Calculation of covariance function
r2 = r * r
r2_lq2 = r2 / lq2[index[indr]]
# Calculation of covariance function
er2_lq2 = np.exp(-r2_lq2)
#Gradient wrt lq
c = 2.*r2_lq2/lq[index[indr]]
glq[indr, indc] = er2_lq2*c
#Complete the lower triangular
# Gradient wrt lq
c = 2.0 * r2_lq2 / lq[index[indr]]
glq[indr, indc] = er2_lq2 * c
# Complete the lower triangular
glq[indc, indr] = glq[indr, indc]
return glq
#Be careful this derivative should be transpose it
def _gkuu_X(self, X, index): #Diagonal terms are always zero
t = X[:, 0].reshape(X.shape[0],)
index = index.reshape(index.size,)
lq = self.lengthscale.values.reshape(self.rank,)
lq2 = lq*lq
#Covariance matrix initialization
# Be careful this derivative should be transpose it
def _gkuu_X(self, X, index): # Diagonal terms are always zero
t = X[:, 0].reshape(
X.shape[0],
)
index = index.reshape(
index.size,
)
lq = self.lengthscale.values.reshape(
self.rank,
)
lq2 = lq * lq
# Covariance matrix initialization
gt = np.zeros((t.size, t.size))
#Upper triangular indices
indtri1, indtri2 = np.triu_indices(t.size, 1) #Offset of 1 from the diagonal
#Block Diagonal indices among Upper Triangular indices
# Upper triangular indices
indtri1, indtri2 = np.triu_indices(t.size, 1) # Offset of 1 from the diagonal
# Block Diagonal indices among Upper Triangular indices
ind = np.where(index[indtri1] == index[indtri2])
indr = indtri1[ind]
indc = indtri2[ind]
r = t[indr] - t[indc]
r2 = r*r
r2_lq2 = r2/(-lq2[index[indr]])
#Calculation of covariance function
r2 = r * r
r2_lq2 = r2 / (-lq2[index[indr]])
# Calculation of covariance function
er2_lq2 = np.exp(r2_lq2)
#Gradient wrt t
c = 2.*r/lq2[index[indr]]
gt[indr, indc] = er2_lq2*c
#Complete the lower triangular
# Gradient wrt t
c = 2.0 * r / lq2[index[indr]]
gt[indr, indc] = er2_lq2 * c
# Complete the lower triangular
gt[indc, indr] = -gt[indr, indc]
return gt
#Gradients for Diagonal Kff
# Gradients for Diagonal Kff
def _gkdiag(self, X, index):
index = index.reshape(index.size,)
#terms that move along t
index = index.reshape(
index.size,
)
# terms that move along t
d = np.unique(index)
B = self.decay[d].values
S = self.W[d, :].values
#Index transformation
# Index transformation
indd = np.arange(self.output_dim)
indd[d] = np.arange(d.size)
index = indd[index]
#Output related variables must be column-wise
# Output related variables must be column-wise
t = X[:, 0].reshape(X.shape[0], 1)
B = B.reshape(B.size, 1)
S2 = S*S
S2 = S * S
#Input related variables must be row-wise
# Input related variables must be row-wise
lq = self.lengthscale.values.reshape(1, self.rank)
gB = np.empty((t.size,))
glq = np.empty((t.size, lq.size))
gS = np.empty((t.size, lq.size))
#Dx1 terms
c0 = S2*lq*np.sqrt(np.pi)
# Dx1 terms
c0 = S2 * lq * np.sqrt(np.pi)
#DxQ terms
nu = (.5*lq)*B
nu2 = nu*nu
# DxQ terms
nu = (0.5 * lq) * B
nu2 = nu * nu
#Nx1 terms
gamt = -B[index]*t
# Nx1 terms
gamt = -B[index] * t
egamt = np.exp(gamt)
e2gamt = egamt*egamt
e2gamt = egamt * egamt
#NxQ terms
t_lq = t/lq
t2_lq2 = -t_lq*t_lq
# NxQ terms
t_lq = t / lq
t2_lq2 = -t_lq * t_lq
etlq2gamt = np.exp(t2_lq2 + gamt) #NXQ
etlq2gamt = np.exp(t2_lq2 + gamt) # NXQ
##Upsilon calculations
#erfnu = erf(nu) #TODO: This can be improved
# erfnu = erf(nu) #TODO: This can be improved
upm = np.exp(nu2[index, :] + lnDifErf( nu[index, :], t_lq + nu[index, :]) )
upm[t[:, 0] == 0, :] = 0.
upm = np.exp(nu2[index, :] + lnDifErf(nu[index, :], t_lq + nu[index, :]))
upm[t[:, 0] == 0, :] = 0.0
upv = np.exp(nu2[index, :] + 2.*gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :]) ) #egamt*upv
upv[t[:, 0] == 0, :] = 0.
upv = np.exp(
nu2[index, :] + 2.0 * gamt + lnDifErf(-t_lq + nu[index, :], nu[index, :])
) # egamt*upv
upv[t[:, 0] == 0, :] = 0.0
#Gradient wrt S
c0_S = (S/B)*(lq*np.sqrt(np.pi))
# Gradient wrt S
c0_S = (S / B) * (lq * np.sqrt(np.pi))
gS = c0_S[index]*(upm - upv)
gS = c0_S[index] * (upm - upv)
#For B
CB1 = (.5*lq)**2 - .5/B**2 #DXQ
lq2_2B = (.5*lq**2)*(S2/B) #DXQ
CB2 = 2.*etlq2gamt - e2gamt - 1. #NxQ
# For B
CB1 = (0.5 * lq) ** 2 - 0.5 / B**2 # DXQ
lq2_2B = (0.5 * lq**2) * (S2 / B) # DXQ
CB2 = 2.0 * etlq2gamt - e2gamt - 1.0 # NxQ
# gradient wrt B NxZ
gB = c0[index, :]*(CB1[index, :]*upm - (CB1[index, :] - t/B[index])*upv) + \
lq2_2B[index, :]*CB2
gB = (
c0[index, :] * (CB1[index, :] * upm - (CB1[index, :] - t / B[index]) * upv)
+ lq2_2B[index, :] * CB2
)
#Gradient wrt lengthscale
#DxQ terms
c0 = (.5*np.sqrt(np.pi))*(S2/B)*(1.+.5*(lq*B)**2)
Clq1 = S2*(lq*.5)
glq = c0[index]*(upm - upv) + Clq1[index]*CB2
# Gradient wrt lengthscale
# DxQ terms
c0 = (0.5 * np.sqrt(np.pi)) * (S2 / B) * (1.0 + 0.5 * (lq * B) ** 2)
Clq1 = S2 * (lq * 0.5)
glq = c0[index] * (upm - upv) + Clq1[index] * CB2
return glq, gS, gB
def _gkfu(self, X, index, Z, index2):
index = index.reshape(index.size,)
#TODO: reduce memory usage
#terms that move along t
index = index.reshape(
index.size,
)
# TODO: reduce memory usage
# terms that move along t
d = np.unique(index)
B = self.decay[d].values
S = self.W[d, :].values
#Index transformation
# Index transformation
indd = np.arange(self.output_dim)
indd[d] = np.arange(d.size)
index = indd[index]
#t column
# t column
t = X[:, 0].reshape(X.shape[0], 1)
B = B.reshape(B.size, 1)
#z row
# z row
z = Z[:, 0].reshape(1, Z.shape[0])
index2 = index2.reshape(index2.size,)
index2 = index2.reshape(
index2.size,
)
lq = self.lengthscale.values.reshape((1, self.rank))
#kfu = np.empty((t.size, z.size))
# kfu = np.empty((t.size, z.size))
glq = np.empty((t.size, z.size))
gSdq = np.empty((t.size, z.size))
gB = np.empty((t.size, z.size))
#Dx1 terms
B_2 = B*.5
S_pi = S*(.5*np.sqrt(np.pi))
#DxQ terms
c0 = S_pi*lq #lq*Sdq*sqrt(pi)
nu = B*lq*.5
nu2 = nu*nu
# Dx1 terms
B_2 = B * 0.5
S_pi = S * (0.5 * np.sqrt(np.pi))
# DxQ terms
c0 = S_pi * lq # lq*Sdq*sqrt(pi)
nu = B * lq * 0.5
nu2 = nu * nu
#1xM terms
z_lq = z/lq[0, index2]
# 1xM terms
z_lq = z / lq[0, index2]
#NxM terms
tz = t-z
tz_lq = tz/lq[0, index2]
etz_lq2 = -np.exp(-tz_lq*tz_lq)
ez_lq_Bt = np.exp(-z_lq*z_lq -B[index]*t)
# NxM terms
tz = t - z
tz_lq = tz / lq[0, index2]
etz_lq2 = -np.exp(-tz_lq * tz_lq)
ez_lq_Bt = np.exp(-z_lq * z_lq - B[index] * t)
# Upsilon calculations
fullind = np.ix_(index, index2)
upsi = np.exp(nu2[fullind] - B[index]*tz + lnDifErf( -tz_lq + nu[fullind], z_lq+nu[fullind] ) )
upsi[t[:, 0] == 0., :] = 0.
upsi = np.exp(
nu2[fullind]
- B[index] * tz
+ lnDifErf(-tz_lq + nu[fullind], z_lq + nu[fullind])
)
upsi[t[:, 0] == 0.0, :] = 0.0
#Gradient wrt S
#DxQ term
Sa1 = lq*(.5*np.sqrt(np.pi))
# Gradient wrt S
# DxQ term
Sa1 = lq * (0.5 * np.sqrt(np.pi))
gSdq = Sa1[0,index2]*upsi
gSdq = Sa1[0, index2] * upsi
#Gradient wrt lq
la1 = S_pi*(1. + 2.*nu2)
Slq = S*lq
uplq = etz_lq2*(tz_lq/lq[0, index2] + B_2[index])
uplq += ez_lq_Bt*(-z_lq/lq[0, index2] + B_2[index])
# Gradient wrt lq
la1 = S_pi * (1.0 + 2.0 * nu2)
Slq = S * lq
uplq = etz_lq2 * (tz_lq / lq[0, index2] + B_2[index])
uplq += ez_lq_Bt * (-z_lq / lq[0, index2] + B_2[index])
glq = la1[fullind]*upsi
glq += Slq[fullind]*uplq
glq = la1[fullind] * upsi
glq += Slq[fullind] * uplq
#Gradient wrt B
Slq = Slq*lq
nulq = nu*lq
# Gradient wrt B
Slq = Slq * lq
nulq = nu * lq
upBd = etz_lq2 + ez_lq_Bt
gB = c0[fullind]*(nulq[fullind] - tz)*upsi + .5*Slq[fullind]*upBd
gB = c0[fullind] * (nulq[fullind] - tz) * upsi + 0.5 * Slq[fullind] * upBd
return glq, gSdq, gB
#TODO: reduce memory usage
def _gkfu_z(self, X, index, Z, index2): #Kfu(t,z)
index = index.reshape(index.size,)
#terms that move along t
# TODO: reduce memory usage
def _gkfu_z(self, X, index, Z, index2): # Kfu(t,z)
index = index.reshape(
index.size,
)
# terms that move along t
d = np.unique(index)
B = self.decay[d].values
S = self.W[d, :].values
#Index transformation
# Index transformation
indd = np.arange(self.output_dim)
indd[d] = np.arange(d.size)
index = indd[index]
#t column
# t column
t = X[:, 0].reshape(X.shape[0], 1)
B = B.reshape(B.size, 1)
#z row
# z row
z = Z[:, 0].reshape(1, Z.shape[0])
index2 = index2.reshape(index2.size,)
index2 = index2.reshape(
index2.size,
)
lq = self.lengthscale.values.reshape((1, self.rank))
#kfu = np.empty((t.size, z.size))
# kfu = np.empty((t.size, z.size))
gz = np.empty((t.size, z.size))
#Dx1 terms
S_pi =S*(.5*np.sqrt(np.pi))
#DxQ terms
#Slq = S*lq
c0 = S_pi*lq #lq*Sdq*sqrt(pi)
nu = (.5*lq)*B
nu2 = nu*nu
# Dx1 terms
S_pi = S * (0.5 * np.sqrt(np.pi))
# DxQ terms
# Slq = S*lq
c0 = S_pi * lq # lq*Sdq*sqrt(pi)
nu = (0.5 * lq) * B
nu2 = nu * nu
#1xM terms
z_lq = z/lq[0, index2]
z_lq2 = -z_lq*z_lq
#NxQ terms
t_lq = t/lq
#NxM terms
# 1xM terms
z_lq = z / lq[0, index2]
z_lq2 = -z_lq * z_lq
# NxQ terms
t_lq = t / lq
# NxM terms
zt_lq = z_lq - t_lq[:, index2]
zt_lq2 = -zt_lq*zt_lq
zt_lq2 = -zt_lq * zt_lq
# Upsilon calculations
fullind = np.ix_(index, index2)
z2 = z_lq + nu[fullind]
z1 = z2 - t_lq[:, index2]
upsi = np.exp(nu2[fullind] - B[index]*(t-z) + lnDifErf(z1,z2) )
upsi[t[:, 0] == 0., :] = 0.
upsi = np.exp(nu2[fullind] - B[index] * (t - z) + lnDifErf(z1, z2))
upsi[t[:, 0] == 0.0, :] = 0.0
#Gradient wrt z
za1 = c0*B
#za2 = S_w
gz = za1[fullind]*upsi + S[fullind]*( np.exp(z_lq2 - B[index]*t) -np.exp(zt_lq2) )
# Gradient wrt z
za1 = c0 * B
# za2 = S_w
gz = za1[fullind] * upsi + S[fullind] * (
np.exp(z_lq2 - B[index] * t) - np.exp(zt_lq2)
)
return gz
def lnDifErf(z1,z2):
#Z2 is always positive
def lnDifErf(z1, z2):
# Z2 is always positive
logdiferf = np.zeros(z1.shape)
ind = np.where(z1>0.)
ind2 = np.where(z1<=0.)
ind = np.where(z1 > 0.0)
ind2 = np.where(z1 <= 0.0)
if ind[0].shape > 0:
z1i = z1[ind]
z12 = z1i*z1i
z12 = z1i * z1i
z2i = z2[ind]
logdiferf[ind] = -z12 + np.log(erfcx(z1i) - erfcx(z2i)*np.exp(z12-z2i**2))
logdiferf[ind] = -z12 + np.log(erfcx(z1i) - erfcx(z2i) * np.exp(z12 - z2i**2))
if ind2[0].shape > 0:
z1i = z1[ind2]

File diff suppressed because it is too large Load diff

View file

@ -121,7 +121,7 @@ class Eq_ode1(Kernpart):
target+=self.initial_variance * np.exp(- self.decay * (t1_mat + t2_mat))
def Kdiag(self,index,target):
#target += np.diag(self.B)[np.asarray(index,dtype=np.int).flatten()]
#target += np.diag(self.B)[np.asarray(index,dtype=int).flatten()]
pass
def _param_grad_helper(self,dL_dK,X,X2,target):
@ -203,7 +203,7 @@ class Eq_ode1(Kernpart):
self._t = X[:, 0]
if not X.shape[1] == 2:
raise ValueError('Input matrix for ode1 covariance should have two columns, one containing times, the other output indices')
self._index = np.asarray(X[:, 1],dtype=np.int)
self._index = np.asarray(X[:, 1],dtype=int)
# Sort indices so that outputs are in blocks for computational
# convenience.
self._order = self._index.argsort()
@ -220,7 +220,7 @@ class Eq_ode1(Kernpart):
if not X2.shape[1] == 2:
raise ValueError('Input matrix for ode1 covariance should have two columns, one containing times, the other output indices')
self._t2 = X2[:, 0]
self._index2 = np.asarray(X2[:, 1],dtype=np.int)
self._index2 = np.asarray(X2[:, 1],dtype=int)
self._order2 = self._index2.argsort()
self._index2 = self._index2[self._order2]
self._t2 = self._t2[self._order2]

View file

@ -7,6 +7,7 @@ from ..inference.latent_function_inference import VarDTC
from .. import kern
from .. import util
class SparseGPCoregionalizedRegression(SparseGP):
"""
Sparse Gaussian Process model for heteroscedastic multioutput regression
@ -34,34 +35,65 @@ class SparseGPCoregionalizedRegression(SparseGP):
:type kernel_name: string
"""
def __init__(self, X_list, Y_list, Z_list=[], kernel=None, likelihoods_list=None, num_inducing=10, X_variance=None, name='SGPCR',W_rank=1,kernel_name='coreg'):
#Input and Output
X,Y,self.output_index = util.multioutput.build_XY(X_list,Y_list)
def __init__(
self,
X_list,
Y_list,
Z_list=[],
kernel=None,
likelihoods_list=None,
num_inducing=10,
X_variance=None,
name="SGPCR",
W_rank=1,
kernel_name="coreg",
):
# Input and Output
X, Y, self.output_index = util.multioutput.build_XY(X_list, Y_list)
Ny = len(Y_list)
#Kernel
# Kernel
if kernel is None:
kernel = kern.RBF(X.shape[1]-1)
kernel = kern.RBF(X.shape[1] - 1)
kernel = util.multioutput.ICM(input_dim=X.shape[1]-1, num_outputs=Ny, kernel=kernel, W_rank=W_rank, name=kernel_name)
kernel = util.multioutput.ICM(
input_dim=X.shape[1] - 1,
num_outputs=Ny,
kernel=kernel,
W_rank=W_rank,
name=kernel_name,
)
#Likelihood
likelihood = util.multioutput.build_likelihood(Y_list,self.output_index,likelihoods_list)
# Likelihood
likelihood = util.multioutput.build_likelihood(
Y_list, self.output_index, likelihoods_list
)
#Inducing inputs list
# Inducing inputs list
if len(Z_list):
assert len(Z_list) == Ny, 'Number of outputs do not match length of inducing inputs list.'
assert (
len(Z_list) == Ny
), "Number of outputs do not match length of inducing inputs list."
else:
if isinstance(num_inducing,np.int):
if isinstance(num_inducing, int):
num_inducing = [num_inducing] * Ny
num_inducing = np.asarray(num_inducing)
assert num_inducing.size == Ny, 'Number of outputs do not match length of inducing inputs list.'
for ni,Xi in zip(num_inducing,X_list):
assert (
num_inducing.size == Ny
), "Number of outputs do not match length of inducing inputs list."
for ni, Xi in zip(num_inducing, X_list):
i = np.random.permutation(Xi.shape[0])[:ni]
Z_list.append(Xi[i].copy())
Z, _, Iz = util.multioutput.build_XY(Z_list)
super(SparseGPCoregionalizedRegression, self).__init__(X, Y, Z, kernel, likelihood, inference_method=VarDTC(), Y_metadata={'output_index':self.output_index})
self['.*inducing'][:,-1].fix()
super(SparseGPCoregionalizedRegression, self).__init__(
X,
Y,
Z,
kernel,
likelihood,
inference_method=VarDTC(),
Y_metadata={"output_index": self.output_index},
)
self[".*inducing"][:, -1].fix()

View file

@ -5,51 +5,109 @@ The Maniforld Relevance Determination model with the spike-and-slab prior
import numpy as np
from ..core import Model
from .ss_gplvm import SSGPLVM
from GPy.core.parameterization.variational import SpikeAndSlabPrior,NormalPosterior,VariationalPrior
from GPy.core.parameterization.variational import (
SpikeAndSlabPrior,
NormalPosterior,
VariationalPrior,
)
from ..util.misc import param_to_array
from ..kern import RBF
from ..core import Param
from numpy.linalg.linalg import LinAlgError
class SSMRD(Model):
def __init__(self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx = 'PCA_concat', initz = 'permute',
num_inducing=10, Zs=None, kernels=None, inference_methods=None, likelihoods=None, group_spike=True,
pi=0.5, name='ss_mrd', Ynames=None, mpi_comm=None, IBP=False, alpha=2., taus=None, ):
class SSMRD(Model):
def __init__(
self,
Ylist,
input_dim,
X=None,
X_variance=None,
Gammas=None,
initx="PCA_concat",
initz="permute",
num_inducing=10,
Zs=None,
kernels=None,
inference_methods=None,
likelihoods=None,
group_spike=True,
pi=0.5,
name="ss_mrd",
Ynames=None,
mpi_comm=None,
IBP=False,
alpha=2.0,
taus=None,
):
super(SSMRD, self).__init__(name)
self.mpi_comm = mpi_comm
self._PROPAGATE_ = False
# initialize X for individual models
X, X_variance, Gammas, fracs = self._init_X(Ylist, input_dim, X, X_variance, Gammas, initx)
X, X_variance, Gammas, fracs = self._init_X(
Ylist, input_dim, X, X_variance, Gammas, initx
)
self.X = NormalPosterior(means=X, variances=X_variance)
if kernels is None:
kernels = [RBF(input_dim, lengthscale=1./fracs, ARD=True) for i in range(len(Ylist))]
kernels = [
RBF(input_dim, lengthscale=1.0 / fracs, ARD=True)
for i in range(len(Ylist))
]
if Zs is None:
Zs = [None]* len(Ylist)
Zs = [None] * len(Ylist)
if likelihoods is None:
likelihoods = [None]* len(Ylist)
likelihoods = [None] * len(Ylist)
if inference_methods is None:
inference_methods = [None]* len(Ylist)
inference_methods = [None] * len(Ylist)
if IBP:
self.var_priors = [IBPPrior_SSMRD(len(Ylist),input_dim,alpha=alpha) for i in range(len(Ylist))]
self.var_priors = [
IBPPrior_SSMRD(len(Ylist), input_dim, alpha=alpha)
for i in range(len(Ylist))
]
else:
self.var_priors = [SpikeAndSlabPrior_SSMRD(nModels=len(Ylist),pi=pi,learnPi=False, group_spike=group_spike) for i in range(len(Ylist))]
self.models = [SSGPLVM(y, input_dim, X=X.copy(), X_variance=X_variance.copy(), Gamma=Gammas[i], num_inducing=num_inducing,Z=Zs[i], learnPi=False, group_spike=group_spike,
kernel=kernels[i],inference_method=inference_methods[i],likelihood=likelihoods[i], variational_prior=self.var_priors[i], IBP=IBP, tau=None if taus is None else taus[i],
name='model_'+str(i), mpi_comm=mpi_comm, sharedX=True) for i,y in enumerate(Ylist)]
self.link_parameters(*(self.models+[self.X]))
self.var_priors = [
SpikeAndSlabPrior_SSMRD(
nModels=len(Ylist), pi=pi, learnPi=False, group_spike=group_spike
)
for i in range(len(Ylist))
]
self.models = [
SSGPLVM(
y,
input_dim,
X=X.copy(),
X_variance=X_variance.copy(),
Gamma=Gammas[i],
num_inducing=num_inducing,
Z=Zs[i],
learnPi=False,
group_spike=group_spike,
kernel=kernels[i],
inference_method=inference_methods[i],
likelihood=likelihoods[i],
variational_prior=self.var_priors[i],
IBP=IBP,
tau=None if taus is None else taus[i],
name="model_" + str(i),
mpi_comm=mpi_comm,
sharedX=True,
)
for i, y in enumerate(Ylist)
]
self.link_parameters(*(self.models + [self.X]))
def _propogate_X_val(self):
if self._PROPAGATE_: return
if self._PROPAGATE_:
return
for m in self.models:
m.X.mean.values[:] = self.X.mean.values
m.X.variance.values[:] = self.X.variance.values
varp_list = [m.X for m in self.models]
[vp._update_inernal(varp_list) for vp in self.var_priors]
self._PROPAGATE_=True
self._PROPAGATE_ = True
def _collate_X_gradient(self):
self._PROPAGATE_ = False
@ -62,82 +120,88 @@ class SSMRD(Model):
def parameters_changed(self):
super(SSMRD, self).parameters_changed()
[m.parameters_changed() for m in self.models]
self._log_marginal_likelihood = sum([m._log_marginal_likelihood for m in self.models])
self._log_marginal_likelihood = sum(
[m._log_marginal_likelihood for m in self.models]
)
self._collate_X_gradient()
def log_likelihood(self):
return self._log_marginal_likelihood
def _init_X(self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx='PCA_concat'):
def _init_X(
self, Ylist, input_dim, X=None, X_variance=None, Gammas=None, initx="PCA_concat"
):
# Divide latent dimensions
idx = np.empty((input_dim,),dtype=np.int)
residue = (input_dim)%(len(Ylist))
idx = np.empty((input_dim,), dtype=int)
residue = (input_dim) % (len(Ylist))
for i in range(len(Ylist)):
if i < residue:
size = input_dim/len(Ylist)+1
idx[i*size:(i+1)*size] = i
size = input_dim / len(Ylist) + 1
idx[i * size : (i + 1) * size] = i
else:
size = input_dim/len(Ylist)
idx[i*size+residue:(i+1)*size+residue] = i
size = input_dim / len(Ylist)
idx[i * size + residue : (i + 1) * size + residue] = i
if X is None:
if initx == 'PCA_concat':
X = np.empty((Ylist[0].shape[0],input_dim))
if initx == "PCA_concat":
X = np.empty((Ylist[0].shape[0], input_dim))
fracs = np.empty((input_dim,))
from ..util.initialization import initialize_latent
for i in range(len(Ylist)):
Y = Ylist[i]
dim = (idx==i).sum()
if dim>0:
x, fr = initialize_latent('PCA', dim, Y)
X[:,idx==i] = x
fracs[idx==i] = fr
elif initx=='PCA_joint':
dim = (idx == i).sum()
if dim > 0:
x, fr = initialize_latent("PCA", dim, Y)
X[:, idx == i] = x
fracs[idx == i] = fr
elif initx == "PCA_joint":
y = np.hstack(Ylist)
from ..util.initialization import initialize_latent
X, fracs = initialize_latent('PCA', input_dim, y)
X, fracs = initialize_latent("PCA", input_dim, y)
else:
X = np.random.randn(Ylist[0].shape[0], input_dim)
fracs = np.ones(input_dim)
else:
fracs = np.ones(input_dim)
if X_variance is None: # The variance of the variational approximation (S)
X_variance = np.random.uniform(0,.1,X.shape)
if X_variance is None: # The variance of the variational approximation (S)
X_variance = np.random.uniform(0, 0.1, X.shape)
if Gammas is None:
Gammas = []
for x in X:
gamma = np.empty_like(X) # The posterior probabilities of the binary variable in the variational approximation
gamma = np.empty_like(
X
) # The posterior probabilities of the binary variable in the variational approximation
gamma[:] = 0.5 + 0.1 * np.random.randn(X.shape[0], input_dim)
gamma[gamma>1.-1e-9] = 1.-1e-9
gamma[gamma<1e-9] = 1e-9
gamma[gamma > 1.0 - 1e-9] = 1.0 - 1e-9
gamma[gamma < 1e-9] = 1e-9
Gammas.append(gamma)
return X, X_variance, Gammas, fracs
@Model.optimizer_array.setter
def optimizer_array(self, p):
if self.mpi_comm != None:
if self._IN_OPTIMIZATION_ and self.mpi_comm.rank==0:
self.mpi_comm.Bcast(np.int32(1),root=0)
if self._IN_OPTIMIZATION_ and self.mpi_comm.rank == 0:
self.mpi_comm.Bcast(np.int32(1), root=0)
self.mpi_comm.Bcast(p, root=0)
Model.optimizer_array.fset(self,p)
Model.optimizer_array.fset(self, p)
def optimize(self, optimizer=None, start=None, **kwargs):
self._IN_OPTIMIZATION_ = True
if self.mpi_comm==None:
super(SSMRD, self).optimize(optimizer,start,**kwargs)
elif self.mpi_comm.rank==0:
super(SSMRD, self).optimize(optimizer,start,**kwargs)
self.mpi_comm.Bcast(np.int32(-1),root=0)
elif self.mpi_comm.rank>0:
if self.mpi_comm == None:
super(SSMRD, self).optimize(optimizer, start, **kwargs)
elif self.mpi_comm.rank == 0:
super(SSMRD, self).optimize(optimizer, start, **kwargs)
self.mpi_comm.Bcast(np.int32(-1), root=0)
elif self.mpi_comm.rank > 0:
x = self.optimizer_array.copy()
flag = np.empty(1,dtype=np.int32)
flag = np.empty(1, dtype=np.int32)
while True:
self.mpi_comm.Bcast(flag,root=0)
if flag==1:
self.mpi_comm.Bcast(flag, root=0)
if flag == 1:
try:
self.optimizer_array = x
self._fail_count = 0
@ -145,7 +209,7 @@ class SSMRD(Model):
if self._fail_count >= self._allowed_failures:
raise
self._fail_count += 1
elif flag==-1:
elif flag == -1:
break
else:
self._IN_OPTIMIZATION_ = False
@ -154,20 +218,42 @@ class SSMRD(Model):
class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior):
def __init__(self, nModels, pi=0.5, learnPi=False, group_spike=True, variance = 1.0, name='SSMRDPrior', **kw):
def __init__(
self,
nModels,
pi=0.5,
learnPi=False,
group_spike=True,
variance=1.0,
name="SSMRDPrior",
**kw
):
self.nModels = nModels
self._b_prob_all = 0.5
super(SpikeAndSlabPrior_SSMRD, self).__init__(pi=pi,learnPi=learnPi,group_spike=group_spike,variance=variance, name=name, **kw)
super(SpikeAndSlabPrior_SSMRD, self).__init__(
pi=pi,
learnPi=learnPi,
group_spike=group_spike,
variance=variance,
name=name,
**kw
)
def _update_inernal(self, varp_list):
"""Make an update of the internal status by gathering the variational posteriors for all the individual models."""
# The probability for the binary variable for the same latent dimension of any of the models is on.
if self.group_spike:
self._b_prob_all = 1.-param_to_array(varp_list[0].gamma_group)
[np.multiply(self._b_prob_all, 1.-vp.gamma_group, self._b_prob_all) for vp in varp_list[1:]]
self._b_prob_all = 1.0 - param_to_array(varp_list[0].gamma_group)
[
np.multiply(self._b_prob_all, 1.0 - vp.gamma_group, self._b_prob_all)
for vp in varp_list[1:]
]
else:
self._b_prob_all = 1.-param_to_array(varp_list[0].binary_prob)
[np.multiply(self._b_prob_all, 1.-vp.binary_prob, self._b_prob_all) for vp in varp_list[1:]]
self._b_prob_all = 1.0 - param_to_array(varp_list[0].binary_prob)
[
np.multiply(self._b_prob_all, 1.0 - vp.binary_prob, self._b_prob_all)
for vp in varp_list[1:]
]
def KL_divergence(self, variational_posterior):
mu = variational_posterior.mean
@ -176,16 +262,20 @@ class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior):
gamma = variational_posterior.binary_prob[0]
else:
gamma = variational_posterior.binary_prob
if len(self.pi.shape)==2:
idx = np.unique(gamma._raveled_index()/gamma.shape[-1])
if len(self.pi.shape) == 2:
idx = np.unique(gamma._raveled_index() / gamma.shape[-1])
pi = self.pi[idx]
else:
pi = self.pi
var_mean = np.square(mu)/self.variance
var_S = (S/self.variance - np.log(S))
var_gamma = (gamma*np.log(gamma/pi)).sum()+((1-gamma)*np.log((1-gamma)/(1-pi))).sum()
return var_gamma +((1.-self._b_prob_all)*(np.log(self.variance)-1. +var_mean + var_S)).sum()/(2.*self.nModels)
var_mean = np.square(mu) / self.variance
var_S = S / self.variance - np.log(S)
var_gamma = (gamma * np.log(gamma / pi)).sum() + (
(1 - gamma) * np.log((1 - gamma) / (1 - pi))
).sum()
return var_gamma + (
(1.0 - self._b_prob_all) * (np.log(self.variance) - 1.0 + var_mean + var_S)
).sum() / (2.0 * self.nModels)
def update_gradients_KL(self, variational_posterior):
mu = variational_posterior.mean
@ -195,63 +285,141 @@ class SpikeAndSlabPrior_SSMRD(SpikeAndSlabPrior):
gamma = variational_posterior.binary_prob.values[0]
else:
gamma = variational_posterior.binary_prob.values
if len(self.pi.shape)==2:
idx = np.unique(gamma._raveled_index()/gamma.shape[-1])
if len(self.pi.shape) == 2:
idx = np.unique(gamma._raveled_index() / gamma.shape[-1])
pi = self.pi[idx]
else:
pi = self.pi
if self.group_spike:
tmp = self._b_prob_all/(1.-gamma)
variational_posterior.binary_prob.gradient -= np.log((1-pi)/pi*gamma/(1.-gamma))/N +tmp*((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2.
tmp = self._b_prob_all / (1.0 - gamma)
variational_posterior.binary_prob.gradient -= (
np.log((1 - pi) / pi * gamma / (1.0 - gamma)) / N
+ tmp
* (
(np.square(mu) + S) / self.variance
- np.log(S)
+ np.log(self.variance)
- 1.0
)
/ 2.0
)
else:
variational_posterior.binary_prob.gradient -= np.log((1-pi)/pi*gamma/(1.-gamma))+((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2.
mu.gradient -= (1.-self._b_prob_all)*mu/(self.variance*self.nModels)
S.gradient -= (1./self.variance - 1./S) * (1.-self._b_prob_all) /(2.*self.nModels)
variational_posterior.binary_prob.gradient -= (
np.log((1 - pi) / pi * gamma / (1.0 - gamma))
+ (
(np.square(mu) + S) / self.variance
- np.log(S)
+ np.log(self.variance)
- 1.0
)
/ 2.0
)
mu.gradient -= (1.0 - self._b_prob_all) * mu / (self.variance * self.nModels)
S.gradient -= (
(1.0 / self.variance - 1.0 / S)
* (1.0 - self._b_prob_all)
/ (2.0 * self.nModels)
)
if self.learnPi:
raise 'Not Supported!'
raise "Not Supported!"
class IBPPrior_SSMRD(VariationalPrior):
def __init__(self, nModels, input_dim, alpha =2., tau=None, name='IBPPrior', **kw):
def __init__(self, nModels, input_dim, alpha=2.0, tau=None, name="IBPPrior", **kw):
super(IBPPrior_SSMRD, self).__init__(name=name, **kw)
from paramz.transformations import Logexp, __fixed__
self.nModels = nModels
self._b_prob_all = 0.5
self.input_dim = input_dim
self.variance = 1.
self.alpha = Param('alpha', alpha, __fixed__)
self.variance = 1.0
self.alpha = Param("alpha", alpha, __fixed__)
self.link_parameter(self.alpha)
def _update_inernal(self, varp_list):
"""Make an update of the internal status by gathering the variational posteriors for all the individual models."""
# The probability for the binary variable for the same latent dimension of any of the models is on.
self._b_prob_all = 1.-param_to_array(varp_list[0].gamma_group)
[np.multiply(self._b_prob_all, 1.-vp.gamma_group, self._b_prob_all) for vp in varp_list[1:]]
self._b_prob_all = 1.0 - param_to_array(varp_list[0].gamma_group)
[
np.multiply(self._b_prob_all, 1.0 - vp.gamma_group, self._b_prob_all)
for vp in varp_list[1:]
]
def KL_divergence(self, variational_posterior):
mu, S, gamma, tau = variational_posterior.mean.values, variational_posterior.variance.values, variational_posterior.gamma_group.values, variational_posterior.tau.values
mu, S, gamma, tau = (
variational_posterior.mean.values,
variational_posterior.variance.values,
variational_posterior.gamma_group.values,
variational_posterior.tau.values,
)
var_mean = np.square(mu)/self.variance
var_S = (S/self.variance - np.log(S))
part1 = ((1.-self._b_prob_all)* (np.log(self.variance)-1. +var_mean + var_S)).sum()/(2.*self.nModels)
var_mean = np.square(mu) / self.variance
var_S = S / self.variance - np.log(S)
part1 = (
(1.0 - self._b_prob_all) * (np.log(self.variance) - 1.0 + var_mean + var_S)
).sum() / (2.0 * self.nModels)
ad = self.alpha/self.input_dim
from scipy.special import betaln,digamma
part2 = (gamma*np.log(gamma)).sum() + ((1.-gamma)*np.log(1.-gamma)).sum() + (betaln(ad,1.)*self.input_dim -betaln(tau[:,0], tau[:,1]).sum())/self.nModels \
+ (( (tau[:,0]-ad)/self.nModels -gamma)*digamma(tau[:,0])).sum() + \
(((tau[:,1]-1.)/self.nModels+gamma-1.)*digamma(tau[:,1])).sum() + (((1.+ad-tau[:,0]-tau[:,1])/self.nModels+1.)*digamma(tau.sum(axis=1))).sum()
return part1+part2
ad = self.alpha / self.input_dim
from scipy.special import betaln, digamma
part2 = (
(gamma * np.log(gamma)).sum()
+ ((1.0 - gamma) * np.log(1.0 - gamma)).sum()
+ (betaln(ad, 1.0) * self.input_dim - betaln(tau[:, 0], tau[:, 1]).sum())
/ self.nModels
+ (((tau[:, 0] - ad) / self.nModels - gamma) * digamma(tau[:, 0])).sum()
+ (
((tau[:, 1] - 1.0) / self.nModels + gamma - 1.0) * digamma(tau[:, 1])
).sum()
+ (
((1.0 + ad - tau[:, 0] - tau[:, 1]) / self.nModels + 1.0)
* digamma(tau.sum(axis=1))
).sum()
)
return part1 + part2
def update_gradients_KL(self, variational_posterior):
mu, S, gamma, tau = variational_posterior.mean.values, variational_posterior.variance.values, variational_posterior.gamma_group.values, variational_posterior.tau.values
mu, S, gamma, tau = (
variational_posterior.mean.values,
variational_posterior.variance.values,
variational_posterior.gamma_group.values,
variational_posterior.tau.values,
)
variational_posterior.mean.gradient -= (1.-self._b_prob_all)*mu/(self.variance*self.nModels)
variational_posterior.variance.gradient -= (1./self.variance - 1./S) * (1.-self._b_prob_all) /(2.*self.nModels)
from scipy.special import digamma,polygamma
tmp = self._b_prob_all/(1.-gamma)
dgamma = (np.log(gamma/(1.-gamma))+ digamma(tau[:,1])-digamma(tau[:,0]))/variational_posterior.num_data
variational_posterior.binary_prob.gradient -= dgamma+tmp*((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2.
ad = self.alpha/self.input_dim
common = ((1.+ad-tau[:,0]-tau[:,1])/self.nModels+1.)*polygamma(1,tau.sum(axis=1))
variational_posterior.tau.gradient[:,0] = -(((tau[:,0]-ad)/self.nModels -gamma)*polygamma(1,tau[:,0])+common)
variational_posterior.tau.gradient[:,1] = -(((tau[:,1]-1.)/self.nModels+gamma-1.)*polygamma(1,tau[:,1])+common)
variational_posterior.mean.gradient -= (
(1.0 - self._b_prob_all) * mu / (self.variance * self.nModels)
)
variational_posterior.variance.gradient -= (
(1.0 / self.variance - 1.0 / S)
* (1.0 - self._b_prob_all)
/ (2.0 * self.nModels)
)
from scipy.special import digamma, polygamma
tmp = self._b_prob_all / (1.0 - gamma)
dgamma = (
np.log(gamma / (1.0 - gamma)) + digamma(tau[:, 1]) - digamma(tau[:, 0])
) / variational_posterior.num_data
variational_posterior.binary_prob.gradient -= (
dgamma
+ tmp
* (
(np.square(mu) + S) / self.variance
- np.log(S)
+ np.log(self.variance)
- 1.0
)
/ 2.0
)
ad = self.alpha / self.input_dim
common = ((1.0 + ad - tau[:, 0] - tau[:, 1]) / self.nModels + 1.0) * polygamma(
1, tau.sum(axis=1)
)
variational_posterior.tau.gradient[:, 0] = -(
((tau[:, 0] - ad) / self.nModels - gamma) * polygamma(1, tau[:, 0]) + common
)
variational_posterior.tau.gradient[:, 1] = -(
((tau[:, 1] - 1.0) / self.nModels + gamma - 1.0) * polygamma(1, tau[:, 1])
+ common
)

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@ import numpy as np
from .util import align_subplot_array, align_subplots
def ax_default(fignum, ax):
if ax is None:
fig = plt.figure(fignum)
@ -13,11 +14,23 @@ def ax_default(fignum, ax):
fig = ax.figure
return fig, ax
def meanplot(x, mu, color='#3300FF', ax=None, fignum=None, linewidth=2,**kw):
_, axes = ax_default(fignum, ax)
return axes.plot(x,mu,color=color,linewidth=linewidth,**kw)
def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, fignum=None, **kwargs):
def meanplot(x, mu, color="#3300FF", ax=None, fignum=None, linewidth=2, **kw):
_, axes = ax_default(fignum, ax)
return axes.plot(x, mu, color=color, linewidth=linewidth, **kw)
def gpplot(
x,
mu,
lower,
upper,
edgecol="#3300FF",
fillcol="#33CCFF",
ax=None,
fignum=None,
**kwargs
):
_, axes = ax_default(fignum, ax)
mu = mu.flatten()
@ -27,51 +40,62 @@ def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, f
plots = []
#here's the mean
# here's the mean
plots.append(meanplot(x, mu, edgecol, axes))
#here's the box
kwargs['linewidth']=0.5
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 0.3
plots.append(axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs))
# here's the box
kwargs["linewidth"] = 0.5
if not "alpha" in kwargs.keys():
kwargs["alpha"] = 0.3
plots.append(
axes.fill(
np.hstack((x, x[::-1])),
np.hstack((upper, lower[::-1])),
color=fillcol,
**kwargs
)
)
#this is the edge:
plots.append(meanplot(x, upper,color=edgecol, linewidth=0.2, ax=axes))
plots.append(meanplot(x, lower,color=edgecol, linewidth=0.2, ax=axes))
# this is the edge:
plots.append(meanplot(x, upper, color=edgecol, linewidth=0.2, ax=axes))
plots.append(meanplot(x, lower, color=edgecol, linewidth=0.2, ax=axes))
return plots
def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs):
_, ax = ax_default(fignum, ax)
plots = []
#here's the box
if 'linewidth' not in kwargs:
kwargs['linewidth'] = 0.5
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 1./(len(percentiles))
# here's the box
if "linewidth" not in kwargs:
kwargs["linewidth"] = 0.5
if not "alpha" in kwargs.keys():
kwargs["alpha"] = 1.0 / (len(percentiles))
# pop where from kwargs
where = kwargs.pop('where') if 'where' in kwargs else None
where = kwargs.pop("where") if "where" in kwargs else None
# pop interpolate, which we actually do not do here!
if 'interpolate' in kwargs: kwargs.pop('interpolate')
if "interpolate" in kwargs:
kwargs.pop("interpolate")
def pairwise(inlist):
l = len(inlist)
for i in range(int(np.ceil(l/2.))):
yield inlist[:][i], inlist[:][(l-1)-i]
for i in range(int(np.ceil(l / 2.0))):
yield inlist[:][i], inlist[:][(l - 1) - i]
polycol = []
for y1, y2 in pairwise(percentiles):
import matplotlib.mlab as mlab
# Handle united data, such as dates
ax._process_unit_info(xdata=x, ydata=y1)
ax._process_unit_info(ydata=y2)
# Convert the arrays so we can work with them
from numpy import ma
x = ma.masked_invalid(ax.convert_xunits(x))
y1 = ma.masked_invalid(ax.convert_yunits(y1))
y2 = ma.masked_invalid(ax.convert_yunits(y2))
@ -103,7 +127,7 @@ def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs):
continue
N = len(xslice)
X = np.zeros((2 * N + 2, 2), np.float)
X = np.zeros((2 * N + 2, 2), float)
# the purpose of the next two lines is for when y2 is a
# scalar like 0 and we want the fill to go all the way
@ -114,19 +138,21 @@ def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs):
X[0] = start
X[N + 1] = end
X[1:N + 1, 0] = xslice
X[1:N + 1, 1] = y1slice
X[N + 2:, 0] = xslice[::-1]
X[N + 2:, 1] = y2slice[::-1]
X[1 : N + 1, 0] = xslice
X[1 : N + 1, 1] = y1slice
X[N + 2 :, 0] = xslice[::-1]
X[N + 2 :, 1] = y2slice[::-1]
polys.append(X)
polycol.extend(polys)
from matplotlib.collections import PolyCollection
plots.append(PolyCollection(polycol, **kwargs))
ax.add_collection(plots[-1], autolim=True)
ax.autoscale_view()
return plots
def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs):
_, axes = ax_default(fignum, ax)
@ -138,17 +164,19 @@ def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs):
plots = []
if edgecol is None:
edgecol='#3300FF'
edgecol = "#3300FF"
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 1.
if not "alpha" in kwargs.keys():
kwargs["alpha"] = 1.0
if not "lw" in kwargs.keys():
kwargs["lw"] = 1.0
if not 'lw' in kwargs.keys():
kwargs['lw'] = 1.
plots.append(axes.errorbar(x,mu,yerr=np.vstack([mu-lower,upper-mu]),color=edgecol,**kwargs))
plots.append(
axes.errorbar(
x, mu, yerr=np.vstack([mu - lower, upper - mu]), color=edgecol, **kwargs
)
)
plots[-1][0].remove()
return plots
@ -156,53 +184,60 @@ def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs):
def removeRightTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_yticklines()):
if i%2 == 1: # odd indices
if i % 2 == 1: # odd indices
line.set_visible(False)
def removeUpperTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_xticklines()):
if i%2 == 1: # odd indices
if i % 2 == 1: # odd indices
line.set_visible(False)
def fewerXticks(ax=None,divideby=2):
def fewerXticks(ax=None, divideby=2):
ax = ax or plt.gca()
ax.set_xticks(ax.get_xticks()[::divideby])
def x_frame1D(X,plot_limits=None,resolution=None):
def x_frame1D(X, plot_limits=None, resolution=None):
"""
Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits
"""
assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs"
assert X.shape[1] == 1, "x_frame1D is defined for one-dimensional inputs"
if plot_limits is None:
from ...core.parameterization.variational import VariationalPosterior
if isinstance(X, VariationalPosterior):
xmin,xmax = X.mean.min(0),X.mean.max(0)
xmin, xmax = X.mean.min(0), X.mean.max(0)
else:
xmin,xmax = X.min(0),X.max(0)
xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin)
elif len(plot_limits)==2:
xmin, xmax = X.min(0), X.max(0)
xmin, xmax = xmin - 0.2 * (xmax - xmin), xmax + 0.2 * (xmax - xmin)
elif len(plot_limits) == 2:
xmin, xmax = plot_limits
else:
raise ValueError("Bad limits for plotting")
Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None]
Xnew = np.linspace(xmin, xmax, resolution or 200)[:, None]
return Xnew, xmin, xmax
def x_frame2D(X,plot_limits=None,resolution=None):
def x_frame2D(X, plot_limits=None, resolution=None):
"""
Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits
"""
assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs"
assert X.shape[1] == 2, "x_frame2D is defined for two-dimensional inputs"
if plot_limits is None:
xmin,xmax = X.min(0),X.max(0)
xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin)
elif len(plot_limits)==2:
xmin, xmax = X.min(0), X.max(0)
xmin, xmax = xmin - 0.2 * (xmax - xmin), xmax + 0.2 * (xmax - xmin)
elif len(plot_limits) == 2:
xmin, xmax = plot_limits
else:
raise ValueError("Bad limits for plotting")
resolution = resolution or 50
xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution]
Xnew = np.vstack((xx.flatten(),yy.flatten())).T
xx, yy = np.mgrid[
xmin[0] : xmax[0] : 1j * resolution, xmin[1] : xmax[1] : 1j * resolution
]
Xnew = np.vstack((xx.flatten(), yy.flatten())).T
return Xnew, xx, yy, xmin, xmax

View file

@ -1,4 +1,4 @@
#===============================================================================
# ===============================================================================
# Copyright (c) 2015, Max Zwiessele
# All rights reserved.
#
@ -26,7 +26,7 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#===============================================================================
# ===============================================================================
import numpy as np
from matplotlib import pyplot as plt
from ..abstract_plotting_library import AbstractPlottingLibrary
@ -37,6 +37,7 @@ from .controllers import ImshowController, ImAnnotateController
import itertools
from .util import legend_ontop
class MatplotlibPlots(AbstractPlottingLibrary):
def __init__(self):
super(MatplotlibPlots, self).__init__()
@ -49,54 +50,86 @@ class MatplotlibPlots(AbstractPlottingLibrary):
fig.gridspec = plt.GridSpec(rows, cols, **gridspec_kwargs)
return fig
def new_canvas(self, figure=None, row=1, col=1, projection='2d', xlabel=None, ylabel=None, zlabel=None, title=None, xlim=None, ylim=None, zlim=None, **kwargs):
if projection == '3d':
def new_canvas(
self,
figure=None,
row=1,
col=1,
projection="2d",
xlabel=None,
ylabel=None,
zlabel=None,
title=None,
xlim=None,
ylim=None,
zlim=None,
**kwargs
):
if projection == "3d":
from mpl_toolkits.mplot3d import Axes3D
elif projection == '2d':
elif projection == "2d":
projection = None
if 'ax' in kwargs:
ax = kwargs.pop('ax')
if "ax" in kwargs:
ax = kwargs.pop("ax")
else:
if figure is not None:
fig = figure
elif 'num' in kwargs and 'figsize' in kwargs:
fig = self.figure(num=kwargs.pop('num'), figsize=kwargs.pop('figsize'))
elif 'num' in kwargs:
fig = self.figure(num=kwargs.pop('num'))
elif 'figsize' in kwargs:
fig = self.figure(figsize=kwargs.pop('figsize'))
elif "num" in kwargs and "figsize" in kwargs:
fig = self.figure(num=kwargs.pop("num"), figsize=kwargs.pop("figsize"))
elif "num" in kwargs:
fig = self.figure(num=kwargs.pop("num"))
elif "figsize" in kwargs:
fig = self.figure(figsize=kwargs.pop("figsize"))
else:
fig = self.figure()
#if hasattr(fig, 'rows') and hasattr(fig, 'cols'):
ax = fig.add_subplot(fig.gridspec[row-1, col-1], projection=projection)
# if hasattr(fig, 'rows') and hasattr(fig, 'cols'):
ax = fig.add_subplot(fig.gridspec[row - 1, col - 1], projection=projection)
if xlim is not None: ax.set_xlim(xlim)
if ylim is not None: ax.set_ylim(ylim)
if xlabel is not None: ax.set_xlabel(xlabel)
if ylabel is not None: ax.set_ylabel(ylabel)
if title is not None: ax.set_title(title)
if projection == '3d':
if zlim is not None: ax.set_zlim(zlim)
if zlabel is not None: ax.set_zlabel(zlabel)
if xlim is not None:
ax.set_xlim(xlim)
if ylim is not None:
ax.set_ylim(ylim)
if xlabel is not None:
ax.set_xlabel(xlabel)
if ylabel is not None:
ax.set_ylabel(ylabel)
if title is not None:
ax.set_title(title)
if projection == "3d":
if zlim is not None:
ax.set_zlim(zlim)
if zlabel is not None:
ax.set_zlabel(zlabel)
return ax, kwargs
def add_to_canvas(self, ax, plots, legend=False, title=None, **kwargs):
#ax.autoscale_view()
fontdict=dict(family='sans-serif', weight='light', size=9)
# ax.autoscale_view()
fontdict = dict(family="sans-serif", weight="light", size=9)
if legend is True:
ax.legend(*ax.get_legend_handles_labels())
elif legend >= 1:
#ax.legend(prop=fontdict)
# ax.legend(prop=fontdict)
legend_ontop(ax, ncol=legend, fontdict=fontdict)
if title is not None: ax.figure.suptitle(title)
if title is not None:
ax.figure.suptitle(title)
return plots
def show_canvas(self, ax, **kwargs):
ax.figure.canvas.draw()
return ax.figure
def scatter(self, ax, X, Y, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, marker='o', **kwargs):
def scatter(
self,
ax,
X,
Y,
Z=None,
color=Tango.colorsHex["mediumBlue"],
label=None,
marker="o",
**kwargs
):
if Z is not None:
return ax.scatter(X, Y, c=color, zs=Z, label=label, marker=marker, **kwargs)
return ax.scatter(X, Y, c=color, label=label, marker=marker, **kwargs)
@ -106,129 +139,258 @@ class MatplotlibPlots(AbstractPlottingLibrary):
return ax.plot(X, Y, color=color, zs=Z, label=label, **kwargs)
return ax.plot(X, Y, color=color, label=label, **kwargs)
def plot_axis_lines(self, ax, X, color=Tango.colorsHex['darkRed'], label=None, **kwargs):
def plot_axis_lines(
self, ax, X, color=Tango.colorsHex["darkRed"], label=None, **kwargs
):
from matplotlib import transforms
from matplotlib.path import Path
if 'marker' not in kwargs:
kwargs['marker'] = Path([[-.2,0.], [-.2,.5], [0.,1.], [.2,.5], [.2,0.], [-.2,0.]],
[Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
if 'transform' not in kwargs:
if "marker" not in kwargs:
kwargs["marker"] = Path(
[
[-0.2, 0.0],
[-0.2, 0.5],
[0.0, 1.0],
[0.2, 0.5],
[0.2, 0.0],
[-0.2, 0.0],
],
[
Path.MOVETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.CLOSEPOLY,
],
)
if "transform" not in kwargs:
if X.shape[1] == 1:
kwargs['transform'] = transforms.blended_transform_factory(ax.transData, ax.transAxes)
kwargs["transform"] = transforms.blended_transform_factory(
ax.transData, ax.transAxes
)
if X.shape[1] == 2:
return ax.scatter(X[:,0], X[:,1], ax.get_zlim()[0], c=color, label=label, **kwargs)
return ax.scatter(
X[:, 0], X[:, 1], ax.get_zlim()[0], c=color, label=label, **kwargs
)
return ax.scatter(X, np.zeros_like(X), c=color, label=label, **kwargs)
def barplot(self, ax, x, height, width=0.8, bottom=0, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
if 'align' not in kwargs:
kwargs['align'] = 'center'
return ax.bar(x=x, height=height, width=width,
bottom=bottom, label=label, color=color,
**kwargs)
def barplot(
self,
ax,
x,
height,
width=0.8,
bottom=0,
color=Tango.colorsHex["mediumBlue"],
label=None,
**kwargs
):
if "align" not in kwargs:
kwargs["align"] = "center"
return ax.bar(
x=x,
height=height,
width=width,
bottom=bottom,
label=label,
color=color,
**kwargs
)
def xerrorbar(self, ax, X, Y, error, color=Tango.colorsHex['darkRed'], label=None, **kwargs):
if not('linestyle' in kwargs or 'ls' in kwargs):
kwargs['ls'] = 'none'
#if Z is not None:
def xerrorbar(
self, ax, X, Y, error, color=Tango.colorsHex["darkRed"], label=None, **kwargs
):
if not ("linestyle" in kwargs or "ls" in kwargs):
kwargs["ls"] = "none"
# if Z is not None:
# return ax.errorbar(X, Y, Z, xerr=error, ecolor=color, label=label, **kwargs)
return ax.errorbar(X, Y, xerr=error, ecolor=color, label=label, **kwargs)
def yerrorbar(self, ax, X, Y, error, color=Tango.colorsHex['darkRed'], label=None, **kwargs):
if not('linestyle' in kwargs or 'ls' in kwargs):
kwargs['ls'] = 'none'
#if Z is not None:
def yerrorbar(
self, ax, X, Y, error, color=Tango.colorsHex["darkRed"], label=None, **kwargs
):
if not ("linestyle" in kwargs or "ls" in kwargs):
kwargs["ls"] = "none"
# if Z is not None:
# return ax.errorbar(X, Y, Z, yerr=error, ecolor=color, label=label, **kwargs)
return ax.errorbar(X, Y, yerr=error, ecolor=color, label=label, **kwargs)
def imshow(self, ax, X, extent=None, label=None, vmin=None, vmax=None, **imshow_kwargs):
if 'origin' not in imshow_kwargs:
imshow_kwargs['origin'] = 'lower'
#xmin, xmax, ymin, ymax = extent
#xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1])
#xmin, xmax, ymin, ymax = extent = xmin-xoffset, xmax+xoffset, ymin-yoffset, ymax+yoffset
return ax.imshow(X, label=label, extent=extent, vmin=vmin, vmax=vmax, **imshow_kwargs)
def imshow(
self, ax, X, extent=None, label=None, vmin=None, vmax=None, **imshow_kwargs
):
if "origin" not in imshow_kwargs:
imshow_kwargs["origin"] = "lower"
# xmin, xmax, ymin, ymax = extent
# xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1])
# xmin, xmax, ymin, ymax = extent = xmin-xoffset, xmax+xoffset, ymin-yoffset, ymax+yoffset
return ax.imshow(
X, label=label, extent=extent, vmin=vmin, vmax=vmax, **imshow_kwargs
)
def imshow_interact(self, ax, plot_function, extent, label=None, resolution=None, vmin=None, vmax=None, **imshow_kwargs):
if imshow_kwargs is None: imshow_kwargs = {}
if 'origin' not in imshow_kwargs:
imshow_kwargs['origin'] = 'lower'
return ImshowController(ax, plot_function, extent, resolution=resolution, vmin=vmin, vmax=vmax, **imshow_kwargs)
def imshow_interact(
self,
ax,
plot_function,
extent,
label=None,
resolution=None,
vmin=None,
vmax=None,
**imshow_kwargs
):
if imshow_kwargs is None:
imshow_kwargs = {}
if "origin" not in imshow_kwargs:
imshow_kwargs["origin"] = "lower"
return ImshowController(
ax,
plot_function,
extent,
resolution=resolution,
vmin=vmin,
vmax=vmax,
**imshow_kwargs
)
def annotation_heatmap(self, ax, X, annotation, extent=None, label=None, imshow_kwargs=None, **annotation_kwargs):
if imshow_kwargs is None: imshow_kwargs = {}
if 'origin' not in imshow_kwargs:
imshow_kwargs['origin'] = 'lower'
if ('ha' not in annotation_kwargs) and ('horizontalalignment' not in annotation_kwargs):
annotation_kwargs['ha'] = 'center'
if ('va' not in annotation_kwargs) and ('verticalalignment' not in annotation_kwargs):
annotation_kwargs['va'] = 'center'
def annotation_heatmap(
self,
ax,
X,
annotation,
extent=None,
label=None,
imshow_kwargs=None,
**annotation_kwargs
):
if imshow_kwargs is None:
imshow_kwargs = {}
if "origin" not in imshow_kwargs:
imshow_kwargs["origin"] = "lower"
if ("ha" not in annotation_kwargs) and (
"horizontalalignment" not in annotation_kwargs
):
annotation_kwargs["ha"] = "center"
if ("va" not in annotation_kwargs) and (
"verticalalignment" not in annotation_kwargs
):
annotation_kwargs["va"] = "center"
imshow = self.imshow(ax, X, extent, label, **imshow_kwargs)
if extent is None:
extent = (0, X.shape[0], 0, X.shape[1])
xmin, xmax, ymin, ymax = extent
xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1])
xoffset, yoffset = (xmax - xmin) / (2.0 * X.shape[0]), (ymax - ymin) / (
2.0 * X.shape[1]
)
xlin = np.linspace(xmin, xmax, X.shape[0], endpoint=False)
ylin = np.linspace(ymin, ymax, X.shape[1], endpoint=False)
annotations = []
for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin)):
annotations.append(ax.text(x+xoffset, y+yoffset, "{}".format(annotation[j, i]), **annotation_kwargs))
annotations.append(
ax.text(
x + xoffset,
y + yoffset,
"{}".format(annotation[j, i]),
**annotation_kwargs
)
)
return imshow, annotations
def annotation_heatmap_interact(self, ax, plot_function, extent, label=None, resolution=15, imshow_kwargs=None, **annotation_kwargs):
if imshow_kwargs is None: imshow_kwargs = {}
if 'origin' not in imshow_kwargs:
imshow_kwargs['origin'] = 'lower'
return ImAnnotateController(ax, plot_function, extent, resolution=resolution, imshow_kwargs=imshow_kwargs or {}, **annotation_kwargs)
def annotation_heatmap_interact(
self,
ax,
plot_function,
extent,
label=None,
resolution=15,
imshow_kwargs=None,
**annotation_kwargs
):
if imshow_kwargs is None:
imshow_kwargs = {}
if "origin" not in imshow_kwargs:
imshow_kwargs["origin"] = "lower"
return ImAnnotateController(
ax,
plot_function,
extent,
resolution=resolution,
imshow_kwargs=imshow_kwargs or {},
**annotation_kwargs
)
def contour(self, ax, X, Y, C, levels=20, label=None, **kwargs):
return ax.contour(X, Y, C, levels=np.linspace(C.min(), C.max(), levels), label=label, **kwargs)
return ax.contour(
X, Y, C, levels=np.linspace(C.min(), C.max(), levels), label=label, **kwargs
)
def surface(self, ax, X, Y, Z, color=None, label=None, **kwargs):
return ax.plot_surface(X, Y, Z, label=label, **kwargs)
def fill_between(self, ax, X, lower, upper, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
def fill_between(
self,
ax,
X,
lower,
upper,
color=Tango.colorsHex["mediumBlue"],
label=None,
**kwargs
):
return ax.fill_between(X, lower, upper, facecolor=color, label=label, **kwargs)
def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
def fill_gradient(
self,
canvas,
X,
percentiles,
color=Tango.colorsHex["mediumBlue"],
label=None,
**kwargs
):
ax = canvas
plots = []
if 'edgecolors' not in kwargs:
kwargs['edgecolors'] = 'none'
if "edgecolors" not in kwargs:
kwargs["edgecolors"] = "none"
if 'facecolors' in kwargs:
color = kwargs.pop('facecolors')
if "facecolors" in kwargs:
color = kwargs.pop("facecolors")
if 'array' in kwargs:
array = kwargs.pop('array')
if "array" in kwargs:
array = kwargs.pop("array")
else:
array = 1.-np.abs(np.linspace(-.97, .97, len(percentiles)-1))
array = 1.0 - np.abs(np.linspace(-0.97, 0.97, len(percentiles) - 1))
if 'alpha' in kwargs:
alpha = kwargs.pop('alpha')
if "alpha" in kwargs:
alpha = kwargs.pop("alpha")
else:
alpha = .8
alpha = 0.8
if 'cmap' in kwargs:
cmap = kwargs.pop('cmap')
if "cmap" in kwargs:
cmap = kwargs.pop("cmap")
else:
cmap = LinearSegmentedColormap.from_list('WhToColor', (color, color), N=array.size)
cmap = LinearSegmentedColormap.from_list(
"WhToColor", (color, color), N=array.size
)
cmap._init()
cmap._lut[:-3, -1] = alpha*array
cmap._lut[:-3, -1] = alpha * array
kwargs['facecolors'] = [cmap(i) for i in np.linspace(0,1,cmap.N)]
kwargs["facecolors"] = [cmap(i) for i in np.linspace(0, 1, cmap.N)]
# pop where from kwargs
where = kwargs.pop('where') if 'where' in kwargs else None
where = kwargs.pop("where") if "where" in kwargs else None
# pop interpolate, which we actually do not do here!
if 'interpolate' in kwargs: kwargs.pop('interpolate')
if "interpolate" in kwargs:
kwargs.pop("interpolate")
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
from itertools import tee
#try:
# try:
# from itertools import izip as zip
#except ImportError:
# except ImportError:
# pass
a, b = tee(iterable)
next(b, None)
@ -245,6 +407,7 @@ class MatplotlibPlots(AbstractPlottingLibrary):
ax._process_unit_info(ydata=y2)
# Convert the arrays so we can work with them
from numpy import ma
x = ma.masked_invalid(ax.convert_xunits(X))
y1 = ma.masked_invalid(ax.convert_yunits(y1))
y2 = ma.masked_invalid(ax.convert_yunits(y2))
@ -263,6 +426,7 @@ class MatplotlibPlots(AbstractPlottingLibrary):
raise ValueError("Argument dimensions are incompatible")
from functools import reduce
mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
if mask is not ma.nomask:
where &= ~mask
@ -277,7 +441,7 @@ class MatplotlibPlots(AbstractPlottingLibrary):
continue
N = len(xslice)
p = np.zeros((2 * N + 2, 2), np.float)
p = np.zeros((2 * N + 2, 2), float)
# the purpose of the next two lines is for when y2 is a
# scalar like 0 and we want the fill to go all the way
@ -288,16 +452,17 @@ class MatplotlibPlots(AbstractPlottingLibrary):
p[0] = start
p[N + 1] = end
p[1:N + 1, 0] = xslice
p[1:N + 1, 1] = y1slice
p[N + 2:, 0] = xslice[::-1]
p[N + 2:, 1] = y2slice[::-1]
p[1 : N + 1, 0] = xslice
p[1 : N + 1, 1] = y1slice
p[N + 2 :, 0] = xslice[::-1]
p[N + 2 :, 1] = y2slice[::-1]
polys.append(p)
polycol.extend(polys)
from matplotlib.collections import PolyCollection
if 'zorder' not in kwargs:
kwargs['zorder'] = 0
if "zorder" not in kwargs:
kwargs["zorder"] = 0
plots.append(PolyCollection(polycol, label=label, **kwargs))
ax.add_collection(plots[-1], autolim=True)
ax.autoscale_view()

View file

@ -24,7 +24,7 @@ class TestObservationModels:
self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None]
self.num_points = self.X.shape[0]
self.f = np.random.rand(self.N, 1)
self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None]
self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=int)[:, None]
# self.binary_Y[self.binary_Y == 0.0] = -1.0
self.positive_Y = np.exp(self.Y.copy())

View file

@ -136,7 +136,7 @@ class TestNoiseModels:
noise = np.random.randn(*self.X[:, 0].shape) * self.real_std
self.Y = (np.sin(self.X[:, 0] * 2 * np.pi) + noise)[:, None]
self.f = np.random.rand(self.N, 1)
self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None]
self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=int)[:, None]
self.binary_Y[self.binary_Y == 0.0] = -1.0
self.positive_Y = np.exp(self.Y.copy())
tmp = (

View file

@ -1432,8 +1432,8 @@ class TestGradient:
y = np.zeros((D * N_train,))
x_test = np.zeros((D * (N - N_train),))
y_test = np.zeros((D * (N - N_train),))
indexD = np.zeros((D * N_train), dtype=np.int)
indexD_test = np.zeros((D * (N - N_train)), dtype=np.int)
indexD = np.zeros((D * N_train), dtype=int)
indexD_test = np.zeros((D * (N - N_train)), dtype=int)
offset_all = 0
offset_train = 0

View file

@ -53,7 +53,7 @@ class TestPickleSupport(ListDictTestCase):
assert par.param_array.tolist() == pcopy.param_array.tolist()
np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full)
assert str(par) == str(pcopy)
assert par.param_array != pcopy.param_array
assert np.all(par.param_array != pcopy.param_array)
assert par.gradient_full != pcopy.gradient_full
assert pcopy.checkgrad()
assert np.any(pcopy.gradient != 0.0)
@ -72,7 +72,7 @@ class TestPickleSupport(ListDictTestCase):
np.testing.assert_allclose(par.param_array, pcopy.param_array)
np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full)
assert str(par) == str(pcopy)
assert par.param_array != pcopy.param_array
assert np.all(par.param_array != pcopy.param_array)
assert par.gradient_full != pcopy.gradient_full
assert pcopy.checkgrad()
assert np.any(pcopy.gradient != 0.0)
@ -97,7 +97,7 @@ class TestPickleSupport(ListDictTestCase):
assert par.param_array.tolist() == pcopy.param_array.tolist()
assert par.gradient_full.tolist() == pcopy.gradient_full.tolist()
assert str(par) == str(pcopy)
assert par.param_array != pcopy.param_array
assert np.all(par.param_array != pcopy.param_array)
assert par.gradient_full != pcopy.gradient_full
with tempfile.TemporaryFile("w+b") as f:
par.pickle(f)
@ -116,7 +116,7 @@ class TestPickleSupport(ListDictTestCase):
assert par.param_array.tolist() == pcopy.param_array.tolist()
assert par.gradient_full.tolist() == pcopy.gradient_full.tolist()
assert str(par) == str(pcopy)
assert par.param_array != pcopy.param_array
assert np.all(par.param_array != pcopy.param_array)
assert par.gradient_full != pcopy.gradient_full
assert par.checkgrad()
assert pcopy.checkgrad()

View file

@ -2,7 +2,8 @@
# Licensed under the BSD 3-clause license (see LICENSE.txt)
import numpy as np
def conf_matrix(p,labels,names=['1','0'],threshold=.5,show=True):
def conf_matrix(p, labels, names=["1", "0"], threshold=0.5, show=True):
"""
Returns error rate and true/false positives in a binary classification problem
- Actual classes are displayed by column.
@ -16,18 +17,18 @@ def conf_matrix(p,labels,names=['1','0'],threshold=.5,show=True):
:type show: False|True
"""
assert p.size == labels.size, "Arrays p and labels have different dimensions."
decision = np.ones((labels.size,1))
decision[p<threshold] = 0
decision = np.ones((labels.size, 1))
decision[p < threshold] = 0
diff = decision - labels
false_0 = diff[diff == -1].size
false_1 = diff[diff == 1].size
true_1 = np.sum(decision[diff ==0])
true_1 = np.sum(decision[diff == 0])
true_0 = labels.size - true_1 - false_0 - false_1
error = (false_1 + false_0)/np.float(labels.size)
error = (false_1 + false_0) / float(labels.size)
if show:
print(100. - error * 100,'% instances correctly classified')
print('%-10s| %-10s| %-10s| ' % ('',names[0],names[1]))
print('----------|------------|------------|')
print('%-10s| %-10s| %-10s| ' % (names[0],true_1,false_0))
print('%-10s| %-10s| %-10s| ' % (names[1],false_1,true_0))
return error,true_1, false_1, true_0, false_0
print(100.0 - error * 100, "% instances correctly classified")
print("%-10s| %-10s| %-10s| " % ("", names[0], names[1]))
print("----------|------------|------------|")
print("%-10s| %-10s| %-10s| " % (names[0], true_1, false_0))
print("%-10s| %-10s| %-10s| " % (names[1], false_1, true_0))
return error, true_1, false_1, true_0, false_0

View file

@ -2,6 +2,7 @@ import numpy as np
import warnings
import GPy
def index_to_slices(index):
"""
take a numpy array of integers (index) and return a nested list of slices such that the slices describe the start, stop points for each integer in the index.
@ -16,28 +17,35 @@ def index_to_slices(index):
returns
>>> [[slice(0,2,None),slice(4,5,None)],[slice(2,4,None),slice(8,10,None)],[slice(5,8,None)]]
"""
if len(index)==0:
return[]
if len(index) == 0:
return []
#contruct the return structure
ind = np.asarray(index,dtype=np.int)
ret = [[] for i in range(ind.max()+1)]
# contruct the return structure
ind = np.asarray(index, dtype=int)
ret = [[] for i in range(ind.max() + 1)]
#find the switchpoints
ind_ = np.hstack((ind,ind[0]+ind[-1]+1))
switchpoints = np.nonzero(ind_ - np.roll(ind_,+1))[0]
# find the switchpoints
ind_ = np.hstack((ind, ind[0] + ind[-1] + 1))
switchpoints = np.nonzero(ind_ - np.roll(ind_, +1))[0]
[ret[ind_i].append(slice(*indexes_i)) for ind_i,indexes_i in zip(ind[switchpoints[:-1]],zip(switchpoints,switchpoints[1:]))]
[
ret[ind_i].append(slice(*indexes_i))
for ind_i, indexes_i in zip(
ind[switchpoints[:-1]], zip(switchpoints, switchpoints[1:])
)
]
return ret
def get_slices(input_list):
num_outputs = len(input_list)
_s = [0] + [ _x.shape[0] for _x in input_list ]
_s = [0] + [_x.shape[0] for _x in input_list]
_s = np.cumsum(_s)
slices = [slice(a,b) for a,b in zip(_s[:-1],_s[1:])]
slices = [slice(a, b) for a, b in zip(_s[:-1], _s[1:])]
return slices
def build_XY(input_list,output_list=None,index=None):
def build_XY(input_list, output_list=None, index=None):
num_outputs = len(input_list)
if output_list is not None:
assert num_outputs == len(output_list)
@ -47,27 +55,35 @@ def build_XY(input_list,output_list=None,index=None):
if index is not None:
assert len(index) == num_outputs
I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,index)] )
I = np.hstack([np.repeat(j, _x.shape[0]) for _x, j in zip(input_list, index)])
else:
I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,range(num_outputs))] )
I = np.hstack(
[np.repeat(j, _x.shape[0]) for _x, j in zip(input_list, range(num_outputs))]
)
X = np.vstack(input_list)
X = np.hstack([X,I[:,None]])
X = np.hstack([X, I[:, None]])
return X,Y,I[:,None]#slices
return X, Y, I[:, None] # slices
def build_likelihood(Y_list,noise_index,likelihoods_list=None):
def build_likelihood(Y_list, noise_index, likelihoods_list=None):
Ny = len(Y_list)
if likelihoods_list is None:
likelihoods_list = [GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for y,j in zip(Y_list,range(Ny))]
likelihoods_list = [
GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" % j)
for y, j in zip(Y_list, range(Ny))
]
else:
assert len(likelihoods_list) == Ny
#likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list, noise_index=noise_index)
likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list)
# likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list, noise_index=noise_index)
likelihood = GPy.likelihoods.mixed_noise.MixedNoise(
likelihoods_list=likelihoods_list
)
return likelihood
def ICM(input_dim, num_outputs, kernel, W_rank=1,W=None,kappa=None,name='ICM'):
def ICM(input_dim, num_outputs, kernel, W_rank=1, W=None, kappa=None, name="ICM"):
"""
Builds a kernel for an Intrinsic Coregionalization Model
@ -80,13 +96,26 @@ def ICM(input_dim, num_outputs, kernel, W_rank=1,W=None,kappa=None,name='ICM'):
"""
if kernel.input_dim != input_dim:
kernel.input_dim = input_dim
warnings.warn("kernel's input dimension overwritten to fit input_dim parameter.")
warnings.warn(
"kernel's input dimension overwritten to fit input_dim parameter."
)
K = kernel.prod(GPy.kern.Coregionalize(1, num_outputs, active_dims=[input_dim], rank=W_rank,W=W,kappa=kappa,name='B'),name=name)
K = kernel.prod(
GPy.kern.Coregionalize(
1,
num_outputs,
active_dims=[input_dim],
rank=W_rank,
W=W,
kappa=kappa,
name="B",
),
name=name,
)
return K
def LCM(input_dim, num_outputs, kernels_list, W_rank=1,name='ICM'):
def LCM(input_dim, num_outputs, kernels_list, W_rank=1, name="ICM"):
"""
Builds a kernel for an Linear Coregionalization Model
@ -98,15 +127,15 @@ def LCM(input_dim, num_outputs, kernels_list, W_rank=1,name='ICM'):
:type W_rank: integer
"""
Nk = len(kernels_list)
K = ICM(input_dim,num_outputs,kernels_list[0],W_rank,name='%s%s' %(name,0))
K = ICM(input_dim, num_outputs, kernels_list[0], W_rank, name="%s%s" % (name, 0))
j = 1
for kernel in kernels_list[1:]:
K += ICM(input_dim,num_outputs,kernel,W_rank,name='%s%s' %(name,j))
K += ICM(input_dim, num_outputs, kernel, W_rank, name="%s%s" % (name, j))
j += 1
return K
def Private(input_dim, num_outputs, kernel, output, kappa=None,name='X'):
def Private(input_dim, num_outputs, kernel, output, kappa=None, name="X"):
"""
Builds a kernel for an Intrinsic Coregionalization Model
@ -117,7 +146,7 @@ def Private(input_dim, num_outputs, kernel, output, kappa=None,name='X'):
:param W_rank: number tuples of the corregionalization parameters 'W'
:type W_rank: integer
"""
K = ICM(input_dim,num_outputs,kernel,W_rank=1,kappa=kappa,name=name)
K = ICM(input_dim, num_outputs, kernel, W_rank=1, kappa=kappa, name=name)
K.B.W.fix(0)
_range = range(num_outputs)
_range.pop(output)