Skip to content

KLEOR

View colab tutorial | View source | 📰 Paper

KLEOR for Knowledge-Light Explanation-Oriented Retrieval was introduced by Cummins & Bridge in 2006. It is a method that use counterfactuals, Nearest Unlike Neighbor (NUN), to guide the selection of a semi-factual (SF) example.

Given a distance function \(dist\), the NUN of a sample \((x, y)\) is the closest sample in the training dataset which has a different label than \(y\).

The KLEOR method actually have three variants including:

  • The Sim-Miss approach
  • The Global-Sim approach

In the Sim-Miss approach, the SF of the sample \((x,y)\) is the closest training sample from the corresponding NUN which has the same label as \(y\).

Denoting the training dataset as \(\mathcal{D}\):

\[Sim-Miss(x, y, NUN(x,y), \mathcal{D}) = arg \\ min_{(x',y') \in \mathcal{D} \\ | \\ y'=y} dist(x', NUN(x,y))\]

In the Global-Sim approach, they add an additional constraint that the SF should lie between the sample \((x,y)\) and the NUN that is: \(dist(x, SF) < dist(x, NUN(x,y))\).

We extended to the \(k\) nearest neighbors of the NUN for both approaches.

Info

In our implementation, we rather consider the labels predicted by the model \(\hat{y}\) (i.e. the targets) rather than \(y\)!

Tips

As KLEOR methods use counterfactuals, they can also return them. Therefore, it is possible to obtain both semi-factuals and counterfactuals with an unique method. To do so "nuns" and "nuns_labels" should be added to the cases_returns list.

Examples

from xplique.example_based import KLEORGlobalSim  # or KLEORSimMiss
from xplique.example_based.projections import LatentSpaceProjection

# load the training dataset and the model
cases_dataset = ... # load the training dataset
targets_dataset = ... # load the one-hot encoding of predicted labels of the training dataset
model = ...

# load the test samples
test_samples = ... # load the test samples to search for
test_targets = ... # compute a one hot encoding of the model's prediction on the samples

# parameters
k = 1  # number of example for each input
case_returns = "all"  # elements returned by the explain function
distance = "euclidean"
latent_layer = "last_conv"  # where to split your model for the projection

# construct a projection with your model
projection = LatentSpaceProjection(model, latent_layer=latent_layer)

# instantiate the KLEORGlobalSim object (could be KLEORSimMiss, the code do not change)
sf_explainer = KLEORGlobalSim(
    cases_dataset=cases_dataset,
    targets_dataset=targets_dataset,
    k=k,
    projection=projection,
    case_returns=case_returns,
    distance=distance,
)

# search the SFs for the test samples
sf_output_dict = sf_explainer.explain(
    inputs=test_samples,
    targets=test_targets,
)

# get the semi-factuals
semifactuals = sf_output_dict["examples"]

# get the counterfactuals
counterfactuals = sf_output_dict["nuns"]

Notebooks

KLEORSimMiss

The KLEORSimMiss method search for Semi-Factuals examples by searching for the Nearest Unlike Neighbor (NUN) of the query. The NUN is the closest example to the query that has a different prediction than the query. Then, the method search for the K-Nearest Neighbors (KNN) of the NUN that have the same prediction as the query.

__init__(self,
         cases_dataset: ~DatasetOrTensor,
         targets_dataset: ~DatasetOrTensor,
         labels_dataset: Optional[~DatasetOrTensor] = None,
         k: int = 1,
         projection: Union[xplique.example_based.projections.base.Projection, Callable] = None,
         case_returns: Union[List[str], str] = 'examples',
         batch_size: Optional[int] = None,
         distance: Union[int, str, Callable] = 'euclidean')

explain(self,
        inputs: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray],
        targets: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray, None] = None)

Return the relevant examples to explain the (inputs, targets). It projects inputs with self.projection in the search space and find examples with the self.search_method.

Parameters

  • inputs : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray]

    • Tensor or Array. Input samples to be explained.

      Expected shape among (N, W), (N, T, W), (N, W, H, C).

      More information in the documentation.

  • targets : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray, None] = None

    • Targets associated to the inputs for projection.

      Shape: (n, nb_classes) where n is the number of samples and nb_classes is the number of classes.

      It is used in the projection. But projection can compute it internally.

Return

  • return_dict

    • Dictionary with listed elements in self.returns.

      The elements that can be returned are defined with the _returns_possibilities static attribute of the class.


format_search_output(self,
                     search_output: Dict[str, tensorflow.python.framework.tensor.Tensor],
                     inputs: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray])

Format the output of the search_method to match the expected returns in self.returns.

Parameters

  • search_output : Dict[str, tensorflow.python.framework.tensor.Tensor]

    • Dictionary with the required outputs from the search_method.

  • inputs : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray]

    • Tensor or Array. Input samples to be explained.

      Expected shape among (N, W), (N, T, W), (N, W, H, C).

Return

  • return_dict

    • Dictionary with listed elements in self.returns.

      The elements that can be returned are defined with the _returns_possibilities static attribute of the class.


KLEORGlobalSim

The KLEORGlobalSim method search for Semi-Factuals examples by searching for the Nearest Unlike Neighbor (NUN) of the query. The NUN is the closest example to the query that has a different prediction than the query. Then, the method search for the K-Nearest Neighbors (KNN) of the NUN that have the same prediction as the query.

__init__(self,
         cases_dataset: ~DatasetOrTensor,
         targets_dataset: ~DatasetOrTensor,
         labels_dataset: Optional[~DatasetOrTensor] = None,
         k: int = 1,
         projection: Union[xplique.example_based.projections.base.Projection, Callable] = None,
         case_returns: Union[List[str], str] = 'examples',
         batch_size: Optional[int] = None,
         distance: Union[int, str, Callable] = 'euclidean')

explain(self,
        inputs: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray],
        targets: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray, None] = None)

Return the relevant examples to explain the (inputs, targets). It projects inputs with self.projection in the search space and find examples with the self.search_method.

Parameters

  • inputs : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray]

    • Tensor or Array. Input samples to be explained.

      Expected shape among (N, W), (N, T, W), (N, W, H, C).

      More information in the documentation.

  • targets : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray, None] = None

    • Targets associated to the inputs for projection.

      Shape: (n, nb_classes) where n is the number of samples and nb_classes is the number of classes.

      It is used in the projection. But projection can compute it internally.

Return

  • return_dict

    • Dictionary with listed elements in self.returns.

      The elements that can be returned are defined with the _returns_possibilities static attribute of the class.


format_search_output(self,
                     search_output: Dict[str, tensorflow.python.framework.tensor.Tensor],
                     inputs: Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray])

Format the output of the search_method to match the expected returns in self.returns.

Parameters

  • search_output : Dict[str, tensorflow.python.framework.tensor.Tensor]

    • Dictionary with the required outputs from the search_method.

  • inputs : Union[tensorflow.python.framework.tensor.Tensor, numpy.ndarray]

    • Tensor or Array. Input samples to be explained.

      Expected shape among (N, W), (N, T, W), (N, W, H, C).

Return

  • return_dict

    • Dictionary with listed elements in self.returns.

      The elements that can be returned are defined with the _returns_possibilities static attribute of the class.