def calculate_bayes_opt(self, y0_prob, y1_prob, t_obs, t_obs_cf):
     bayes_opt_pred_t0 = np.round(y0_prob)
     bayes_opt_pred_t1 = np.round(y1_prob)
     bayes_opt_pred_f = switch(bayes_opt_pred_t0, bayes_opt_pred_t1, t_obs)
     bayes_opt_pred_cf = switch(bayes_opt_pred_t0, bayes_opt_pred_t1,
                                t_obs_cf)
     bayes_opt_trmt_by_num = (y1_prob > y0_prob).astype(float)
     bayes_opt_trmt_by_fcf = switch(y0_prob > y1_prob, y1_prob > y0_prob,
                                    t_obs)
     # bayes_opt_trmt_by_fcf = switch(1 - bayes_opt_trmt_by_num, bayes_opt_trmt_by_num, np.equal(bayes_opt_trmt_by_num > 0.5, t_obs > 0.5))
     return bayes_opt_pred_f, bayes_opt_pred_cf, bayes_opt_trmt_by_num, bayes_opt_trmt_by_fcf
 def choose_observed_treatment(self, x, a, z):
     # A = 0 treatment
     a0_t_obs_prob = np.expand_dims(
         sigmoid(np.mean(x + z, axis=1) / self.outcome_scale), 1)
     a0_t_obs = np.random.binomial(1, a0_t_obs_prob)
     a0_t_obs_cf = 1 - a0_t_obs
     # A = 1 treatment
     a1_t_obs_prob = np.expand_dims(
         sigmoid(np.mean(x - z, axis=1) / self.outcome_scale), 1)
     a1_t_obs = np.random.binomial(1, a1_t_obs_prob)
     a1_t_obs_cf = 1 - a1_t_obs
     #combine outcomes by A
     t_obs = switch(a0_t_obs, a1_t_obs, a)
     t_obs_prob = switch(a0_t_obs_prob, a1_t_obs_prob, a)
     t_obs_cf = switch(a0_t_obs_cf, a1_t_obs_cf, a)
     return t_obs, t_obs_cf, t_obs_prob
 def generate_outcomes(self, x, a, z):
     mn = np.mean(x, axis=1)
     logit_below_0 = mn / self.outcome_scale
     logit_above_0 = (mn + self.offset) / self.outcome_scale
     logits = switch(logit_below_0, logit_above_0, mn > 0)
     y0_prob = np.expand_dims(sigmoid(logits), 1)
     y1_prob = np.expand_dims(sigmoid(-logits), 1)
     y0 = np.random.binomial(1, y0_prob)
     y1 = np.random.binomial(1, y1_prob)
     return y0, y1, y0_prob, y1_prob
 def generate_factual_and_counterfactual_data(self):
     #everything the same, but then select observed A at the end
     #make dataset
     x0, a0, z0 = self.generate_factual_data(self.mu0, self.sd0,
                                             self.num_data, self.xdim, 0)
     x0_cf, a0_cf, z0_cf = self.generate_counterfactual_data(
         x0, a0, z0, self.mu0, self.sd0, self.mu1, self.sd1)
     dat0 = self.get_treatment_outcome_data(x0, a0, z0)
     dat0_cf = self.get_treatment_outcome_data(x0_cf, a0_cf, z0_cf)
     #select observed sensitive attribute as a function of Z
     observed_a = self.choose_observed_sensitive_attribute(z0)
     #save data
     save_dict_f = {
         k: switch(dat0[k], dat0_cf[k], observed_a)
         for k in dat0
     }
     save_dict_cf = {
         k: switch(dat0[k], dat0_cf[k], 1 - observed_a)
         for k in dat0
     }
     return save_dict_f, save_dict_cf
 def generate_outcomes(self, x, a, z):
     #A = 0 outcomes
     a0_y0_prob = np.expand_dims(
         sigmoid(np.mean(x + z, axis=1) / self.outcome_scale), 1)
     a0_y1_prob = np.expand_dims(
         sigmoid(-np.mean(x - z, axis=1) / self.outcome_scale), 1)
     a0_y0 = np.random.binomial(1, a0_y0_prob)
     a0_y1 = np.random.binomial(1, a0_y1_prob)
     #A = 1 outcomes
     a1_y0_prob = np.expand_dims(
         sigmoid(np.mean(x - z, axis=1) / self.outcome_scale), 1)
     a1_y1_prob = np.expand_dims(
         sigmoid(-np.mean(x + z, axis=1) / self.outcome_scale), 1)
     a1_y0 = np.random.binomial(1, a1_y0_prob)
     a1_y1 = np.random.binomial(1, a1_y1_prob)
     #combine outcomes by A
     y0 = switch(a0_y0, a1_y0, a)
     y1 = switch(a0_y1, a1_y1, a)
     y0_prob = switch(a0_y0_prob, a1_y0_prob, a)
     y1_prob = switch(a0_y1_prob, a1_y1_prob, a)
     return y0, y1, y0_prob, y1_prob
def calculate_bayes_opt(y0_prob, y1_prob, t_obs, t_obs_cf):
    bayes_opt_pred_t0 = np.round(y0_prob)
    bayes_opt_pred_t1 = np.round(y1_prob)
    bayes_opt_pred_f = switch(bayes_opt_pred_t0, bayes_opt_pred_t1, t_obs)
    bayes_opt_pred_cf = switch(bayes_opt_pred_t0, bayes_opt_pred_t1, t_obs_cf)
    return bayes_opt_pred_f, bayes_opt_pred_cf