Source code for dice_ml.counterfactual_explanations

import json
import pandas as pd

import dice_ml.diverse_counterfactuals as exp
from dice_ml.utils.serialize import DummyDataInterface


[docs]def json_converter(obj): """ Helper function to convert CounterfactualExplanations object to json. """ if isinstance(obj, CounterfactualExplanations): rdict = obj.__dict__ return rdict try: return obj.to_json() except AttributeError: return obj.__dict__
[docs]def as_counterfactual_explanations(json_dict): """ Helper function to convert json string to a CounterfactualExplanations object. """ if 'metadata' in json_dict: cf_examples_list = [] for cf_examples_str in json_dict["cf_examples_list"]: cf_examples_dict = json.loads(cf_examples_str) test_instance_df = pd.read_json(cf_examples_dict["test_instance_df"]) cfs_df = pd.read_json(cf_examples_dict["final_cfs_df"]) # Creating the object for dummy_data_interface dummy_data_interface = DummyDataInterface(**cf_examples_dict["data_interface"]) cf_examples_list.append( exp.CounterfactualExamples(data_interface=dummy_data_interface, test_instance_df=test_instance_df, final_cfs_df=cfs_df, final_cfs_df_sparse=cfs_df, posthoc_sparsity_param=None, desired_class=cf_examples_dict["desired_class"], desired_range=cf_examples_dict["desired_range"], model_type=cf_examples_dict["model_type"]) ) return CounterfactualExplanations(cf_examples_list, local_importance=json_dict["local_importance"], summary_importance=json_dict["summary_importance"]) else: return json_dict
[docs]class CounterfactualExplanations: """A class to store counterfactual examples for one or more inputs and feature importance scores. :param cf_examples_list: A list of CounterfactualExamples instances :param local_importance: List of estimated local importance scores. The size of the list is the number of input instances, each containing feature importance scores for that input. :param summary_importance: Estimated global feature importance scores based on the input set of CounterfactualExamples instances """ def __init__(self, cf_examples_list, local_importance=None, summary_importance=None): self._cf_examples_list = cf_examples_list self._local_importance = local_importance self._summary_importance = summary_importance self._metadata = {'version': '1.0'} def __eq__(self, other_cf): if (isinstance(other_cf, CounterfactualExplanations)): return self.cf_examples_list == other_cf.cf_examples_list and \ self.local_importance == other_cf.local_importance and \ self.summary_importance == other_cf.summary_importance and \ self.metadata == other_cf.metadata return False @property def __dict__(self): return {'cf_examples_list': self.cf_examples_list, 'local_importance': self.local_importance, 'summary_importance': self.summary_importance, 'metadata': self.metadata} @property def cf_examples_list(self): return self._cf_examples_list @property def local_importance(self): if isinstance(self._local_importance, list): sorted_local_importance = [] for local_importance_instance in self._local_importance: local_importance_instance = \ dict(sorted(local_importance_instance.items(), key=lambda x: x[1], reverse=True)) sorted_local_importance.append(local_importance_instance) self._local_importance = sorted_local_importance return self._local_importance @property def summary_importance(self): if isinstance(self._summary_importance, dict): self._summary_importance = \ dict(sorted(self._summary_importance.items(), key=lambda x: x[1], reverse=True)) return self._summary_importance @property def metadata(self): return self._metadata def __eq__(self, other_cf): if (isinstance(other_cf, CounterfactualExplanations)): return self.cf_examples_list == other_cf.cf_examples_list and \ self.local_importance == other_cf.local_importance and \ self.summary_importance == other_cf.summary_importance and \ self.metadata == other_cf.metadata return False
[docs] def visualize_as_dataframe(self, display_sparse_df=True, show_only_changes=False): for cf_examples in self.cf_examples_list: cf_examples.visualize_as_dataframe( display_sparse_df=display_sparse_df, show_only_changes=show_only_changes)
[docs] def visualize_as_list(self, display_sparse_df=True, show_only_changes=False): for cf_examples in self.cf_examples_list: cf_examples.visualize_as_list( display_sparse_df=display_sparse_df, show_only_changes=show_only_changes)
[docs] def to_json(self): """ Serialize Explanations object to json. """ return json.dumps(self, default=json_converter, indent=2)
[docs] @staticmethod def from_json(json_str): """ Deserialize json string to a CounterfactualExplanations object. """ return json.loads(json_str, object_hook=as_counterfactual_explanations)