Module ablation.explanations
Expand source code
from typing import List
import numpy as np
from ablation.dataset import NumpyDataset
class Explanations:
"""
Explanations is an object that allows for quick conversion/access
to both sparse and dense explanations. These explanation values
depend on the composition of types used for the specific dataset
under test. It leverages the feature name mappings that are typically
created by library transformer objects (e.g., ColumnTransformer from sklearn)
"""
def __init__(self, explanation_values: np.ndarray, agg_map: List[List[int]]):
"""Constructor for Explanations class
Args:
explanation_values (np.ndarray): explanation values in sparse (i.e., post-encoded) format.
agg_map (List[List[int]]): Aggregation map for sparse to dense.
"""
self.explanation_values = explanation_values
self.agg_map = agg_map
# Calculate the dense explanation values
self.dense_explanation_values = self.transform_explanations_sparse_to_dense(
self.explanation_values
)
def data(self, format: str = "dense") -> np.ndarray:
"""
Getter for the underlying np.ndarray structure that contains the explanation values.
Those values are either sparse (not aggregated) or dense (aggregated).
Args:
format (str): "dense" or "sparse" formats to obtain np.ndarray explanations.
Returns:
np.array: explanation values
"""
if format.lower() == "dense":
return self.dense_explanation_values
elif format.lower() == "sparse":
return self.explanation_values
else:
raise ValueError(
f"Supported formats for raw explanations are 'dense' and 'sparse'. Got '{format.lower()}'."
)
def transform_explanations_sparse_to_dense(self, sparse_explanations: np.ndarray):
"""
Calculates dense explanations from sparse explanations using class member aggregation map
Args:
sparse_explanations (np.ndarray): Explanations in sparse format.
Returns:
np.array: Explanations in dense format.
"""
# Assume input is local sparse SHAP values
sparse_rep_local_shap = sparse_explanations
# If the aggregation map is None, indicating that there is no difference between
# sparse and dense representations, simply return sparse_rep_local_shap.
if self.agg_map is None:
return sparse_rep_local_shap
dense_rep_local_shap = np.zeros(
(sparse_rep_local_shap.shape[0], len(self.agg_map))
)
for (i, map) in enumerate(self.agg_map):
dense_rep_local_shap[:, i] = np.sum(sparse_rep_local_shap[:, map], axis=1)
return dense_rep_local_shap
Classes
class Explanations (explanation_values: numpy.ndarray, agg_map: List[List[int]])
-
Explanations is an object that allows for quick conversion/access to both sparse and dense explanations. These explanation values depend on the composition of types used for the specific dataset under test. It leverages the feature name mappings that are typically created by library transformer objects (e.g., ColumnTransformer from sklearn)
Constructor for Explanations class
Args
explanation_values
:np.ndarray
- explanation values in sparse (i.e., post-encoded) format.
agg_map
:List[List[int]]
- Aggregation map for sparse to dense.
Expand source code
class Explanations: """ Explanations is an object that allows for quick conversion/access to both sparse and dense explanations. These explanation values depend on the composition of types used for the specific dataset under test. It leverages the feature name mappings that are typically created by library transformer objects (e.g., ColumnTransformer from sklearn) """ def __init__(self, explanation_values: np.ndarray, agg_map: List[List[int]]): """Constructor for Explanations class Args: explanation_values (np.ndarray): explanation values in sparse (i.e., post-encoded) format. agg_map (List[List[int]]): Aggregation map for sparse to dense. """ self.explanation_values = explanation_values self.agg_map = agg_map # Calculate the dense explanation values self.dense_explanation_values = self.transform_explanations_sparse_to_dense( self.explanation_values ) def data(self, format: str = "dense") -> np.ndarray: """ Getter for the underlying np.ndarray structure that contains the explanation values. Those values are either sparse (not aggregated) or dense (aggregated). Args: format (str): "dense" or "sparse" formats to obtain np.ndarray explanations. Returns: np.array: explanation values """ if format.lower() == "dense": return self.dense_explanation_values elif format.lower() == "sparse": return self.explanation_values else: raise ValueError( f"Supported formats for raw explanations are 'dense' and 'sparse'. Got '{format.lower()}'." ) def transform_explanations_sparse_to_dense(self, sparse_explanations: np.ndarray): """ Calculates dense explanations from sparse explanations using class member aggregation map Args: sparse_explanations (np.ndarray): Explanations in sparse format. Returns: np.array: Explanations in dense format. """ # Assume input is local sparse SHAP values sparse_rep_local_shap = sparse_explanations # If the aggregation map is None, indicating that there is no difference between # sparse and dense representations, simply return sparse_rep_local_shap. if self.agg_map is None: return sparse_rep_local_shap dense_rep_local_shap = np.zeros( (sparse_rep_local_shap.shape[0], len(self.agg_map)) ) for (i, map) in enumerate(self.agg_map): dense_rep_local_shap[:, i] = np.sum(sparse_rep_local_shap[:, map], axis=1) return dense_rep_local_shap
Methods
def data(self, format: str = 'dense') ‑> numpy.ndarray
-
Getter for the underlying np.ndarray structure that contains the explanation values. Those values are either sparse (not aggregated) or dense (aggregated).
Args
format
:str
- "dense" or "sparse" formats to obtain np.ndarray explanations.
Returns
np.array
- explanation values
Expand source code
def data(self, format: str = "dense") -> np.ndarray: """ Getter for the underlying np.ndarray structure that contains the explanation values. Those values are either sparse (not aggregated) or dense (aggregated). Args: format (str): "dense" or "sparse" formats to obtain np.ndarray explanations. Returns: np.array: explanation values """ if format.lower() == "dense": return self.dense_explanation_values elif format.lower() == "sparse": return self.explanation_values else: raise ValueError( f"Supported formats for raw explanations are 'dense' and 'sparse'. Got '{format.lower()}'." )
def transform_explanations_sparse_to_dense(self, sparse_explanations: numpy.ndarray)
-
Calculates dense explanations from sparse explanations using class member aggregation map
Args
sparse_explanations
:np.ndarray
- Explanations in sparse format.
Returns
np.array
- Explanations in dense format.
Expand source code
def transform_explanations_sparse_to_dense(self, sparse_explanations: np.ndarray): """ Calculates dense explanations from sparse explanations using class member aggregation map Args: sparse_explanations (np.ndarray): Explanations in sparse format. Returns: np.array: Explanations in dense format. """ # Assume input is local sparse SHAP values sparse_rep_local_shap = sparse_explanations # If the aggregation map is None, indicating that there is no difference between # sparse and dense representations, simply return sparse_rep_local_shap. if self.agg_map is None: return sparse_rep_local_shap dense_rep_local_shap = np.zeros( (sparse_rep_local_shap.shape[0], len(self.agg_map)) ) for (i, map) in enumerate(self.agg_map): dense_rep_local_shap[:, i] = np.sum(sparse_rep_local_shap[:, map], axis=1) return dense_rep_local_shap