コード例 #1
0
ファイル: test_olse.py プロジェクト: yorkerlin/ep-stan
        if not oracle:
            Q2, r2 = invert_normal_params(S2,
                                          m2,
                                          out_A='in-place',
                                          out_b='in-place')
            r2s[:, i] = r2
            Q2s[:, :, i] = Q2

    # Get samples
    samp = N1.rvs(n)
    mt = np.mean(samp, axis=0)
    samp -= mt
    St = np.dot(samp.T, samp).T

    # olse
    olse(St / n, n, P=Q1 if oracle else Q2, out=Q_hats[:, :, i])
    r_hats[:, i] = Q_hats[:, :, i].dot(mt)

    # Basic sample estimates
    St /= n - 1
    invert_normal_params(St, mt, out_A=Q_samps[:, :, i], out_b=r_samps[:, i])
    # Unbiased natural parameter estimates
    unbias_k = (n - d - 2) / (n - 1)
    Q_samps[:, :, i] *= unbias_k
    r_samps[:, i] *= unbias_k

# Print result statistics
print 'Statistics of {} estimates'.format(N)
print('{:9}' + 4 * ' {:>13}').format('estimate', 'me (bias)', 'std', 'mse',
                                     '97.5se')
print 65 * '-'
コード例 #2
0
    def tilted(self, dQi, dri, save_fit=False):
        """Estimate the tilted distribution parameters.
        
        This method estimates the tilted distribution parameters and calculates
        the resulting site parameter updates into the given arrays. The cavity
        distribution has to be calculated before this method is called, i.e. the
        method cavity has to be run before this.
        
        After calling this method the instance variables self.Mat and self.vec
        hold the tilted distribution moment parameters (note however that the
        covariance matrix is unnormalised and the number of samples contributing
        to this matrix is stored in the instance variable self.nsamp).
        
        Parameters
        ----------
        dQi, dri : ndarray
            Output arrays where the site parameter updates are placed.
        
        save_fit : bool, optional
            If True, the Stan fit-object is saved into the instance variable
            `fit` for later use. Default is False.
        
        Returns
        -------
        pos_def
            True if the estimated tilted distribution covariance matrix is
            positive definite. False otherwise.
        
        """

        if self.phase != 1:
            raise RuntimeError('Cavity has to be calculated before tilted.')

        # FIXME: Temp fix for RandomState problem in 32-bit Python
        if self.fix32bit:
            self.stan_params['seed'] = self.rstate.randint(2**31 - 1)

        # Sample from the model
        with suppress_stdout():
            time_start = timer()
            fit = self.stan_model.sampling(data=self.data, **self.stan_params)
            time_end = timer()
            self.last_time = (time_end - time_start)

        if self.verbose:
            # Mean stepsize
            steps = [
                np.mean(p['stepsize__']) for p in fit.get_sampler_params()
            ]
            print '\n    mean stepsize: {:.4}'.format(np.mean(steps))
            # Max Rhat (from all but last row in the last column)
            print '    max Rhat: {:.4}'.format(
                np.max(fit.summary()['summary'][:-1, -1]))

        if self.init_prev:
            # Store the last sample of each chain
            if isinstance(self.stan_params['init'], basestring):
                # No samples stored before ... initialise list of dicts
                self.stan_params['init'] = get_last_fit_sample(fit)
            else:
                get_last_fit_sample(fit, out=self.stan_params['init'])

        # Extract samples
        # TODO: preallocate space for samples
        samp = copy_fit_samples(fit, self.fit_pnames)
        self.nsamp = samp.shape[0]

        if save_fit:
            # Save fit
            self.fit = fit
        else:
            # Dereference fit here so that it can be garbage collected
            fit = None

        # Estimate precision matrix
        try:
            # Basic sample estimate
            if self.prec_estim == 'sample' or self.prec_estim_skip > 0:
                # Mean
                mt = np.mean(samp, axis=0, out=self.vec)
                # Center samples
                samp -= mt
                # Use QR-decomposition for obtaining Cholesky of the scatter
                # matrix (only R needed, Q-less algorithm would be nice)
                _, _, _, info = dgeqrf_routine(samp, overwrite_a=True)
                if info:
                    raise linalg.LinAlgError(
                        "dgeqrf LAPACK routine failed with error code {}".
                        format(info))
                # Copy the relevant part of the array into contiguous memory
                np.copyto(self.Mat, samp[:self.dphi, :])
                invert_normal_params(self.Mat,
                                     mt,
                                     out_A=dQi,
                                     out_b=dri,
                                     cho_form=True)
                # Unbiased (for normal distr.) natural parameter estimates
                unbias_k = (self.nsamp - self.dphi - 2)
                dQi *= unbias_k
                dri *= unbias_k
                if self.prec_estim_skip > 0:
                    self.prec_estim_skip -= 1

            # Optimal linear shrinkage estimate
            elif self.prec_estim == 'olse':
                # Mean
                mt = np.mean(samp, axis=0, out=self.vec)
                # Center samples
                samp -= mt
                # Sample covariance
                np.dot(samp.T, samp, out=self.Mat.T)
                # Normalise self.Mat into dQi
                np.divide(self.Mat, self.nsamp, out=dQi)
                # Estimate
                olse(dQi, self.nsamp, P=self.Q, out='in-place')
                np.dot(dQi, mt, out=dri)

            # Graphical lasso with cross validation
            elif self.prec_estim == 'glassocv':
                # Mean
                mt = np.mean(samp, axis=0, out=self.vec)
                # Center samples
                samp -= mt
                # Fit
                self.glassocv.fit(samp)
                if self.verbose:
                    print '    glasso alpha: {:.4}'.format(
                        self.glassocv.alpha_)
                np.copyto(dQi, self.glassocv.precision_.T)
                # Calculate corresponding r
                np.dot(dQi, mt, out=dri)

            else:
                raise ValueError("Invalid value for option `prec_estim`")

            # Calculate the difference into the output arrays
            np.subtract(dQi, self.Q, out=dQi)
            np.subtract(dri, self.r, out=dri)

        except linalg.LinAlgError:
            # Precision estimate failed
            pos_def = False
            self.phase = 0
            dQi.fill(0)
            dri.fill(0)
            if self.init_prev:
                # Reset initialisation method
                self.init = self.init_orig
        else:
            # Set return and phase flag
            pos_def = True
            self.phase = 2

        self.iteration += 1
        return pos_def
コード例 #3
0
ファイル: test_olse.py プロジェクト: amoliu/ep-stan
        Q1, r1 = invert_normal_params(S1, m1)
        r1s[:, i] = r1
        Q1s[:, :, i] = Q1
        if not oracle:
            Q2, r2 = invert_normal_params(S2, m2, out_A="in_place", out_b="in_place")
            r2s[:, i] = r2
            Q2s[:, :, i] = Q2

    # Get samples
    samp = N1.rvs(n)
    mt = np.mean(samp, axis=0)
    samp -= mt
    St = np.dot(samp.T, samp).T

    # olse
    olse(St / n, n, P=Q1 if oracle else Q2, out=Q_hats[:, :, i])
    r_hats[:, i] = Q_hats[:, :, i].dot(mt)

    # Basic sample estimates
    St /= n - 1
    invert_normal_params(St, mt, out_A=Q_samps[:, :, i], out_b=r_samps[:, i])
    # Unbiased natural parameter estimates
    unbias_k = (n - d - 2) / (n - 1)
    Q_samps[:, :, i] *= unbias_k
    r_samps[:, i] *= unbias_k

# Print result statistics
print "Statistics of {} estimates".format(N)
print ("{:9}" + 4 * " {:>13}").format("estimate", "me (bias)", "std", "mse", "97.5se")
print 65 * "-"
for i in xrange(min(d, print_max)):
コード例 #4
0
    def tilted(self, dQi, dri):
        """Estimate the tilted distribution parameters.
        
        This method estimates the tilted distribution parameters and calculates
        the resulting site parameter updates into the given arrays. The cavity
        distribution has to be calculated before this method is called, i.e. the
        method cavity has to be run before this.
        
        After calling this method the instance variables self.Mat and self.vec
        hold the tilted distribution moment parameters (note however that the
        covariance matrix is unnormalised and the number of samples contributing
        to this matrix is stored in the instance variable self.nsamp).
        
        Parameters
        ----------
        dQi, dri : ndarray
            Output arrays where the site parameter updates are placed.
        
        Returns
        -------
        pos_def
            True if the estimated tilted distribution covariance matrix is
            positive definite. False otherwise.
        
        """

        if self.phase != 1:
            raise RuntimeError('Cavity has to be calculated before tilted.')

        # FIXME: Temp fix for RandomState problem in 32-bit Python
        if self.fix32bit:
            self.stan_params['seed'] = self.rstate.randint(2**31 - 1)

        # Sample from the model
        try:
            with suppress_stdout():
                fit = self.stan_model.sampling(data=self.data,
                                               pars=('phi'),
                                               **self.stan_params)
        except ValueError:
            print 'Worker {} failed'.format(self.index)
            with open('stan_params.pkl', 'wb') as f:
                pickle.dump(self.stan_params, f)
            with open('data.pkl', 'wb') as f:
                pickle.dump(self.data, f)
            raise ValueError('Jaahast')

        if self.init_prev:
            # Store the last sample of each chain
            if isinstance(self.stan_params['init'], basestring):
                # No samples stored before ... initialise list of dicts
                self.stan_params['init'] = get_last_sample(fit)
            else:
                get_last_sample(fit, out=self.stan_params['init'])

        # TODO: Make a non-copying extract
        samp = fit.extract(pars='phi')['phi']
        self.nsamp = samp.shape[0]

        # Assign arrays
        St = self.Mat
        mt = self.vec

        # Sample mean and covariance
        np.mean(samp, axis=0, out=mt)
        samp -= mt
        np.dot(samp.T, samp, out=St.T)

        if not self.smooth is None:
            # Smoothen the distribution (use dri and dQi as temp arrays)
            St, mt = self._apply_smooth(dri, dQi)

        # Estimate precision matrix
        try:
            # Basic sample estimate
            if self.prec_estim == 'sample' or self.prec_estim_skip > 0:
                # Normalise St unbiased into dQi
                np.divide(St, self.nsamp - 1, out=dQi)
                # Convert moment params to natural params
                invert_normal_params(dQi, mt, out_A='in_place', out_b=dri)
                # Unbiased natural parameter estimates
                unbias_k = (self.nsamp - self.dphi - 2) / (self.nsamp - 1)
                dQi *= unbias_k
                dri *= unbias_k

            # Optimal linear shrinkage estimate
            elif self.prec_estim == 'olse':
                # Normalise St into dQi
                np.divide(St, self.nsamp, out=dQi)
                # Estimate
                olse(dQi, self.nsamp, P=self.Q, out='in_place')
                np.dot(dQi, mt, out=dri)

            else:
                raise ValueError("Invalid value for option `prec_estim`")

            # Calculate the difference into the output arrays
            np.subtract(dQi, self.Q, out=dQi)
            np.subtract(dri, self.r, out=dri)

        except linalg.LinAlgError:
            # Precision estimate failed
            pos_def = False
            self.phase = 0
            dQi.fill(0)
            dri.fill(0)
            if not self.smooth is None:
                # Reset tilted memory
                self.prev_stored = 0
            if self.init_prev:
                # Reset initialisation method
                self.init = self.init_orig
        else:
            # Set return and phase flag
            pos_def = True
            self.phase = 2

        self.iteration += 1
        return pos_def