class_docstr: Class for TabNet model.
class_docstr_tok: ["Class","for","TabNet","model","."]
docstr: Return local explanation
  
  Parameters
  ----------
  X : tensor: `torch.Tensor` or matrix: `scipy.sparse.csr_matrix`
      Input data
  normalize : bool (default False)
      Wheter to normalize so that sum of features are equal to 1
  
  Returns
  -------
  M_explain : matrix
      Importance per sample, per columns.
  masks : matrix
      Sparse matrix showing attention masks used by network.
docstr_tok: ["Return","local","explanation","Parameters","--","--","--","--","--","X",":","tensor",":","`","torch.Tensor","`","or","matrix",":","`","scipy.sparse.csr_matrix","`","Input","data","normalize",":","bool","(","default","False",")","Wheter","to","normalize","so","that","sum","of","features","are","equal","to","1","Returns","--","--","--","-","M_explain",":","matrix","Importance","per","sample",",","per","columns",".","masks",":","matrix","Sparse","matrix","showing","attention","masks","used","by","network","."]
code: def explain(self, X, normalize=False):
      """
      Return local explanation
  
      Parameters
      ----------
      X : tensor: `torch.Tensor` or matrix: `scipy.sparse.csr_matrix`
          Input data
      normalize : bool (default False)
          Wheter to normalize so that sum of features are equal to 1
  
      Returns
      -------
      M_explain : matrix
          Importance per sample, per columns.
      masks : matrix
          Sparse matrix showing attention masks used by network.
      """
      self.network.eval()
  
      if scipy.sparse.issparse(X):
          dataloader = DataLoader(
              SparsePredictDataset(X),
              batch_size=self.batch_size,
              shuffle=False,
          )
      else:
          dataloader = DataLoader(
              PredictDataset(X),
              batch_size=self.batch_size,
              shuffle=False,
          )
  
      res_explain = []
  
      for batch_nb, data in enumerate(dataloader):
          data = data.to(self.device).float()
  
          M_explain, masks = self.network.forward_masks(data)
          for key, value in masks.items():
              masks[key] = csc_matrix.dot(
                  value.cpu().detach().numpy(), self.reducing_matrix
              )
          original_feat_explain = csc_matrix.dot(
              M_explain.cpu().detach().numpy(), self.reducing_matrix
          )
          res_explain.append(original_feat_explain)
  
          if batch_nb == 0:
              res_masks = masks
          else:
              for key, value in masks.items():
                  res_masks[key] = np.vstack([res_masks[key], value])
  
      res_explain = np.vstack(res_explain)
  
      if normalize:
          res_explain /= np.sum(res_explain, axis=1)[:, None]
  
      return res_explain, res_masks
  
imports: from dataclasses import dataclass, field
  from typing import List, Any, Dict
  import torch
  from torch.nn.utils import clip_grad_norm_
  import numpy
  from scipy.sparse import csc_matrix
  from abc import abstractmethod
  from pytorch_tabnet import tab_network
  from pytorch_tabnet.utils import SparsePredictDataset, PredictDataset, create_explain_matrix, validate_eval_set, create_dataloaders, define_device, ComplexEncoder, check_input, check_warm_start, create_group_matrix, check_embedding_parameters
  from pytorch_tabnet.callbacks import CallbackContainer, History, EarlyStopping, LRSchedulerCallback
  from pytorch_tabnet.metrics import MetricContainer, check_metrics
  from sklearn.base import BaseEstimator
  from torch.utils.data import DataLoader
  import io
  import json
  from pathlib import Path
  import shutil
  import zipfile
  import warnings
  import copy
  import scipy
label_desc: Use image node_id 5 for calling the TabModel obj's underlying member method code with example usage: obj.explain(X, normalize) and returns: res_explain,  res_masks