class_docstr: Estimate effect of treatment by weighing the data by
  inverse probability of occurrence.
  
  Straightforward application of the back-door criterion.
  
  Supports additional parameters as listed below.
code: def estimate_effect(
      self,
      data: pd.DataFrame,
      treatment_value: Any = 1,
      control_value: Any = 0,
      target_units=None,
      **_,
  ):
      self._target_units = target_units
      self._treatment_value = treatment_value
      self._control_value = control_value
      if self.propensity_score_column not in data:
          self.estimate_propensity_score_column(data)
  
      # trim propensity score weights
      data[self.propensity_score_column] = np.minimum(
          self.max_ps_score, data[self.propensity_score_column]
      )
      data[self.propensity_score_column] = np.maximum(
          self.min_ps_score, data[self.propensity_score_column]
      )
  
      # ips ==> (isTreated(y)/ps(y)) + ((1-isTreated(y))/(1-ps(y)))
      # nips ==> ips / (sum of ips over all units)
      # icps ==> ps(y)/(1-ps(y)) / (sum of (ps(y)/(1-ps(y))) over all control units)
      # itps ==> ps(y)/(1-ps(y)) / (sum of (ps(y)/(1-ps(y))) over all treatment units)
      ipst_sum = sum(
          data[self._target_estimand.treatment_variable[0]]
          / data[self.propensity_score_column]
      )
      ipsc_sum = sum(
          (1 - data[self._target_estimand.treatment_variable[0]])
          / (1 - data[self.propensity_score_column])
      )
      num_units = len(data[self._target_estimand.treatment_variable[0]])
      num_treatment_units = sum(
          data[self._target_estimand.treatment_variable[0]]
      )
      num_control_units = num_units - num_treatment_units
  
      # Vanilla IPS estimator
      data["ips_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] / data[self.propensity_score_column] + (
          1 - data[self._target_estimand.treatment_variable[0]]
      ) / (
          1 - data[self.propensity_score_column]
      )
      data["tips_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] + (
          1 - data[self._target_estimand.treatment_variable[0]]
      ) * data[
          self.propensity_score_column
      ] / (
          1 - data[self.propensity_score_column]
      )
      data["cips_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] * (1 - data[self.propensity_score_column]) / data[
          self.propensity_score_column
      ] + (
          1 - data[self._target_estimand.treatment_variable[0]]
      )
  
      # The Hajek estimator (or the self-normalized estimator)
      data["ips_normalized_weight"] = (
          data[self._target_estimand.treatment_variable[0]]
          / data[self.propensity_score_column]
          / ipst_sum
          + (1 - data[self._target_estimand.treatment_variable[0]])
          / (1 - data[self.propensity_score_column])
          / ipsc_sum
      )
      ipst_for_att_sum = sum(
          data[self._target_estimand.treatment_variable[0]]
      )
      ipsc_for_att_sum = sum(
          (1 - data[self._target_estimand.treatment_variable[0]])
          / (1 - data[self.propensity_score_column])
          * data[self.propensity_score_column]
      )
      data["tips_normalized_weight"] = (
          data[self._target_estimand.treatment_variable[0]]
          / ipst_for_att_sum
          + (1 - data[self._target_estimand.treatment_variable[0]])
          * data[self.propensity_score_column]
          / (1 - data[self.propensity_score_column])
          / ipsc_for_att_sum
      )
      ipst_for_atc_sum = sum(
          data[self._target_estimand.treatment_variable[0]]
          / data[self.propensity_score_column]
          * (1 - data[self.propensity_score_column])
      )
      ipsc_for_atc_sum = sum(
          (1 - data[self._target_estimand.treatment_variable[0]])
      )
      data["cips_normalized_weight"] = (
          data[self._target_estimand.treatment_variable[0]]
          * (1 - data[self.propensity_score_column])
          / data[self.propensity_score_column]
          / ipst_for_atc_sum
          + (1 - data[self._target_estimand.treatment_variable[0]])
          / ipsc_for_atc_sum
      )
  
      # Stabilized weights (from Robins, Hernan, Brumback (2000))
      # Paper: Marginal Structural Models and Causal Inference in Epidemiology
      p_treatment = (
          sum(data[self._target_estimand.treatment_variable[0]])
          / num_units
      )
      data["ips_stabilized_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] / data[self.propensity_score_column] * p_treatment + (
          1 - data[self._target_estimand.treatment_variable[0]]
      ) / (
          1 - data[self.propensity_score_column]
      ) * (
          1 - p_treatment
      )
      data["tips_stabilized_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] * p_treatment + (
          1 - data[self._target_estimand.treatment_variable[0]]
      ) * data[
          self.propensity_score_column
      ] / (
          1 - data[self.propensity_score_column]
      ) * (
          1 - p_treatment
      )
      data["cips_stabilized_weight"] = data[
          self._target_estimand.treatment_variable[0]
      ] * (1 - data[self.propensity_score_column]) / data[
          self.propensity_score_column
      ] * p_treatment + (
          1 - data[self._target_estimand.treatment_variable[0]]
      ) * (
          1 - p_treatment
      )
  
      if (
          isinstance(target_units, pd.DataFrame)
          or target_units == "ate"
      ):
          weighting_scheme_name = self.weighting_scheme
      elif target_units == "att":
          weighting_scheme_name = "t" + self.weighting_scheme
      elif target_units == "atc":
          weighting_scheme_name = "c" + self.weighting_scheme
      else:
          raise ValueError(
              f"Target units value {target_units} not supported"
          )
  
      # Calculating the effect
      data["d_y"] = (
          data[weighting_scheme_name]
          * data[self._target_estimand.treatment_variable[0]]
          * data[self._target_estimand.outcome_variable[0]]
      )
      data["dbar_y"] = (
          data[weighting_scheme_name]
          * (1 - data[self._target_estimand.treatment_variable[0]])
          * data[self._target_estimand.outcome_variable[0]]
      )
      sum_dy_weights = np.sum(
          data[self._target_estimand.treatment_variable[0]]
          * data[weighting_scheme_name]
      )
      sum_dbary_weights = np.sum(
          (1 - data[self._target_estimand.treatment_variable[0]])
          * data[weighting_scheme_name]
      )
      # Subtracting the weighted means
      est = (
          data["d_y"].sum() / sum_dy_weights
          - data["dbar_y"].sum() / sum_dbary_weights
      )
  
      # TODO - how can we add additional information into the returned estimate?
      estimate = CausalEstimate(
          data=data,
          treatment_name=self._target_estimand.treatment_variable,
          outcome_name=self._target_estimand.outcome_variable,
          estimate=est,
          control_value=control_value,
          treatment_value=treatment_value,
          target_estimand=self._target_estimand,
          realized_estimand_expr=self.symbolic_estimator,
          propensity_scores=data[self.propensity_score_column],
      )
  
      estimate.add_estimator(self)
      return estimate
  
file_path: dowhy/dowhy/causal_estimators/propensity_score_weighting_estimator.py
imports: from typing import Any, List, Optional, Union
  import numpy
  import pandas
  from dowhy.causal_estimator import CausalEstimate, CausalEstimator
  from dowhy.causal_estimators.propensity_score_estimator import PropensityScoreEstimator
  from dowhy.causal_identifier import IdentifiedEstimand
label_desc: Use image node_id 3 for calling the PropensityScoreWeightingEstimator obj's underlying member method code with example usage: obj.estimate_effect(data, treatment_value, control_value, target_units) and returns: estimate