Example #1
0
    def _assign(self, x):
        # Assignment should be biased towards treatments that help more.
        assert self.centroids is not None, "Must call __fit__ before __assign__."

        distances = self.get_centroid_weights(x)

        expected_responses = []
        for treatment in range(self.num_treatments + 1):
            _, response_mean, response_std = self.centroids[treatment]
            y_this_treatment = self.random_generator.normal(
                response_mean, response_std)
            expected_responses.append(
                clip_percentage(
                    y_this_treatment +
                    self.random_generator.normal(0.0, self.epsilon_std)))
        expected_responses = np.array(expected_responses)

        y = []
        control_response, control_distance = expected_responses[-1], distances[
            -1]
        if self.with_exposure:
            treatment_means = [0.6, 0.65, 0.4]
            treatment_strengths = []
            for treatment_idx in range(self.num_treatments):
                dose_response_curve, d, d0_mean, d0_std, d0_min, d1_mean, d1_std, d1_min \
                    = self.get_dose_response_curve(x,
                                                   treatment_idx,
                                                   return_all=True)

                treatment_mean = treatment_means[treatment_idx] \
                    if treatment_idx < len(treatment_means) else treatment_means[-1]

                if treatment_mean is None:
                    treatment_strength = self.random_generator.uniform()
                else:
                    treatment_strength = clip_percentage(
                        self.random_generator.normal(treatment_mean, 0.1))

                treatment_strengths.append(treatment_strength)
                this_y = dose_response_curve(treatment_strength)
                y.append(this_y * expected_responses[treatment_idx])
            treatment_strengths = np.array(treatment_strengths)
        else:
            for treatment_idx in range(self.num_treatments):
                this_response, this_distance = expected_responses[
                    treatment_idx], distances[treatment_idx]
                y.append(this_response * (this_distance + control_distance))
        y = np.array(y)

        # Invert the expected responses, because a lower percentage of recurrence/death is a better outcome.
        treatment_chosen = self.random_generator.choice(
            self.num_treatments,
            p=stable_softmax(self.strength_of_assignment_bias * y))

        if self.with_exposure:
            return treatment_chosen, self.scaling_offset + self.scaling_constant * y, treatment_strengths
        else:
            return treatment_chosen, self.scaling_offset + self.scaling_constant * y
Example #2
0
    def _assign(self, x):
        # Assignment should be biased towards treatments that help more.
        assert self.centroids is not None, "Must call __fit__ before __assign__."

        if not self.is_v2:
            # TODO: Assignment and Y are independent = no assignment bias.
            expected_responses = np.dot(self.centroids.T,
                                        x[7:]) + self.random_generator.normal(
                                            0, 0.1)

            treatment_chosen = self.random_generator.binomial(
                1, p=sigmoid(expected_responses))

            lighter_sex, heavier_sex = x[3], x[4]

            if self.num_treatments == 2:
                outcomes = [x[5], x[6]]
            else:
                outcomes = [None, None, None, None]

                if lighter_sex == DataAccess.GENDER_MALE:
                    outcomes[0] = x[5]
                else:
                    outcomes[2] = x[5]

                if heavier_sex == DataAccess.GENDER_MALE:
                    outcomes[1] = x[6]
                else:
                    outcomes[3] = x[6]

                if (treatment_chosen == 0 and lighter_sex == DataAccess.GENDER_FEMALE) or\
                   (treatment_chosen == 1 and heavier_sex == DataAccess.GENDER_FEMALE):
                    treatment_chosen += 2

            return treatment_chosen, outcomes
        else:
            distances = self.get_centroid_weights(x)

            y = []
            control_distance = distances[-1]
            for treatment_idx in range(self.num_treatments):
                this_distance = distances[treatment_idx]
                y.append(50 * (this_distance + control_distance) +
                         self.random_generator.normal(0.0, 1.0))
            y = np.array(y)

            # Invert the expected responses, because a lower percentage of recurrence/death is a better outcome.
            choice_percentage = stable_softmax(
                self.strength_of_assignment_bias * distances[:-1])
            treatment_chosen = self.random_generator.choice(
                self.num_treatments, p=choice_percentage)

            return treatment_chosen, y
Example #3
0
    def _assign(self, x):
        # Assignment should be biased towards treatments that help more.
        assert self.centroids is not None, "Must call __fit__ before __assign__."

        distances = self.get_centroid_weights(x)

        expected_responses = []
        for treatment in range(self.num_treatments + 1):
            _, response_mean, response_std = self.centroids[treatment]
            y_this_treatment = self.random_generator.normal(response_mean, response_std)
            expected_responses.append(
                clip_percentage(y_this_treatment + self.random_generator.normal(0.0, self.epsilon_std))
            )
        expected_responses = np.array(expected_responses)
        control_response, control_distance = expected_responses[-1], distances[-1]

        y = []
        if self.with_exposure:
            treatment_strengths = []
            for treatment_idx in range(self.num_treatments):
                dose_response_curve, d, d0_mean, d0_std, d0_min, d1_mean, d1_std, d1_min \
                    = self.get_dose_response_curve(x,
                                                   treatment_idx,
                                                   return_all=True)

                treatment_strength = clip_percentage(
                    self.random_generator.exponential(scale=0.25)
                )

                treatment_strengths.append(treatment_strength)
                this_y = dose_response_curve(treatment_strength)
                y.append(this_y * expected_responses[treatment_idx])
            treatment_strengths = np.array(treatment_strengths)
        else:
            for treatment_idx in range(self.num_treatments):
                this_response, this_distance = expected_responses[treatment_idx], distances[treatment_idx]
                y.append(this_response * (this_distance + control_distance))
        y = np.array(y)

        treatment_chosen = self.random_generator.choice(self.num_treatments,
                                                        p=stable_softmax(
                                                            self.strength_of_assignment_bias * y)
                                                        )

        if self.with_exposure:
            return treatment_chosen, self.scaling_constant*y, treatment_strengths
        else:
            return treatment_chosen, self.scaling_constant*y
Example #4
0
    def get_dose_response_curve(self, z, treatment_idx, return_all=False):
        dosage_distances = self.get_centroid_weights(z, centroids=self.dosage_centroids[treatment_idx])
        normalised_distances = stable_softmax(self.strength_of_assignment_bias * dosage_distances)
        d = normalised_distances
        _, d0_mean, d0_std, d0_min = self.dosage_centroids[treatment_idx][0]
        _, d1_mean, d1_std, d1_min = self.dosage_centroids[treatment_idx][1]

        def dose_response_curve(treatment_strength):
            this_y = d[0] * gaussian(treatment_strength - d0_min, d0_mean, d0_std) + \
                     d[1] * gaussian(treatment_strength - d1_min, d1_mean, d1_std)
            return this_y

        if return_all:
            return dose_response_curve, d, d0_mean, d0_std, d0_min, d1_mean, d1_std, d1_min
        else:
            return dose_response_curve