class_docstr: Kernel SHAP is a method that uses the LIME framework to compute
  Shapley Values. Setting the loss function, weighting kernel and
  regularization terms appropriately in the LIME framework allows
  theoretically obtaining Shapley Values more efficiently than
  directly computing Shapley Values.
  
  More information regarding this method and proof of equivalence
  can be found in the original paper here:
  https://arxiv.org/abs/1705.07874
class_docstr_tok: ["Kernel","SHAP","is","a","method","that","uses","the","LIME","framework","to","compute","Shapley","Values",".","Setting","the","loss","function",",","weighting","kernel","and","regularization","terms","appropriately","in","the","LIME","framework","allows","theoretically","obtaining","Shapley","Values","more","efficiently","than","directly","computing","Shapley","Values",".","More","information","regarding","this","method","and","proof","of","equivalence","can","be","found","in","the","original","paper","here",":","https",":","\/\/arxiv.org\/abs\/1705.07874"]
docstr: Perturbations are sampled by the following process:
   - Choose k (number of selected features), based on the distribution
          p(k) = (M - 1) / (k * (M - k))
  
      where M is the total number of features in the interpretable space
  
   - Randomly select a binary vector with k ones, each sample is equally
      likely. This is done by generating a random vector of normal
      values and thresholding based on the top k elements.
  
   Since there are M choose k vectors with k ones, this weighted sampling
   is equivalent to applying the Shapley kernel for the sample weight,
   defined as:
   k(M, k) = (M - 1) / (k * (M - k) * (M choose k))
docstr_tok: ["Perturbations","are","sampled","by","the","following","process",":","-","Choose","k","(","number","of","selected","features",")",",","based","on","the","distribution","p","(","k",")","=","(","M","-","1",")","\/","(","k","*","(","M","-","k",")",")","where","M","is","the","total","number","of","features","in","the","interpretable","space","-","Randomly","select","a","binary","vector","with","k","ones",",","each","sample","is","equally","likely",".","This","is","done","by","generating","a","random","vector","of","normal","values","and","thresholding","based","on","the","top","k","elements",".","Since","there","are","M","choose","k","vectors","with","k","ones",",","this","weighted","sampling","is","equivalent","to","applying","the","Shapley","kernel","for","the","sample","weight",",","defined","as",":","k","(","M",",","k",")","=","(","M","-","1",")","\/","(","k","*","(","M","-","k",")","*","(","M","choose","k",")",")"]
code: def kernel_shap_perturb_generator(
      self, original_inp: Union[Tensor, Tuple[Tensor, ...]], **kwargs
  ) -> Generator[Tensor, None, None]:
      r"""
      Perturbations are sampled by the following process:
       - Choose k (number of selected features), based on the distribution
              p(k) = (M - 1) / (k * (M - k))
  
          where M is the total number of features in the interpretable space
  
       - Randomly select a binary vector with k ones, each sample is equally
          likely. This is done by generating a random vector of normal
          values and thresholding based on the top k elements.
  
       Since there are M choose k vectors with k ones, this weighted sampling
       is equivalent to applying the Shapley kernel for the sample weight,
       defined as:
       k(M, k) = (M - 1) / (k * (M - k) * (M choose k))
      """
      assert (
          "num_select_distribution" in kwargs
          and "num_interp_features" in kwargs
      ), (
          "num_select_distribution and num_interp_features are necessary"
          " to use kernel_shap_perturb_func"
      )
      if isinstance(original_inp, Tensor):
          device = original_inp.device
      else:
          device = original_inp[0].device
      num_features = kwargs["num_interp_features"]
      yield torch.ones(1, num_features, device=device, dtype=torch.long)
      yield torch.zeros(
          1, num_features, device=device, dtype=torch.long
      )
      while True:
          num_selected_features = kwargs[
              "num_select_distribution"
          ].sample()
          rand_vals = torch.randn(1, num_features)
          threshold = torch.kthvalue(
              rand_vals, num_features - num_selected_features
          ).values.item()
          yield (rand_vals > threshold).to(device=device).long()
  
file_path: captum/captum/attr/_core/kernel_shap.py
imports: from typing import Any, Callable, Generator, Tuple, Union
  import torch
  from captum._utils.models.linear_model import SkLearnLinearRegression
  from captum._utils.typing import BaselineType, TargetType, TensorOrTupleOfTensorsGeneric
  from captum.attr._core.lime import construct_feature_mask, Lime
  from captum.attr._utils.common import _format_input_baseline
  from captum.log import log_usage
  from torch import Tensor
  from torch.distributions.categorical import Categorical
label_desc: Use image node_id 4 for calling the KernelShap obj's underlying member method code with example usage: obj.kernel_shap_perturb_generator(original_inp) without return types