def choose(node_info: MixtureGaussianParams, pvals: List[Union[str, float]]) -> Optional[float]: """ Func to get value from current node node_info: nodes info from distributions pvals: parent values Return value from MixtureGaussian node """ mean = node_info["mean"] covariance = node_info["covars"] w = node_info["coef"] n_comp = len(node_info['coef']) if n_comp != 0: if pvals: indexes = [i for i in range(1, len(pvals) + 1)] if not np.isnan(np.array(pvals)).all(): gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=covariance) cond_gmm = gmm.condition(indexes, [pvals]) sample = cond_gmm.sample(1)[0][0] else: sample = np.nan else: gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=covariance) sample = gmm.sample(1)[0][0] else: sample = np.nan return sample
def choose(self, pvalues, method, outcome): ''' Randomly choose state of node from probability distribution conditioned on *pvalues*. This method has two parts: (1) determining the proper probability distribution, and (2) using that probability distribution to determine an outcome. Arguments: 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. ''' random.seed() sample = 0 if method == 'simple': # calculate Bayesian parameters (mean and variance) mean = self.Vdataentry["mean_base"] if (self.Vdataentry["parents"] != None): for x in range(len(self.Vdataentry["parents"])): if (pvalues[x] != "default"): mean += pvalues[x] * self.Vdataentry["mean_scal"][x] else: print( "Attempted to sample node with unassigned parents." ) variance = self.Vdataentry["variance"] sample = random.gauss(mean, math.sqrt(variance)) else: mean = self.Vdataentry["mean_base"] variance = self.Vdataentry["variance"] w = self.Vdataentry["mean_scal"] n_comp = len(self.Vdataentry["mean_scal"]) if n_comp != 0: if (self.Vdataentry["parents"] != None): indexes = [ i for i in range(1, (len(self.Vdataentry["parents"]) + 1), 1) ] if not np.isnan(np.array(pvalues)).all(): gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) sample = gmm.predict(indexes, [pvalues])[0][0] else: sample = np.nan else: gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) sample = gmm.sample(1)[0][0] else: sample = np.nan return sample
def choose_gmm(self, pvalues, outcome): ''' Randomly choose state of node from probability distribution conditioned on *pvalues*. This method has two parts: (1) determining the proper probability distribution, and (2) using that probability distribution to determine an outcome. Arguments: 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. ''' random.seed() # calculate Bayesian parameters (mean and variance) s = 0 mean = self.Vdataentry["mean_base"] variance = self.Vdataentry["variance"] w = self.Vdataentry["mean_scal"] n_comp = len(self.Vdataentry["mean_scal"]) indexes = [ i for i in range(1, (len(self.Vdataentry["parents"]) + 1), 1) ] if (self.Vdataentry["parents"] != None): # for x in range(len(self.Vdataentry["parents"])): # if (pvalues[x] != "default"): # X.append(pvalues[x]) # else: # print ("Attempted to sample node with unassigned parents.") if not np.isnan(np.array(pvalues)).any(): gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) s = gmm.predict(indexes, [pvalues])[0][0] else: s = np.nan else: gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) s = gmm.sample(1)[0][0] # draw random outcome from Gaussian # note that this built in function takes the standard deviation, not the # variance, thus requiring a square root return s
def choose(node_info: Dict[str, Dict[str, CondMixtureGaussParams]], pvals: List[Union[str, float]]) -> Optional[float]: """ Function to get value from ConditionalMixtureGaussian node params: node_info: nodes info from distributions pvals: parent values """ dispvals = [] lgpvals = [] for pval in pvals: if ((isinstance(pval, str)) | ((isinstance(pval, int)))): dispvals.append(pval) else: lgpvals.append(pval) lgdistribution = node_info["hybcprob"][str(dispvals)] mean = lgdistribution["mean"] covariance = lgdistribution["covars"] w = lgdistribution["coef"] if len(w) != 0: if len(lgpvals) != 0: indexes = [i for i in range(1, (len(lgpvals) + 1), 1)] if not np.isnan(np.array(lgpvals)).all(): n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=covariance) cond_gmm = gmm.condition(indexes, [lgpvals]) sample = cond_gmm.sample(1)[0][0] else: sample = np.nan else: n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=covariance) sample = gmm.sample(1)[0][0] else: sample = np.nan return sample
def test_estimate_moments(): """Test moments estimated from samples and sampling from GMM.""" global X global random_state gmm = GMM(n_components=2, random_state=random_state) gmm.from_samples(X) assert_less(np.linalg.norm(gmm.means[0] - means[0]), 0.005) assert_less(np.linalg.norm(gmm.covariances[0] - covariances[0]), 0.01) assert_less(np.linalg.norm(gmm.means[1] - means[1]), 0.01) assert_less(np.linalg.norm(gmm.covariances[1] - covariances[1]), 0.03) X = gmm.sample(n_samples=100000) gmm = GMM(n_components=2, random_state=random_state) gmm.from_samples(X) assert_less(np.linalg.norm(gmm.means[0] - means[0]), 0.01) assert_less(np.linalg.norm(gmm.covariances[0] - covariances[0]), 0.03) assert_less(np.linalg.norm(gmm.means[1] - means[1]), 0.01) assert_less(np.linalg.norm(gmm.covariances[1] - covariances[1]), 0.04)
random_state = np.random.RandomState(100) gmm = GMM(n_components=2, priors=np.array([0.2, 0.8]), means=np.array([[0.0, 0.0], [0.0, 5.0]]), covariances=np.array([[[1.0, 2.0], [2.0, 9.0]], [[9.0, 2.0], [2.0, 1.0]]]), random_state=random_state) n_samples = 1000 plt.figure(figsize=(20, 5)) ax = plt.subplot(141) ax.set_title("Unconstrained Sampling") samples = gmm.sample(n_samples) ax.scatter(samples[:, 0], samples[:, 1], alpha=0.9, s=1, label="Samples") plot_error_ellipses(ax, gmm, factors=(1.0, 2.0), colors=["orange", "orange"]) ax.set_xlim((-10, 10)) ax.set_ylim((-10, 10)) ax = plt.subplot(142) ax.set_title(r"95.45 % Confidence Region ($2\sigma$)") samples = gmm.sample_confidence_region(n_samples, 0.9545) ax.scatter(samples[:, 0], samples[:, 1], alpha=0.9, s=1, label="Samples") plot_error_ellipses(ax, gmm, factors=(1.0, 2.0), colors=["orange", "orange"]) ax.set_xlim((-10, 10)) ax.set_ylim((-10, 10)) ax = plt.subplot(143) ax.set_title(r"68.27 % Confidence Region ($\sigma$)")
gmm.from_samples(X) cond = gmm.condition(np.array([0]), np.array([1.0])) plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.title("Gaussian Mixture Model") plt.xlim((-10, 10)) plt.ylim((-10, 10)) plot_error_ellipses(plt.gca(), gmm, colors=["r", "g", "b"]) plt.scatter(X[:, 0], X[:, 1]) plt.subplot(1, 3, 2) plt.title("Probability Density and Samples") plt.xlim((-10, 10)) plt.ylim((-10, 10)) x, y = np.meshgrid(np.linspace(-10, 10, 100), np.linspace(-10, 10, 100)) X_test = np.vstack((x.ravel(), y.ravel())).T p = gmm.to_probability_density(X_test) p = p.reshape(*x.shape) plt.contourf(x, y, p) X_sampled = gmm.sample(100) plt.scatter(X_sampled[:, 0], X_sampled[:, 1], c="r") plt.subplot(1, 3, 3) plt.title("Conditional PDF $p(y | x = 1)$") X_test = np.linspace(-10, 10, 100) plt.plot(X_test, cond.to_probability_density(X_test[:, np.newaxis])) plt.show()
def choose(self, pvalues, method, outcome): ''' Randomly choose state of node from probability distribution conditioned on *pvalues*. This method has two parts: (1) determining the proper probability distribution, and (2) using that probability distribution to determine an outcome. Arguments: 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. The function goes to the entry of ``"cprob"`` that matches the outcomes of its discrete parents. Then, it constructs a Gaussian distribution based on its Gaussian parents and the parameters found at that entry. Last, it samples from that distribution and returns its outcome. ''' random.seed() sample = 0 if method == 'simple': dispvals = [] lgpvals = [] for pval in pvalues: if ((isinstance(pval, str)) | ((isinstance(pval, int)))): dispvals.append(pval) else: lgpvals.append(pval) lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] mean = lgdistribution["mean_base"] if (self.Vdataentry["parents"] != None): for x in range(len(lgpvals)): if (lgpvals[x] != "default"): mean += lgpvals[x] * lgdistribution["mean_scal"][x] else: print ("Attempted to sample node with unassigned parents.") variance = lgdistribution["variance"] sample = random.gauss(mean, math.sqrt(variance)) else: dispvals = [] lgpvals = [] for pval in pvalues: if ((isinstance(pval, str)) | ((isinstance(pval, int)))): dispvals.append(pval) else: lgpvals.append(pval) lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] mean = lgdistribution["mean_base"] variance = lgdistribution["variance"] w = lgdistribution["mean_scal"] if len(w) != 0: if (len(lgpvals) != 0): indexes = [i for i in range (1, (len(lgpvals)+1), 1)] if not np.isnan(np.array(lgpvals)).all(): n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) sample = gmm.predict(indexes, [lgpvals])[0][0] else: sample = np.nan else: n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) sample = gmm.sample(1)[0][0] else: sample = np.nan return sample
def choose_gmm(self, pvalues, outcome): ''' Randomly choose state of node from probability distribution conditioned on *pvalues*. This method has two parts: (1) determining the proper probability distribution, and (2) using that probability distribution to determine an outcome. Arguments: 1. *pvalues* -- An array containing the assigned states of the node's parents. This must be in the same order as the parents appear in ``self.Vdataentry['parents']``. The function creates a Gaussian distribution in the manner described in :doc:`lgbayesiannetwork`, and samples from that distribution, returning its outcome. ''' random.seed() # split parents by type dispvals = [] lgpvals = [] for pval in pvalues: if (isinstance(pval, str)): dispvals.append(pval) else: lgpvals.append(pval) # error check try: a = dispvals[0] a = lgpvals[0] except IndexError: #print ("Did not find LG and discrete type parents.") s = "Did not find LG and discrete type parents." # find correct Gaussian lgdistribution = self.Vdataentry["hybcprob"][str(dispvals)] s = 0 # calculate Bayesian parameters (mean and variance) mean = lgdistribution["mean_base"] variance = lgdistribution["variance"] w = lgdistribution["mean_scal"] #if (self.Vdataentry["parents"] != None): if (len(lgpvals) != 0): if isinstance(mean, list): indexes = [i for i in range (1, (len(lgpvals)+1), 1)] # for x in range(len(lgpvals)): # if (lgpvals[x] != "default"): # X.append(lgpvals[x]) # else: # # temporary error check # print ("Attempted to sample node with unassigned parents.") if not np.isnan(np.array(lgpvals)).any(): n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) s = gmm.predict(indexes, [lgpvals])[0][0] else: s = np.nan else: for x in range(len(lgpvals)): if (lgpvals[x] != "default"): mean += lgpvals[x] * w[x] else: # temporary error check print ("Attempted to sample node with unassigned parents.") s = random.gauss(mean, math.sqrt(variance)) else: if isinstance(mean, list): n_comp = len(w) gmm = GMM(n_components=n_comp, priors=w, means=mean, covariances=variance) s = gmm.sample(1) s = s[0][0] else: s = random.gauss(mean, math.sqrt(variance)) # draw random outcome from Gaussian # note that this built in function takes the standard deviation, not the # variance, thus requiring a square root return s