예제 #1
0
파일: step_methods.py 프로젝트: wqren/pymc
 def reject(self):
     self.rejected += 1
     if self.verbose:
         print_(self._id + ' rejecting')
     # Revert the field evaluation and the rest of the field.
     self.f_eval.revert()
     self.f.revert()
예제 #2
0
def plot_envelope(M,C,mesh):
    """
    plot_envelope(M,C,mesh)


    plots the pointwise mean +/- sd envelope defined by M and C
    along their base mesh.


    :Arguments:

        -   `M`: A Gaussian process mean.

        -   `C`: A Gaussian process covariance

        -   `mesh`: The mesh on which to evaluate the mean and cov.
    """

    try:
        from pylab import fill, plot, clf, axis
        x=concatenate((mesh, mesh[::-1]))
        mean, var = point_eval(M,C,mesh)
        sig = sqrt(var)
        mean = M(mesh)
        y=concatenate((mean-sig, (mean+sig)[::-1]))
        # clf()
        fill(x,y,facecolor='.8',edgecolor='1.')
        plot(mesh, mean, 'k-.')
    except ImportError:
        print_("Matplotlib is not installed; plotting is disabled.")
예제 #3
0
def plot_envelope(M, C, mesh):
    """
    plot_envelope(M,C,mesh)


    plots the pointwise mean +/- sd envelope defined by M and C
    along their base mesh.


    :Arguments:

        -   `M`: A Gaussian process mean.

        -   `C`: A Gaussian process covariance

        -   `mesh`: The mesh on which to evaluate the mean and cov.
    """

    try:
        from pylab import fill, plot, clf, axis
        x = concatenate((mesh, mesh[::-1]))
        mean, var = point_eval(M, C, mesh)
        sig = sqrt(var)
        mean = M(mesh)
        y = concatenate((mean - sig, (mean + sig)[::-1]))
        # clf()
        fill(x, y, facecolor='.8', edgecolor='1.')
        plot(mesh, mean, 'k-.')
    except ImportError:
        print_("Matplotlib is not installed; plotting is disabled.")
예제 #4
0
파일: step_methods.py 프로젝트: Gwill/pymc
 def reject(self):
     self.rejected += 1
     if self.verbose:
         print_(self._id + ' rejecting')
     # Revert the field evaluation and the rest of the field.
     self.f_eval.revert()
     self.f.revert()
예제 #5
0
파일: diagnostics.py 프로젝트: wqren/pymc
        def wrapped_f(pymc_obj, *args, **kwargs):

            # Figure out what type of object it is
            try:
                values = {}
                # First try Model type
                for variable in pymc_obj._variables_to_tally:
                    if self.all_chains:
                        k = pymc_obj.db.chains
                        data = [variable.trace(chain=i) for i in range(k)]
                    else:
                        data = variable.trace()
                    name = variable.__name__
                    if kwargs.get('verbose'):
                        print_("\nDiagnostic for %s ..." % name)
                    values[name] = f(data, *args, **kwargs)
                return values
            except AttributeError:
                pass

            try:
                # Then try Node type
                if self.all_chains:
                    k = pymc_obj.trace.db.chains
                    data = [pymc_obj.trace(chain=i) for i in range(k)]
                else:
                    data = pymc_obj.trace()
                name = pymc_obj.__name__
                return f(data, *args, **kwargs)
            except (AttributeError, ValueError):
                pass

            # If others fail, assume that raw data is passed
            return f(pymc_obj, *args, **kwargs)
예제 #6
0
        def wrapped_f(pymc_obj, *args, **kwargs):

            # Figure out what type of object it is
            try:
                values = {}
                # First try Model type
                for variable in pymc_obj._variables_to_tally:
                    if self.all_chains:
                        k = pymc_obj.db.chains
                        data = [variable.trace(chain=i) for i in range(k)]
                    else:
                        data = variable.trace()
                    name = variable.__name__
                    if kwargs.get('verbose'):
                        print_("\nDiagnostic for %s ..." % name)
                    values[name] = f(data, *args, **kwargs)
                return values
            except AttributeError:
                pass
        
            try:
                # Then try Node type
                if self.all_chains:
                    k = pymc_obj.trace.db.chains
                    data = [pymc_obj.trace(chain=i) for i in range(k)]
                else:
                    data = pymc_obj.trace()
                name = pymc_obj.__name__
                return f(data, *args, **kwargs)
            except (AttributeError,ValueError):
                pass
        
            # If others fail, assume that raw data is passed
            return f(pymc_obj, *args, **kwargs)
예제 #7
0
def discrepancy(observed, simulated, expected):
    """Calculates Freeman-Tukey statistics (Freeman and Tukey 1950) as
    a measure of discrepancy between observed and r replicates of simulated data. This
    is a convenient method for assessing goodness-of-fit (see Brooks et al. 2000).
    
    D(x|\theta) = \sum_j (\sqrt{x_j} - \sqrt{e_j})^2
    
    :Parameters:
      observed : Iterable of observed values (length n)
      simulated : Iterable of simulated values (length rxn)
      expected : Iterable of expected values (length rxn)
    
    :Returns:
      D_obs : Discrepancy of observed values
      D_sim : Discrepancy of simulated values
    
    """
    try:
        simulated = simulated.astype(float)
    except AttributeError:
        simulated = simulated.trace().astype(float)
    try:
        expected = expected.astype(float)
    except AttributeError:
        expected = expected.trace().astype(float)
    
    D_obs = np.sum([(np.sqrt(observed)-np.sqrt(e))**2 for e in expected], 1)
    D_sim = np.sum([(np.sqrt(s)-np.sqrt(e))**2 for s,e in zip(simulated, expected)], 1)
    
    # Print p-value
    count = sum(s>o for o,s in zip(D_obs,D_sim))
    print_('Bayesian p-value: p=%.3f' % (1.*count/len(D_obs)))
    
    return D_obs, D_sim
예제 #8
0
파일: dram.py 프로젝트: meqash/PyMC-DRAM
    def propose_first(self):
        """
        This method proposes values for stochastics based on the empirical
        covariance of the values sampled so far.
        The proposal jumps are drawn from a multivariate normal distribution.
        """

        arrayjump = np.dot(
            self.proposal_sd,
            np.random.normal(size=self.proposal_sd.shape[0]),
        )
        # save in case needed for calculating second proposal probability
        self.arrayjump1 = arrayjump.copy()  # is a copy needed?

        if self.verbose > 2: print_('First jump:', arrayjump)

        # Update each stochastic individually.
        for stochastic in self.stochastics:
            jump = arrayjump[self._slices[stochastic]].squeeze()

            if np.iterable(stochastic.value):
                jump = np.reshape(
                    arrayjump[self._slices[stochastic]],
                    np.shape(stochastic.value),
                )

            if self.isdiscrete[stochastic]:
                jump = round_array(jump)

            stochastic.value = stochastic.value + jump
예제 #9
0
파일: base.py 프로젝트: wanderlustzoe/pymc
    def stats(self,
              alpha=0.05,
              start=0,
              batches=100,
              chain=None,
              quantiles=(2.5, 25, 50, 75, 97.5)):
        """
        Generate posterior statistics for node.

        :Parameters:
        name : string
          The name of the tallyable object.

        alpha : float
          The alpha level for generating posterior intervals. Defaults to
          0.05.

        start : int
          The starting index from which to summarize (each) chain. Defaults
          to zero.

        batches : int
          Batch size for calculating standard deviation for non-independent
          samples. Defaults to 100.

        chain : int
          The index for which chain to summarize. Defaults to None (all
          chains).

        quantiles : tuple or list
          The desired quantiles to be calculated. Defaults to (2.5, 25, 50, 75, 97.5).
        """

        try:
            trace = np.squeeze(
                np.array(self.db.trace(self.name)(chain=chain), float))[start:]

            n = len(trace)
            if not n:
                print_('Cannot generate statistics for zero-length trace in',
                       self.__name__)
                return

            return {
                'n':
                n,
                'standard deviation':
                trace.std(0),
                'mean':
                trace.mean(0),
                '%s%s HPD interval' % (int(100 * (1 - alpha)), '%'):
                utils.hpd(trace, alpha),
                'mc error':
                batchsd(trace, batches),
                'quantiles':
                utils.quantiles(trace, qlist=quantiles)
            }
        except:
            print_('Could not generate output statistics for', self.name)
            return
예제 #10
0
def plot_GP_envelopes(f, x, HPD=[
                      .25, .5, .95], transx=None, transy=None):
    """
    plot_GP_envelopes(f, x[, HPD, transx, transy])


    Plots centered posterior probability envelopes for f, which is a GP instance,
    which is a function of one variable.


    :Arguments:

        -   `f`: A GaussianProcess object.

        -   `x`: The mesh on which to plot the envelopes.

        -   `HPD`: A list of values between 0 and 1 giving the probability mass
            contained in each envelope.

        -   `transx`: Any transformation of the x-axis.

        -   `transy`: Any transformation of the y-axis.
    """
    try:
        from pymc.Matplot import centered_envelope

        f_trace = f.trace()
        x = x.ravel()
        N = len(f_trace)
        func_stacks = np.zeros((N, len(x)), dtype=float)

        def identity(y):
            return y

        if transy is None:
            transy = identity
        if transx is None:
            transx = identity

        # Get evaluations
        for i in range(N):
            f = copy(f_trace[i])
            func_stacks[i, :] = transy(f(transx(x)))

        # Plot envelopes
        HPD = np.sort(HPD)
        sorted_func_stack = np.sort(func_stacks, 0)
        for m in HPD[::-1]:
            env = centered_envelope(sorted_func_stack, m)
            # from IPython.Debugger import Pdb
            # Pdb(color_scheme='LightBG').set_trace()
            env.display(x, alpha=1. - m * .5, new=False)
        centered_envelope(
            sorted_func_stack,
            0.).display(x,
                        alpha=1.,
                        new=False)
    except ImportError:
        six.print_('Plotter could not be imported; plotting disabled')
예제 #11
0
 def savestate(self, state):
     """Save the sampler's state in a state.txt file."""
     oldstate = np.get_printoptions()
     np.set_printoptions(threshold=1e6)
     try:
         with open(os.path.join(self._directory, 'state.txt'), 'w') as f:
             print_(state, file=f)
     finally:
         np.set_printoptions(**oldstate)
예제 #12
0
파일: txt.py 프로젝트: Bitburg-chef/pymc
 def savestate(self, state):
     """Save the sampler's state in a state.txt file."""
     oldstate = np.get_printoptions()
     np.set_printoptions(threshold=1e6)
     try:
         with open(os.path.join(self._directory, 'state.txt'), 'w') as f:
             print_(state, file=f)
     finally:
         np.set_printoptions(**oldstate)
예제 #13
0
파일: step_methods.py 프로젝트: jsiah/pymc
    def propose(self):

        if self.verbose:
            print_(self._id + " proposing")

        fc = pm.gp.fast_matrix_copy

        eps_p_f = pm.utils.value(self.eps_p_f)
        f = pm.utils.value(self.f_eval)
        for i in xrange(len(self.scratch3)):
            self.scratch3[i] = np.sum(eps_p_f[self.ti[i]] - f[i])

        # Compute Cholesky factor of covariance of eps_p_f, C(x,x) + V
        C_eval_value = pm.utils.value(self.C_eval)
        C_eval_shape = C_eval_value.shape

        # Get the Cholesky factor of C_eval, plus the nugget.
        # I don't think you can use S_eval for speed, unfortunately.
        in_chol = fc(C_eval_value, self.scratch1)

        v_val = pm.utils.value(self.V)
        for i in xrange(pm.utils.value(C_eval_shape)[0]):
            in_chol[i, i] += v_val[i] / np.alen(self.ti[i])

        info = pm.gp.linalg_utils.dpotrf_wrap(in_chol)
        if info > 0:
            raise np.linalg.LinAlgError

        # Compute covariance of f conditional on eps_p_f.
        offdiag = fc(C_eval_value, self.scratch2)
        offdiag = pm.gp.trisolve(in_chol, offdiag, uplo="U", transa="T", inplace=True)

        C_step = offdiag.T * offdiag
        C_step *= -1
        C_step += C_eval_value

        # Compute mean of f conditional on eps_p_f.
        for i in xrange(len(self.scratch3)):
            self.scratch3[i] = np.mean(eps_p_f[self.ti[i]])
        m_step = (
            pm.utils.value(self.M_eval)
            + np.dot(offdiag.T, pm.gp.trisolve(in_chol, (self.scratch3 - self.M_eval.value), uplo="U", transa="T"))
            .view(np.ndarray)
            .ravel()
        )

        sig_step = C_step
        info = pm.gp.linalg_utils.dpotrf_wrap(C_step.T)
        if info > 0:
            warnings.warn("Full conditional covariance was not positive definite.")
            return

        # Update value of f.
        self.f_eval.value = m_step + np.dot(sig_step, np.random.normal(size=sig_step.shape[1])).view(np.ndarray).ravel()
        # Propose the rest of the field from its conditional prior.
        self.f.rand()
예제 #14
0
def plot_GP_envelopes(f, x, HPD=[.25, .5, .95], transx=None, transy=None):
    """
    plot_GP_envelopes(f, x[, HPD, transx, transy])


    Plots centered posterior probability envelopes for f, which is a GP instance,
    which is a function of one variable.


    :Arguments:

        -   `f`: A GaussianProcess object.

        -   `x`: The mesh on which to plot the envelopes.

        -   `HPD`: A list of values between 0 and 1 giving the probability mass
            contained in each envelope.

        -   `transx`: Any transformation of the x-axis.

        -   `transy`: Any transformation of the y-axis.
    """
    try:
        from pymc.Matplot import centered_envelope

        f_trace = f.trace()
        x = x.ravel()
        N = len(f_trace)
        func_stacks = np.zeros((N, len(x)), dtype=float)

        def identity(y):
            return y

        if transy is None:
            transy = identity
        if transx is None:
            transx = identity

        # Get evaluations
        for i in range(N):
            f = copy(f_trace[i])
            func_stacks[i, :] = transy(f(transx(x)))

        # Plot envelopes
        HPD = np.sort(HPD)
        sorted_func_stack = np.sort(func_stacks, 0)
        for m in HPD[::-1]:
            env = centered_envelope(sorted_func_stack, m)
            # from IPython.Debugger import Pdb
            # Pdb(color_scheme='LightBG').set_trace()
            env.display(x, alpha=1. - m * .5, new=False)
        centered_envelope(sorted_func_stack, 0.).display(x,
                                                         alpha=1.,
                                                         new=False)
    except ImportError:
        six.print_('Plotter could not be imported; plotting disabled')
예제 #15
0
    def stats(self, alpha=0.05, start=0, batches=100,
              chain=None, quantiles=(2.5, 25, 50, 75, 97.5)):
        """
        Generate posterior statistics for node.

        :Parameters:
        name : string
          The name of the tallyable object.

        alpha : float
          The alpha level for generating posterior intervals. Defaults to
          0.05.

        start : int
          The starting index from which to summarize (each) chain. Defaults
          to zero.

        batches : int
          Batch size for calculating standard deviation for non-independent
          samples. Defaults to 100.

        chain : int
          The index for which chain to summarize. Defaults to None (all
          chains).

        quantiles : tuple or list
          The desired quantiles to be calculated. Defaults to (2.5, 25, 50, 75, 97.5).
        """

        try:
            trace = np.squeeze(
                np.array(
                    self.db.trace(
                        self.name)(
                            chain=chain),
                    float))[
                        start:]

            n = len(trace)
            if not n:
                print_(
                    'Cannot generate statistics for zero-length trace in',
                    self.__name__)
                return

            return {
                'n': n,
                'standard deviation': trace.std(0),
                'mean': trace.mean(0),
                '%s%s HPD interval' % (int(100 * (1 - alpha)), '%'): utils.hpd(trace, alpha),
                'mc error': batchsd(trace, min(n, batches)),
                'quantiles': utils.quantiles(trace, qlist=quantiles)
            }
        except:
            print_('Could not generate output statistics for', self.name)
            return
예제 #16
0
    def hastings_factor(self):
        tau = 1./(self.adaptive_scale_factor * self.proposal_sd)**2
        cur_val = self.stochastic.value
        last_val = self.stochastic.last_value

        lp_for = pm.truncnorm_like(cur_val, last_val, tau, self.low_bound, self.up_bound)
        lp_bak = pm.truncnorm_like(last_val, cur_val, tau, self.low_bound, self.up_bound)

        if self.verbose > 1:
            six.print_(self._id + ': Hastings factor %f'%(lp_bak - lp_for))
        return lp_bak - lp_for
예제 #17
0
    def hastings_factor(self):
        tau = 1. / (self.adaptive_scale_factor * self.proposal_sd)**2
        cur_val = self.stochastic.value
        last_val = self.stochastic.last_value

        lp_for = pm.truncnorm_like(cur_val, last_val, tau, self.low_bound,
                                   self.up_bound)
        lp_bak = pm.truncnorm_like(last_val, cur_val, tau, self.low_bound,
                                   self.up_bound)

        if self.verbose > 1:
            six.print_(self._id + ': Hastings factor %f' % (lp_bak - lp_for))
        return lp_bak - lp_for
예제 #18
0
파일: diagnostics.py 프로젝트: wqren/pymc
def iat(x, maxlag=None):
    """Calculate the integrated autocorrelation time (IAT), given the trace from a Stochastic."""

    if not maxlag:
        # Calculate maximum lag to which autocorrelation is calculated
        maxlag = _find_max_lag(x)

    acr = [autocorr(x, lag) for lag in range(1, maxlag + 1)]

    # Calculate gamma values
    gammas = [(acr[2 * i] + acr[2 * i + 1]) for i in range(maxlag // 2)]

    cut = _cut_time(gammas)

    if cut + 1 == len(gammas):
        print_("Not enough lag to calculate IAT")

    return np.sum(2 * gammas[:cut + 1]) - 1.0
예제 #19
0
def iat(x, maxlag=None):
    """Calculate the integrated autocorrelation time (IAT), given the trace from a Stochastic."""
    
    if not maxlag:
        # Calculate maximum lag to which autocorrelation is calculated
        maxlag = _find_max_lag(x)
    
    acr = [autocorr(x, lag) for lag in range(1, maxlag+1)]
    
    # Calculate gamma values
    gammas = [(acr[2*i]+acr[2*i+1]) for i in range(maxlag//2)]
    
    cut = _cut_time(gammas)
    
    if cut+1 == len(gammas):
        print_("Not enough lag to calculate IAT")
    
    return np.sum(2*gammas[:cut+1]) - 1.0
예제 #20
0
def _find_max_lag(x, rho_limit=0.05, maxmaxlag=20000, verbose=0):
    """Automatically find an appropriate maximum lag to calculate IAT"""
    
    # Fetch autocovariance matrix
    acv = autocov(x)
    # Calculate rho
    rho = acv[0,1]/acv[0,0]
    
    lam = -1./np.log(abs(rho))
    
    # Initial guess at 1.5 times lambda (i.e. 3 times mean life)
    maxlag = int(np.floor(3.*lam)) + 1
    
    # Jump forward 1% of lambda to look for rholimit threshold
    jump = int(np.ceil(0.01*lam)) + 1
    
    T = len(x)
    
    while ((abs(rho) > rho_limit) & (maxlag < min(T/2, maxmaxlag))):
        
        acv = autocov(x, maxlag)
        rho = acv[0,1]/acv[0,0]
        maxlag += jump
    
    # Add 30% for good measure
    maxlag = int(np.floor(1.3*maxlag))
    
    if maxlag >= min(T/2, maxmaxlag):
        maxlag = min(min(T/2, maxlag), maxmaxlag)
        "maxlag fixed to %d" % maxlag
        return maxlag
    
    if maxlag <= 1:
        print_("maxlag = %d, fixing value to 10" % maxlag)
        return 10
    
    if verbose:
        print_("maxlag = %d" % maxlag)
    return maxlag
예제 #21
0
파일: diagnostics.py 프로젝트: wqren/pymc
def _find_max_lag(x, rho_limit=0.05, maxmaxlag=20000, verbose=0):
    """Automatically find an appropriate maximum lag to calculate IAT"""

    # Fetch autocovariance matrix
    acv = autocov(x)
    # Calculate rho
    rho = acv[0, 1] / acv[0, 0]

    lam = -1. / np.log(abs(rho))

    # Initial guess at 1.5 times lambda (i.e. 3 times mean life)
    maxlag = int(np.floor(3. * lam)) + 1

    # Jump forward 1% of lambda to look for rholimit threshold
    jump = int(np.ceil(0.01 * lam)) + 1

    T = len(x)

    while ((abs(rho) > rho_limit) & (maxlag < min(T / 2, maxmaxlag))):

        acv = autocov(x, maxlag)
        rho = acv[0, 1] / acv[0, 0]
        maxlag += jump

    # Add 30% for good measure
    maxlag = int(np.floor(1.3 * maxlag))

    if maxlag >= min(T / 2, maxmaxlag):
        maxlag = min(min(T / 2, maxlag), maxmaxlag)
        "maxlag fixed to %d" % maxlag
        return maxlag

    if maxlag <= 1:
        print_("maxlag = %d, fixing value to 10" % maxlag)
        return 10

    if verbose:
        print_("maxlag = %d" % maxlag)
    return maxlag
예제 #22
0
파일: dram.py 프로젝트: meqash/PyMC-DRAM
    def propose_second(self):
        """
        This method proposes values for stochastics based on the empirical
        covariance of the values sampled so far.
        The proposal jumps are drawn from a multivariate normal distribution.
        """

        arrayjump = self.drscale * np.dot(
            self.proposal_sd,
            np.random.normal(size=self.proposal_sd.shape[0]),
        )

        if self.verbose > 2: print_('Second jump:', arrayjump)

        # Update each stochastic individually.
        for stochastic in self.stochastics:
            jump = arrayjump[self._slices[stochastic]].squeeze()

            if np.iterable(stochastic.value):
                jump = np.reshape(
                    arrayjump[self._slices[stochastic]],
                    np.shape(stochastic.value),
                )

            if self.isdiscrete[stochastic]:
                jump = round_array(jump)

            stochastic.value = stochastic.value + jump

        arrayjump1 = self.arrayjump1
        arrayjump2 = arrayjump

        self.q = np.exp(
            -0.5 * (
                np.linalg.norm(np.dot(arrayjump2 - arrayjump1, self.proposal_sd_inv), ord=2) ** 2 \
                - np.linalg.norm(np.dot(-arrayjump1, self.proposal_sd_inv), ord=2) ** 2
            )
        )
예제 #23
0
파일: diagnostics.py 프로젝트: wqren/pymc
def discrepancy(observed, simulated, expected):
    """Calculates Freeman-Tukey statistics (Freeman and Tukey 1950) as
    a measure of discrepancy between observed and r replicates of simulated data. This
    is a convenient method for assessing goodness-of-fit (see Brooks et al. 2000).
    
    D(x|\theta) = \sum_j (\sqrt{x_j} - \sqrt{e_j})^2
    
    :Parameters:
      observed : Iterable of observed values (size=(n,))
      simulated : Iterable of simulated values (size=(r,n))
      expected : Iterable of expected values (size=(r,) or (r,n))
    
    :Returns:
      D_obs : Discrepancy of observed values
      D_sim : Discrepancy of simulated values
    
    """
    try:
        simulated = simulated.astype(float)
    except AttributeError:
        simulated = simulated.trace().astype(float)
    try:
        expected = expected.astype(float)
    except AttributeError:
        expected = expected.trace().astype(float)
    # Ensure expected values are rxn
    expected = np.resize(expected, simulated.shape)

    D_obs = np.sum([(np.sqrt(observed) - np.sqrt(e))**2 for e in expected], 1)
    D_sim = np.sum([(np.sqrt(s) - np.sqrt(e))**2
                    for s, e in zip(simulated, expected)], 1)

    # Print p-value
    count = sum(s > o for o, s in zip(D_obs, D_sim))
    print_('Bayesian p-value: p=%.3f' % (1. * count / len(D_obs)))

    return D_obs, D_sim
예제 #24
0
 def callback(p):
     try:
         print_('Current log-probability : %f' % self.logp)
     except ZeroProbability:
         print_('Current log-probability : %f' % -Inf)
예제 #25
0
import pymc
from pymc import six
from . import simple_von_mises

model=pymc.MCMC(simple_von_mises)
model.sample(iter=1000, burn=500, thin=2)

six.print_('mu',model.mu.value)
six.print_('kappa',model.kappa.value)
예제 #26
0
    except:
        pass
try:
    import scipy.stats
    from scipy import integrate, special
    from scipy.misc import factorial, comb
    from scipy.stats import genextreme, exponweib
    from scipy.optimize import fmin
    SP = True
except:
    SP = False

try:
    import pylab as P
except:
    six.print_('Plotting disabled')
    PLOT = False


# Some python densities for comparison
def cauchy(x, x0, gamma):
    return 1/pi * gamma/((x-x0)**2 + gamma**2)

def gamma(x, alpha, beta):
    return x**(alpha-1) * exp(-x/beta)/(special.gamma(alpha) * beta**alpha)

def multinomial_beta(alpha):
    nom = (special.gamma(alpha)).prod(0)
    den = special.gamma(alpha.sum(0))
    return nom/den
예제 #27
0
    except:
        pass
try:
    import scipy.stats
    from scipy import integrate, special
    from scipy.misc import factorial, comb
    from scipy.stats import genextreme, exponweib
    from scipy.optimize import fmin
    SP = True
except:
    SP = False

try:
    import pylab as P
except:
    six.print_('Plotting disabled')
    PLOT = False


# Some python densities for comparison
def cauchy(x, x0, gamma):
    return 1 / pi * gamma / ((x - x0)**2 + gamma**2)


def gamma(x, alpha, beta):
    return x**(alpha - 1) * exp(
        -x / beta) / (special.gamma(alpha) * beta**alpha)


def multinomial_beta(alpha):
    nom = (special.gamma(alpha)).prod(0)
예제 #28
0
파일: step_methods.py 프로젝트: wqren/pymc
    def propose(self):

        if self.verbose:
            print_(self._id + ' proposing')

        fc = pm.gp.fast_matrix_copy

        eps_p_f = pm.utils.value(self.eps_p_f)
        f = pm.utils.value(self.f_eval)
        for i in xrange(len(self.scratch3)):
            self.scratch3[i] = np.sum(eps_p_f[self.ti[i]] - f[i])

        # Compute Cholesky factor of covariance of eps_p_f, C(x,x) + V
        C_eval_value = pm.utils.value(self.C_eval)
        C_eval_shape = C_eval_value.shape

        # Get the Cholesky factor of C_eval, plus the nugget.
        # I don't think you can use S_eval for speed, unfortunately.
        in_chol = fc(C_eval_value, self.scratch1)

        v_val = pm.utils.value(self.V)
        for i in xrange(pm.utils.value(C_eval_shape)[0]):
            in_chol[i, i] += v_val[i] / np.alen(self.ti[i])

        info = pm.gp.linalg_utils.dpotrf_wrap(in_chol)
        if info > 0:
            raise np.linalg.LinAlgError

        # Compute covariance of f conditional on eps_p_f.
        offdiag = fc(C_eval_value, self.scratch2)
        offdiag = pm.gp.trisolve(in_chol,
                                 offdiag,
                                 uplo='U',
                                 transa='T',
                                 inplace=True)

        C_step = offdiag.T * offdiag
        C_step *= -1
        C_step += C_eval_value

        # Compute mean of f conditional on eps_p_f.
        for i in xrange(len(self.scratch3)):
            self.scratch3[i] = np.mean(eps_p_f[self.ti[i]])
        m_step = pm.utils.value(self.M_eval) + np.dot(
            offdiag.T,
            pm.gp.trisolve(in_chol, (self.scratch3 - self.M_eval.value),
                           uplo='U',
                           transa='T')).view(np.ndarray).ravel()

        sig_step = C_step
        info = pm.gp.linalg_utils.dpotrf_wrap(C_step.T)
        if info > 0:
            warnings.warn(
                'Full conditional covariance was not positive definite.')
            return

        # Update value of f.
        self.f_eval.value = m_step + np.dot(
            sig_step, np.random.normal(size=sig_step.shape[1])).view(
                np.ndarray).ravel()
        # Propose the rest of the field from its conditional prior.
        self.f.rand()
예제 #29
0
    def step(self):
        """
        Perform the Robust Metropolis step.
        """

        self._current_iter += 1

        # Probability and likelihood for s's current value:

        if self.verbose > 2:
            print_()
            print_(self._id + ' getting initial logp.')

        logp = self.logp_plus_loglike

        if self.verbose > 2:
            print_(self._id + ' proposing.')

        # Sample a candidate value
        unit_proposal = self.unit_proposal(
        )  # First get unit proposal from a normal or t distribution.
        # Now scale this unit proposal
        if self._dim == 1:
            centered_proposal = self._cholesky_factor * unit_proposal
        else:
            centered_proposal = np.transpose(
                self._cholesky_factor).dot(unit_proposal)

        self.stochastic.value = self.stochastic.value + centered_proposal

        # Probability and likelihood for s's proposed value:
        try:
            logp_p = self.logp_plus_loglike

        except ZeroProbability:

            # Reject proposal
            if self.verbose > 2:
                print_(self._id + ' rejecting due to ZeroProbability.')
            self.reject()

            # Increment rejected count
            self._rejected += 1

            if self.verbose > 2:
                print_(self._id + ' returning.')

            return

        if self.verbose > 2:
            print_('logp_p - logp: ', logp_p - logp)

        # Evaluate acceptance ratio
        alpha = min(1.0, np.exp(logp_p - logp))

        unif = np.random.uniform()

        if unif > alpha:

            # Revert s if fail
            self.reject()

            # Increment rejected count
            self._rejected += 1
            if self.verbose > 2:
                print_(self._id + ' rejecting')
        else:
            # Increment accepted count
            self._accepted += 1
            if self.verbose > 2:
                print_(self._id + ' accepting')

        if (self._current_iter < self._stop_adapting) & (np.isfinite(alpha)):
            # Update the scale matrix of the proposals
            self.update_covar(alpha, unit_proposal, centered_proposal)

        if self.verbose > 2:
            print_(self._id + ' returning.')
예제 #30
0
    def step(self):
        """
        Perform the Robust Metropolis step.
        """

        self._current_iter += 1

        # Probability and likelihood for s's current value:

        if self.verbose > 2:
            print_()
            print_(self._id + ' getting initial logp.')

        logp = self.logp_plus_loglike

        if self.verbose > 2:
            print_(self._id + ' proposing.')

        # Sample a candidate value
        unit_proposal = self.unit_proposal()  # First get unit proposal from a normal or t distribution.
        # Now scale this unit proposal
        if self._dim == 1:
            centered_proposal = self._cholesky_factor * unit_proposal
        else:
            centered_proposal = np.transpose(self._cholesky_factor).dot(unit_proposal)

        self.stochastic.value = self.stochastic.value + centered_proposal

        # Probability and likelihood for s's proposed value:
        try:
            logp_p = self.logp_plus_loglike

        except ZeroProbability:

            # Reject proposal
            if self.verbose > 2:
                print_(self._id + ' rejecting due to ZeroProbability.')
            self.reject()

            # Increment rejected count
            self._rejected += 1

            if self.verbose > 2:
                print_(self._id + ' returning.')

            return

        if self.verbose > 2:
            print_('logp_p - logp: ', logp_p - logp)

        # Evaluate acceptance ratio
        alpha = min(1.0, np.exp(logp_p - logp))

        unif = np.random.uniform()

        if unif > alpha:

            # Revert s if fail
            self.reject()

            # Increment rejected count
            self._rejected += 1
            if self.verbose > 2:
                print_(self._id + ' rejecting')
        else:
            # Increment accepted count
            self._accepted += 1
            if self.verbose > 2:
                print_(self._id + ' accepting')

        if (self._current_iter < self._stop_adapting) & (np.isfinite(alpha)):
            # Update the scale matrix of the proposals
            self.update_covar(alpha, unit_proposal, centered_proposal)

        if self.verbose > 2:
            print_(self._id + ' returning.')
예제 #31
0
파일: diagnostics.py 프로젝트: wqren/pymc
def validate(sampler,
             replicates=20,
             iterations=10000,
             burn=5000,
             thin=1,
             deterministic=False,
             db='ram',
             plot=True,
             verbose=0):
    """
    Model validation method, following Cook et al. (Journal of Computational and
    Graphical Statistics, 2006, DOI: 10.1198/106186006X136976).
    
    Generates posterior samples based on 'true' parameter values and data simulated
    from the priors. The quantiles of the parameter values are calculated, based on
    the samples. If the model is valid, the quantiles should be uniformly distributed
    over [0,1].
    
    Since this relies on the generation of simulated data, all data stochastics
    must have a valid random() method for validation to proceed.
    
    Parameters
    ----------
    sampler : Sampler
      An MCMC sampler object.
    replicates (optional) : int
      The number of validation replicates (i.e. number of quantiles to be simulated).
      Defaults to 100.
    iterations (optional) : int
      The number of MCMC iterations to be run per replicate. Defaults to 2000.
    burn (optional) : int
      The number of burn-in iterations to be run per replicate. Defaults to 1000.
    thin (optional) : int
      The thinning factor to be applied to posterior sample. Defaults to 1 (no thinning)
    deterministic (optional) : bool
      Flag for inclusion of deterministic nodes in validation procedure. Defaults
      to False.
    db (optional) : string
      The database backend to use for the validation runs. Defaults to 'ram'.
    plot (optional) : bool
      Flag for validation plots. Defaults to True.
    
    Returns
    -------
    stats : dict
      Return a dictionary containing tuples with the chi-square statistic and
      associated p-value for each data stochastic.
    
    Notes
    -----
    This function requires SciPy.
    """
    import scipy as sp
    # Set verbosity for models to zero
    sampler.verbose = 0

    # Specify parameters to be evaluated
    parameters = sampler.stochastics
    if deterministic:
        # Add deterministics to the mix, if requested
        parameters = parameters | sampler.deterministics

    # Assign database backend
    original_backend = sampler.db.__name__
    sampler._assign_database_backend(db)

    # Empty lists for quantiles
    quantiles = {}

    if verbose:
        print_("\nExecuting Cook et al. (2006) validation procedure ...\n")

    # Loop over replicates
    for i in range(replicates):

        # Sample from priors
        for p in sampler.stochastics:
            if not p.extended_parents:
                p.random()

        # Sample "true" data values
        for o in sampler.observed_stochastics:
            # Generate simuated data for data stochastic
            o.set_value(o.random(), force=True)
            if verbose:
                print_("Data for %s is %s" % (o.__name__, o.value))

        param_values = {}
        # Record data-generating parameter values
        for s in parameters:
            param_values[s] = s.value

        try:
            # Fit models given parameter values
            sampler.sample(iterations, burn=burn, thin=thin)

            for s in param_values:

                if not i:
                    # Initialize dict
                    quantiles[s.__name__] = []
                trace = s.trace()
                q = sum(trace < param_values[s], 0) / float(len(trace))
                quantiles[s.__name__].append(open01(q))

            # Replace data values
            for o in sampler.observed_stochastics:
                o.revert()

        finally:
            # Replace data values
            for o in sampler.observed_stochastics:
                o.revert()

            # Replace backend
            sampler._assign_database_backend(original_backend)

        if not i % 10 and i and verbose:
            print_("\tCompleted validation replicate", i)

    # Replace backend
    sampler._assign_database_backend(original_backend)

    stats = {}
    # Calculate chi-square statistics
    for param in quantiles:
        q = quantiles[param]
        # Calculate chi-square statistics
        X2 = sum(sp.special.ndtri(q)**2)
        # Calculate p-value
        p = sp.special.chdtrc(replicates, X2)

        stats[param] = (X2, p)

    if plot:
        # Convert p-values to z-scores
        p = copy(stats)
        for i in p:
            p[i] = p[i][1]
        pymc.Matplot.zplot(p, verbose=verbose)

    return stats
예제 #32
0
파일: dram.py 프로젝트: meqash/PyMC-DRAM
    def __init__(
        self,
        stochastic,
        cov=None,
        delay=1000,
        interval=200,
        greedy=True,
        drscale=0.1,
        shrink_if_necessary=False,
        scales=None,
        verbose=-1,
        tally=False,
    ):
        # Verbosity flag
        self.verbose = verbose

        self.accepted = 0
        self.rejected = 0  # Just a dummy variable for compatibility with the superclass
        self.rejected_then_accepted = 0
        self.rejected_twice = 0

        if not np.iterable(stochastic) or isinstance(stochastic,
                                                     pymc.Variable):
            stochastic = [stochastic]

        # Initialize superclass
        pymc.StepMethod.__init__(self, stochastic, verbose, tally)

        self._id = 'DelayedRejectionAdaptiveMetropolis_' + '_'.join(
            [p.__name__ for p in self.stochastics])
        # State variables used to restore the state in a latter session.
        self._state += [
            'accepted', 'rejected_then_accepted', 'rejected_twice',
            '_trace_count', '_current_iter', 'C', 'proposal_sd',
            '_proposal_deviate', '_trace', 'shrink_if_necessary'
        ]
        self._tuning_info = ['C']

        self.proposal_sd = None
        self.shrink_if_necessary = shrink_if_necessary

        # Number of successful steps before the empirical covariance is
        # computed
        self.delay = delay
        # Interval between covariance updates
        self.interval = interval
        # Flag for tallying only accepted jumps until delay reached
        self.greedy = greedy
        # Scale for second attempt
        self.drscale = drscale

        # Initialization methods
        self.check_type()
        self.dimension()

        # Set the initial covariance using cov, or the following fallback mechanisms:
        # 1. If scales is provided, use it.
        # 2. If a trace is present, compute the covariance matrix empirically from it.
        # 3. Use the stochastics value as a guess of the variance.
        if cov is not None:
            self.C = cov
        elif scales:
            self.C = self.cov_from_scales(scales)
        else:
            try:
                self.C = self.cov_from_trace()
            except AttributeError:
                self.C = self.cov_from_value(100.)

        self.updateproposal_sd()

        # Keep track of the internal trace length
        # It may be different from the iteration count since greedy
        # sampling can be done during warm-up period.
        self._trace_count = 0
        self._current_iter = 0

        self._proposal_deviate = np.zeros(self.dim)
        self.chain_mean = np.asmatrix(np.zeros(self.dim))
        self._trace = []

        if self.verbose >= 2:
            print_("Initialization...")
            print_('Dimension: ', self.dim)
            print_("C_0: ", self.C)
            print_("Sigma: ", self.proposal_sd)
예제 #33
0
from . import PyMCmodel
import pymc as pm
from pymc import six
import numpy as np
import matplotlib.pyplot as pl
import matplotlib
matplotlib.rcParams['axes.facecolor'] = 'w'
import time

n_iter = 10000

rej = []
times = []
mesh_sizes = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
for mesh_size in [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]:
    six.print_(mesh_size)
    m = PyMCmodel.make_model(mesh_size, False)
    if mesh_size == 0:
        sm = pm.gp.MeshlessGPMetropolis(m['sm'].f)
    else:
        sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01)
    t1 = time.time()
    for i in xrange(n_iter):
        sm.step()
    times.append((time.time() - t1) / float(n_iter))
    rej.append(sm.rejected / float(sm.rejected + sm.accepted))

m = PyMCmodel.make_model(0, True)
sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01)
t1 = time.time()
for i in xrange(n_iter):
예제 #34
0
파일: diagnostics.py 프로젝트: wqren/pymc
def raftery_lewis(x, q, r, s=.95, epsilon=.001, verbose=1):
    """
    Return the number of iterations needed to achieve a given
    precision.
    
    :Parameters:
        x : sequence
            Sampled series.
        q : float
            Quantile.
        r : float
            Accuracy requested for quantile.
        s (optional) : float
            Probability of attaining the requested accuracy (defaults to 0.95).
        epsilon (optional) : float
             Half width of the tolerance interval required for the q-quantile (defaults to 0.001).
        verbose (optional) : int
            Verbosity level for output (defaults to 1).
    
    :Return:
        nmin : int
            Minimum number of independent iterates required to achieve
            the specified accuracy for the q-quantile.
        kthin : int
            Skip parameter sufficient to produce a first-order Markov
            chain.
        nburn : int
            Number of iterations to be discarded at the beginning of the
            simulation, i.e. the number of burn-in iterations.
        nprec : int
            Number of iterations not including the burn-in iterations which
            need to be obtained in order to attain the precision specified
            by the values of the q, r and s input parameters.
        kmind : int
            Minimum skip parameter sufficient to produce an independence
            chain.
    
    :Example:
        >>> raftery_lewis(x, q=.025, r=.005)
    
    :Reference:
        Raftery, A.E. and Lewis, S.M. (1995).  The number of iterations,
        convergence diagnostics and generic Metropolis algorithms.  In
        Practical Markov Chain Monte Carlo (W.R. Gilks, D.J. Spiegelhalter
        and S. Richardson, eds.). London, U.K.: Chapman and Hall.
        
        See the fortran source file `gibbsit.f` for more details and references.
    """
    if np.rank(x) > 1:
        return [
            raftery_lewis(y, q, r, s, epsilon, verbose)
            for y in np.transpose(x)
        ]

    output = nmin, kthin, nburn, nprec, kmind = pymc.flib.gibbmain(
        x, q, r, s, epsilon)

    if verbose:

        print_("\n========================")
        print_("Raftery-Lewis Diagnostic")
        print_("========================")
        print_()
        print_(
            "%s iterations required (assuming independence) to achieve %s accuracy with %i percent probability."
            % (nmin, r, 100 * s))
        print_()
        print_(
            "Thinning factor of %i required to produce a first-order Markov chain."
            % kthin)
        print_()
        print_(
            "%i iterations to be discarded at the beginning of the simulation (burn-in)."
            % nburn)
        print_()
        print_("%s subsequent iterations required." % nprec)
        print_()
        print_(
            "Thinning factor of %i required to produce an independence chain."
            % kmind)

    return output
예제 #35
0
def raftery_lewis(x, q, r, s=.95, epsilon=.001, verbose=1):
    """
    Return the number of iterations needed to achieve a given
    precision.
    
    :Parameters:
        x : sequence
            Sampled series.
        q : float
            Quantile.
        r : float
            Accuracy requested for quantile.
        s (optional) : float
            Probability of attaining the requested accuracy (defaults to 0.95).
        epsilon (optional) : float
             Half width of the tolerance interval required for the q-quantile (defaults to 0.001).
        verbose (optional) : int
            Verbosity level for output (defaults to 1).
    
    :Return:
        nmin : int
            Minimum number of independent iterates required to achieve
            the specified accuracy for the q-quantile.
        kthin : int
            Skip parameter sufficient to produce a first-order Markov
            chain.
        nburn : int
            Number of iterations to be discarded at the beginning of the
            simulation, i.e. the number of burn-in iterations.
        nprec : int
            Number of iterations not including the burn-in iterations which
            need to be obtained in order to attain the precision specified
            by the values of the q, r and s input parameters.
        kmind : int
            Minimum skip parameter sufficient to produce an independence
            chain.
    
    :Example:
        >>> raftery_lewis(x, q=.025, r=.005)
    
    :Reference:
        Raftery, A.E. and Lewis, S.M. (1995).  The number of iterations,
        convergence diagnostics and generic Metropolis algorithms.  In
        Practical Markov Chain Monte Carlo (W.R. Gilks, D.J. Spiegelhalter
        and S. Richardson, eds.). London, U.K.: Chapman and Hall.
        
        See the fortran source file `gibbsit.f` for more details and references.
    """
    if np.rank(x)>1:
        return [raftery_lewis(y, q, r, s, epsilon, verbose) for y in np.transpose(x)]
    
    output = nmin, kthin, nburn, nprec, kmind = pymc.flib.gibbmain(x, q, r, s, epsilon)
    
    if verbose:
        
        print_("\n========================")
        print_("Raftery-Lewis Diagnostic")
        print_("========================")
        print_()
        print_("%s iterations required (assuming independence) to achieve %s accuracy with %i percent probability." % (nmin, r, 100*s))
        print_()
        print_("Thinning factor of %i required to produce a first-order Markov chain." % kthin)
        print_()
        print_("%i iterations to be discarded at the beginning of the simulation (burn-in)." % nburn)
        print_()
        print_("%s subsequent iterations required." % nprec)
        print_()
        print_("Thinning factor of %i required to produce an independence chain." % kmind)
    
    return output
예제 #36
0
    def __init__(self, input=None, eps=.001, diff_order = 5, verbose=-1):
        if not scipy_imported:
            raise ImportError('Scipy must be installed to use NormApprox and MAP.')

        Model.__init__(self, input, verbose=verbose)

        # Allocate memory for internal traces and get stochastic slices
        self._slices = {}
        self.len = 0
        self.stochastic_len = {}
        self.fitted = False

        self.stochastic_list = list(self.stochastics)
        self.N_stochastics = len(self.stochastic_list)
        self.stochastic_indices = []
        self.stochastic_types = []
        self.stochastic_type_dict = {}

        for i in xrange(len(self.stochastic_list)):

            stochastic = self.stochastic_list[i]

            # Check types of all stochastics.
            type_now = check_type(stochastic)[0]
            self.stochastic_type_dict[stochastic] = type_now

            if not type_now is float:
                print_("Warning: Stochastic " + stochastic.__name__ + "'s value is neither numerical nor array with " + \
                            "floating-point dtype. Recommend fitting method fmin (default).")

            # Inspect shapes of all stochastics and create stochastic slices.
            if isinstance(stochastic.value, ndarray):
                self.stochastic_len[stochastic] = len(ravel(stochastic.value))
            else:
                self.stochastic_len[stochastic] = 1
            self._slices[stochastic] = slice(self.len, self.len + self.stochastic_len[stochastic])
            self.len += self.stochastic_len[stochastic]

            # Record indices that correspond to each stochastic.
            for j in range(len(ravel(stochastic.value))):
                self.stochastic_indices.append((stochastic, j))
                self.stochastic_types.append(type_now)

        self.data_len = 0
        for datum in self.observed_stochastics:
            self.data_len += len(ravel(datum.value))

        # Unpack step
        self.eps = zeros(self.len,dtype=float)
        if isinstance(eps,dict):
            for stochastic in self.stochastics:
                self.eps[self._slices[stochastic]] = eps[stochastic]
        else:
            self.eps[:] = eps

        self.diff_order = diff_order

        self._len_range = arange(self.len)

        # Initialize gradient and Hessian matrix.
        self.grad = zeros(self.len, dtype=float)
        self.hess = asmatrix(zeros((self.len, self.len), dtype=float))

        self._mu = None

        # Initialize NormApproxMu object.
        self.mu = NormApproxMu(self)

        def func_for_diff(val, index):
            """
            The function that gets passed to the derivatives.
            """
            self[index] = val
            return self.i_logp(index)

        self.func_for_diff = func_for_diff
예제 #37
0
파일: dram.py 프로젝트: meqash/PyMC-DRAM
    def step(self):
        """
        Perform a Metropolis step.
        Stochastic parameters are block-updated using a multivariate normal
        distribution whose covariance is updated every self.interval once
        self.delay steps have been performed.
        The AM instance keeps a local copy of the stochastic parameter's trace.
        This trace is used to computed the empirical covariance, and is
        completely independent from the Database backend.
        If self.greedy is True and the number of iterations is smaller than
        self.delay, only accepted jumps are stored in the internal
        trace to avoid computing singular covariance matrices.
        """

        # Probability and likelihood for stochastic's current value:
        # PROBLEM: I am using logp plus loglike everywhere... and I shouldn't be!! TODO
        logp = self.logp_plus_loglike

        if self.verbose > 1:
            print_('Current value: ', self.stoch2array())
            print_('Current likelihood: ', logp)

        # Sample a candidate value
        self.propose_first()

        # Metropolis acception/rejection test
        accept = False

        try:
            # Probability and likelihood for stochastic's 1st proposed value:
            self.logp_p1 = self.logp_plus_loglike
            logp_p1 = float(self.logp_p1)
            self.logalpha01 = min(0, logp_p1 - logp)
            logalpha01 = self.logalpha01

            if self.verbose > 2:
                print_('First proposed value: ', self.stoch2array())
                print_('First proposed likelihood: ', logp_p1)

            if np.log(np.random.random()) < logalpha01:
                accept = True
                self.accepted += 1

                if self.verbose > 2:
                    print_('Accepted')
                logp_p = logp_p1
            else:
                if self.verbose > 2:
                    print_('Delaying rejection...')

                for stochastic in self.stochastics:
                    stochastic.revert()

                self.propose_second()

                try:
                    # Probability and likelihood for stochastic's 2nd proposed value:
                    # CHECK THAT THIS IS RECALCULATED WITH PROPOSE_SECODN
                    # CHECK THAT logp_p1 iS NOT CHANGED WHEN THIS IS RECALCD
                    logp_p2 = self.logp_plus_loglike
                    logalpha21 = min(0, logp_p1 - logp_p2)
                    l = logp_p2 - logp
                    q = self.q

                    logalpha_02 = np.log(
                        l * q * (1 - np.exp(logalpha21)) \
                        / (1 - np.exp(logalpha01))
                    )

                    if self.verbose > 2:
                        print_('Second proposed value: ', self.stoch2array())
                        print_('Second proposed likelihood: ', logp_p2)

                    if np.log(np.random.random()) < logalpha_02:
                        accept = True
                        self.rejected_then_accepted += 1
                        logp_p = logp_p2
                        if self.verbose > 2:
                            print_('Accepted after one rejection')

                    else:
                        self.rejected_twice += 1
                        logp_p = None

                        if self.verbose > 2:
                            print_('Rejected twice')

                except pymc.ZeroProbability:
                    self.rejected_twice += 1
                    logp_p = None

                    if self.verbose > 2:
                        print_('Rejected twice')

        except pymc.ZeroProbability:
            if self.verbose > 2:
                print_('Delaying rejection...')

            for stochastic in self.stochastics:
                stochastic.revert()

            self.propose_second()

            try:
                # Probability and likelihood for stochastic's proposed value:
                logp_p2 = self.logp_plus_loglike
                logp_p1 = -np.inf
                logalpha01 = -np.inf
                logalpha21 = min(0, logp_p1 - logp_p2)
                l = np.exp(logp_p2 - logp)
                q = self.q

                logalpha_02 = np.log(
                    l * q * (1 - np.exp(logalpha21)) \
                    / (1 - np.exp(logalpha01))
                )

                if self.verbose > 2:
                    print_('Second proposed value: ', self.stoch2array())
                    print_('Second proposed likelihood: ', logp_p2)

                if np.log(np.random.random()) < logalpha_02:
                    accept = True
                    self.rejected_then_accepted += 1
                    logp_p = logp_p2

                    if self.verbose > 2:
                        print_(
                            'Accepted after one rejection with ZeroProbability'
                        )
                else:
                    self.rejected_twice += 1
                    logp_p = None

                    if self.verbose > 2:
                        print_('Rejected twice')

            except pymc.ZeroProbability:
                self.rejected_twice += 1
                logp_p = None

                if self.verbose > 2:
                    print_('Rejected twice with ZeroProbability Error.')
        #print_('\n\nRejected then accepted number of times: ',self.rejected_then_accepted)
        #print_('Rejected twice number of times: ',self.rejected_twice)

        if (not self._current_iter % self.interval) and self.verbose > 1:
            print_("Step ", self._current_iter)
            print_("\tLogprobability (current, proposed): ", logp, logp_p)

            for stochastic in self.stochastics:
                print_(
                    "\t",
                    stochastic.__name__,
                    stochastic.last_value,
                    stochastic.value,
                )

            if accept:
                print_("\tAccepted\t*******\n")

            else:
                print_("\tRejected\n")

            print_("\tAcceptance ratio: ",
                   (self.accepted + self.rejected_then_accepted) /
                   (self.accepted + 2. * self.rejected_then_accepted +
                    2. * self.rejected_twice))

        if self._current_iter == self.delay:
            self.greedy = False

        if not accept:
            self.reject()

        if accept or not self.greedy:
            self.internal_tally()

        if self._current_iter > self.delay and self._current_iter % self.interval == 0:
            self.update_cov()

        self._current_iter += 1
예제 #38
0
from . import PyMCmodel
import pymc as pm
from pymc import six
import numpy as np
import matplotlib.pyplot as pl
import matplotlib
matplotlib.rcParams['axes.facecolor']='w'
import time

n_iter = 10000

rej = []
times = []
mesh_sizes = [0,1,2,4,8,16,32,64,128,256,512]
for mesh_size in [0,1,2,4,8,16,32,64,128,256,512]:
    six.print_(mesh_size)
    m = PyMCmodel.make_model(mesh_size, False)
    if mesh_size==0:
        sm = pm.gp.MeshlessGPMetropolis(m['sm'].f)
    else:
        sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01)
    t1 = time.time()
    for i in xrange(n_iter):
        sm.step()
    times.append((time.time()-t1)/float(n_iter))
    rej.append(sm.rejected/float(sm.rejected + sm.accepted))

m = PyMCmodel.make_model(0, True)    
sm = pm.gp.GPEvaluationMetropolis(m['sm'].f_eval, proposal_sd=.01)
t1 = time.time()
for i in xrange(n_iter):
예제 #39
0
 def callback(p):
     try:
         print_('Current log-probability : %f' % self.logp)
     except ZeroProbability:
         print_('Current log-probability : %f' % -Inf)
예제 #40
0
def validate(sampler, replicates=20, iterations=10000, burn=5000, thin=1, deterministic=False, db='ram', plot=True, verbose=0):
    """
    Model validation method, following Cook et al. (Journal of Computational and
    Graphical Statistics, 2006, DOI: 10.1198/106186006X136976).
    
    Generates posterior samples based on 'true' parameter values and data simulated
    from the priors. The quantiles of the parameter values are calculated, based on
    the samples. If the model is valid, the quantiles should be uniformly distributed
    over [0,1].
    
    Since this relies on the generation of simulated data, all data stochastics
    must have a valid random() method for validation to proceed.
    
    Parameters
    ----------
    sampler : Sampler
      An MCMC sampler object.
    replicates (optional) : int
      The number of validation replicates (i.e. number of quantiles to be simulated).
      Defaults to 100.
    iterations (optional) : int
      The number of MCMC iterations to be run per replicate. Defaults to 2000.
    burn (optional) : int
      The number of burn-in iterations to be run per replicate. Defaults to 1000.
    thin (optional) : int
      The thinning factor to be applied to posterior sample. Defaults to 1 (no thinning)
    deterministic (optional) : bool
      Flag for inclusion of deterministic nodes in validation procedure. Defaults
      to False.
    db (optional) : string
      The database backend to use for the validation runs. Defaults to 'ram'.
    plot (optional) : bool
      Flag for validation plots. Defaults to True.
    
    Returns
    -------
    stats : dict
      Return a dictionary containing tuples with the chi-square statistic and
      associated p-value for each data stochastic.
    
    Notes
    -----
    This function requires SciPy.
    """
    import scipy as sp
    # Set verbosity for models to zero
    sampler.verbose = 0
    
    # Specify parameters to be evaluated
    parameters = sampler.stochastics
    if deterministic:
        # Add deterministics to the mix, if requested
        parameters = parameters | sampler.deterministics
    
    # Assign database backend
    original_backend = sampler.db.__name__
    sampler._assign_database_backend(db)
    
    # Empty lists for quantiles
    quantiles = {}
    
    if verbose:
        print_("\nExecuting Cook et al. (2006) validation procedure ...\n")
    
    # Loop over replicates
    for i in range(replicates):
        
        # Sample from priors
        for p in sampler.stochastics:
            if not p.extended_parents:
                p.random()
        
        # Sample "true" data values
        for o in sampler.observed_stochastics:
            # Generate simuated data for data stochastic
            o.set_value(o.random(), force=True)
            if verbose:
                print_("Data for %s is %s" % (o.__name__, o.value))
        
        param_values = {}
        # Record data-generating parameter values
        for s in parameters:
            param_values[s] = s.value
        
        try:
            # Fit models given parameter values
            sampler.sample(iterations, burn=burn, thin=thin)
            
            for s in param_values:
                
                if not i:
                    # Initialize dict
                    quantiles[s.__name__] = []
                trace = s.trace()
                q = sum(trace<param_values[s], 0)/float(len(trace))
                quantiles[s.__name__].append(open01(q))
            
            # Replace data values
            for o in sampler.observed_stochastics:
                o.revert()
        
        finally:
            # Replace data values
            for o in sampler.observed_stochastics:
                o.revert()
            
            # Replace backend
            sampler._assign_database_backend(original_backend)
        
        if not i % 10 and i and verbose:
            print_("\tCompleted validation replicate", i)

    
    # Replace backend
    sampler._assign_database_backend(original_backend)
    
    stats = {}
    # Calculate chi-square statistics
    for param in quantiles:
        q = quantiles[param]
        # Calculate chi-square statistics
        X2 = sum(sp.special.ndtri(q)**2)
        # Calculate p-value
        p = sp.special.chdtrc(replicates, X2)
        
        stats[param] = (X2, p)
    
    if plot:
        # Convert p-values to z-scores
        p = copy(stats)
        for i in p:
            p[i] = p[i][1]
        pymc.Matplot.zplot(p, verbose=verbose)
    
    return stats
예제 #41
0
    def __init__(self, input=None, eps=.001, diff_order=5, verbose=-1):
        if not scipy_imported:
            raise ImportError(
                'Scipy must be installed to use NormApprox and MAP.')

        Model.__init__(self, input, verbose=verbose)

        # Allocate memory for internal traces and get stochastic slices
        self._slices = {}
        self.len = 0
        self.stochastic_len = {}
        self.fitted = False

        self.stochastic_list = list(self.stochastics)
        self.N_stochastics = len(self.stochastic_list)
        self.stochastic_indices = []
        self.stochastic_types = []
        self.stochastic_type_dict = {}

        for i in xrange(len(self.stochastic_list)):

            stochastic = self.stochastic_list[i]

            # Check types of all stochastics.
            type_now = check_type(stochastic)[0]
            self.stochastic_type_dict[stochastic] = type_now

            if not type_now is float:
                print_("Warning: Stochastic " + stochastic.__name__ + "'s value is neither numerical nor array with " + \
                            "floating-point dtype. Recommend fitting method fmin (default).")

            # Inspect shapes of all stochastics and create stochastic slices.
            if isinstance(stochastic.value, ndarray):
                self.stochastic_len[stochastic] = len(ravel(stochastic.value))
            else:
                self.stochastic_len[stochastic] = 1
            self._slices[stochastic] = slice(
                self.len, self.len + self.stochastic_len[stochastic])
            self.len += self.stochastic_len[stochastic]

            # Record indices that correspond to each stochastic.
            for j in range(len(ravel(stochastic.value))):
                self.stochastic_indices.append((stochastic, j))
                self.stochastic_types.append(type_now)

        self.data_len = 0
        for datum in self.observed_stochastics:
            self.data_len += len(ravel(datum.value))

        # Unpack step
        self.eps = zeros(self.len, dtype=float)
        if isinstance(eps, dict):
            for stochastic in self.stochastics:
                self.eps[self._slices[stochastic]] = eps[stochastic]
        else:
            self.eps[:] = eps

        self.diff_order = diff_order

        self._len_range = arange(self.len)

        # Initialize gradient and Hessian matrix.
        self.grad = zeros(self.len, dtype=float)
        self.hess = asmatrix(zeros((self.len, self.len), dtype=float))

        self._mu = None

        # Initialize NormApproxMu object.
        self.mu = NormApproxMu(self)

        def func_for_diff(val, index):
            """
            The function that gets passed to the derivatives.
            """
            self[index] = val
            return self.i_logp(index)

        self.func_for_diff = func_for_diff