def _credit_clusters(): return distributions.Mixture( components=[ _single_credit_cluster(idx) for idx in range(feature_dim) ], weights=cluster_probs, )
def two_group_credit_clusters( group_likelihoods=(0.5, 0.5), cluster_probabilities=DELAYED_IMPACT_CLUSTER_PROBS, success_probabilities=DELAYED_IMPACT_SUCCESS_PROBS): """Returns a mixture of two credit cluster distributions. Args: group_likelihoods: Probabilities of choosing from each group. Should be non-negative and sum to one. cluster_probabilities: cluster_probabilities[i][j] gives the probability of being drawn from credit cluster j conditioned on being from group i. success_probabilities: success_probabilities[j] gives the probability of successfully paying back a loan conditioned on being from being from credit cluster j. """ components = [] for idx in [0, 1]: # Use a one-hot encoding of group-id. group_vec = np.zeros(2) group_vec[idx] = 1 components.append( _credit_cluster_builder( group_membership=tuple(group_vec), cluster_probs=tuple(cluster_probabilities[idx]), success_probs=tuple(success_probabilities))()) return distributions.Mixture(components=components, weights=group_likelihoods)
def test_mixture_returns_components(self): my_distribution = distributions.Mixture(components=[ distributions.Constant((0, )), distributions.Constant((1, )) ], weights=[0.1, 0.9]) rng = np.random.RandomState(seed=100) samples = [my_distribution.sample(rng) for _ in range(1000)] self.assertSetEqual(set(samples), {(0, ), (1, )}) self.assertAlmostEqual(np.mean(samples), 0.9, delta=0.1)
def test_improper_distributions_raise_errors(self): for p in [-10, -0.9, 1.3]: with self.assertRaises(ValueError): _ = distributions.Bernoulli(p=p) for vec in [ [0.1, 0.3, 0.5], # Does not sum to one. [0.5, 0.9, -0.4], # Has negative values. ]: with self.assertRaises(ValueError): _ = distributions.Mixture( weights=vec, components=[distributions.Constant(mean=(0, ))] * len(vec))
def _single_gmm(): """Returns a mixture of gaussian applicant distributions.""" return distributions.Mixture( components=[ ApplicantDistribution( features=distributions.Gaussian(mean=mean, std=0.5), group_membership=distributions.Constant(group), will_default=distributions.Bernoulli(p=default_likelihoods[0])), ApplicantDistribution( features=distributions.Gaussian( mean=np.array(mean) + np.array(intercluster_vec), std=0.5), group_membership=distributions.Constant(group), will_default=distributions.Bernoulli(p=default_likelihoods[1])) ], weights=[0.3, 0.7])
def _rotated_gmm(): """Returns a mixture of applicant distributions. The second applicant distribution is a rotated version of the first. """ return distributions.Mixture(components=[ _gmm_applicant_builder(mean=mean, intercluster_vec=intercluster_vec, default_likelihoods=default_likelihoods, group=[1, 0])(), _gmm_applicant_builder(mean=_rotate(mean, degrees), intercluster_vec=_rotate( intercluster_vec, degrees), default_likelihoods=default_likelihoods, group=[0, 1])(), ], weights=group_likelihoods)
def test_measure_distribution_change_measurement(self): # The lower cluster has a 100% success rate and the upper cluster has a 0% # success rate. This causes applicants to move constantly between clusters. clusters = distributions.Mixture( components=[ lending_params._credit_cluster_builder( group_membership=[1, 0], cluster_probs=[0.1, 0.9], success_probs=[1.0, 0.0])(), lending_params._credit_cluster_builder( group_membership=[0, 1], cluster_probs=[0.8, 0.2], success_probs=[1.0, 0.0])(), ], weights=(0.5, 0.5), ) env = lending.DelayedImpactEnv( lending_params.DelayedImpactParams( applicant_distribution=clusters)) initial_distribution = lending_metrics.CreditDistribution(env, 0) final_distribution = lending_metrics.CreditDistribution(env, -1) # Giving a loan should change the distribution. env.step(np.asarray(1)) # Take another step to move current state into history. This step does not # change the distribution because the loan is rejected. env.step(np.asarray(0)) self.assertEqual({ "0": [0.1, 0.9], "1": [0.8, 0.2] }, initial_distribution.measure(env)) self.assertNotEqual({ "0": [0.1, 0.9], "1": [0.8, 0.2] }, final_distribution.measure(env))