in dowhy/causal_identifier.py [0:0]
def identify_backdoor(self, treatment_name, outcome_name,
include_unobserved=False, dseparation_algo="default"):
backdoor_sets = []
backdoor_paths = None
bdoor_graph = None
if dseparation_algo == "naive":
backdoor_paths = self._graph.get_backdoor_paths(treatment_name, outcome_name)
elif dseparation_algo == "default":
bdoor_graph = self._graph.do_surgery(treatment_name,
remove_outgoing_edges=True)
else:
raise ValueError(f"d-separation algorithm {dseparation_algo} is not supported")
method_name = self.method_name if self.method_name != CausalIdentifier.BACKDOOR_DEFAULT else CausalIdentifier.DEFAULT_BACKDOOR_METHOD
# First, checking if empty set is a valid backdoor set
empty_set = set()
check = self._graph.check_valid_backdoor_set(treatment_name,
outcome_name, empty_set,
backdoor_paths=backdoor_paths, new_graph=bdoor_graph,
dseparation_algo=dseparation_algo)
if check["is_dseparated"]:
backdoor_sets.append({'backdoor_set':empty_set})
# If the method is `minimal-adjustment`, return the empty set right away.
if method_name == CausalIdentifier.BACKDOOR_MIN:
return backdoor_sets
# Second, checking for all other sets of variables. If include_unobserved is false, then only observed variables are eligible.
eligible_variables = self._graph.get_all_nodes(include_unobserved=include_unobserved) \
- set(treatment_name) \
- set(outcome_name)
eligible_variables -= self._graph.get_descendants(treatment_name)
# If var is d-separated from both treatment or outcome, it cannot
# be a part of the backdoor set
filt_eligible_variables = set()
for var in eligible_variables:
dsep_treat_var = self._graph.check_dseparation(
treatment_name, parse_state(var),
set())
dsep_outcome_var = self._graph.check_dseparation(
outcome_name, parse_state(var), set())
if not dsep_outcome_var or not dsep_treat_var:
filt_eligible_variables.add(var)
if method_name in CausalIdentifier.METHOD_NAMES:
backdoor_sets, found_valid_adjustment_set = self.find_valid_adjustment_sets(
treatment_name, outcome_name,
backdoor_paths, bdoor_graph,
dseparation_algo,
backdoor_sets, filt_eligible_variables,
method_name=method_name,
max_iterations= CausalIdentifier.MAX_BACKDOOR_ITERATIONS)
if method_name == CausalIdentifier.BACKDOOR_DEFAULT and found_valid_adjustment_set:
# repeat the above search with BACKDOOR_MIN
backdoor_sets, _ = self.find_valid_adjustment_sets(
treatment_name, outcome_name,
backdoor_paths, bdoor_graph,
dseparation_algo,
backdoor_sets, filt_eligible_variables,
method_name=CausalIdentifier.BACKDOOR_MIN,
max_iterations= CausalIdentifier.MAX_BACKDOOR_ITERATIONS)
else:
raise ValueError(f"Identifier method {method_name} not supported. Try one of the following: {CausalIdentifier.METHOD_NAMES}")
return backdoor_sets