Exemple #1
0
    def construct_mediation_estimand(self, estimand_type, treatment_name,
                                     outcome_name, mediators_names):
        # TODO: support multivariate treatments better.
        expr = None
        if estimand_type in (CausalIdentifier.NONPARAMETRIC_NDE,
                             CausalIdentifier.NONPARAMETRIC_NIE):
            outcome_name = outcome_name[0]
            sym_outcome = spstats.Normal(outcome_name, 0, 1)
            sym_treatment_symbols = [
                spstats.Normal(t, 0, 1) for t in treatment_name
            ]
            sym_treatment = sp.Array(sym_treatment_symbols)
            sym_mediators_symbols = [
                sp.Symbol(inst) for inst in mediators_names
            ]
            sym_mediators = sp.Array(sym_mediators_symbols)
            sym_outcome_derivative = sp.Derivative(sym_outcome, sym_mediators)
            sym_treatment_derivative = sp.Derivative(sym_mediators,
                                                     sym_treatment)
            # For direct effect
            num_expr_str = outcome_name
            if len(mediators_names) > 0:
                num_expr_str += "|" + ",".join(mediators_names)
            sym_mu = sp.Symbol("mu")
            sym_sigma = sp.Symbol("sigma", positive=True)
            sym_conditional_outcome = spstats.Normal(num_expr_str, sym_mu,
                                                     sym_sigma)
            sym_directeffect_derivative = sp.Derivative(
                sym_conditional_outcome, sym_treatment)
            if estimand_type == CausalIdentifier.NONPARAMETRIC_NIE:
                sym_effect = spstats.Expectation(sym_treatment_derivative *
                                                 sym_outcome_derivative)
            elif estimand_type == CausalIdentifier.NONPARAMETRIC_NDE:
                sym_effect = spstats.Expectation(sym_directeffect_derivative)
            sym_assumptions = {
                "Mediation":
                ("{2} intercepts (blocks) all directed paths from {0} to {1} except the path {{{0}}}\N{RIGHTWARDS ARROW}{{{1}}}."
                 ).format(",".join(treatment_name), ",".join(outcome_name),
                          ",".join(mediators_names)),
                "First-stage-unconfoundedness":
                (u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{{{1}}}"
                 " then P({1}|{0},U) = P({1}|{0})").format(
                     ",".join(treatment_name), ",".join(mediators_names)),
                "Second-stage-unconfoundedness":
                (u"If U\N{RIGHTWARDS ARROW}{{{2}}} and U\N{RIGHTWARDS ARROW}{1}"
                 " then P({1}|{2}, {0}, U) = P({1}|{2}, {0})").format(
                     ",".join(treatment_name), outcome_name,
                     ",".join(mediators_names))
            }
        else:
            raise ValueError(
                "Estimand type not supported. Supported estimand types are {0} or {1}'."
                .format(CausalIdentifier.NONPARAMETRIC_NDE,
                        CausalIdentifier.NONPARAMETRIC_NIE))

        estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions}
        return estimand
    def construct_symbolic_estimator(self, estimand):
        sym_outcome = (spstats.Normal(",".join(estimand.outcome_variable), 0,
                                      1))
        sym_treatment = (spstats.Normal(",".join(estimand.treatment_variable),
                                        0, 1))
        sym_instrument = sp.Symbol(estimand.instrumental_variables[0])
        sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument)
        sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument)
        sym_effect = (spstats.Expectation(sym_outcome_derivative) /
                      sp.stats.Expectation(sym_treatment_derivative))
        estimator_assumptions = {
            "treatment_effect_homogeneity":
            ("Each unit's treatment {0} is".format(self._treatment_name) +
             "affected in the same way by common causes of "
             "{0} and {1}".format(self._treatment_name, self._outcome_name)),
            "outcome_effect_homogeneity":
            ("Each unit's outcome {0} is".format(self._outcome_name) +
             "affected in the same way by common causes of "
             "{0} and {1}".format(self._treatment_name, self._outcome_name)),
        }
        sym_assumptions = {
            **estimand.estimands["iv"]["assumptions"],
            **estimator_assumptions
        }

        symbolic_estimand = RealizedEstimand(estimand,
                                             estimator_name="Wald Estimator")
        symbolic_estimand.update_assumptions(sym_assumptions)
        symbolic_estimand.update_estimand_expression(sym_effect)
        return symbolic_estimand
    def construct_backdoor_estimand(self, estimand_type, treatment_name,
                                    outcome_name, common_causes):
        # TODO: outputs string for now, but ideally should do symbolic
        # expressions Mon 19 Feb 2018 04:54:17 PM DST
        expr = None
        if estimand_type == "ate":
            num_expr_str = outcome_name + "|"
            num_expr_str += ",".join(common_causes)
            expr = "d(" + num_expr_str + ")/d" + treatment_name
            sym_mu = sp.Symbol("mu")
            sym_sigma = sp.Symbol("sigma", positive=True)
            sym_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma)
            # sym_common_causes = [sp.stats.Normal(common_cause, sym_mu, sym_sigma) for common_cause in common_causes]
            sym_treatment = sp.Symbol(treatment_name)
            sym_conditional_outcome = spstats.Expectation(sym_outcome)
            sym_effect = sp.Derivative(sym_conditional_outcome, sym_treatment)

            sym_assumptions = {
                'Unconfoundedness': (
                    u"If U\N{RIGHTWARDS ARROW}{0} and U\N{RIGHTWARDS ARROW}{1}"
                    " then P({1}|{0},{2},U) = P({1}|{0},{2})"
                ).format(treatment_name, outcome_name, ",".join(common_causes))
            }

        estimand = {
            'estimand': sym_effect,
            'assumptions': sym_assumptions
        }
        return estimand
    def construct_iv_estimand(self, estimand_type, treatment_name,
                              outcome_name, instrument_names):
        expr = None
        if estimand_type == "ate":
            sym_outcome = spstats.Normal(outcome_name, 0, 1)
            sym_treatment = spstats.Normal(treatment_name, 0, 1)
            sym_instrument = sp.Symbol(instrument_names[0])  # ",".join(instrument_names))
            sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument)
            sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument)
            sym_effect = spstats.Expectation(sym_outcome_derivative / sym_treatment_derivative)
            sym_assumptions = {
                "As-if-random": (
                    "If U\N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{0} then "
                    "\N{NOT SIGN}(U \N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{1})"
                ).format(outcome_name, ",".join(instrument_names)),
                "Exclusion": (
                    u"If we remove {{{0}}}\N{RIGHTWARDS ARROW}{1}, then "
                    u"\N{NOT SIGN}({0}\N{RIGHTWARDS ARROW}{2})"
                ).format(",".join(instrument_names), treatment_name,
                         outcome_name)
            }

        estimand = {
            'estimand': sym_effect,
            'assumptions': sym_assumptions
        }
        return estimand
Exemple #5
0
    def construct_iv_estimand(self, estimand_type, treatment_name,
                              outcome_name, instrument_names):
        # TODO: support multivariate treatments better.
        expr = None
        outcome_name = outcome_name[0]
        sym_outcome = spstats.Normal(outcome_name, 0, 1)
        sym_treatment_symbols = [
            spstats.Normal(t, 0, 1) for t in treatment_name
        ]
        sym_treatment = sp.Array(sym_treatment_symbols)
        sym_instrument_symbols = [sp.Symbol(inst) for inst in instrument_names]
        sym_instrument = sp.Array(
            sym_instrument_symbols)  # ",".join(instrument_names))
        sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument)
        sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument)
        sym_effect = spstats.Expectation(sym_outcome_derivative /
                                         sym_treatment_derivative)
        sym_assumptions = {
            "As-if-random":
            ("If U\N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{0} then "
             "\N{NOT SIGN}(U \N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{{{1}}})"
             ).format(outcome_name, ",".join(instrument_names)),
            "Exclusion":
            (u"If we remove {{{0}}}\N{RIGHTWARDS ARROW}{{{1}}}, then "
             u"\N{NOT SIGN}({{{0}}}\N{RIGHTWARDS ARROW}{2})").format(
                 ",".join(instrument_names), ",".join(treatment_name),
                 outcome_name)
        }

        estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions}
        return estimand
Exemple #6
0
    def construct_backdoor_estimand(self, estimand_type, treatment_name,
                                    outcome_name, common_causes):
        # TODO: outputs string for now, but ideally should do symbolic
        # expressions Mon 19 Feb 2018 04:54:17 PM DST
        # TODO Better support for multivariate treatments

        expr = None
        outcome_name = outcome_name[0]
        num_expr_str = outcome_name
        if len(common_causes) > 0:
            num_expr_str += "|" + ",".join(common_causes)
        expr = "d(" + num_expr_str + ")/d" + ",".join(treatment_name)
        sym_mu = sp.Symbol("mu")
        sym_sigma = sp.Symbol("sigma", positive=True)
        sym_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma)
        sym_treatment_symbols = [sp.Symbol(t) for t in treatment_name]
        sym_treatment = sp.Array(sym_treatment_symbols)
        sym_conditional_outcome = spstats.Expectation(sym_outcome)
        sym_effect = sp.Derivative(sym_conditional_outcome, sym_treatment)

        sym_assumptions = {
            'Unconfoundedness':
            (u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{1}"
             " then P({1}|{0},{2},U) = P({1}|{0},{2})").format(
                 ",".join(treatment_name), outcome_name,
                 ",".join(common_causes))
        }

        estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions}
        return estimand
Exemple #7
0
    def construct_frontdoor_estimand(self, estimand_type, treatment_name,
                              outcome_name, frontdoor_variables_names):
        # TODO: support multivariate treatments better.
        expr = None
        outcome_name = outcome_name[0]
        sym_outcome = spstats.Normal(outcome_name, 0, 1)
        sym_treatment_symbols = [spstats.Normal(t, 0, 1) for t in treatment_name]
        sym_treatment = sp.Array(sym_treatment_symbols)
        sym_frontdoor_symbols = [sp.Symbol(inst) for inst in frontdoor_variables_names]
        sym_frontdoor = sp.Array(sym_frontdoor_symbols)  # ",".join(instrument_names))
        sym_outcome_derivative = sp.Derivative(sym_outcome, sym_frontdoor)
        sym_treatment_derivative = sp.Derivative(sym_frontdoor, sym_treatment)
        sym_effect = spstats.Expectation(sym_treatment_derivative * sym_outcome_derivative)
        sym_assumptions = {
            "Full-mediation": (
                "{2} intercepts (blocks) all directed paths from {0} to {1}."
            ).format(",".join(treatment_name), ",".join(outcome_name), ",".join(frontdoor_variables_names)),
            "First-stage-unconfoundedness": (
                u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{{{1}}}"
                " then P({1}|{0},U) = P({1}|{0})"
            ).format(",".join(treatment_name), ",".join(frontdoor_variables_names)),
            "Second-stage-unconfoundedness": (
                u"If U\N{RIGHTWARDS ARROW}{{{2}}} and U\N{RIGHTWARDS ARROW}{1}"
                " then P({1}|{2}, {0}, U) = P({1}|{2}, {0})"
            ).format(",".join(treatment_name), outcome_name, ",".join(frontdoor_variables_names))
        }

        estimand = {
            'estimand': sym_effect,
            'assumptions': sym_assumptions
        }
        return estimand