class_docstr: Implementation of the permutation feature importance for tabular datasets. The method measure the importance
  of a feature as the relative increase/decrease in the loss/score function when the feature values are permuted.
  Supports black-box models.
  
  For details of the method see the papers:
  
   - https://link.springer.com/article/10.1023/A:1010933404324
  
   - https://arxiv.org/abs/1801.01489
docstr: Computes the permutation feature importance for each feature with respect to the given loss or score
  functions and the dataset `(X, y)`.
  
  Parameters
  ----------
  X
      A `N x F` input feature dataset used to calculate the permutation feature importance. This is typically the
      test dataset.
  y
      Ground-truth labels array  of size `N` (i.e. `(N, )`) corresponding the input feature `X`.
  features
      An optional list of features or tuples of features for which to compute the permutation feature
      importance. If not provided, the permutation feature importance will be computed for every single features
      in the dataset. Some example of `features` would be: ``[0, 2]``, ``[0, 2, (0, 2)]``, ``[(0, 2)]``,
      where ``0`` and ``2`` correspond to column 0 and 2 in `X`, respectively.
  method
      The method to be used to compute the feature importance. If set to ``'exact'``, a "switch" operation is
      performed across all observed pairs, by excluding pairings that are actually observed in the original
      dataset. This operation is quadratic in the number of samples (`N x (N - 1)` samples) and thus can be
      computationally intensive. If set to ``'estimate'``, the dataset will be divided in half. The values of
      the first half containing the ground-truth labels the rest of the features (i.e. features that are left
      intact) is matched with the values of the second half of the permuted features, and the other way around.
      This method is computationally lighter and provides estimate error bars given by the standard deviation.
      Note that for some specific loss and score functions, the estimate does not converge to the exact metric
      value.
  kind
      Whether to report the importance as the loss/score ratio or the loss/score difference.
      Available values are: ``'ratio'`` | ``'difference'``.
  n_repeats
      Number of times to permute the feature values. Considered only when ``method='estimate'``.
  sample_weight
      Optional weight for each sample instance.
  
  Returns
  -------
  explanation
      An `Explanation` object containing the data and the metadata of the permutation feature importance.
      See usage at `Permutation feature importance examples`_ for details
  
      .. _Permutation feature importance examples:
          https://docs.seldon.io/projects/alibi/en/stable/methods/PermutationImportance.html
docstr_tok: ["Computes","the","permutation","feature","importance","for","each","feature","with","respect","to","the","given","loss","or","score","functions","and","the","dataset","`","(","X",",","y",")","`",".","Parameters","--","--","--","--","--","X","A","`","N","x","F","`","input","feature","dataset","used","to","calculate","the","permutation","feature","importance",".","This","is","typically","the","test","dataset",".","y","Ground-truth","labels","array","of","size","`","N","`","(","i.e",".","`","(","N",",",")","`",")","corresponding","the","input","feature","`","X","`",".","features","An","optional","list","of","features","or","tuples","of","features","for","which","to","compute","the","permutation","feature","importance",".","If","not","provided",",","the","permutation","feature","importance","will","be","computed","for","every","single","features","in","the","dataset",".","Some","example","of","`","features","`","would","be",":","``","[","0",",","2","]","``",",","``","[","0",",","2",",","(","0",",","2",")","]","``",",","``","[","(","0",",","2",")","]","``",",","where","``","0","``","and","``","2","``","correspond","to","column","0","and","2","in","`","X","`",",","respectively",".","method","The","method","to","be","used","to","compute","the","feature","importance",".","If","set","to","``","'exact","'","``",",","a","``","switch","''","operation","is","performed","across","all","observed","pairs",",","by","excluding","pairings","that","are","actually","observed","in","the","original","dataset",".","This","operation","is","quadratic","in","the","number","of","samples","(","`","N","x","(","N","-","1",")","`","samples",")","and","thus","can","be","computationally","intensive",".","If","set","to","``","'estimate","'","``",",","the","dataset","will","be","divided","in","half",".","The","values","of","the","first","half","containing","the","ground-truth","labels","the","rest","of","the","features","(","i.e",".","features","that","are","left","intact",")","is","matched","with","the","values","of","the","second","half","of","the","permuted","features",",","and","the","other","way","around",".","This","method","is","computationally","lighter","and","provides","estimate","error","bars","given","by","the","standard","deviation",".","Note","that","for","some","specific","loss","and","score","functions",",","the","estimate","does","not","converge","to","the","exact","metric","value",".","kind","Whether","to","report","the","importance","as","the","loss\/score","ratio","or","the","loss\/score","difference",".","Available","values","are",":","``","'ratio","'","``","|","``","'difference","'","``",".","n_repeats","Number","of","times","to","permute","the","feature","values",".","Considered","only","when","``","method='estimate","'","``",".","sample_weight","Optional","weight","for","each","sample","instance",".","Returns","--","--","--","-","explanation","An","`","Explanation","`","object","containing","the","data","and","the","metadata","of","the","permutation","feature","importance",".","See","usage","at","`","Permutation","feature","importance","examples","`","_","for","details","..","_Permutation","feature","importance","examples",":","https",":","\/\/docs.seldon.io\/projects\/alibi\/en\/stable\/methods\/PermutationImportance.html"]
code: def explain(
      self,  # type: ignore[override]
      X: np.ndarray,
      y: np.ndarray,
      features: Optional[List[Union[int, Tuple[int, ...]]]] = None,
      method: Literal["estimate", "exact"] = "estimate",
      kind: Literal["ratio", "difference"] = "ratio",
      n_repeats: int = 50,
      sample_weight: Optional[np.ndarray] = None,
  ) -> Explanation:
      """
      Computes the permutation feature importance for each feature with respect to the given loss or score
      functions and the dataset `(X, y)`.
  
      Parameters
      ----------
      X
          A `N x F` input feature dataset used to calculate the permutation feature importance. This is typically the
          test dataset.
      y
          Ground-truth labels array  of size `N` (i.e. `(N, )`) corresponding the input feature `X`.
      features
          An optional list of features or tuples of features for which to compute the permutation feature
          importance. If not provided, the permutation feature importance will be computed for every single features
          in the dataset. Some example of `features` would be: ``[0, 2]``, ``[0, 2, (0, 2)]``, ``[(0, 2)]``,
          where ``0`` and ``2`` correspond to column 0 and 2 in `X`, respectively.
      method
          The method to be used to compute the feature importance. If set to ``'exact'``, a "switch" operation is
          performed across all observed pairs, by excluding pairings that are actually observed in the original
          dataset. This operation is quadratic in the number of samples (`N x (N - 1)` samples) and thus can be
          computationally intensive. If set to ``'estimate'``, the dataset will be divided in half. The values of
          the first half containing the ground-truth labels the rest of the features (i.e. features that are left
          intact) is matched with the values of the second half of the permuted features, and the other way around.
          This method is computationally lighter and provides estimate error bars given by the standard deviation.
          Note that for some specific loss and score functions, the estimate does not converge to the exact metric
          value.
      kind
          Whether to report the importance as the loss/score ratio or the loss/score difference.
          Available values are: ``'ratio'`` | ``'difference'``.
      n_repeats
          Number of times to permute the feature values. Considered only when ``method='estimate'``.
      sample_weight
          Optional weight for each sample instance.
  
      Returns
      -------
      explanation
          An `Explanation` object containing the data and the metadata of the permutation feature importance.
          See usage at `Permutation feature importance examples`_ for details
  
          .. _Permutation feature importance examples:
              https://docs.seldon.io/projects/alibi/en/stable/methods/PermutationImportance.html
      """
      n_features = X.shape[1]
  
      # set the `features_names` when the user did not provide the feature names
      if self.feature_names is None:
          self.feature_names = [f"f_{i}" for i in range(n_features)]
  
      # construct `feature_names` based on the `features`. If `features` is ``None``, then initialize
      # `features` with all single feature available in the dataset.
      if features:
          feature_names = [
              tuple([self.feature_names[f] for f in features])
              if isinstance(features, tuple)
              else self.feature_names[features]
              for features in features
          ]
      else:
          feature_names = self.feature_names  # type: ignore[assignment]
          features = list(range(n_features))
  
      # unaltered model predictions
      y_hat = self.predictor(X)
  
      # compute original loss
      loss_orig = PermutationImportance._compute_metrics(
          metric_fns=self.loss_fns,
          y=y,
          y_hat=y_hat,
          sample_weight=sample_weight,
      )
  
      # compute original score
      score_orig = PermutationImportance._compute_metrics(
          metric_fns=self.score_fns,
          y=y,
          y_hat=y_hat,
          sample_weight=sample_weight,
      )
  
      # compute permutation feature importance for every feature
      # TODO: implement parallel version - future work as it can be done for ALE too
      individual_feature_importance = []
  
      for ifeatures in tqdm(features, disable=not self.verbose):
          individual_feature_importance.append(
              self._compute_permutation_importance(
                  X=X,
                  y=y,
                  method=method,
                  kind=kind,
                  n_repeats=n_repeats,
                  sample_weight=sample_weight,
                  features=ifeatures,
                  loss_orig=loss_orig,
                  score_orig=score_orig,
              )
          )
  
      # update meta data params
      self.meta["params"].update(
          feature_names=feature_names,
          method=method,
          kind=kind,
          n_repeats=n_repeats,
          sample_weight=sample_weight,
      )
  
      # build and return the explanation object
      return self._build_explanation(
          feature_names=feature_names,  # type: ignore[arg-type]
          individual_feature_importance=individual_feature_importance,
      )
  
imports: import copy
  import inspect
  import logging
  import math
  import numbers
  import sys
  from collections import defaultdict
  from copy import deepcopy
  from enum import Enum
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union, no_type_check
  import matplotlib.pyplot
  import numpy
  import sklearn.metrics
  from tqdm import tqdm
  from alibi.api.defaults import DEFAULT_DATA_PERMUTATION_IMPORTANCE, DEFAULT_META_PERMUTATION_IMPORTANCE
  from alibi.api.interfaces import Explainer, Explanation
label_desc: Use image node_id 2 for calling the PermutationImportance obj's underlying member method code with example usage: obj.explain(X, y, features, method, kind, n_repeats, sample_weight) and returns: self