code: def feature_relevance_sample(
      prediction_method: Callable[[np.ndarray], np.ndarray],
      feature_samples: np.ndarray,
      baseline_samples: np.ndarray,
      subset_scoring_func: Callable[
          [np.ndarray, np.ndarray], Union[np.ndarray, float]
      ],
      baseline_target_values: Optional[np.ndarray] = None,
      average_set_function: bool = False,
      max_batch_size: int = 100,
      randomize_features_jointly: bool = True,
      shapley_config: Optional[ShapleyConfig] = None,
  ) -> np.ndarray:
      """Estimates the feature relevance of the prediction_method for each sample in baseline_noise_samples. This
      method uses all samples given in feature_samples as 'background' samples. This is, they should represent samples
      from the joint distribution of the input features. The subset_scoring_func defines the comparison between the
      output of the prediction_method when certain features are randomized and the outputs when no features are
      randomized. The most common function would be the difference between the expectations.
  
      If the randomized predictions should rather be compared to the original data, this has (and can) be defined via
      the set function by ignoring the second input parameter (the predicted values using all feauters). Instead, the
      original data can be used.
  
      Related paper:
      Janzing, D., Minorics, L., & Bloebaum, P. (2020).
      Feature relevance quantification in explainable AI: A causal problem.
      In International Conference on Artificial Intelligence and Statistics (pp. 2907-2916). PMLR.
  
      :param prediction_method: A callable that is expected to return a prediction for given samples.
      :param feature_samples: Samples from the joint distribution. These are used as 'background samples' to randomize features that are not in a subset.
      :param baseline_samples: Samples for which the feature relevance should be estimated.
      :param subset_scoring_func: Set function for estimating the quantity of interest based on the model outcomes. This function
                                  expects two inputs; the outcome of the prediction model for some samples if certain features are permuted and the
                                  outcome of the model for the same samples when no features were permuted. A typical choice for regression models
                                  would be the difference between expectations. This is then used as the 'characteristic function'
                                  in coalition games when estimating the Shapley values.
      :param baseline_target_values: These baseline values are compared with the subset specific outcomes of the prediction method. If set to None (default),
                                     the baseline values are the outcomes of the given prediction_method applied to the baseline_noise_samples, i.e. the outcome of the empty subset.
      :param max_batch_size: Maximum batch size for a estimating the predictions. This has a significant influence on the
                             overall memory usage. If set to -1, all samples are used in one batch.
      :param average_set_function: If set to True, the averaged result of the set function applied to each sample of
                                   interest is used for estimating the Shapley values. If set to False, Shapley values for each sample of interest
                                   are estimated separately.
      :param randomize_features_jointly: If set to True, features that are not in a subset are jointly permuted.
                                         Note that this still represents an interventional distribution. If set to False, features that are not in a subset
                                         are independently permuted. Note: The theory in the linked publication assumes that this is set to True.
      :param shapley_config: Config for the Shapley estimator.
      :return: A numpy array with the feature relevance for each sample in baseline_noise_samples.
      """
      feature_samples = shape_into_2d(feature_samples)
      if baseline_target_values is None:
          baseline_target_values = prediction_method(baseline_samples)
      else:
          if (
              baseline_samples.shape[0]
              != baseline_target_values.shape[0]
          ):
              raise ValueError(
                  "Samples of interest and the given baseline values need to have the same sample size! "
                  "Make sure that the given baseline values correspond to the samples of interest."
              )
  
      if shapley_config is None:
          shapley_config = ShapleyConfig()
  
      def single_sample_set_function(
          subset: np.ndarray,
      ) -> Union[np.ndarray, float]:
          results = np.zeros(baseline_target_values.shape[0])
          predictions = marginal_expectation(
              prediction_method,
              feature_samples=feature_samples,
              baseline_samples=baseline_samples,
              baseline_feature_indices=np.arange(
                  0, feature_samples.shape[1]
              )[subset == 1],
              return_averaged_results=False,
              feature_perturbation="randomize_columns_jointly"
              if randomize_features_jointly
              else "randomize_columns_independently",
              max_batch_size=max_batch_size,
          )
  
          for i in range(baseline_target_values.shape[0]):
              results[i] = subset_scoring_func(
                  predictions[i], baseline_target_values[i]
              )
  
          if average_set_function:
              return np.mean(results)
          else:
              return results
  
      return estimate_shapley_values(
          single_sample_set_function,
          feature_samples.shape[1],
          shapley_config,
      )
  
file_path: dowhy/dowhy/gcm/feature_relevance.py
imports: from typing import Any, Callable, Dict, Optional, Tuple, Union
  import numpy
  import pandas
  from dowhy.gcm.causal_mechanisms import ProbabilityEstimatorModel
  from dowhy.gcm.causal_models import StructuralCausalModel, validate_node
  from dowhy.gcm.fitting_sampling import draw_samples
  from dowhy.gcm.shapley import ShapleyConfig, estimate_shapley_values
  from dowhy.gcm.stats import marginal_expectation
  from dowhy.gcm.util.general import shape_into_2d, variance_of_deviations, variance_of_matching_values
  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: feature_relevance_sample(prediction_method, feature_samples, baseline_samples, subset_scoring_func, baseline_target_values, average_set_function, max_batch_size, randomize_features_jointly, shapley_config) and returns: estimate_shapley_values, np, results