MODULE REFERENCE
invertible_data_transformer
anomx.data.processing.transformers.invertible_data_transformerInvertible Data Transformer Base Class
InvertibleDataTransformer
InvertibleDataTransformer(name: str = 'InvertibleDataTransformer', n_jobs: int = 1, verbose: bool = False, parallel_params: bool | Sequence[str] = False, mask_components: bool = True, columns: str | list[str] | None = None, uses_insample: bool = False)Bases: BaseDataTransformer
| Parameter | Type | Default |
|---|---|---|
name | str | 'InvertibleDataTransformer' |
n_jobs | int | 1 |
verbose | bool | False |
parallel_params | bool | Sequence[str] | False |
mask_components | bool | True |
columns | str | list[str] | None | None |
uses_insample | bool | False |
Abstract class for invertible transformers.
All the deriving classes have to implement the static methods ts_transform() and ts_inverse_transform(). For information on how to implement the ts_transform method, please refer to the anomx.data.processing.transformers.BaseDataTransformer documentation.
The ts_inverse_transform() method should be implemented in a virtually identical way to the ts_transform() method: it should accept a TimeSeries as a first argument, and a dictionary of fixed parameters (as well as fitted parameters if the transformation also inherits from FittableDataTransformer) as a second argument. Additionally, ts_inverse_transform() should also accept *args and **kwargs if additional positional/keyword arguments are expected to be passed. The only difference between ts_inverse_transform() and ts_transform() is that the former should 'undo' the transformation made to a TimeSeries by the latter. Please refer to the ts_inverse_transform() documentation for further information.
This class takes care of parallelizing the transformation on multiple TimeSeries when possible.
Parameters
- name
The data transformer's name
- n_jobs
The number of jobs to run in parallel. Parallel jobs are created only when a Sequence[TimeSeries] is passed as input to a method, parallelising operations regarding different TimeSeries. Defaults to
1(sequential). Setting the parameter to-1means using all the available processors. Note: for a small amount of data, the parallelisation overhead could end up increasing the total required amount of time.- verbose
Optionally, whether to print operations progress
- parallel_params
Optionally, specifies which fixed parameters (i.e. the attributes initialized in the child-most class's
__init__) take on different values for different parallel jobs. Fixed parameters specified byparallel_paramsare assumed to be aSequenceof values that should be used for that parameter in each parallel job; the length of thisSequenceshould equal the number of parallel jobs. Ifparallel_params=True, every fixed parameter will take on a different value for each parallel job. Ifparallel_params=False, every fixed parameter will take on the same value for each parallel job. Ifparallel_paramsis aSequenceof fixed attribute names, only those attribute names specified will take on different values between different parallel jobs.- mask_components
Optionally, whether to automatically apply any provided
component_masks to theTimeSeriesinputs passed totransform,fit,inverse_transform, orfit_transform. IfTrue, any specifiedcomponent_maskwill be applied to each input timeseries before passing them to the called method; the masked components will also be automatically 'unmasked' in the returnedTimeSeries. IfFalse, thencomponent_mask(if provided) will be passed as a keyword argument, but won't automatically be applied to the input timeseries. Seeapply_component_maskmethod ofBaseDataTransformerfor further details.- columns
Optionally, a string or list of strings specifying the names of the components (columns) to transform. If specified, only these components will be transformed, and the remaining components will be kept untouched. For more information refer to the
BaseDataTransformerdocumentation. In case the transformer is applied on multiple TimeSeries, it is expected that all series have the same column order.- uses_insample
Whether the transformer requires the in-sample (historic) series during inverse transformation. If
True,inverse_transformwill use theinsampleargument to pass the transformed historic series tots_inverse_transform. This is needed when inverse transforming a partial series (e.g. a forecast) requires information from earlier times (e.g. foranomx.data.processing.transformers.diff.Diff).
Notes
Note: the ts_transform() and ts_inverse_transform() methods are designed to be static methods instead of instance methods to allow an efficient parallelisation also when the scaler instance is storing a non-negligible amount of data. Using instance methods would imply copying the instance's data through multiple processes, which can easily introduce a bottleneck and nullify parallelisation benefits.
Example
>>> from anomx.data.processing.transformers import InvertibleDataTransformer
>>> from anomx._series_utils.timeseries_generation import linear_timeseries
>>>
>>> class SimpleTransform(InvertibleDataTransformer):
>>>
>>> def __init__(self, a):
>>> self._a = a
>>> super().__init__()
>>>
>>> @staticmethod
>>> def ts_transform(series, params, **kwargs):
>>> a = params['fixed']['_a']
>>> b = kwargs.pop('b')
>>> return a*series + b
>>>
>>> @staticmethod
>>> def ts_inverse_transform(series, params, **kwargs):
>>> a = params['fixed']['_a']
>>> b = kwargs.pop('b')
>>> return (series - b) / a
>>>
>>> series = linear_timeseries(length=5)
>>> print(series.values())
[[0. ]
[0.25]
[0.5 ]
[0.75]
[1. ]]
>>> transform = SimpleTransform(a=2)
>>> series = transform.transform(series, b=3)
>>> print(series.values())
[[3. ]
[3.5]
[4. ]
[4.5]
[5. ]]
>>> series = transform.inverse_transform(series, b=3)
>>> print(series.values())
[[0. ]
[0.25]
[0.5 ]
[0.75]
[1. ]]Members
ts_inverse_transformstaticmethod
ts_inverse_transform(series: TimeSeries, params: Mapping[str, Any], insample: TimeSeries | None = None) -> TimeSeriesThe function that will be applied to each series when inverse_transform is called.
The function must take as first argument a TimeSeries object and, as a second argument, a dictionary containing the fixed and/or fitted parameters of the transformation; this function should then return an inverse transformed TimeSeries object (i.e. ts_inverse_transform should 'undo' the transformation performed by ts_transform).
The params dictionary *can* contain up to two keys:
params['fixed']stores the fixed parameters of the transformation (i.e. attributed defined in the__init__method of the child-most class *before*super().__init__is called);params['fixed']is a dictionary itself, whose keys are the names of the fixed parameter attributes. For example, if_my_fixed_paramis defined as an attribute in the child-most class, then this fixed parameter value can be accessed throughparams['fixed']['_my_fixed_param'].- If the transform inherits from the
anomx.data.processing.transformers.FittableDataTransformerclass, thenparams['fitted']will store the fitted parameters of the transformation; the fitted parameters are simply the output(s) returned by thets_fitfunction, whatever those output(s) may be. Seeanomx.data.processing.transformers.FittableDataTransformerfor further details about fitted parameters.
Any positional/keyword argument supplied to the transform method are passed as positional/keyword arguments to ts_inverse_transform; hence, ts_inverse_transform should also accept *args and/or **kwargs if positional/keyword arguments are passed to transform. Note that if the mask_components attribute of InvertibleDataTransformer is set to False, then the component_mask provided to transform will be passed as an additional keyword argument to ts_inverse_transform.
The BaseDataTransformer class, from which InvertibleDataTransformer inherits, includes some helper methods which may prove useful when implementing a ts_inverse_transform function:
- The
apply_component_maskandunapply_component_maskmethods, which apply and 'unapply'component_masks to aTimeSeriesrespectively; these methods are automatically called intransformif themask_componentattribute ofInvertibleDataTransformeris set toTrue, but you may want to manually call them if you setmask_componentstoFalseand wish to manually specify howcomponent_masks are applied to aTimeSeries. - The
stack_samplesmethod, which stacks all the samples in aTimeSeriesalong the component axis, so that theTimeSeriesgoes from shape(n_timesteps, n_components, n_samples)to shape(n_timesteps, n_components * n_samples). This stacking is useful if a pointwise inverse transform is being implemented (i.e. transforming the value at timetdepends only on the value of the series at that timet). Once transformed, the stackedTimeSeriescan be 'unstacked' using theunstack_samplesmethod.
This method is not implemented in the base class and must be implemented in the deriving classes.
Parameters
- series
series to be transformed.
- params
Dictionary containing the parameters of the transformation function. Fixed parameters (i.e. attributes defined in the child-most class of the transformation prior to calling
super.__init__()) are stored under the'fixed'key. If the transformation inherits from theFittableDataTransformerclass, then the fitted parameters of the transformation (i.e. the values returned byts_fit) are stored under the'fitted'key.- insample
Optionally, the transformed historic (insample) part of
series. This can be used whenseriesis only a tail (for example a forecast) and inverse transforming requires information from earlier times (for example theanomx.data.processing.transformers.diff.Difftransformer). Only used by transformers that require information from earlier times.- args
Any additional keyword arguments provided to
inverse_transform.- kwargs
Any additional keyword arguments provided to
inverse_transform. Note that if themask_componentattribute ofInvertibleDataTransformeris set toFalse, thencomponent_maskwill be passed as a keyword argument.
Notes
This method is designed to be a static method instead of instance methods to allow an efficient parallelisation also when the scaler instance is storing a non-negligible amount of data. Using instance methods would imply copying the instance's data through multiple processes, which can easily introduce a bottleneck and nullify parallelisation benefits.
| Parameter | Type | Default |
|---|---|---|
series | TimeSeries | required |
params | Mapping[str, Any] | required |
insample | TimeSeries | None | None |
Returns TimeSeries
inverse_transformmethod
inverse_transform(series: TimeSeriesLike | Sequence[Sequence[TimeSeries]], *args, component_mask: np.ndarray | None = None, series_idx: int | Sequence[int] | None = None, insample: TimeSeriesLike | None = None, **kwargs) -> TimeSeriesLike | Sequence[Sequence[TimeSeries]]Inverse transforms a (sequence of) series by calling the user-implemented ts_inverse_transform method.
In case a sequence or list of lists is passed as input data, this function takes care of parallelising the transformation of multiple series in the sequence at the same time. Additionally, if the mask_components attribute was set to True when instantiating InvertibleDataTransformer, then any provided component_masks will be automatically applied to each input TimeSeries; please refer to 'Notes' for further details on component masking.
Any additionally specified *args and **kwargs are automatically passed to ts_inverse_transform.
Parameters
- series
The series to inverse-transform. If a single
TimeSeries, returns a single series. If a sequence ofTimeSeries, returns a list of series. The series should be in the same order as the sequence used to fit the transformer. If a list of lists ofTimeSeries, returns a list of lists of series. This can for example be the output ofForecastingModel.historical_forecasts()when using multiple series. Each inner list should containTimeSeriesrelated to the same series. The order of inner lists should be the same as the sequence used to fit the transformer.- args
Additional positional arguments for the
ts_inverse_transform()method- component_mask
Optionally, a 1-D boolean np.ndarray of length
series.n_componentsthat specifies which components of the underlyingseriesthe inverse transform should consider.- series_idx
Optionally, the index(es) of each series corresponding to their positions within the series used to fit the transformer (to retrieve the appropriate transformer parameters).
- insample
Optionally, the transformed historic (insample) part of
series. This can be used whenseriesis only a tail (for example a forecast) and inverse transforming requires information from earlier times (for example theanomx.data.processing.transformers.diff.Difftransformer). Eachinsampleseries must start before theseriesstart time and extend at least until one step before the start time of theseries. Ifseriesis aSequence[Sequence[TimeSeries]], theninsampleshould be aSequence[TimeSeries]with the same length. Otherwise, it should have the same type asseries. Only used by transformers that require information from earlier times.- kwargs
Additional keyword arguments for the
ts_inverse_transform()method
Returns
- TimeSeries | List[TimeSeries] | List[List[TimeSeries]]
Inverse transformed data.
Notes
If the mask_components attribute was set to True when instantiating InvertibleDataTransformer, then any provided component_masks will be automatically applied to each TimeSeries input to transform; component_masks are simply boolean arrays of shape (series.n_components,) that specify which components of each series should be transformed using ts_inverse_transform and which components should not. If component_mask[i] is True, then the ith component of each series will be transformed by ts_inverse_transform. Conversely, if component_mask[i] is False, the ith component will be removed from each series before being passed to ts_inverse_transform; after transforming this masked series, the untransformed ith component will be 'added back' to the output. Note that automatic component_masking can only be performed if the ts_inverse_transform does *not* change the number of timesteps in each series; if this were to happen, then the transformed and untransformed components are unable to be concatenated back together along the component axis.
If mask_components was set to False when instantiating InvertibleDataTransformer, then any provided component_masks will be passed as a keyword argument ts_inverse_transform; the user can then manually specify how the component_mask should be applied to each series.
| Parameter | Type | Default |
|---|---|---|
series | TimeSeriesLike | Sequence[Sequence[TimeSeries]] | required |
*args | — | — |
component_maskkeyword only | np.ndarray | None | None |
series_idxkeyword only | int | Sequence[int] | None | None |
insamplekeyword only | TimeSeriesLike | None | None |
**kwargs | — | — |
Returns TimeSeriesLike | Sequence[Sequence[TimeSeries]]