def l1_cross_distances(X, Y=None): """ Computes the nonzero componentwise L1 cross-distances between the vectors in X and Y. Args ---- X: array_like An array with shape (n_samples_X, n_features) Y: array_like An array with shape (n_samples_Y, n_features) Returns ------- D: array with shape (n_samples * (n_samples - 1) / 2, n_features) The array of componentwise L1 cross-distances. """ if Y is None: X = array2d(X) n_samples, n_features = X.shape n_nonzero_cross_dist = n_samples * (n_samples - 1) // 2 D = np.zeros((n_nonzero_cross_dist, n_features)) ll_1 = 0 for k in range(n_samples - 1): ll_0 = ll_1 ll_1 = ll_0 + n_samples - k - 1 D[ll_0:ll_1] = np.abs(X[k] - X[(k + 1):]) return D else: X = array2d(X) Y = array2d(Y) n_samples_X, n_features_X = X.shape n_samples_Y, n_features_Y = Y.shape if n_features_X != n_features_Y: raise ValueError("X and Y must have the same dimensions.") n_features = n_features_X n_nonzero_cross_dist = n_samples_X * n_samples_Y D = np.zeros((n_nonzero_cross_dist, n_features)) ll_1 = 0 for k in range(n_samples_X): ll_0 = ll_1 ll_1 = ll_0 + n_samples_Y# - k - 1 D[ll_0:ll_1] = np.abs(X[k] - Y) return D
def _check_params(self): """ Perform sanity checks on all parameters. """ # Check regression model if not callable(self.regr): if self.regr in self._regression_types: self.regr = self._regression_types[self.regr] else: raise ValueError( f"regr should be one of {self._regression_types.keys()} or " f"callable, {self.regr} was given.") # Check rho regression model if not callable(self.rho_regr): if self.rho_regr in self._regression_types: self.rho_regr = self._regression_types[self.rho_regr] else: raise ValueError( f"regr should be one of {self._regression_types.keys()} or " f"callable, {self.rho_regr} was given.") for i in range(self.nlevel): # Check correlation parameters if self.theta[i] is not None: self.theta[i] = array2d(self.theta[i]) if np.any(self.theta[i] <= 0): raise ValueError("theta must be strictly positive.") if self.theta0[i] is not None: self.theta0[i] = array2d(self.theta0[i]) if np.any(self.theta0[i] <= 0): raise ValueError("theta0 must be strictly positive.") else: self.theta0[i] = array2d(self.n_features * [THETA0_DEFAULT]) lth = self.theta0[i].size if self.thetaL[i] is not None: self.thetaL[i] = array2d(self.thetaL[i]) if self.thetaL[i].size != lth: raise ValueError( "theta0 and thetaL must have the same length.") else: self.thetaL[i] = array2d(self.n_features * [THETAL_DEFAULT]) if self.thetaU[i] is not None: self.thetaU[i] = array2d(self.thetaU[i]) if self.thetaU[i].size != lth: raise ValueError( "theta0 and thetaU must have the same length.") else: self.thetaU[i] = array2d(self.n_features * [THETAU_DEFAULT]) if np.any(self.thetaL[i] <= 0) or np.any( self.thetaU[i] < self.thetaL[i]): raise ValueError( "The bounds must satisfy O < thetaL <= thetaU.") return
def _check_params(self): """ Perform sanity checks on all parameters. """ # Check regression model if not callable(self.regr): if self.regr in self._regression_types: self.regr = self._regression_types[self.regr] else: raise ValueError("regr should be one of %s or callable, " "%s was given." % (self._regression_types.keys(), self.regr)) # Check rho regression model if not callable(self.rho_regr): if self.rho_regr in self._regression_types: self.rho_regr = self._regression_types[self.rho_regr] else: raise ValueError("rho_regr should be one of %s or callable, " "%s was given." % (self._regression_types.keys(), self.rho_regr)) for i in range(self.nlevel): # Check correlation parameters if self.theta[i] is not None: self.theta[i] = array2d(self.theta[i]) if np.any(self.theta[i] <= 0): raise ValueError("theta0 must be strictly positive.") if self.theta0[i] is not None: self.theta0[i] = array2d(self.theta0[i]) if np.any(self.theta0[i] <= 0): raise ValueError("theta0 must be strictly positive.") else: self.theta0[i] = array2d(self.n_features * [THETA0_DEFAULT]) lth = self.theta0[i].size if self.thetaL[i] is not None: self.thetaL[i] = array2d(self.thetaL[i]) if self.thetaL[i].size != lth: raise ValueError("theta0 and thetaL must have the " "same length.") else: self.thetaL[i] = array2d(self.n_features * [THETAL_DEFAULT]) if self.thetaU[i] is not None: self.thetaU[i] = array2d(self.thetaU[i]) if self.thetaU[i].size != lth: raise ValueError("theta0 and thetaU must have the " "same length.") else: self.thetaU[i] = array2d(self.n_features * [THETAU_DEFAULT]) if np.any(self.thetaL[i] <= 0) or np.any(self.thetaU[i] < self.thetaL[i]): raise ValueError("The bounds must satisfy O < thetaL <= " "thetaU.") return
def predict(self, X, eval_MSE=True): """ Perform the predictions of the kriging model on X. Parameters ---------- X : array_like An array with shape (n_eval, n_features) giving the point(s) at which the prediction(s) should be made. eval_MSE : boolean, optional A boolean specifying whether the Mean Squared Error should be evaluated or not. Default assumes evalMSE is True. Returns ------- array_like An array with shape (n_eval, ) with the Best Linear Unbiased Prediction at X. If all_levels is set to True, an array with shape (n_eval, nlevel) giving the BLUP for all levels. array_like, optional (if eval_MSE is True) An array with shape (n_eval, ) with the Mean Squared Error at X. If all_levels is set to True, an array with shape (n_eval, nlevel) giving the MSE for all levels. """ X = array2d(X) nlevel = self.nlevel n_eval, n_features_X = X.shape # Calculate kriging mean and variance at level 0 mu = np.zeros((n_eval, nlevel)) f = self.regr(X) f0 = self.regr(X) dx = l1_cross_distances(X, Y=self.X[0]) # Get regression function and correlation F = self.F[0] C = self.C[0] beta = self.beta[0] Ft = solve_triangular(C, F, lower=True) yt = solve_triangular(C, self.y[0], lower=True) r_ = self.corr(self.theta[0], dx).reshape(n_eval, self.n_samples[0]) gamma = solve_triangular(C.T, yt - np.dot(Ft, beta), lower=False) # Scaled predictor mu[:, 0] = (np.dot(f, beta) + np.dot(r_, gamma)).ravel() if eval_MSE: self.sigma2_rho = nlevel * [None] MSE = np.zeros((n_eval, nlevel)) r_t = solve_triangular(C, r_.T, lower=True) G = self.G[0] u_ = solve_triangular(G.T, f.T - np.dot(Ft.T, r_t), lower=True) MSE[:, 0] = self.sigma2[0] * \ (1 - (r_t**2).sum(axis=0) + (u_**2).sum(axis=0)) # Calculate recursively kriging mean and variance at level i for i in range(1, nlevel): C = self.C[i] F = self.F[i] g = self.rho_regr(X) dx = l1_cross_distances(X, Y=self.X[i]) r_ = self.corr(self.theta[i], dx).reshape(n_eval, self.n_samples[i]) f = np.vstack((g.T * mu[:, i - 1], f0.T)) Ft = solve_triangular(C, F, lower=True) yt = solve_triangular(C, self.y[i], lower=True) r_t = solve_triangular(C, r_.T, lower=True) G = self.G[i] beta = self.beta[i] # scaled predictor mu[:, i] = (np.dot(f.T, beta) + np.dot(r_t.T, yt - np.dot(Ft, beta))).ravel() if eval_MSE: Q_ = (np.dot((yt - np.dot(Ft, beta)).T, yt - np.dot(Ft, beta)))[0, 0] u_ = solve_triangular(G.T, f - np.dot(Ft.T, r_t), lower=True) sigma2_rho = np.dot( g, self.sigma2[i] * linalg.inv(np.dot(G.T, G))[:self.q[i], :self.q[i]] + np.dot(beta[:self.q[i]], beta[:self.q[i]].T)) sigma2_rho = (sigma2_rho * g).sum(axis=1) MSE[:, i] = sigma2_rho * MSE[:, i - 1] \ + Q_ / (2 * (self.n_samples[i] - self.p[i] - self.q[i])) \ * (1 - (r_t**2).sum(axis=0)) \ + self.sigma2[i] * (u_**2).sum(axis=0) # scaled predictor for i in range(nlevel): # Predictor mu[:, i] = self.y_mean + self.y_std * mu[:, i] if eval_MSE: MSE[:, i] = self.y_std**2 * MSE[:, i] if eval_MSE: return mu[:, -1].reshape((n_eval, 1)), MSE[:, -1].reshape( (n_eval, 1)) else: return mu[:, -1].reshape((n_eval, 1))
def predict(self, X, eval_MSE=True): """ Perform the predictions of the kriging model on X. Parameters ---------- X : array_like An array with shape (n_eval, n_features) giving the point(s) at which the prediction(s) should be made. eval_MSE : boolean, optional A boolean specifying whether the Mean Squared Error should be evaluated or not. Default assumes evalMSE is True. Returns ------- array_like An array with shape (n_eval, ) with the Best Linear Unbiased Prediction at X. If all_levels is set to True, an array with shape (n_eval, nlevel) giving the BLUP for all levels. array_like, optional (if eval_MSE is True) An array with shape (n_eval, ) with the Mean Squared Error at X. If all_levels is set to True, an array with shape (n_eval, nlevel) giving the MSE for all levels. """ X = array2d(X) nlevel = self.nlevel n_eval, n_features_X = X.shape # Calculate kriging mean and variance at level 0 mu = np.zeros((n_eval, nlevel)) f = self.regr(X) f0 = self.regr(X) dx = l1_cross_distances(X, Y=self.X[0]) # Get regression function and correlation F = self.F[0] C = self.C[0] beta = self.beta[0] Ft = solve_triangular(C, F, lower=True) yt = solve_triangular(C, self.y[0], lower=True) r_ = self.corr(self.theta[0], dx).reshape(n_eval, self.n_samples[0]) gamma = solve_triangular(C.T, yt - np.dot(Ft, beta), lower=False) # Scaled predictor mu[:, 0] = (np.dot(f, beta) + np.dot(r_, gamma)).ravel() if eval_MSE: self.sigma2_rho = nlevel * [None] MSE = np.zeros((n_eval, nlevel)) r_t = solve_triangular(C, r_.T, lower=True) G = self.G[0] u_ = solve_triangular(G.T, f.T - np.dot(Ft.T, r_t), lower=True) MSE[:, 0] = self.sigma2[0] * \ (1 - (r_t**2).sum(axis=0) + (u_**2).sum(axis=0)) # Calculate recursively kriging mean and variance at level i for i in range(1, nlevel): C = self.C[i] F = self.F[i] g = self.rho_regr(X) dx = l1_cross_distances(X, Y=self.X[i]) r_ = self.corr(self.theta[i], dx).reshape( n_eval, self.n_samples[i]) f = np.vstack((g.T * mu[:, i - 1], f0.T)) Ft = solve_triangular(C, F, lower=True) yt = solve_triangular(C, self.y[i], lower=True) r_t = solve_triangular(C, r_.T, lower=True) G = self.G[i] beta = self.beta[i] # scaled predictor mu[:, i] = (np.dot(f.T, beta) + np.dot(r_t.T, yt - np.dot(Ft, beta))).ravel() if eval_MSE: Q_ = (np.dot((yt - np.dot(Ft, beta)).T, yt - np.dot(Ft, beta)))[0, 0] u_ = solve_triangular(G.T, f - np.dot(Ft.T, r_t), lower=True) sigma2_rho = np.dot(g, self.sigma2[ i] * linalg.inv(np.dot(G.T, G))[:self.q[i], :self.q[i]] + np.dot(beta[:self.q[i]], beta[:self.q[i]].T)) sigma2_rho = (sigma2_rho * g).sum(axis=1) MSE[:, i] = sigma2_rho * MSE[:, i - 1] \ + Q_ / (2 * (self.n_samples[i] - self.p[i] - self.q[i])) \ * (1 - (r_t**2).sum(axis=0)) \ + self.sigma2[i] * (u_**2).sum(axis=0) # scaled predictor for i in range(nlevel): # Predictor mu[:, i] = self.y_mean + self.y_std * mu[:, i] if eval_MSE: MSE[:, i] = self.y_std**2 * MSE[:, i] if eval_MSE: return mu[:, -1].reshape((n_eval, 1)), MSE[:, -1].reshape((n_eval, 1)) else: return mu[:, -1].reshape((n_eval, 1))