class_docstr: Analysis block that estimates column importance with SHAP (SHapley Additive exPlanations), a game theoretic approach
  to explain the ouput of any machine learning model. SHAP assigns each feature an importance value for a particular
  prediction.
  
  Reference:
      https://shap.readthedocs.io/en/stable/
      https://proceedings.neurips.cc/paper/2017/file/8a20a8621978632d76c43dfd28b67767-Paper.pdf
class_docstr_tok: ["Analysis","block","that","estimates","column","importance","with","SHAP","(","SHapley","Additive","exPlanations",")",",","a","game","theoretic","approach","to","explain","the","ouput","of","any","machine","learning","model",".","SHAP","assigns","each","feature","an","importance","value","for","a","particular","prediction",".","Reference",":","https",":","\/\/shap.readthedocs.io\/en\/stable\/","https",":","\/\/proceedings.neurips.cc\/paper\/2017\/file\/8a20a8621978632d76c43dfd28b67767-Paper.pdf"]
code: def explain(
      self,
      row_insights: pd.DataFrame,
      global_insights: Dict[str, object],
      **kwargs,
  ) -> Tuple[pd.DataFrame, Dict[str, object]]:
      log.info(
          "Computing feature importance values with Kernel SHAP method"
      )
      ns = SimpleNamespace(**kwargs)
  
      shap_explainer = ns.analysis.get("shap_explainer", None)
      if shap_explainer is None:
          return row_insights, global_insights
  
      with warnings.catch_warnings():
          warnings.filterwarnings("ignore", category=DeprecationWarning)
          shap_values = shap_explainer.shap_values(
              ns.data[self.columns], silent=True
          )
  
      shap_values_df = pd.DataFrame(shap_values).rename(
          mapper=lambda i: f"shap_contribution_{self.columns[i]}",
          axis="columns",
      )
  
      if kwargs.get("target_dtype", None) in (
          dtype.binary,
          dtype.categorical,
          dtype.tags,
      ):
          predictions = self.label_encoder.transform(
              row_insights["prediction"]
          )
      else:
          predictions = row_insights["prediction"]
  
      base_response = (
          predictions - shap_values_df.sum(axis="columns")
      ).mean()
  
      row_insights = pd.concat(
          [row_insights, shap_values_df], axis="columns"
      )
      row_insights["shap_base_response"] = base_response
      row_insights["shap_final_response"] = predictions
  
      return row_insights, global_insights
  
file_path: lightwood/lightwood/analysis/helpers/shap.py
imports: import warnings
  from types import SimpleNamespace
  from typing import Dict, Optional, Tuple
  import numpy
  import pandas
  from lightwood.analysis.base import BaseAnalysisBlock
  from type_infer.dtype import dtype
  from lightwood.api.types import PredictionArguments
  from lightwood.data.encoded_ds import EncodedDs
  from lightwood.helpers.log import log
  from sklearn.preprocessing import LabelEncoder
  import shap
label_desc: Use image node_id 3 for calling the ShapleyValues obj's underlying member method code with example usage: obj.explain(row_insights, global_insights) and returns: row_insights,  global_insights, row_insights,  global_insights