class_docstr: Counterfactual Reinforcement Learning. 
class_docstr_tok: ["Counterfactual","Reinforcement","Learning","."]
docstr: Explains an input instance
  
  Parameters
  ----------
  X
      Instances to be explained.
  Y_t
      Counterfactual targets.
  C
      Conditional vectors. If ``None``, it means that no conditioning was used during training (i.e. the
      `conditional_func` returns ``None``).
  batch_size
      Batch size to be used when generating counterfactuals.
  
  Returns
  -------
  explanation
      `Explanation` object containing the counterfactual with additional metadata as attributes.             See usage at `CFRL examples`_ for details.
  
      .. _CFRL examples:
          https://docs.seldon.io/projects/alibi/en/stable/methods/CFRL.html
code: def explain(
      self,  # type: ignore[override]
      X: np.ndarray,
      Y_t: np.ndarray,
      C: Optional[np.ndarray] = None,
      batch_size: int = 100,
  ) -> Explanation:
      """
          Explains an input instance
  
          Parameters
          ----------
          X
              Instances to be explained.
          Y_t
              Counterfactual targets.
          C
              Conditional vectors. If ``None``, it means that no conditioning was used during training (i.e. the
              `conditional_func` returns ``None``).
          batch_size
              Batch size to be used when generating counterfactuals.
  
          Returns
          -------
          explanation
              `Explanation` object containing the counterfactual with additional metadata as attributes. \
              See usage at `CFRL examples`_ for details.
  
              .. _CFRL examples:
                  https://docs.seldon.io/projects/alibi/en/stable/methods/CFRL.html
          """
      # General validation.
      self._validate_target(Y_t)
      self._validate_condition(C)
  
      # Check the number of target labels.
      if Y_t.shape[0] != 1 and Y_t.shape[0] != X.shape[0]:
          raise ValueError(
              "The number target labels should be 1 or equals the number of samples in X."
          )
  
      # Check the number of conditional vectors
      if (
          (C is not None)
          and C.shape[0] != 1
          and C.shape[0] != X.shape[0]
      ):
          raise ValueError(
              "The number of conditional vectors should be 1 or equals the number if samples in X."
          )
  
      # Transform target into a 2D array.
      Y_t = Y_t.reshape(Y_t.shape[0], -1)
  
      # Repeat the same label to match the number of input instances.
      if Y_t.shape[0] == 1:
          Y_t = np.tile(Y_t, (X.shape[0], 1))
  
      # Repeat the same conditional vectors to match the number of input instances.
      if C is not None:
          C = np.tile(C, (X.shape[0], 1))
  
      # Perform prediction in mini-batches.
      n_minibatch = int(np.ceil(X.shape[0] / batch_size))
      all_results: Dict[str, Optional[np.ndarray]] = {}
  
      for i in tqdm(range(n_minibatch)):
          istart, istop = i * batch_size, min(
              (i + 1) * batch_size, X.shape[0]
          )
          results = self._compute_counterfactual(
              X=X[istart:istop],
              Y_t=Y_t[istart:istop],
              C=C[istart:istop] if (C is not None) else C,
          )
  
          # Initialize the dict.
          if not all_results:
              all_results = results
              continue
  
          # Append the new batch off results.
          for key in all_results:
              all_results_val, results_val = (
                  all_results[key],
                  results[key],
              )
              if (
                  all_results_val is not None
                  and results_val is not None
              ):
                  all_results[key] = np.concatenate(
                      [all_results_val, results_val], axis=0
                  )
  
      # see https://github.com/python/mypy/issues/5382 for the type ignore
      return self._build_explanation(**all_results)
  
imports: import logging
  import os
  from abc import ABC, abstractmethod
  from copy import deepcopy
  from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Union, cast
  import numpy
  from tqdm import tqdm
  from alibi.api.defaults import DEFAULT_DATA_CFRL, DEFAULT_META_CFRL
  from alibi.api.interfaces import Explainer, Explanation, FitMixin
  from alibi.explainers.backends.cfrl_base import generate_empty_condition, get_classification_reward, get_hard_distribution, identity_function
  from alibi.utils.frameworks import Framework, has_pytorch, has_tensorflow
label_desc: Use image node_id 14 for calling the CounterfactualRL obj's underlying member method code with example usage: obj.explain(X, Y_t, C, batch_size) and returns: self