Source code for utils.wrappers.base
import abc
import typing
import numpy as np
[docs]class Wrapper(metaclass=abc.ABCMeta):
"""Base Wrapper
Warning: This class should not be used directly.
Use derived classes instead.
Attributes:
default_label (str): Default dict key for single value model outputs.
"""
def __init__(self, prediction_function, feature_names):
self._feature_names: list = feature_names
self._prediction_function = prediction_function
self.default_label = 'output'
[docs] @abc.abstractmethod
def __call__(self, x: typing.Union[typing.List[dict], dict]) -> typing.Union[dict, typing.List[dict]]:
raise NotImplementedError
# {features: values} -> [[values]]
[docs] def convert_1d_input_to_arr(self, x_dict: dict) -> np.ndarray:
"""Transforms a 1d input (a single dict) into an array of shape (1, N_Features).
Note:
If the `feature_names` parameter is not None in the initialization of the Wrapper. The transformed output
array is resorted in this order and to only contain the specified features.
Args:
x_dict (dict): Input dictionary of type `{feature_name: feature_value}`.
Returns:
(np.ndarray): The transformed input array of shape (1, N_Features).
Examples:
Basic usage:
>>> x_input = {'feature_1': 'value_1', 'feature_2': 2}
>>> x_array = Wrapper.convert_1d_input_to_arr(x_input)
>>> print(x_array, x_array.shape)
>>> [['value_1', 2]], (1, 2)
"""
if self._feature_names is not None:
x_dict = {feature: x_dict[feature] for feature in self._feature_names}
return np.asarray(list(x_dict.values())).reshape(1, -1)
# [{features: values_1}, {features: values_2}] -> [[values], [values_2]]
[docs] def convert_2d_input_to_arr(self, x_dicts: typing.Sequence[dict]) -> np.ndarray:
"""Transforms a 2d input (a list of dicts) into an array of shape (N_Instances, N_Features).
Note:
If the `feature_names` parameter is not None in the initialization of the Wrapper. The transformed output
array is resorted in this order and to only contain the specified features.
Args:
x_dicts (list[dict]): List of input dictionaries of type `{feature_name: feature_value}`.
Returns:
(np.ndarray): The transformed input array of shape (N_Instances, N_Features).
Examples:
Basic usage:
>>> x_inputs = [{'feature_1': 'value_1', 'feature_2': 2}, {'feature_1': 'value_1', 'feature_2': 3}]
>>> x_array = Wrapper.convert_1d_input_to_arr(x_inputs)
>>> print(x_array, x_array.shape)
>>> [['value_1', 2], ['value_1', 3]], (2, 2)
"""
x_input = []
for i in range(len(x_dicts)):
if self._feature_names is not None:
x_input_i = [x_dicts[i][feature] for feature in self._feature_names]
else:
x_input_i = list(x_dicts[i].values())
x_input.append(x_input_i)
return np.asarray(x_input)
# [[output]] or [output] -> {'output': output}, [[output_1, output_2]] -> {0: output_1, 1: output_2}
[docs] def convert_arr_output_to_dict(self, y_prediction: np.ndarray) -> dict:
"""Transforms a prediction output into a dict of outputs.
Note:
If the `feature_names` parameter is not None in the initialization of the Wrapper. The transformed output
array is resorted in this order and to only contain the specified features.
Args:
y_prediction (np.ndarray): Output array from model, of shape (1, N_Outputs) or (N_Outputs)
Returns:
(dict): The transformed output dictionary. If the output dimension of the model is 1 (e.g. regression,
classification labels) the output dict contains one element mapping from 'output' key to the model
output (e.g. original output was `[[1]]` or `[1]` then `{'output': 1}` is the transformed output).
Examples:
Onedimensional Model Output (Labels):
>>> model_output = np.asarray([1])
>>> Wrapper.convert_arr_output_to_dict(model_output)
>>> {'output': 1}
>>> model_output = np.asarray([[1]])
>>> Wrapper.convert_arr_output_to_dict(model_output)
>>> {'output': 1}
Multidimnesnional Model Output (Probas):
>>> model_output = np.asarray([[0.05, 0.5, 0.45]])
>>> Wrapper.convert_arr_output_to_dict(model_output)
>>> {0: 0.05, 1: 0.5, 2: 0.45}
Raises:
ValueError: If the model outputs are strings.
"""
try:
return {self.default_label: float(y_prediction)}
except TypeError: # y_prediction is not a size-1 array or real_valued number
y_prediction = y_prediction.flatten()
y_prediction = {i: y_prediction[i] for i in range(y_prediction.shape[0])}
except ValueError as e: # y_prediction is probably a size-1 array containing a string
raise ValueError(f"Prediction is probably a string: {y_prediction}. Only numeric values allowed. "
f"Exception is raised: {e}.")
return y_prediction