def __init__( self, values, base_values = None, data = None, display_data = None, instance_names = None, feature_names = None, output_names = None, output_indexes = None, lower_bounds = None, upper_bounds = None, main_effects = None, hierarchical_values = None, clustering = None ): self.op_history = [] # cloning. TODO: better cloning :) if issubclass(type(values), Explanation): e = values values = e.values base_values = e.base_values data = e.data output_dims = compute_output_dims(values, base_values, data) if len(_compute_shape(feature_names)) == 1: # TODO: should always be an alias once slicer supports per-row aliases values_shape = _compute_shape(values) if len(values_shape) >= 1 and len(feature_names) == values_shape[0]: feature_names = Alias(list(feature_names), 0) elif len(values_shape) >= 2 and len(feature_names) == values_shape[1]: feature_names = Alias(list(feature_names), 1) if len(_compute_shape(output_names)) == 1: # TODO: should always be an alias once slicer supports per-row aliases values_shape = _compute_shape(values) if len(values_shape) >= 1 and len(output_names) == values_shape[0]: output_names = Alias(list(output_names), 0) elif len(values_shape) >= 2 and len(output_names) == values_shape[1]: output_names = Alias(list(output_names), 1) self._s = Slicer( values = values, base_values = None if base_values is None else Obj(base_values, [0] + list(output_dims)), data = data, display_data = display_data, instance_names = None if instance_names is None else Alias(instance_names, 0), feature_names = feature_names, output_names = output_names, # None if output_names is None else Alias(output_names, output_dims), output_indexes = None if output_indexes is None else (output_dims, output_indexes), lower_bounds = lower_bounds, upper_bounds = lower_bounds, main_effects = main_effects, hierarchical_values = hierarchical_values, clustering = None if clustering is None else Obj(clustering, [0]) )
def object_hook(self, obj): if "_type" not in obj: return obj _type = obj["_type"] if _type == "array": return np.array(obj["value"]) elif _type == "explanation": cls = getattr(import_module(obj["module"]), obj["class"]) return cls.from_components(obj["components"]) elif _type == "component": cls = getattr(import_module(obj["module"]), obj["class"]) return cls.from_fields(obj["fields"]) elif _type == "obj": return Obj(obj["value"], obj["dim"]) elif _type == "alias": return Alias(obj["value"], obj["dim"]) elif _type == "dim": return Dim(obj["dim"]) return obj
def __init__( self, values, base_values=None, data=None, display_data=None, instance_names=None, feature_names=None, output_names=None, output_indexes=None, lower_bounds=None, upper_bounds=None, main_effects=None, hierarchical_values=None, clustering=None, interactions=None, feature_groups=None, ): self.op_history = [] # cloning. TODO: better cloning :) if issubclass(type(values), Explanation): e = values values = e.values base_values = e.base_values data = e.data output_dims = compute_output_dims(values, base_values, data) if len( _compute_shape(feature_names) ) == 1: # TODO: should always be an alias once slicer supports per-row aliases values_shape = _compute_shape(values) if len(values_shape) >= 1 and len( feature_names) == values_shape[0]: feature_names = Alias(list(feature_names), 0) elif len(values_shape) >= 2 and len( feature_names) == values_shape[1]: feature_names = Alias(list(feature_names), 1) if len( _compute_shape(output_names) ) == 1: # TODO: should always be an alias once slicer supports per-row aliases values_shape = _compute_shape(values) output_names = Alias(list(output_names), output_dims[0]) # if len(values_shape) >= 1 and len(output_names) == values_shape[0]: # output_names = Alias(list(output_names), 0) # elif len(values_shape) >= 2 and len(output_names) == values_shape[1]: # output_names = Alias(list(output_names), 1) if output_names is not None and not isinstance(output_names, Alias): l = len(_compute_shape(output_names)) if l == 0: pass elif l == 1: output_names = Obj(output_names, output_dims) elif l == 2: output_names = Obj(output_names, [0] + list(output_dims)) else: raise ValueError( "shap.Explanation does not yet support output_names of order greater than 3!" ) self._s = Slicer( values=values, base_values=None if base_values is None else Obj( base_values, [0] + list(output_dims)), data=data, display_data=display_data, instance_names=None if instance_names is None else Alias( instance_names, 0), feature_names=feature_names, output_names=output_names, output_indexes=None if output_indexes is None else (output_dims, output_indexes), lower_bounds=lower_bounds, upper_bounds=upper_bounds, main_effects=main_effects, hierarchical_values=hierarchical_values, clustering=None if clustering is None else Obj(clustering, [0]), interactions=interactions, feature_groups=feature_groups)
def __init__( # pylint: disable=too-many-arguments self, values, base_values=None, data=None, display_data=None, instance_names=None, feature_names=None, output_names=None, output_indexes=None, lower_bounds=None, upper_bounds=None, error_std=None, main_effects=None, hierarchical_values=None, clustering=None, compute_time=None): self.op_history = [] self.compute_time = compute_time # cloning. TODOsomeday: better cloning :) if issubclass(type(values), Explanation): e = values values = e.values base_values = e.base_values data = e.data self.output_dims = compute_output_dims(values, base_values, data, output_names) values_shape = _compute_shape(values) if output_names is None and len(self.output_dims) == 1: output_names = [ f"Output {i}" for i in range(values_shape[self.output_dims[0]]) ] if len( _compute_shape(feature_names) ) == 1: # TODOsomeday: should always be an alias once slicer supports per-row aliases if len(values_shape) >= 1 and len( feature_names) == values_shape[0]: feature_names = Alias(list(feature_names), 0) elif len(values_shape) >= 2 and len( feature_names) == values_shape[1]: feature_names = Alias(list(feature_names), 1) if len( _compute_shape(output_names) ) == 1: # TODOsomeday: should always be an alias once slicer supports per-row aliases output_names = Alias(list(output_names), self.output_dims[0]) # if len(values_shape) >= 1 and len(output_names) == values_shape[0]: # output_names = Alias(list(output_names), 0) # elif len(values_shape) >= 2 and len(output_names) == values_shape[1]: # output_names = Alias(list(output_names), 1) if output_names is not None and not isinstance(output_names, Alias): l = len(_compute_shape(output_names)) if l == 0: pass elif l == 1: output_names = Obj(output_names, self.output_dims) elif l == 2: output_names = Obj(output_names, [0] + list(self.output_dims)) else: raise ValueError( "shap.Explanation does not yet support output_names of order greater than 3!" ) if not hasattr(base_values, "__len__") or len(base_values) == 0: pass elif len(_compute_shape(base_values)) == len(self.output_dims): base_values = Obj(base_values, list(self.output_dims)) else: base_values = Obj(base_values, [0] + list(self.output_dims)) self._s = Slicer( values=values, base_values=base_values, data=list_wrap(data), display_data=list_wrap(display_data), instance_names=None if instance_names is None else Alias( instance_names, 0), feature_names=feature_names, output_names=output_names, output_indexes=None if output_indexes is None else (self.output_dims, output_indexes), lower_bounds=list_wrap(lower_bounds), upper_bounds=list_wrap(upper_bounds), error_std=list_wrap(error_std), main_effects=list_wrap(main_effects), hierarchical_values=list_wrap(hierarchical_values), clustering=None if clustering is None else Obj(clustering, [0]))