Spaces:
Runtime error
Runtime error
from abc import abstractmethod | |
from functools import wraps | |
from aif360.datasets import Dataset | |
from aif360.decorating_metaclass import ApplyDecorator | |
# TODO: Use sklearn.exceptions.NotFittedError instead? | |
class NotFittedError(ValueError, AttributeError): | |
"""Error to be raised if `predict` or `transform` is called before `fit`.""" | |
def addmetadata(func): | |
"""Decorator for instance methods which perform a transformation and return | |
a new dataset. | |
Automatically populates the `metadata` field of the new dataset to reflect | |
details of the transformation that occurred, e.g.:: | |
{ | |
'transformer': 'TransformerClass.function_name', | |
'params': kwargs_from_init, | |
'previous': [all_datasets_used_by_func] | |
} | |
""" | |
def wrapper(self, *args, **kwargs): | |
new_dataset = func(self, *args, **kwargs) | |
if isinstance(new_dataset, Dataset): | |
new_dataset.metadata = new_dataset.metadata.copy() | |
new_dataset.metadata.update({ | |
'transformer': '{}.{}'.format(type(self).__name__, func.__name__), | |
'params': self._params, | |
'previous': [a for a in args if isinstance(a, Dataset)] | |
}) | |
return new_dataset | |
return wrapper | |
BaseClass = ApplyDecorator(addmetadata) | |
class Transformer(BaseClass): | |
"""Abstract base class for transformers. | |
Transformers are an abstraction for any process which acts on a | |
:obj:`Dataset` and returns a new, modified Dataset. This definition | |
encompasses pre-processing, in-processing, and post-processing algorithms. | |
""" | |
def __init__(self, **kwargs): | |
"""Initialize a Transformer object. | |
Algorithm-specific configuration parameters should be passed here. | |
""" | |
self._params = kwargs | |
def fit(self, dataset): | |
"""Train a model on the input. | |
Args: | |
dataset (Dataset): Input dataset. | |
Returns: | |
Transformer: Returns self. | |
""" | |
return self | |
def predict(self, dataset): | |
"""Return a new dataset with labels predicted by running this | |
Transformer on the input. | |
Args: | |
dataset (Dataset): Input dataset. | |
Returns: | |
Dataset: Output dataset. `metadata` should reflect the details of | |
this transformation. | |
""" | |
raise NotImplementedError("'predict' is not supported for this class. " | |
"Perhaps you meant 'transform' or 'fit_predict' instead?") | |
def transform(self, dataset): | |
"""Return a new dataset generated by running this Transformer on the | |
input. | |
This function could return different `dataset.features`, | |
`dataset.labels`, or both. | |
Args: | |
dataset (Dataset): Input dataset. | |
Returns: | |
Dataset: Output dataset. `metadata` should reflect the details of | |
this transformation. | |
""" | |
raise NotImplementedError("'transform' is not supported for this class." | |
" Perhaps you meant 'predict' or 'fit_transform' instead?") | |
def fit_predict(self, dataset): | |
"""Train a model on the input and predict the labels. | |
Equivalent to calling `fit(dataset)` followed by `predict(dataset)`. | |
Args: | |
dataset (Dataset): Input dataset. | |
Returns: | |
Dataset: Output dataset. `metadata` should reflect the details of | |
this transformation. | |
""" | |
return self.fit(dataset).predict(dataset) | |
def fit_transform(self, dataset): | |
"""Train a model on the input and transform the dataset accordingly. | |
Equivalent to calling `fit(dataset)` followed by `transform(dataset)`. | |
Args: | |
dataset (Dataset): Input dataset. | |
Returns: | |
Dataset: Output dataset. `metadata` should reflect the details of | |
this transformation. | |
""" | |
return self.fit(dataset).transform(dataset) | |