Exemplo n.º 1
0
class PmcAbc(object): 

    def __init__(self, data, simulator, 
            prior_dict = {}, 
            N = 1000, 
            eps0 = 0.01, 
            T = 20, 
            Nthreads = 10): 

        """ Class taht describes PMC-ABC 

        """

        self.data = data
        self.N = N 
        self.eps0 = eps0 
        self.T = T 
        self.Nthreads = Nthreads 

        # simulator function has to be a function of theta_star 
        self.simz = simulator

        self.prior_param(param_dict = prior_dict)  # first run prior parameters

    def prior_param(self, param_dict={}): 
        """ Pass priors of parameters in theta
        """ 
        self.param_obj = Params(param_dict)     # parameter object 
        self.param_names = param_dict.keys() 
        self.n_params = len(param_dict.keys())  # number of parameters in theta 

    def priors_sample(self): 
        """ Sample from priors derived from parameter object
        """
    
        theta_star = np.zeros(self.n_params)

        for i in xrange(self.n_params): 
            np.random.seed() 
            theta_star[i] = self.param_obj.prior()[i].rvs(size=1)[0]

        return theta_star

    def prior_of_priors(self, tt): 
        """ Multiply priors of multile dimensions

        p(theta) = p(theta_0) * p(theta_1) * ... * p(theta_n_params)

        """
        for i in xrange(self.n_params): 
            try: 
                p_theta *= self.param_obj.prior()[i].pdf(tt[i])        

            except UnboundLocalError: 
                p_theta = self.param_obj.prior()[i].pdf(tt[i])        

        return p_theta

    def initial_sampling(self, params):
        """Wrapper for parallelized initial pool sampling

        """
        i = params
        theta_star = self.priors_sample()
        model = self.simz( theta_star )
        rho = test_dist(self.data, model)
        while rho > self.eps0: 
            theta_star = self.priors_sample()
            model = self.simz( theta_star )
            rho = test_dist(self.data, model)
        data_list = [np.int(i)]

        for i_param in xrange(self.n_params): 
            data_list.append(theta_star[i_param])
        data_list.append(1./np.float(self.N))
        data_list.append(rho)
	return np.array(data_list)   

    def initial_pool(self):
        """
        Creating the initial pool
        """
        self.t = 0 
        self.theta_t = np.zeros((self.n_params, self.N))
        self.w_t = np.zeros((self.N))
        self.rhos = np.zeros((self.N)) 

        #pool = InterruptiblePool(self.Nthreads)    
        #mapfn = pool.map
        args_list = [(i) for i in xrange(self.N)]
        results = [] 
        for arg in args_list:
            print self.initial_sampling(arg) 
            results.append(self.initial_sampling(arg))
        #unwrap_self_initial_sampling(zip([self]*len(args_list), args_list)[0])
        #results = mapfn(unwrap_self_initial_sampling, zip([self]*len(args_list), args_list))
        #pool.close()
        #pool.terminate()
        #pool.join()
        print 'Initial Pool Complete'

 	pars = np.array(results).T
        self.theta_t = pars[1:self.n_params+1,:]
        self.w_t     = pars[self.n_params+1,:]
        self.rhos    = pars[self.n_params+2,:]

        self.sig_t = 2.0 * np.cov( self.theta_t )    # covariance matrix

        self.writeout()
        self.plotout()

        return np.array(self.rhos)   

    def importance_sampling(self, params): 
        """ Wrapper for parallelized importance sampling

        """
        i_part = params

        theta_star = weighted_sampling( self.theta_t_1, self.w_t_1 ) 
        np.random.seed()

        theta_starstar = multivariate_normal( theta_star, self.sig_t_1 ).rvs(size=1)
        model_starstar = self.simz( theta_starstar )

        rho = test_dist(self.data, model_starstar) 

        while rho > self.eps_t: 
            theta_star = weighted_sampling( self.theta_t_1, self.w_t_1 )
            theta_starstar = multivariate_normal(theta_star, self.sig_t_1).rvs(size=1)

            model_starstar = self.simz( theta_starstar )

            rho = test_dist(self.data, model_starstar) 

        p_theta = self.prior_of_priors(theta_starstar)

        pos_t = np.dstack(self.theta_t_1)

        tmp_w_t = p_theta / np.sum(self.w_t_1 * multivariate_normal(self.theta_t[:,i_part], self.sig_t_1).pdf(pos_t))

        data_list = [np.int(i_part)]

        for i_param in xrange(self.n_params): 

            data_list.append(theta_starstar[i_param])

        data_list.append(tmp_w_t)
        data_list.append(rho)

        return  np.array(data_list) 

    def pmc_abc(self): 
        """
        """
        self.rhos = self.initial_pool()

        while self.t < self.T: 
            self.eps_t = np.percentile(self.rhos, 75)

            print 'Epsilon t', self.eps_t

            self.theta_t_1 = self.theta_t.copy()

            self.w_t_1 = self.w_t.copy()

            self.sig_t_1 = self.sig_t.copy()

            pool = InterruptiblePool(self.Nthreads)
            mapfn = pool.map
            args_list = [ i for i in xrange(self.N) ] 
            results = mapfn(unwrap_self_importance_sampling, zip([self]*len(args_list), args_list))

            pool.close()
            pool.terminate()
            pool.join()

            pars = np.array(results).T
            self.theta_t = pars[1:self.n_params+1,:].copy()
            self.w_t     = pars[self.n_params+1,:].copy()
            self.rhos    = pars[self.n_params+2,:].copy()

            self.sig_t = 2.0 * np.cov(self.theta_t)
            self.t += 1 

            self.writeout()
            self.plotout()

        return None

    def writeout(self): 
        """ Write out theta_t and w_t

        """
        out_file = ''.join(['theta_w_t', str(self.t), '.dat'])
        data_list = [] 

        for i in xrange(self.n_params): 
            data_list.append( self.theta_t[i,:] ) 

        data_list.append(self.w_t)

        np.savetxt(
                out_file, 
                (np.vstack(np.array(data_list))).T, 
                delimiter='\t'
                )

        return None 

    def plotout(self, plot_type = 'seabreeze'): 
        """ Triangle plot the things 
        """

        if plot_type == 'seabreeze':
            figure = sns.jointplot(x = self.theta_t[0,:], y = self.theta_t[1,:], kind = 'kde', 
                    style = 'white', weights = self.w_t, 
                    xlim = [-1.0, 1], 
                    ylim = [0.0, 2.0]
                    )

            plt.savefig("seabreeze_theta_t"+str(self.t)+".png")
            plt.close()

        elif plot_type == 'triangle': 
            # Clunky based on which version of corner.py you have
            # Clunky based on which version of corner.py you have
            # Clunky based on which version of corner.py you have
            # Clunky based on which version of corner.py you have

            figure = triangle.corner(
                   (self.theta_t).T, 
                   labels = self.param_names, 
                   weights = self.w_t, 
                   show_titles=True, 
                   title_args={"fontsize": 12},
                   smooth=False
                   ) 

            figure.gca().annotate(
                    str(self.t), 
                    xy=(0.5, 1.0), 
                    xycoords="figure fraction",
                    xytext=(0, -5), 
                    textcoords="offset points",
                    ha="center", 
                    va="top"
                    ) 

            figure.savefig("triangle_theta_t"+str(self.t)+".png")
            plt.close()

        elif plot_type == 'scatter': 
            if len(self.theta_t[:,0]) != 2: 
                warnings.warn("Can only plot two axes on scatter plot. No plot generated")
                return 

            figure = plt.figure(1)
            sub = figure.add_subplot(111)
            sub.scatter(self.theta_t[0,:], self.theta_t[1,:]) 
            sub.set_xlim([-1.0, 1.0])
            sub.set_ylim([0.8, 1.5])

            figure.savefig("scatter_theta_t"+str(self.t)+".png")

            plt.close()
Exemplo n.º 2
0
def pmc_abc(data, 
        N = 1000,
        eps0 = 0.01, 
        T = 20
        ): 

    start_time = time.time()

    toolz = Params({
                'mu': {'shape': 'gauss', 'mean': .0, 'stddev': 1.0}, 
                'sigma': { 'shape': 'uniform', 'min': 0.0, 'max': 2.0}
                })

    t = 0 
    theta_t = np.zeros((2, N))
    w_t = np.zeros((N))

    for i in xrange(N): 
        
        theta_star = np.zeros(2)
        theta_star[0] = toolz.prior()[0].rvs(size=1)[0]
        theta_star[1] = toolz.prior()[1].rvs(size=1)[0]
	#print theta_star
        model = toolz.simulator( theta_star )

        rho = test_dist(data[1], model(data[0]))

        while rho > eps0: 

            theta_star[0] = toolz.prior()[0].rvs(size=1)[0]
            theta_star[1] = toolz.prior()[1].rvs(size=1)[0]

            model = toolz.simulator( theta_star )

            rho = test_dist(data[1], model(data[0]))
         
        theta_t[:,i] = theta_star

        w_t[i] = 1.0/np.float(N)

    sig_t = 2.0 * np.cov( theta_t )    # covariance matrix
    print sig_t
    
    # write out 
    np.savetxt(
            ''.join(['theta_w_t', str(t), '.dat']), 
            np.c_[theta_t[0,:], theta_t[1,:], w_t ]
            )

    print 'Initial Pool ', time.time() - start_time

    fig = plt.figure(1)
    sub = fig.add_subplot(111)
    sub.scatter(
            theta_t[0,:], 
            theta_t[1,:], 
            alpha = 1. , 
            color = 'b'
            )
            #s = 10.**10.*w_t/w_t.sum() , 
    sub.set_xlim([-2. , 2.])
    sub.set_ylim([ 0. , 2.])
    sub.set_xlabel(r'$\mu$')
    sub.set_ylabel(r'$\sigma$')
    plt.savefig("theta_scatter"+str(t)+".png")
    plt.close()

    start_time = time.time()

    while t < T: 

        eps_t = np.percentile(rho, 75)
        print 'Epsilon t', eps_t

        theta_t_1 = theta_t.copy()
        w_t_1 = w_t.copy()
        sig_t_1 = sig_t.copy()

        for i in xrange(N): 
            start_time = time.time()

            theta_star = weighted_sampling( theta_t_1, w_t_1 ) 
            theta_starstar = multivariate_normal( theta_star, sig_t_1 ).rvs(size=1)
	    
	    while theta_starstar[1] < 0 :
		    theta_star = weighted_sampling( theta_t_1, w_t_1 )
		    theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1)
	    #print theta_starstar
            model_starstar = toolz.simulator( theta_starstar )
            rho = test_dist(data[1], model_starstar(data[0])) 
        
            while rho > eps_t: 

                theta_star = weighted_sampling( theta_t_1, w_t_1 )
		 
                theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1)
		while theta_starstar[1] < 0 :
			theta_star = weighted_sampling( theta_t_1, w_t_1 )
			theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1)
		#print theta_starstar
                model_starstar = toolz.simulator( theta_starstar )
                rho = test_dist(data[1], model_starstar(data[0])) 

            #print theta_star, theta_starstar
            theta_t[:,i] = theta_starstar
	    #print sig_t_1
	    p_theta = toolz.prior()[0].pdf(theta_t[0,i]) * toolz.prior()[1].pdf(theta_t[1,i])
	    #print p_theta
	    pos_t = np.dstack((theta_t_1[0,:],theta_t_1[1,:]))
	    #print multivariate_normal(theta_t[:,i], sig_t_1).pdf(pos_t).shape , w_t_1.shape
            w_t[i] = p_theta / np.sum(w_t_1 * multivariate_normal(theta_t[:,i], sig_t_1).pdf(pos_t))
            #print test_dist(data[1], model_starstar(data[0])), w_t[i]
            
            #print 'For loop ', time.time() - start_time
        
        sig_t = 2.0 * np.cov(theta_t)
        t += 1 
        
        fig = plt.figure(1)
        sub = fig.add_subplot(111)
    	sub.scatter(
                theta_t[0,:], 
                theta_t[1,:], 
                alpha = 0.5
                )
        #        s = w_t/w_t.sum() , 
        sub.set_xlim([-2. , 2.])
        sub.set_ylim([ 0. , 2.])
        sub.set_xlabel(r'$\mu$')
        sub.set_ylabel(r'$\sigma$')
        plt.savefig("theta_scatter"+str(t)+".png")
        plt.close()

        np.savetxt(
		    ''.join(['theta_w_t', str(t), '.dat']), 
		    np.c_[theta_t[0,:], theta_t[1,:], w_t ]
		    )

        print t, ' ;D'