Generate SHAP explanations for model predictions given a set of inputs. Args: inputs: The subset of inputs from the dataset to get prediction for. If empty, falls back to dataset.examples. model: The model making the predictions that get explained. dataset: The dataset
(
self,
inputs: list[JsonDict],
model: lit_model.Model,
dataset: lit_dataset.Dataset,
model_outputs: Optional[list[JsonDict]] = None,
config: Optional[JsonDict] = None
)
| 109 | return {'saliency': types.FeatureSalience(autorun=False, signed=True)} |
| 110 | |
| 111 | def run( |
| 112 | self, |
| 113 | inputs: list[JsonDict], |
| 114 | model: lit_model.Model, |
| 115 | dataset: lit_dataset.Dataset, |
| 116 | model_outputs: Optional[list[JsonDict]] = None, |
| 117 | config: Optional[JsonDict] = None |
| 118 | ) -> Optional[list[dict[str, dtypes.FeatureSalience]]]: |
| 119 | """Generate SHAP explanations for model predictions given a set of inputs. |
| 120 | |
| 121 | Args: |
| 122 | inputs: The subset of inputs from the dataset to get prediction for. If |
| 123 | empty, falls back to dataset.examples. |
| 124 | model: The model making the predictions that get explained. |
| 125 | dataset: The dataset from which the inputs originated. |
| 126 | model_outputs: Unused, but reqired by the base class. |
| 127 | config: A dictionary containing the key of the feature to explain, and the |
| 128 | optional sample size if taking a random sample from the inputs. |
| 129 | |
| 130 | Returns: |
| 131 | A list of FeatureSalience objects, one for each (randomly sampled) input, |
| 132 | containing per-input feature salience values in the range of [-1, 1]. |
| 133 | |
| 134 | Raises: |
| 135 | ValueError: if the value of `config[EXPLAIN_KEY]` is not found in the |
| 136 | model's output spec. |
| 137 | """ |
| 138 | del model_outputs # Unused. SHAP calls the model directly |
| 139 | |
| 140 | config_defaults = {k: v.default for k, v in self.config_spec().items()} |
| 141 | config = dict(config_defaults, **(config or {})) |
| 142 | |
| 143 | default_pred_key = utils.find_spec_keys( |
| 144 | model.output_spec(), _SUPPORTED_OUTPUT_TYPES)[0] |
| 145 | pred_key = config.get(EXPLAIN_KEY) or default_pred_key |
| 146 | pred_spec = model.output_spec().get(pred_key) |
| 147 | if not pred_spec: |
| 148 | raise ValueError('SHAP requires a prediction field to explain. Could not ' |
| 149 | f'find {pred_key} in spec, {str(model.output_spec())}.') |
| 150 | |
| 151 | input_feats = [key for key in model.input_spec() if key in dataset.spec()] |
| 152 | |
| 153 | example_data = inputs or dataset.examples |
| 154 | examples: pd.DataFrame = pd.DataFrame(example_data)[input_feats] |
| 155 | sample_size = int(config.get(SAMPLE_KEY, 0)) |
| 156 | if sample_size and len(examples) > sample_size: |
| 157 | inputs_to_use: pd.DataFrame = examples.sample(sample_size) |
| 158 | else: |
| 159 | inputs_to_use: pd.DataFrame = examples |
| 160 | |
| 161 | random_baseline = dataset.sample(1).examples |
| 162 | background = pd.DataFrame(random_baseline)[input_feats] |
| 163 | |
| 164 | def prediction_fn(examples): |
| 165 | dict_examples: list[JsonDict] = [ |
| 166 | dict(zip(input_feats, feature_values)) for feature_values in examples |
| 167 | ] |
| 168 |
nothing calls this directly
no test coverage detected