jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def __init__(self, n_components=2,
                 mean=np.array([[-0.1], [0.05]]),
                 covar=np.array([0.0007, 0.007]),
                 weight=np.array([0.4, 0.6]),
                 covariance_type='spherical'):
        super(GMMInputDistribution, self).__init__()
        self.model = mixture.GaussianMixture(n_components=n_components, covariance_type=covariance_type)
        self.model.means_ = mean
        self.model.covariances_ = covar
        self.model.weights_ = weight

        # update the estimated distribution
        _samp_size = 10 ** 5
        self.samples, _ = self.model.sample(_samp_size)
        self.n_var = len(self.samples[0])
        self._est_mean = self.samples.mean(axis=0)
        self._est_var = self.samples.var(axis=0)
//  [python]
def __init__(self, n_components=2,
                 mean=np.array([[-0.1], [0.05]]),
                 covar=np.array([0.0007, 0.007]),
                 weight=np.array([0.4, 0.6]),
                 covariance_type='spherical'):
        super(GMMInputDistribution, self).__init__()
        self.model = GaussianMixture(n_components=n_components, covariance_type=covariance_type)
        self.model.means_ = mean
        self.model.covariances_ = covar
        self.model.weights_ = weight

        # update the estimated distribution
        _samp_size = 10 ** 5
        self.samples, _ = self.model.sample(_samp_size)
        self.n_var = len(self.samples[0])
        self._est_mean = self.samples.mean(axis=0)
        self._est_var = self.samples.var(axis=0)
//  [python]
def sample(self,x,t,feature):
        observations = x[:,:t]
        p_s_past={} #p(s_t-1|X_{0:t-1})
        for st in self.states:
            p_s_past[st],_,_ = fwd_bkw(observations, self.states, self.start_probability, self.transition_probability, self.emission_probability,st)

        #p_currstate_past={'Healthy': 0., 'Sick':0.} #p(s_t | X_{0:t-1})
        p_currstate_past={}
        for s in self.states:
            p_currstate_past[s] = 0.

        for curr_state in self.states: 
            for st in self.states:
                p_currstate_past[curr_state] += self.transition_probability[curr_state][st]*p_s_past[st]
        
        gmm = mixture.GaussianMixture(n_components = len(self.states),covariance_type='full')
        gmm.fit(np.random.randn(10, observations.shape[0]))
        gmm.weights_ = list(p_currstate_past.values())
        gmm.means_ = np.array(self.mean)
        gmm.covariances_ = np.array(self.cov)
        for i in  range(2):
            gmm.precisions_[i] = np.linalg.inv(gmm.covariances_[i])
            gmm.precisions_cholesky_[i] = np.linalg.cholesky(gmm.covariances_[i])

        x_sampled = gmm.sample()[0]
        return x_sampled[0,feature]
//  [python]
def sample(self,x,t,feature):
        observations = x[:,:t]
        p_s_past={} #p(s_t-1|X_{0:t-1})
        for st in self.states:
            p_s_past[st],_,_ = fwd_bkw(observations, self.states, self.start_probability, self.transition_probability, self.emission_probability,st)

        #p_currstate_past={'Healthy': 0., 'Sick':0.} #p(s_t | X_{0:t-1})
        p_currstate_past={}
        for s in self.states:
            p_currstate_past[s] = 0.

        for curr_state in self.states: 
            for st in self.states:
                p_currstate_past[curr_state] += self.transition_probability[curr_state][st]*p_s_past[st]
        
        gmm = GaussianMixture(n_components = len(self.states),covariance_type='full')
        gmm.fit(np.random.randn(10, observations.shape[0]))
        gmm.weights_ = list(p_currstate_past.values())
        gmm.means_ = np.array(self.mean)
        gmm.covariances_ = np.array(self.cov)
        for i in  range(2):
            gmm.precisions_[i] = np.linalg.inv(gmm.covariances_[i])
            gmm.precisions_cholesky_[i] = np.linalg.cholesky(gmm.covariances_[i])

        x_sampled = gmm.sample()[0]
        return x_sampled[0,feature]
//  [python]
def log_prob(self,x,t,feature,samples):
        observations = x[:,:t]
        p_s_past={} #p(s_t-1|X_{0:t-1})
        for st in self.states:
            p_s_past[st],_,_ = fwd_bkw(observations, self.states, self.start_probability, self.transition_probability, self.emission_probability,st)

        p_currstate_past={}
        for s in self.states:
            p_currstate_past[s] = 0.

        for curr_state in self.states: 
            for st in self.states:
                p_currstate_past[curr_state] += self.transition_probability[curr_state][st]*p_s_past[st]
        
        gmm = mixture.GaussianMixture(n_components = len(self.states),covariance_type='full')
        gmm.fit(np.random.randn(10, observations.shape[0]))
        gmm.weights_ = list(p_currstate_past.values())
        gmm.means_ = np.array(self.mean)
        gmm.covariances_ = np.array(self.cov)
        for i in range(2):
            gmm.precisions_[i] = np.linalg.inv(gmm.covariances_[i])
            gmm.precisions_cholesky_[i] = np.linalg.cholesky(gmm.covariances_[i])
        
        return gmm.score_samples(samples)
//  [python]
def log_prob(self,x,t,feature,samples):
        observations = x[:,:t]
        p_s_past={} #p(s_t-1|X_{0:t-1})
        for st in self.states:
            p_s_past[st],_,_ = fwd_bkw(observations, self.states, self.start_probability, self.transition_probability, self.emission_probability,st)

        p_currstate_past={}
        for s in self.states:
            p_currstate_past[s] = 0.

        for curr_state in self.states: 
            for st in self.states:
                p_currstate_past[curr_state] += self.transition_probability[curr_state][st]*p_s_past[st]
        
        gmm = GaussianMixture(n_components = len(self.states),covariance_type='full')
        gmm.fit(np.random.randn(10, observations.shape[0]))
        gmm.weights_ = list(p_currstate_past.values())
        gmm.means_ = np.array(self.mean)
        gmm.covariances_ = np.array(self.cov)
        for i in range(2):
            gmm.precisions_[i] = np.linalg.inv(gmm.covariances_[i])
            gmm.precisions_cholesky_[i] = np.linalg.cholesky(gmm.covariances_[i])
        
        return gmm.score_samples(samples)
//  [python]
def gmm_score_func(self, data, data_idx, cell_coor, radius, threshold, p_num, queue, lock, err_log_fp=None):
        # t0 = time.time()
        p_data = []
        count = len(data_idx)
        err_logs = []
        for idx, i in enumerate(data_idx):
            try:
                clf = mixture.GaussianMixture(n_components=3, covariance_type='spherical')
                # Gaussian Mixture Model GPU version
                cell_test = data[(data.x < cell_coor.loc[i].x + radius) & (data.x > cell_coor.loc[i].x - radius)
                                 & (data.y > cell_coor.loc[i].y - radius) & (data.y < cell_coor.loc[i].y + radius)]
                # fit GaussianMixture Model
                clf.fit(cell_test[cell_test.label == cell_coor.loc[i].label][['x', 'y', 'UMICount']].values)
                # cell_test_bg = cell_test[cell_test.label == 0]
                # # threshold 20
                # score = pd.Series(-clf.score_samples(cell_test_bg[['x', 'y', 'UMICount']].values))
                cell_test_bg_ori = cell_test[cell_test.label == 0]
                bg_group = cell_test_bg_ori.groupby(['x', 'y']).agg(UMI_max=('UMICount', 'max')).reset_index()
                cell_test_bg = pd.merge(cell_test_bg_ori, bg_group, on=['x', 'y'])
                # threshold 20
                score = pd.Series(-clf.score_samples(cell_test_bg[['x', 'y', 'UMI_max']].values))
                cell_test_bg['score'] = score.values
                # threshold = self.threshold
                cell_test_bg['label'] = np.where(score < threshold, cell_coor.loc[i].label, 0)
                # used multiprocessing have to save result to file
                p_data.append(cell_test_bg)
            except Exception as e:
                if err_log_fp is not None:
                    err_msg = f"proc {p_num}, cell id {cell_coor.loc[i].label}, {e}\n"
                    err_logs.append(err_msg)

            if len(err_logs) >= 10 or ((idx + 1) == count and len(err_logs) > 0):
                try:
                    lock.acquire()
                    err_log_fp.writelines(err_logs)
                    err_log_fp.flush()
                finally:
                    lock.release()
                    err_logs.clear()

            mod = (idx + 1) % self.progress_update_interval
            if (mod == 0) or (idx + 1 == count):
                c = self.progress_update_interval if mod == 0 else mod
                queue.put((False, p_num, c))

        out = pd.concat(p_data)
        out.drop('UMI_max', axis=1, inplace=True)
        queue.put((True, p_num, out))
//  [python]
def gmm_score_func(self, data, data_idx, cell_coor, radius, threshold, p_num, queue, lock, err_log_fp=None):
        # t0 = time.time()
        p_data = []
        count = len(data_idx)
        err_logs = []
        for idx, i in enumerate(data_idx):
            try:
                clf = GaussianMixture(n_components=3, covariance_type='spherical')
                # Gaussian Mixture Model GPU version
                cell_test = data[(data.x < cell_coor.loc[i].x + radius) & (data.x > cell_coor.loc[i].x - radius)
                                 & (data.y > cell_coor.loc[i].y - radius) & (data.y < cell_coor.loc[i].y + radius)]
                # fit GaussianMixture Model
                clf.fit(cell_test[cell_test.label == cell_coor.loc[i].label][['x', 'y', 'UMICount']].values)
                # cell_test_bg = cell_test[cell_test.label == 0]
                # # threshold 20
                # score = pd.Series(-clf.score_samples(cell_test_bg[['x', 'y', 'UMICount']].values))
                cell_test_bg_ori = cell_test[cell_test.label == 0]
                bg_group = cell_test_bg_ori.groupby(['x', 'y']).agg(UMI_max=('UMICount', 'max')).reset_index()
                cell_test_bg = pd.merge(cell_test_bg_ori, bg_group, on=['x', 'y'])
                # threshold 20
                score = pd.Series(-clf.score_samples(cell_test_bg[['x', 'y', 'UMI_max']].values))
                cell_test_bg['score'] = score.values
                # threshold = self.threshold
                cell_test_bg['label'] = np.where(score < threshold, cell_coor.loc[i].label, 0)
                # used multiprocessing have to save result to file
                p_data.append(cell_test_bg)
            except Exception as e:
                if err_log_fp is not None:
                    err_msg = f"proc {p_num}, cell id {cell_coor.loc[i].label}, {e}\n"
                    err_logs.append(err_msg)

            if len(err_logs) >= 10 or ((idx + 1) == count and len(err_logs) > 0):
                try:
                    lock.acquire()
                    err_log_fp.writelines(err_logs)
                    err_log_fp.flush()
                finally:
                    lock.release()
                    err_logs.clear()

            mod = (idx + 1) % self.progress_update_interval
            if (mod == 0) or (idx + 1 == count):
                c = self.progress_update_interval if mod == 0 else mod
                queue.put((False, p_num, c))

        out = pd.concat(p_data)
        out.drop('UMI_max', axis=1, inplace=True)
        queue.put((True, p_num, out))
//  [python]
def initialize(self):
        """Initialize sklearn GMM.
        """
        self.model = sklearn.mixture.GMM(
            n_components=self.K,
            covariance_type=self.covar_type,
            random_state=0,
            verbose=self.verbose,
            verbose_interval=self.verbose_interval
        )
//  [python]
def initialize(self):
        """Initialize sklearn GMM.
        """
        self.model = sklearn.mixture.GaussianMixture(
            n_components=self.K,
            covariance_type=self.covar_type,
            random_state=0,
            verbose=self.verbose,
            verbose_interval=self.verbose_interval
        )
//  [python]
def genee_EM(betas, reg_covar=0.000001):
    # based on https://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_selection.html#sphx-glr-auto-examples-mixture-plot-gmm-selection-py
    lowest_bic = np.inf
    for n_components in range(1, 10):
        gmm = mixture.GaussianMixture(
            n_components=n_components, reg_covar=reg_covar, random_state=0
        ).fit(betas)
        bic = gmm.bic(betas)
        if bic < lowest_bic:
            lowest_bic = bic
            best_gmm = gmm

    covars = best_gmm.covariances_.squeeze()
    if best_gmm.n_components == 1:  # pragma: no cover
        epsilon_effect = covars[0]
    else:
        # TODO: handle case where first component composed more than 50% SNPs
        # https://github.com/ramachandran-lab/genee/blob/a357a956241df93f16e07664e24f3aeac65f4177/genee/R/genee_EM.R#L28-L29
        covars_decreasing = np.sort(covars)[::-1]
        epsilon_effect = covars_decreasing[1]

    return epsilon_effect
//  [python]
def genee_EM(betas, reg_covar=0.000001):
    # based on https://scikit-learn.org/stable/auto_examples/mixture/plot_gmm_selection.html#sphx-glr-auto-examples-mixture-plot-gmm-selection-py
    lowest_bic = np.inf
    for n_components in range(1, 10):
        gmm = GaussianMixture(
            n_components=n_components, reg_covar=reg_covar, random_state=0
        ).fit(betas)
        bic = gmm.bic(betas)
        if bic < lowest_bic:
            lowest_bic = bic
            best_gmm = gmm

    covars = best_gmm.covariances_.squeeze()
    if best_gmm.n_components == 1:  # pragma: no cover
        epsilon_effect = covars[0]
    else:
        # TODO: handle case where first component composed more than 50% SNPs
        # https://github.com/ramachandran-lab/genee/blob/a357a956241df93f16e07664e24f3aeac65f4177/genee/R/genee_EM.R#L28-L29
        covars_decreasing = np.sort(covars)[::-1]
        epsilon_effect = covars_decreasing[1]

    return epsilon_effect
//  [python]
def get_statistic_gmm(data: List[np.ndarray], num_clusters: int) -> List[StatisticGMM]:
    """Compute the statistics of the data based on GMM

    Parameters
    ----------
    data: List[np.ndarray]
        (z_dim,), List of the numpy 1-d arrays
    num_clusters: int
        The number of clusters in GMM

    Returns
    -------
    List[Statistic]
        List of mean, covariance of the data
    """
    gm = mixture.GaussianMixture(n_components=num_clusters).fit(data)

    means = gm.means_
    covs = gm.covariances_
    weights = gm.weights_

    return [
        StatisticGMM(mean=means[cdx], cov=covs[cdx], weight=weights[cdx])
        for cdx in range(num_clusters)
    ]
//  [python]
def get_statistic_gmm(data: List[np.ndarray], num_clusters: int) -> List[StatisticGMM]:
    """Compute the statistics of the data based on GMM

    Parameters
    ----------
    data: List[np.ndarray]
        (z_dim,), List of the numpy 1-d arrays
    num_clusters: int
        The number of clusters in GMM

    Returns
    -------
    List[Statistic]
        List of mean, covariance of the data
    """
    gm = GaussianMixture(n_components=num_clusters).fit(data)

    means = gm.means_
    covs = gm.covariances_
    weights = gm.weights_

    return [
        StatisticGMM(mean=means[cdx], cov=covs[cdx], weight=weights[cdx])
        for cdx in range(num_clusters)
    ]
//  [python]
def _estimate_GMM(self, x, n_component_lim):
		"""
        Find the GMM that best fit the data in x using Bayesian information criterion.
        """
		min_comp = n_component_lim[0]
		max_comp = n_component_lim[1]

		lowest_BIC = np.inf
		best_GMM_ind = 0
		all_GMMs = []
		counter = 0
		for i_comp in range(min_comp, max_comp + 1):
			all_GMMs.append(mixture.GaussianMixture(i_comp))
			all_GMMs[-1].fit(x)
			BIC = all_GMMs[-1].bic(x)
			if BIC < lowest_BIC:
				lowest_BIC = BIC
				best_GMM_ind = counter
			counter += 1

		best_GMM = all_GMMs[best_GMM_ind]
		return best_GMM
//  [python]
def _estimate_GMM(self, x, n_component_lim):
		"""
        Find the GMM that best fit the data in x using Bayesian information criterion.
        """
		min_comp = n_component_lim[0]
		max_comp = n_component_lim[1]

		lowest_BIC = np.inf
		best_GMM_ind = 0
		all_GMMs = []
		counter = 0
		for i_comp in range(min_comp, max_comp + 1):
			all_GMMs.append(GaussianMixture(i_comp))
			all_GMMs[-1].fit(x)
			BIC = all_GMMs[-1].bic(x)
			if BIC < lowest_BIC:
				lowest_BIC = BIC
				best_GMM_ind = counter
			counter += 1

		best_GMM = all_GMMs[best_GMM_ind]
		return best_GMM
//  [python]
def generate_sample_data(self, n_clusters:int=3, n_samples:int=100):
        """
        Generate random sample data from Gaussian Mixture model.
        """
        gmm = mixture.GaussianMixture(n_components=n_clusters)
        w = np.random.random(n_clusters)
        gmm.weights_ = w/np.sum(w)
        gmm.means_ = np.random.normal(size=(n_clusters, 2))
        # covariance matrix must be positive-deterministic
        t = np.random.normal(size=(n_clusters, 2, 2))/3
        gmm.covariances_ = np.einsum("ijk,ilk->ijl", t, t)
        self.data = gmm.sample(n_samples)[0]
//  [python]
def generate_sample_data(self, n_clusters:int=3, n_samples:int=100):
        """
        Generate random sample data from Gaussian Mixture model.
        """
        gmm = GaussianMixture(n_components=n_clusters)
        w = np.random.random(n_clusters)
        gmm.weights_ = w/np.sum(w)
        gmm.means_ = np.random.normal(size=(n_clusters, 2))
        # covariance matrix must be positive-deterministic
        t = np.random.normal(size=(n_clusters, 2, 2))/3
        gmm.covariances_ = np.einsum("ijk,ilk->ijl", t, t)
        self.data = gmm.sample(n_samples)[0]
//  [python]
def _gmmtrain(self, n_components, max_iter, covariance_type, data, modelname):
    classifier = mixture.GaussianMixture(n_components=n_components, \
            max_iter=max_iter, covariance_type=covariance_type)
    classifier.fit(data)
    joblib.dump(classifier, os.path.join(self.modeldir, modelname))
    time.sleep(3)
//  [python]
def _gmmtrain(self, n_components, max_iter, covariance_type, data, modelname):
    classifier = GaussianMixture(n_components=n_components, \
            max_iter=max_iter, covariance_type=covariance_type)
    classifier.fit(data)
    joblib.dump(classifier, os.path.join(self.modeldir, modelname))
    time.sleep(3)
//  [python]
def generate_GM(self, n_components=None, modes=None):

        true_keys = [i for i in self.observables.keys() if
                     self.observables[i] is not None]
        true_distributions = []

        for key in true_keys:

            if 'mags' in key:

                for obs in self.observables[key].values():
                    true_distributions.append(obs)

            else:

                true_distributions.append(self.observables[key])

        true_distributions = np.c_[true_distributions].T

        if n_components is None:
            n_components = len(true_keys)

        if modes is not None:

            if len(modes) > n_components:
                n_components = len(modes)

            means_init = []

            for i in range(n_components):

                mode = modes[i % len(modes)]
                mode_params = []

                for key in true_keys:

                    if 'mags' in key:

                        for obs in mode[key].values():
                            mode_params.append(obs)

                    else:

                        mode_params.append(mode[key])

                means_init.append(mode_params)
        else:
            means_init = None

        gm = s.GaussianMixture(n_components=n_components, means_init=means_init)
        gm.fit(true_distributions)
        self.gm = gm
        self.gm_keys = true_keys.copy()
//  [python]
def generate_GM(self, n_components=None, modes=None):

        true_keys = [i for i in self.observables.keys() if
                     self.observables[i] is not None]
        true_distributions = []

        for key in true_keys:

            if 'mags' in key:

                for obs in self.observables[key].values():
                    true_distributions.append(obs)

            else:

                true_distributions.append(self.observables[key])

        true_distributions = np.c_[true_distributions].T

        if n_components is None:
            n_components = len(true_keys)

        if modes is not None:

            if len(modes) > n_components:
                n_components = len(modes)

            means_init = []

            for i in range(n_components):

                mode = modes[i % len(modes)]
                mode_params = []

                for key in true_keys:

                    if 'mags' in key:

                        for obs in mode[key].values():
                            mode_params.append(obs)

                    else:

                        mode_params.append(mode[key])

                means_init.append(mode_params)
        else:
            means_init = None

        gm = skmix.GaussianMixture(n_components=n_components, means_init=means_init)
        gm.fit(true_distributions)
        self.gm = gm
        self.gm_keys = true_keys.copy()
//  [python]
def __init__(self, mu, logvar, n_components=10, z_num_samples=10, **mog_kwargs):
        self.mu = mu
        self.logvar = logvar
        self.N, self.D = mu.shape
        self.z = torch.cat([mu + (0.5 * logvar).exp() * torch.randn_like(logvar) for s in range(z_num_samples)], dim=0)
        self.n_components = n_components
        self.mog = mixture.GaussianMixture(n_components=self.n_components, **mog_kwargs)
        self.mog.fit(self.z.cpu().numpy())
        print('mog-{}. Converged: {} in {} iters, log likelihood lower bound: {:.4f}'.format(
            self.n_components, self.mog.converged_, self.mog.n_iter_, self.mog.lower_bound_))
//  [python]
def __init__(self, mu, logvar, n_components=10, z_num_samples=10, **mog_kwargs):
        self.mu = mu
        self.logvar = logvar
        self.N, self.D = mu.shape
        self.z = torch.cat([mu + (0.5 * logvar).exp() * torch.randn_like(logvar) for s in range(z_num_samples)], dim=0)
        self.n_components = n_components
        self.mog = sklearn.mixture.GaussianMixture(n_components=self.n_components, **mog_kwargs)
        self.mog.fit(self.z.cpu().numpy())
        print('mog-{}. Converged: {} in {} iters, log likelihood lower bound: {:.4f}'.format(
            self.n_components, self.mog.converged_, self.mog.n_iter_, self.mog.lower_bound_))
//  [python]
ax.set(ylabel = iris.feature_names[idx2])
save_fig("iris-2d-unlabeled")
plt.show()


K = 3
y_pred = mixture.GaussianMixture(n_components=K, random_state=42).fit(X).predict(X)
//  [python]
ax.set(ylabel = iris.feature_names[idx2])
save_fig("iris-2d-unlabeled")
plt.show()


K = 3
y_pred = GaussianMixture(n_components=K, random_state=42).fit(X).predict(X)
//  [python]
def test(args, seed):
    np.random.seed(seed)
    gmm = mixture.GaussianMixture(n_components=args.num, tol=1e-3, max_iter=200, n_init=1, verbose=1)

    if args.pca_num > 0:
        pca = PCA(n_components=args.pca_num)


    train_x = np.loadtxt(os.path.join(args.exp_dir, "train.vec"), delimiter="\t")
    valid_x = np.loadtxt(os.path.join(args.exp_dir, "val.vec"), delimiter="\t")
    test_x = np.loadtxt(os.path.join(args.exp_dir, "test.vec"), delimiter="\t")

    if args.pca_num > 0:
        pca.fit(train_x)

        train_x = pca.transform(train_x)
        valid_x = pca.transform(valid_x)
        test_x = pca.transform(test_x)

    print(train_x.shape)

    print("start fitting gmm on training data")
    gmm.fit(train_x)

    valid_pred_y = gmm.predict(valid_x)
    valid_true_y = np.loadtxt(os.path.join(args.exp_dir, "val.label"), dtype=np.int)

    if args.one2one:
        print("linear assignment")
        cost_matrix = np.zeros((args.num, args.num))

        for i, j in zip(valid_pred_y, valid_true_y):
            cost_matrix[i,j] -= 1

        row_ind, col_ind = linear_sum_assignment(cost_matrix)
    else:
        # (nsamples, ncomponents)
        valid_score = gmm.predict_proba(valid_x)
        valid_max_index = np.argmax(valid_score, axis=0)
        col_ind = {}
        for i in range(args.num):
            col_ind[i] = valid_true_y[valid_max_index[i]]

    print(col_ind)
    correct = 0.
    for i, j in zip(valid_pred_y, valid_true_y):
        if col_ind[i] == j:
            correct += 1
    print("validation acc {}".format(correct / len(valid_pred_y)))

    test_pred_y = gmm.predict(test_x)
    test_true_y = np.loadtxt(os.path.join(args.exp_dir, "test.label"), dtype=np.int)
    correct = 0.
    for i, j in zip(test_pred_y, test_true_y):
        if col_ind[i] == j:
            correct += 1
    print("test acc {}".format(correct / len(test_pred_y)))

    train_pred_y = gmm.predict(train_x)
    train_true_y = np.loadtxt(os.path.join(args.exp_dir, "train.label"), dtype=np.int)
    correct = 0.
    for i, j in zip(train_pred_y, train_true_y):
        if col_ind[i] == j:
            correct += 1
    print("train acc {}".format(correct / len(train_pred_y)))
    return correct / len(train_pred_y)
//  [python]
def test(args, seed):
    np.random.seed(seed)
    gmm = GaussianMixture(n_components=args.num, tol=1e-3, max_iter=200, n_init=1, verbose=1)

    if args.pca_num > 0:
        pca = PCA(n_components=args.pca_num)


    train_x = np.loadtxt(os.path.join(args.exp_dir, "train.vec"), delimiter="\t")
    valid_x = np.loadtxt(os.path.join(args.exp_dir, "val.vec"), delimiter="\t")
    test_x = np.loadtxt(os.path.join(args.exp_dir, "test.vec"), delimiter="\t")

    if args.pca_num > 0:
        pca.fit(train_x)

        train_x = pca.transform(train_x)
        valid_x = pca.transform(valid_x)
        test_x = pca.transform(test_x)

    print(train_x.shape)

    print("start fitting gmm on training data")
    gmm.fit(train_x)

    valid_pred_y = gmm.predict(valid_x)
    valid_true_y = np.loadtxt(os.path.join(args.exp_dir, "val.label"), dtype=np.int)

    if args.one2one:
        print("linear assignment")
        cost_matrix = np.zeros((args.num, args.num))

        for i, j in zip(valid_pred_y, valid_true_y):
            cost_matrix[i,j] -= 1

        row_ind, col_ind = linear_sum_assignment(cost_matrix)
    else:
        # (nsamples, ncomponents)
        valid_score = gmm.predict_proba(valid_x)
        valid_max_index = np.argmax(valid_score, axis=0)
        col_ind = {}
        for i in range(args.num):
            col_ind[i] = valid_true_y[valid_max_index[i]]

    print(col_ind)
    correct = 0.
    for i, j in zip(valid_pred_y, valid_true_y):
        if col_ind[i] == j:
            correct += 1
    print("validation acc {}".format(correct / len(valid_pred_y)))

    test_pred_y = gmm.predict(test_x)
    test_true_y = np.loadtxt(os.path.join(args.exp_dir, "test.label"), dtype=np.int)
    correct = 0.
    for i, j in zip(test_pred_y, test_true_y):
        if col_ind[i] == j:
            correct += 1
    print("test acc {}".format(correct / len(test_pred_y)))

    train_pred_y = gmm.predict(train_x)
    train_true_y = np.loadtxt(os.path.join(args.exp_dir, "train.label"), dtype=np.int)
    correct = 0.
    for i, j in zip(train_pred_y, train_true_y):
        if col_ind[i] == j:
            correct += 1
    print("train acc {}".format(correct / len(train_pred_y)))
    return correct / len(train_pred_y)
//  [python]
def calc_pdf_gmm(x, x_bins, n_components=4):
    gmm = mixture.GMM(n_components=n_components)
    gmm.fit(x.reshape(-1, 1))
    pdf = np.exp(gmm.score(x_bins.reshape(-1, 1)))
    return pdf
//  [python]
def calc_pdf_gmm(x, x_bins, n_components=4):
    gmm = GaussianMixture(n_components=n_components)
    gmm.fit(x.reshape(-1, 1))
    pdf = np.exp(gmm.score_samples(x_bins.reshape(-1, 1)))
    return pdf
//  [python]
gmm = mixture.GaussianMixture(n_components=4, random_state=42)
plot_gmm(gmm, X)

#on stretched data
gmm = mixture.GaussianMixture(n_components=4, covariance_type='full', random_state=42)
//  [python]
gmm = GaussianMixture(n_components=4, random_state=42)
plot_gmm(gmm, X)

#on stretched data
gmm = GaussianMixture(n_components=4, covariance_type='full', random_state=42)
//  [python]
def _get_GMM_params(L, vertices, scaling, n_components):

    def delta_func(v):
        v = v - scaling['dataset_min']
        v = v / scaling['dataset_scale']
        return L @ v

    deltas = np.array([delta_func(v) for v in vertices])

    means = []
    covs = []
    for dim in tf.range(deltas.shape[2]):
        dim_means = []
        dim_covs = []
        gmm = mixture.GaussianMixture(n_components=n_components, covariance_type="diag")
        gmm.fit(deltas[:,:,dim])
        for k in tf.range(n_components):
            dim_means.append(gmm.means_[k])
            dim_covs.append(gmm.covariances_[k])
        means.append(dim_means)
        covs.append(dim_covs)

    means = tf.constant(np.array(means))
    covs = tf.constant(np.array(covs))

    return means, covs
//  [python]
def _get_GMM_params(L, vertices, scaling, n_components):

    def delta_func(v):
        v = v - scaling['dataset_min']
        v = v / scaling['dataset_scale']
        return L @ v

    deltas = np.array([delta_func(v) for v in vertices])

    means = []
    covs = []
    for dim in tf.range(deltas.shape[2]):
        dim_means = []
        dim_covs = []
        gmm = GaussianMixture(n_components=n_components, covariance_type="diag")
        gmm.fit(deltas[:,:,dim])
        for k in tf.range(n_components):
            dim_means.append(gmm.means_[k])
            dim_covs.append(gmm.covariances_[k])
        means.append(dim_means)
        covs.append(dim_covs)

    means = tf.constant(np.array(means))
    covs = tf.constant(np.array(covs))

    return means, covs
//  [python]
def read_pred():
    means = readFloat('%s-mixture_distribution_means.float3' % predition_path)  # shape (4, 2)
    sigmas = readFloat('%s-mixture_distribution_sigmas.float3' % predition_path)  # shape (4, 2)
    weights = readFloat('%s-mixture_distribution_weights.float3' % predition_path)  # shape (4)

    sigmas = 2 * sigmas * sigmas

    gmm = mixture.GMM(n_components=4, covariance_type='diag')

    precisions_cholesky = _compute_precision_cholesky(sigmas, 'diag')
    gmm.weights_ = weights
    gmm.means_ = means
    gmm.precisions_cholesky_ = precisions_cholesky
    gmm.covariances_ = sigmas

    return gmm
//  [python]
def read_pred():
    means = readFloat('%s-mixture_distribution_means.float3' % predition_path)  # shape (4, 2)
    sigmas = readFloat('%s-mixture_distribution_sigmas.float3' % predition_path)  # shape (4, 2)
    weights = readFloat('%s-mixture_distribution_weights.float3' % predition_path)  # shape (4)

    sigmas = 2 * sigmas * sigmas

    gmm = GaussianMixture(n_components=4, covariance_type='diag')

    precisions_cholesky = _compute_precision_cholesky(sigmas, 'diag')
    gmm.weights_ = weights
    gmm.means_ = means
    gmm.precisions_cholesky_ = precisions_cholesky
    gmm.covariances_ = sigmas

    return gmm
//  [python]
def plot_kmeans_gmm(X, k):
    fig, ax = plt.subplots(1, 3, figsize=(16, 4))    
    ax[0].set_title("Original dataset")
    ax[0].set_xlabel("Feature 0")
    ax[0].set_ylabel("Feature 1")    
    discrete_scatter(X[:, 0], X[:, 1], ax=ax[0]);
    # cluster the data into three clusters
    # plot the cluster assignments and cluster centers

    kmeans = KMeans(n_clusters=k, n_init='auto', random_state=42)
    kmeans.fit(X)
    ax[1].set_title(f"KMeans clusters n_clusters={k}")    
    ax[1].set_xlabel("Feature 0")
    ax[1].set_ylabel("Feature 1")        
    discrete_scatter(X[:, 0], X[:, 1], kmeans.labels_, markers='o', ax=ax[1])
    discrete_scatter(
        kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], range(0,k), s=15, 
        markers='*', markeredgewidth=1.0, ax=ax[1])   
    
    gmm = mixture.GaussianMixture(n_components=k, random_state=42)
    gmm.fit(X)
    ax[2].set_title(f"Gaussian Mixture clusters n_components={k}")    
    ax[2].set_xlabel("Feature 0")
    ax[2].set_ylabel("Feature 1")        
    discrete_scatter(X[:, 0], X[:, 1], gmm.predict(X), markers='o', ax=ax[2])
//  [python]
def plot_kmeans_gmm(X, k):
    fig, ax = plt.subplots(1, 3, figsize=(16, 4))    
    ax[0].set_title("Original dataset")
    ax[0].set_xlabel("Feature 0")
    ax[0].set_ylabel("Feature 1")    
    discrete_scatter(X[:, 0], X[:, 1], ax=ax[0]);
    # cluster the data into three clusters
    # plot the cluster assignments and cluster centers

    kmeans = KMeans(n_clusters=k, n_init='auto', random_state=42)
    kmeans.fit(X)
    ax[1].set_title(f"KMeans clusters n_clusters={k}")    
    ax[1].set_xlabel("Feature 0")
    ax[1].set_ylabel("Feature 1")        
    discrete_scatter(X[:, 0], X[:, 1], kmeans.labels_, markers='o', ax=ax[1])
    discrete_scatter(
        kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], range(0,k), s=15, 
        markers='*', markeredgewidth=1.0, ax=ax[1])   
    
    gmm = GaussianMixture(n_components=k, random_state=42)
    gmm.fit(X)
    ax[2].set_title(f"Gaussian Mixture clusters n_components={k}")    
    ax[2].set_xlabel("Feature 0")
    ax[2].set_ylabel("Feature 1")        
    discrete_scatter(X[:, 0], X[:, 1], gmm.predict(X), markers='o', ax=ax[2])
//  [python]
def kde_entropy_sklearn_gmm(points, n_est=None, n_components=None):
    """
    Use sklearn.neigbors.KernelDensity pdf to estimate entropy.

    Data is standardized before kde.

    Sample points drawn from gaussian mixture model from original points.

    Fails for bimodal and dirichlet, similar to statsmodels kde.
    """
    from sklearn.mixture import BayesianGaussianMixture as GMM
    n, d = points.shape

    # Default to the full set
    if n_est is None:
        n_est = n

    # reduce size of draw to n_est
    if n_est >= n:
        x = points
    else:
        x = points[permutation(n)[:n_est]]
        n = n_est

    if n_components is None:
        n_components = int(5*sqrt(d))

    predictor = GMM(n_components=n_components, covariance_type='full',
                    #verbose=True,
                    max_iter=1000)
    predictor.fit(x)
    evaluation_points, _ = predictor.sample(n_est)

    logp = sklearn_log_density(x, evaluation_points=evaluation_points)
    H = -np.mean(logp)
    return H / LN2
//  [python]
def gmm_clustering(data, n_clusters=2, n_iters=100, n_restarts=3, cov_type='diag',  rand_gen=None):

    if rand_gen is None:
        rand_gen = numpy.random.RandomState(RND_SEED)

    #
    # creating the cluster from sklearn
    gmm_c = s.GaussianMixture(n_components=n_clusters,
                                            covariance_type=cov_type,
                                            random_state=rand_gen,
                                            max_iter=n_iters,
                                            n_init=n_restarts)

    #
    # fitting to training set
    fit_start_t = perf_counter()
    gmm_c.fit(data)
    fit_end_t = perf_counter()
    logging.debug('GMM clustering fitted in {}'.format(fit_end_t - fit_start_t))

    #
    # getting the cluster assignment
    pred_start_t = perf_counter()
    clustering = gmm_c.predict(data)
    pred_end_t = perf_counter()
    logging.debug('Cluster assignment predicted in {}'.format(pred_end_t - pred_start_t))

    if n_clusters == 2:
        ones = clustering.sum()
        logging.info('Binary GMM split #0/#1: {}/{}'.format(data.shape[0] - ones,
                                                            ones))

    return clustering
//  [python]
def gmm_clustering(data, n_clusters=2, n_iters=100, n_restarts=3, cov_type='diag',  rand_gen=None):

    if rand_gen is None:
        rand_gen = numpy.random.RandomState(RND_SEED)

    #
    # creating the cluster from sklearn
    gmm_c = sklearn.mixture.GaussianMixture(n_components=n_clusters,
                                            covariance_type=cov_type,
                                            random_state=rand_gen,
                                            max_iter=n_iters,
                                            n_init=n_restarts)

    #
    # fitting to training set
    fit_start_t = perf_counter()
    gmm_c.fit(data)
    fit_end_t = perf_counter()
    logging.debug('GMM clustering fitted in {}'.format(fit_end_t - fit_start_t))

    #
    # getting the cluster assignment
    pred_start_t = perf_counter()
    clustering = gmm_c.predict(data)
    pred_end_t = perf_counter()
    logging.debug('Cluster assignment predicted in {}'.format(pred_end_t - pred_start_t))

    if n_clusters == 2:
        ones = clustering.sum()
        logging.info('Binary GMM split #0/#1: {}/{}'.format(data.shape[0] - ones,
                                                            ones))

    return clustering
//  [python]
def GMM(train, x_train, y_train, x_test, y_test, n_components=16, model=False):
    print("Train GMM-UBM model !")
    # split x,y to train and test
    start_time = get_time()
    # if model is True, it will load model from Model/GMM_MFCC_model.pkl.
    # if False,it will train and save model

    if model:
        print("load model from file...")
        with open("Model/GMM_MFCC_model.pkl", 'rb') as f:
            GMM = pkl.load(f)
        with open("Model/UBM_MFCC_model.pkl", 'rb') as f:
            UBM = pkl.load(f)
    else:
        # speaker_list = os.listdir('dataset/ASR_GMM')
        GMM = []
        ubm_train = None
        flag = False
        # UBM = []
        print("Train GMM!")
        for speaker in tqdm(label_encoder.values()):
            # print(type(speaker))
            # speaker = label_encoder[speaker]
            # GMM based on speaker
            gmm = mixture.GaussianMixture(n_components = n_components, covariance_type='diag')
            gmm.fit(train[speaker])
            GMM.append(gmm)
            if flag:
                ubm_train = np.vstack((ubm_train, train[speaker]))
            else:
                ubm_train = train[speaker]
                flag = True

        # UBM based on background
        print("Train UBM!")
        UBM = mixture.GaussianMixture(n_components = n_components, covariance_type='diag')
        UBM.fit(ubm_train)
        # UBM.append(gmm)

        if not os.path.exists('Model'):
            os.mkdir("Model")

        with open("Model/GMM_MFCC_model.pkl", 'wb') as f:
            pkl.dump(GMM, f)
        with open("Model/UBM_MFCC_model.pkl", 'wb') as f:
            pkl.dump(UBM, f)

    # train accuracy
    valid = np.zeros((len(x_train), len(GMM)))
    for i in range(len(GMM)):
        for j in range(len(x_train)):
            valid[j, i] = GMM[i].score(x_train[j]) - UBM.score(x_train[j])

    valid = valid.argmax(axis=1)
    acc_train = (valid==np.array(y_train)).sum()/len(x_train)

    # test accuracy
    pred = np.zeros((len(x_test), len(GMM)))
    for i in range(len(GMM)):
        for j in range(len(x_test)):
            pred[j, i] = GMM[i].score(x_test[j]) - UBM.score(x_test[j])

    pred = pred.argmax(axis=1)
    acc = (pred==np.array(y_test)).sum()/len(x_test)

    print("spend {:.2f}s, train acc {:.2%}, test acc {:.2%}".format(get_time(start_time), acc_train,acc))
//  [python]
def GMM(train, x_train, y_train, x_test, y_test, n_components=16, model=False):
    print("Train GMM-UBM model !")
    # split x,y to train and test
    start_time = get_time()
    # if model is True, it will load model from Model/GMM_MFCC_model.pkl.
    # if False,it will train and save model

    if model:
        print("load model from file...")
        with open("Model/GMM_MFCC_model.pkl", 'rb') as f:
            GMM = pkl.load(f)
        with open("Model/UBM_MFCC_model.pkl", 'rb') as f:
            UBM = pkl.load(f)
    else:
        # speaker_list = os.listdir('dataset/ASR_GMM')
        GMM = []
        ubm_train = None
        flag = False
        # UBM = []
        print("Train GMM!")
        for speaker in tqdm(label_encoder.values()):
            # print(type(speaker))
            # speaker = label_encoder[speaker]
            # GMM based on speaker
            gmm = GaussianMixture(n_components = n_components, covariance_type='diag')
            gmm.fit(train[speaker])
            GMM.append(gmm)
            if flag:
                ubm_train = np.vstack((ubm_train, train[speaker]))
            else:
                ubm_train = train[speaker]
                flag = True

        # UBM based on background
        print("Train UBM!")
        UBM = GaussianMixture(n_components = n_components, covariance_type='diag')
        UBM.fit(ubm_train)
        # UBM.append(gmm)

        if not os.path.exists('Model'):
            os.mkdir("Model")

        with open("Model/GMM_MFCC_model.pkl", 'wb') as f:
            pkl.dump(GMM, f)
        with open("Model/UBM_MFCC_model.pkl", 'wb') as f:
            pkl.dump(UBM, f)

    # train accuracy
    valid = np.zeros((len(x_train), len(GMM)))
    for i in range(len(GMM)):
        for j in range(len(x_train)):
            valid[j, i] = GMM[i].score(x_train[j]) - UBM.score(x_train[j])

    valid = valid.argmax(axis=1)
    acc_train = (valid==np.array(y_train)).sum()/len(x_train)

    # test accuracy
    pred = np.zeros((len(x_test), len(GMM)))
    for i in range(len(GMM)):
        for j in range(len(x_test)):
            pred[j, i] = GMM[i].score(x_test[j]) - UBM.score(x_test[j])

    pred = pred.argmax(axis=1)
    acc = (pred==np.array(y_test)).sum()/len(x_test)

    print("spend {:.2f}s, train acc {:.2%}, test acc {:.2%}".format(get_time(start_time), acc_train,acc))
//  [python]
def fit_gmm(x, max_components=10, **gmm_kwargs):

    models, scores = [], []
    for n in range(1, max_components + 1):
        gmm = mixture.GaussianMixture(n_components=n, **gmm_kwargs)
        gmm.fit(x)

        models.append(gmm)
        scores.append(gmm.bic(x))

    best_idx = np.argmin(scores)
    best_score = scores[best_idx]
    best_model = models[best_idx]

    return best_model, best_score
//  [python]
def fit_gmm(x, max_components=10, **gmm_kwargs):

    models, scores = [], []
    for n in range(1, max_components + 1):
        gmm = GaussianMixture(n_components=n, **gmm_kwargs)
        gmm.fit(x)

        models.append(gmm)
        scores.append(gmm.bic(x))

    best_idx = np.argmin(scores)
    best_score = scores[best_idx]
    best_model = models[best_idx]

    return best_model, best_score
//  [python]
y_true = y_true % 2
y = np.full(shape=y_true.shape, fill_value=MISSING_LABEL)

# Initialise the classifier.
clf = SklearnClassifier(LogisticRegression(), classes=np.unique(y_true))
# Initialise the query strategy.
qs = UncertaintySampling(method='least_confident', random_state=random_state)
gmm = mixture.GaussianMixture(init_params='kmeans', n_components=5)
//  [python]
y_true = y_true % 2
y = np.full(shape=y_true.shape, fill_value=MISSING_LABEL)

# Initialise the classifier.
clf = SklearnClassifier(LogisticRegression(), classes=np.unique(y_true))
# Initialise the query strategy.
qs = UncertaintySampling(method='least_confident', random_state=random_state)
gmm = GaussianMixture(init_params='kmeans', n_components=5)
//  [python]
def uncertain_gmm_clustering(data, n_clusters=2, threshold=0.7, n_iters=100, n_restarts=3, cov_type='diag',  rand_gen=None):

    if rand_gen is None:
        rand_gen = numpy.random.RandomState(RND_SEED)

    #
    # first perform GMM clustering
    gmm_c = sklearn.mixture.GMM(n_components=n_clusters,
                                            covariance_type=cov_type,
                                            random_state=rand_gen,
                                            n_iter=n_iters,
                                            n_init=n_restarts)

    #
    # fitting to training set
    fit_start_t = perf_counter()
    gmm_c.fit(data)
    fit_end_t = perf_counter()
    logging.debug('UGMM clustering fitted in {}'.format(fit_end_t - fit_start_t))

    #
    # getting the cluster probabilities
    n_instances = data.shape[0]
    pred_start_t = perf_counter()
    clustering_probs = gmm_c.predict_proba(data)
    hard_clustering = numpy.argmax(clustering_probs, axis=1)
    assert hard_clustering.shape[0] == n_instances
    max_probs = clustering_probs[numpy.arange(n_instances), hard_clustering]
    print('max probs', max_probs)
    unc_clustering = max_probs < threshold

    clustering = gmm_c.predict(data)
    unc_cluster_id = max(clustering) + 1
    print('# cluster', unc_cluster_id)
    #
    # assigning to uncertain cluster
    clustering[unc_clustering] = unc_cluster_id
    print(clustering)

    pred_end_t = perf_counter()
    logging.debug('Cluster assignment predicted in {}'.format(pred_end_t - pred_start_t))

    #
    # then, make

    if n_clusters == 2:
        ones = clustering.sum()
        logging.info('Binary UGMM split #0/#1: {}/{}'.format(data.shape[0] - ones,
                                                             ones))

    return clustering
//  [python]
def uncertain_gmm_clustering(data, n_clusters=2, threshold=0.7, n_iters=100, n_restarts=3, cov_type='diag',  rand_gen=None):

    if rand_gen is None:
        rand_gen = numpy.random.RandomState(RND_SEED)

    #
    # first perform GMM clustering
    gmm_c = sklearn.mixture.GaussianMixture(n_components=n_clusters,
                                            covariance_type=cov_type,
                                            random_state=rand_gen,
                                            max_iter=n_iters,
                                            n_init=n_restarts)

    #
    # fitting to training set
    fit_start_t = perf_counter()
    gmm_c.fit(data)
    fit_end_t = perf_counter()
    logging.debug('UGMM clustering fitted in {}'.format(fit_end_t - fit_start_t))

    #
    # getting the cluster probabilities
    n_instances = data.shape[0]
    pred_start_t = perf_counter()
    clustering_probs = gmm_c.predict_proba(data)
    hard_clustering = numpy.argmax(clustering_probs, axis=1)
    assert hard_clustering.shape[0] == n_instances
    max_probs = clustering_probs[numpy.arange(n_instances), hard_clustering]
    print('max probs', max_probs)
    unc_clustering = max_probs < threshold

    clustering = gmm_c.predict(data)
    unc_cluster_id = max(clustering) + 1
    print('# cluster', unc_cluster_id)
    #
    # assigning to uncertain cluster
    clustering[unc_clustering] = unc_cluster_id
    print(clustering)

    pred_end_t = perf_counter()
    logging.debug('Cluster assignment predicted in {}'.format(pred_end_t - pred_start_t))

    #
    # then, make

    if n_clusters == 2:
        ones = clustering.sum()
        logging.info('Binary UGMM split #0/#1: {}/{}'.format(data.shape[0] - ones,
                                                             ones))

    return clustering
//  [python]
def gmm_entropy(points, n_est=None, n_components=None):
    r"""
    Use sklearn.mixture.BayesianGaussianMixture to estimate entropy.

    *points* are the data points in the sample.

    *n_est* are the number of points to use in the estimation; default is
    10,000 points, or 0 for all the points.

    *n_components* are the number of Gaussians in the mixture. Default is
    $5 \sqrt{d}$ where $d$ is the number of dimensions.

    Returns estimated entropy and uncertainty in the estimate.

    This method uses BayesianGaussianMixture from scikit-learn to build a
    model of the point distribution, then uses Monte Carlo sampling to
    determine the entropy of that distribution. The entropy uncertainty is
    computed from the variance in the MC sample scaled by the number of
    samples. This does not incorporate any uncertainty in the sampling that
    generated the point distribution or the uncertainty in the GMM used to
    model that distribution.
    """
    #from sklearn.mixture import GaussianMixture as GMM
    from sklearn.mixture import BayesianGaussianMixture as GMM
    n, d = points.shape

    # Default to the full set
    if n_est is None:
        n_est = 10000
    elif n_est == 0:
        n_est = n

    # reduce size of draw to n_est
    if n_est >= n:
        x = points
        n_est = n
    else:
        x = points[permutation(n)[:n_est]]
        n = n_est

    if n_components is None:
        n_components = int(5*sqrt(d))

    ## Standardization doesn't seem to help
    ## Note: sigma may be zero
    #x, mu, sigma = standardize(x)   # if standardized
    predictor = GMM(n_components=n_components, covariance_type='full',
                    #verbose=True,
                    max_iter=1000)
    predictor.fit(x)
    eval_x, _ = predictor.sample(n_est)
    weight_x = predictor.score_samples(eval_x)
    H = -np.mean(weight_x)
    #with np.errstate(divide='ignore'): H = H + np.sum(np.log(sigma))   # if standardized
    dH = np.std(weight_x, ddof=1) / sqrt(n)
    ## cross-check against own calcs
    #alt = GaussianMixture(predictor.weights_, mu=predictor.means_, sigma=predictor.covariances_)
    #print("alt", H, alt.entropy())
    #print(np.vstack((weight_x[:10], alt.logpdf(eval_x[:10]))).T)
    return H / LN2, dH / LN2