code: def attribute_anomalies(
      causal_model: InvertibleStructuralCausalModel,
      target_node: Any,
      anomaly_samples: pd.DataFrame,
      anomaly_scorer: Optional[AnomalyScorer] = None,
      attribute_mean_deviation: bool = False,
      num_distribution_samples: int = 1500,
      shapley_config: Optional[ShapleyConfig] = None,
  ) -> Dict[Any, np.ndarray]:
      """Estimates the contributions of upstream nodes to the anomaly score of the target_node for each sample in
      anomaly_samples. By default, the anomaly score is based on the information theoretic (IT) score
      -log(P(g(X) >= g(x))), where g is the anomaly_scorer, X samples from the marginal
      distribution of the target_node and x an observation of the target_node in anomaly_samples. If
      attribute_mean_deviation is set to True, the contribution to g(x) - E[g(X)] is estimated instead, i.e. the feature
      relevance for the given scoring function. The underlying algorithm utilizes the reconstructed noise of upstream
      nodes (including the target_node itself) for the given anomaly_samples. By this, it is possible to estimate how
      much of the anomaly score can be explained by upstream anomalies with respect to anomalous noise values.
  
      Note: This function requires that the noise can be recovered from samples, i.e. the causal models of non-root nodes
      need to be an InvertibleNoiseModel (e.g. AdditiveNoiseModel).
  
      Related paper:
      Janzing, D., Budhathoki, K., Minorics, L., & Bloebaum, P. (2019).
      Causal structure based root cause analysis of outliers
      https://arxiv.org/abs/1912.02724
  
      :param causal_model: The fitted InvertibleStructuralCausalModel.
      :param target_node: Target node for which the contributions are estimated.
      :param anomaly_samples: Anomalous observations for which the contributions are estimated.
      :param anomaly_scorer: Anomaly scorer g. If None is given, a MedianCDFQuantileScorer is used.
      :param attribute_mean_deviation: If set to False, the contribution is estimated based on the IT score and if it is
                                       set to True, the contribution is based on the feature relevance with respect to the given scoring function.
      :param num_distribution_samples: Number of samples from X, the marginal distribution of the target. These are used
                                       for evaluating the tail probability in case of the IT score
                                       (attribute_mean_deviation is False) or as samples for randomization in case of
                                       feature relevance (attribute_mean_deviation is True).
      :param shapley_config: :class:`~dowhy.gcm.shapley.ShapleyConfig` for the Shapley estimator.
      :return: A dictionary that assigns a numpy array to each upstream node including the target_node itself. The
               i-th entry of an array indicates the contribution of the corresponding node to the anomaly score of the target
               for the i-th observation in anomaly_samples.
      """
      validate_causal_dag(causal_model.graph)
  
      if anomaly_scorer is None:
          anomaly_scorer = MedianCDFQuantileScorer()
  
      noise_of_anomaly_samples = compute_noise_from_data(
          causal_model, anomaly_samples
      )
      node_samples, noise_samples = noise_samples_of_ancestors(
          causal_model, target_node, num_distribution_samples
      )
      (
          noise_dependent_function,
          nodes_order,
      ) = get_noise_dependent_function(causal_model, target_node)
      anomaly_scorer.fit(node_samples[target_node].to_numpy())
  
      attributions = attribute_anomaly_scores(
          noise_of_anomaly_samples[nodes_order].to_numpy(),
          noise_samples[nodes_order].to_numpy(),
          lambda x: anomaly_scorer.score(noise_dependent_function(x)),
          attribute_mean_deviation,
          shapley_config,
      )
  
      return {
          node: attributions[:, i] for i, node in enumerate(nodes_order)
      }
  
file_path: dowhy/dowhy/gcm/anomaly.py
imports: from typing import Any, Callable, Dict, Optional, Union
  import numpy
  import pandas
  from numpy.matlib import repmat
  from tqdm import tqdm
  from dowhy.gcm import config
  from dowhy.gcm._noise import compute_noise_from_data, get_noise_dependent_function, noise_samples_of_ancestors
  from dowhy.gcm.anomaly_scorer import AnomalyScorer
  from dowhy.gcm.anomaly_scorers import MedianCDFQuantileScorer, RescaledMedianCDFQuantileScorer
  from dowhy.gcm.causal_mechanisms import ConditionalStochasticModel
  from dowhy.gcm.causal_models import InvertibleStructuralCausalModel, ProbabilisticCausalModel, validate_causal_dag
  from dowhy.gcm.shapley import ShapleyConfig, estimate_shapley_values
  from dowhy.gcm.stats import permute_features
  from dowhy.gcm.util.general import shape_into_2d
  from dowhy.graph import get_ordered_predecessors, is_root_node
label_desc: Use image node_id 3 for calling a global function with example usage: attribute_anomalies(causal_model, target_node, anomaly_samples, anomaly_scorer, attribute_mean_deviation, num_distribution_samples, shapley_config) and returns: unknown