def predict_G(self,xTest,eval_MSE=True):
        """
        compute predictive mean and variance
        Input Parameters
        ----------
        xTest: the testing points 
        
        Returns
        -------
        mean, var
        """    
        if len(xTest.shape)==1: # 1d
            xTest=xTest.reshape((-1,self.X.shape[1]))
        
        # prevent singular matrix
        ur = unique_rows(self.X)
        X=self.X[ur]
        #Y=self.Y[ur]
        #G=self.G[ur]
    
        
        #print("only SE kernel is implemented")
        Euc_dist=euclidean_distances(xTest,xTest)
        KK_xTest_xTest=np.exp(-np.square(Euc_dist)/self.lengthscale)+np.eye(xTest.shape[0])*self.noise_delta
        
        Euc_dist_test_train=euclidean_distances(xTest,X)
        KK_xTest_xTrain=np.exp(-np.square(Euc_dist_test_train)/self.lengthscale)

        
        meanG=np.dot(KK_xTest_xTrain,self.alphaG)+np.sqrt(2*self.fstar) # non zero prior mean

        v=np.linalg.solve(self.L,KK_xTest_xTrain.T)
        varG=KK_xTest_xTest-np.dot(v.T,v)
        
        return meanG.ravel(),np.diag(varG)  
    def fit(self,X,Y,fstar=None,IsOptimize=0):
        """
        Fit Gaussian Process model

        Input Parameters
        ----------
        x: the observed points 
        y: the outcome y=f(x)
        
        """ 
        ur = unique_rows(X)
        X=X[ur]
        Y=Y[ur]
        
        self.X=X
        self.Y=Y
        if fstar is not None:
            self.fstar=fstar
        self.G=np.sqrt(2.0*(fstar-Y))
        #self.G=np.log(1.0*(fstar-Y))
        
        # print("only SE kernel is implemented!")
        #Euc_dist=euclidean_distances(X,X)
        
        if IsOptimize:
            self.hyper['lengthscale']=self.optimise()         # optimise GP hyperparameters
        #self.hyper['epsilon'],self.hyper['lengthscale'],self.noise_delta=self.optimise()         # optimise GP hyperparameters
        self.KK_x_x=self.mycov(self.X,self.X,self.hyper)+np.eye(len(X))*self.noise_delta 
        #self.KK_x_x=np.exp(-np.square(Euc_dist)/self.lengthscale)+np.eye(len(X))*self.noise_delta
        
        if np.isnan(self.KK_x_x).any(): #NaN
            print("nan in KK_x_x")
        
   
        self.L=np.linalg.cholesky(self.KK_x_x)
        
        # no zero mean
        
        # zero mean
        if self.IsZeroMean:
            tempG=np.linalg.solve(self.L,self.G)
        else:
            tempG=np.linalg.solve(self.L,self.G-np.sqrt(2*self.fstar))
        
        #self.alpha=np.linalg.solve(self.L.T,temp)
        self.alphaG=np.linalg.solve(self.L.T,tempG)
Exemple #3
0
    def select_next_point_bk(self):
        """
        Main optimization method.

        Input parameters
        ----------
        gp_params: parameter for Gaussian Process

        Returns
        -------
        x: recommented point for evaluation
        """

        fstar_scaled = (self.fstar - np.mean(self.Y_ori)) / np.std(self.Y_ori)

        # init a new Gaussian Process
        if self.IsTGP == 1:
            self.gp = TransformedGP(self.scaleSearchSpace,
                                    verbose=self.verbose,
                                    IsZeroMean=self.IsZeroMean)
            # Find unique rows of X to avoid GP from breaking
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled)
        else:
            self.gp = GaussianProcess(self.scaleSearchSpace,
                                      verbose=self.verbose)
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur])

        # check if the surrogate hit the optimum value f*, check if UCB and LCB cover the fstar
        x_ucb, y_ucb = acq_max_with_name(gp=self.gp,
                                         SearchSpace=self.scaleSearchSpace,
                                         acq_name="ucb",
                                         IsReturnY=True,
                                         fstar_scaled=fstar_scaled)
        x_lcb, y_lcb = acq_max_with_name(gp=self.gp,
                                         SearchSpace=self.scaleSearchSpace,
                                         acq_name="lcb",
                                         IsReturnY=True,
                                         IsMax=False)

        if y_lcb > fstar_scaled or y_ucb < fstar_scaled:  # f* > ucb
            self.gp.IsZeroMean = True
            self.IsZeroMean = True

            if self.verbose == 1:
                print("y_lcb={} y_ucb={} fstar_scaled={:.4f}".format(
                    y_lcb, y_ucb, fstar_scaled))
                print("ZeroMean")
        else:
            self.gp.IsZeroMean = False
            self.IsZeroMean = False

        # optimize GP parameters after 3*dim iterations
        if len(self.Y) % (3 * self.dim) == 0:
            self.gp.optimise()

        # Set acquisition function
        start_opt = time.time()
        # run the acquisition function for the first time to get xstar

        x_max = acq_max_with_name(gp=self.gp,
                                  SearchSpace=self.scaleSearchSpace,
                                  acq_name=self.acq_name,
                                  fstar_scaled=fstar_scaled)

        if np.any(np.abs((self.X - x_max)).sum(axis=1) <= (self.dim * 1e-5)):

            if self.verbose == 1:
                print("{} x_max is repeated".format(self.acq_name))

            # lift up the surrogate function
            self.gp.IsZeroMean = True
            self.IsZeroMean = True
            self.gp = TransformedGP(self.scaleSearchSpace,
                                    verbose=self.verbose,
                                    IsZeroMean=self.IsZeroMean)
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled)

            x_max = acq_max_with_name(gp=self.gp,
                                      SearchSpace=self.scaleSearchSpace,
                                      acq_name=self.acq_name,
                                      fstar_scaled=fstar_scaled)

        # record the optimization time
        finished_opt = time.time()
        elapse_opt = finished_opt - start_opt
        self.time_opt = np.hstack((self.time_opt, elapse_opt))

        # store X
        self.X = np.vstack((self.X, x_max.reshape((1, -1))))

        # compute X in original scale
        x_max_ori = self.Xscaler.inverse_transform(
            np.reshape(x_max, (-1, self.dim)))

        self.X_ori = np.vstack((self.X_ori, x_max_ori))
        # evaluate Y using original X

        #self.Y = np.append(self.Y, self.f(temp_X_new_original))
        Y_ori = self.f(x_max_ori)
        self.Y_ori = np.append(self.Y_ori, Y_ori)

        # update Y after change Y_ori
        self.Y = (self.Y_ori - np.mean(self.Y_ori)) / np.std(self.Y_ori)

        return x_max
Exemple #4
0
    def select_next_point(self):
        """
        select the next point to evaluate
        -------
        x: recommented point for evaluation
        """

        fstar_scaled = (self.fstar - np.mean(self.Y_ori)) / np.std(self.Y_ori)

        # init a new Gaussian Process
        if self.IsTGP == 1:
            self.gp = TransformedGP(self.scaleSearchSpace,
                                    verbose=self.verbose,
                                    IsZeroMean=self.IsZeroMean)
            # Find unique rows of X to avoid GP from breaking
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled)
        else:
            self.gp = GaussianProcess(self.scaleSearchSpace,
                                      verbose=self.verbose)
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur])
            self.gp.set_optimum_value(fstar_scaled)

        # optimize GP parameters after 3*dim iterations
        if len(self.Y) % (3 * self.dim) == 0:
            self.gp.optimise()

        # check if the surrogate hit the optimum value f*, check if UCB and LCB cover the fstar
        x_ucb, y_ucb = acq_max_with_name(gp=self.gp,
                                         SearchSpace=self.scaleSearchSpace,
                                         acq_name="ucb",
                                         IsReturnY=True,
                                         fstar_scaled=fstar_scaled)
        x_lcb, y_lcb = acq_max_with_name(gp=self.gp,
                                         SearchSpace=self.scaleSearchSpace,
                                         acq_name="lcb",
                                         IsReturnY=True,
                                         IsMax=False)

        #start_opt=time.time()

        if y_ucb < fstar_scaled:  # f* > ucb we initially use EI with the vanilla GP until the fstar is covered by the upper bound
            x_max = acq_max_with_name(gp=self.gp,
                                      SearchSpace=self.scaleSearchSpace,
                                      acq_name="ei")
            self.marker.append(0)
            if self.verbose == 1:
                print("y_lcb={} y_ucb={} fstar_scaled={:.4f}".format(
                    y_lcb, y_ucb, fstar_scaled))
                print("EI")
        else:  # perform TransformGP and ERM/CBM
            self.marker.append(1)
            self.IsTGP = 1
            x_max=acq_max_with_name(gp=self.gp,SearchSpace=self.scaleSearchSpace,acq_name=self.acq_name, \
                                    fstar_scaled=fstar_scaled)

        if np.any(np.abs((self.X - x_max)).sum(axis=1) <= (self.dim * 1e-5)):

            if self.verbose == 1:
                print("{} x_max is repeated".format(self.acq_name))

            # lift up the surrogate function
            self.gp.IsZeroMean = True
            self.IsZeroMean = True
            self.gp = TransformedGP(self.scaleSearchSpace,
                                    verbose=self.verbose,
                                    IsZeroMean=self.IsZeroMean)
            ur = unique_rows(self.X)
            self.gp.fit(self.X[ur], self.Y[ur], fstar_scaled)

            x_max = acq_max_with_name(gp=self.gp,
                                      SearchSpace=self.scaleSearchSpace,
                                      acq_name=self.acq_name,
                                      fstar_scaled=fstar_scaled)

        # store X
        self.X = np.vstack((self.X, x_max.reshape((1, -1))))

        # compute X in original scale
        x_max_ori = self.Xscaler.inverse_transform(
            np.reshape(x_max, (-1, self.dim)))

        self.X_ori = np.vstack((self.X_ori, x_max_ori))
        # evaluate Y using original X

        #self.Y = np.append(self.Y, self.f(temp_X_new_original))
        Y_ori = self.f(x_max_ori)
        self.Y_ori = np.append(self.Y_ori, Y_ori)

        # update Y after change Y_ori
        self.Y = (self.Y_ori - np.mean(self.Y_ori)) / np.std(self.Y_ori)

        return x_max