class_docstr: Class Feature Interpreter.
  
  The class is used to generate the following information:
      - feature distribution
      - feature correlation
      - feature importance ranking for a trained model
docstr: Get shap values for all samples group by features
  
  Args:
      trained_model: model obj, the trained model object
      train_x: numpy.dnarray, training data
      mode: str, regression or classification (default)
  
  Returns:
      A list of tuple (feature name, shap values for each sample) if aggregation is False
docstr_tok: ["Get","shap","values","for","all","samples","group","by","features","Args",":","trained_model",":","model","obj",",","the","trained","model","object","train_x",":","numpy.dnarray",",","training","data","mode",":","str",",","regression","or","classification","(","default",")","Returns",":","A","list","of","tuple","(","feature","name",",","shap","values","for","each","sample",")","if","aggregation","is","False"]
code: def get_feature_shap_values(
      self,
      trained_model,
      train_x: numpy.ndarray,
      mode: str = MODE.CLASSIFICATION,
  ) -> List[Tuple[str, List[float]]]:
      """
      Get shap values for all samples group by features
  
      Args:
          trained_model: model obj, the trained model object
          train_x: numpy.dnarray, training data
          mode: str, regression or classification (default)
  
      Returns:
          A list of tuple (feature name, shap values for each sample) if aggregation is False
  
      """
      enable_kernel_explainer = False
      try:
          explainer = shap.TreeExplainer(trained_model)
      except Exception as e:
          if "Model type not yet supported by TreeExplainer" in str(e):
              enable_kernel_explainer = True
              warnings.warn(
                  message="Warning: the current model type (%s) is not supported by TreeExplainer in shap. "
                  "Will call KernelExplainer and may take longer to generate the feature importance."
                  % type(trained_model)
              )
          else:
              raise e
      if enable_kernel_explainer:
          predict_call = getattr(trained_model, "predict_proba", None)
          if predict_call is None or not callable(predict_call):
              if not callable(getattr(trained_model, "predict", None)):
                  raise Exception(
                      "Fail to initialize explainer as model does not have the function call <predict_proba> and <predict>"
                  )
              explainer = shap.KernelExplainer(
                  model=trained_model.predict, data=train_x
              )
          else:
              explainer = shap.KernelExplainer(
                  model=trained_model.predict_proba, data=train_x
              )
  
      shap_values = explainer.shap_values(train_x)
      feature_values = list(
          zip(
              self._feature_names,
              numpy.array(shap_values).transpose().tolist(),
          )
      )
      if mode == MODE.REGRESSION:
          feature_values = [
              (feature_name, [[x] for x in feature_value])
              for feature_name, feature_value in feature_values
          ]
      return feature_values
  
imports: import operator
  import warnings
  import numpy
  import pandas
  from scipy import stats
  from typing import List, Dict, Tuple
  import shap
  from xai import ALG, MODE
  from xai.data.constants import DATATYPE
  from xai.data.explorer.data_analyzer_suite import DataAnalyzerSuite
  from xai.model.interpreter.exceptions import InconsistentSize, TrainingDataNotProvided
  from xai.model.interpreter.exceptions import UnsupportedMethodType
label_desc: Use image node_id 9 for calling the FeatureInterpreter obj's underlying member method code with example usage: obj.get_feature_shap_values(trained_model, train_x, mode) and returns: feature_values