gluonts.mx.distribution.box_cox_transform module#
- class gluonts.mx.distribution.box_cox_transform.BoxCoxTransform(lambda_1: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], lambda_2: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], tol_lambda_1: float = 0.01, F=None)[source]#
Bases:
gluonts.mx.distribution.bijection.Bijection
Implements Box-Cox transformation of a uni-variate random variable.
The Box-Cox transformation of an observation \(z\) is given by:
\[\begin{split}BoxCox(z; \lambda_1, \lambda_2) = \begin{cases} ((z + \lambda_2)^{\lambda_1} - 1) / \lambda_1, \quad & \text{if } \lambda_1 \neq 0, \\ \log (z + \lambda_2), \quad & \text{otherwise.} \end{cases}\end{split}\]Here, \(\lambda_1\) and \(\lambda_2\) are learnable parameters. Note that the domain of the transformation is not restricted.
For numerical stability, instead of checking \(\lambda_1\) is exactly zero, we use the condition
\[|\lambda_1| < tol\_lambda\_1\]for a pre-specified tolerance tol_lambda_1.
Inverse of the Box-Cox Transform is given by
\[\begin{split}BoxCox^{-1}(y; \lambda_1, \lambda_2) = \begin{cases} (y \lambda_1 + 1)^{(1/\lambda_1)} - \lambda_2, \quad & \text{if } \lambda_1 \neq 0, \\ \exp (y) - \lambda_2, \quad & \text{otherwise.} \end{cases}\end{split}\]Notes on numerical stability:
1. For the forward transformation, \(\lambda_2\) must always be chosen such that
\[z + \lambda_2 > 0.\]To achieve this one needs to know a priori the lower bound on the observations. This is set in BoxCoxTransformOutput, since \(\lambda_2\) is learnable.
2. Similarly for the inverse transformation to work reliably, a sufficient condition is
\[y \lambda_1 + 1 \geq 0,\]where \(y\) is the input to the inverse transformation.
This cannot always be guaranteed especially when \(y\) is a sample from a transformed distribution. Hence we always truncate \(y \lambda_1 + 1\) at zero.
An example showing why this could happen in our case: consider transforming observations from the unit interval (0, 1) with parameters
\[\begin{split}\begin{align} \lambda_1 = &\ 1.1, \\ \lambda_2 = &\ 0. \end{align}\end{split}\]Then the range of the transformation is (-0.9090, 0.0). If Gaussian is fit to the transformed observations and a sample is drawn from it, then it is likely that the sample is outside this range, e.g., when the mean is close to -0.9. The subsequent inverse transformation of the sample is not a real number anymore.
>>> y = -0.91 >>> lambda_1 = 1.1 >>> lambda_2 = 0.0 >>> (y * lambda_1 + 1) ** (1 / lambda_1) + lambda_2 (-0.0017979146510711471+0.0005279153735965289j)
- Parameters
lambda_1 –
lambda_2 –
tol_lambda_1 – For numerical stability, treat lambda_1 as zero if it is less than tol_lambda_1
F –
- arg_names = ['box_cox.lambda_1', 'box_cox.lambda_2']#
- property args: List#
current values of the parameters
- Type
List
- property event_dim: int#
- f(z: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol] [source]#
Forward transformation of observations z
- Parameters
z – observations
- Returns
Transformed observations
- Return type
Tensor
- f_inv(y: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol] [source]#
Inverse of the Box-Cox Transform.
- Parameters
y – Transformed observations
- Returns
Observations
- Return type
Tensor
- log_abs_det_jac(z: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], y: Optional[Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]] = None) Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol] [source]#
Logarithm of the absolute value of the Jacobian determinant corresponding to the Box-Cox Transform is given by.
\[\begin{split}\log \frac{d}{dz} BoxCox(z; \lambda_1, \lambda_2) = \begin{cases} \log (z + \lambda_2) (\lambda_1 - 1), \quad & \text{if } \lambda_1 \neq 0, \\ -\log (z + \lambda_2), \quad & \text{otherwise.} \end{cases}\end{split}\]Note that the derivative of the transformation is always non-negative.
- Parameters
z – observations
y – not used
- Return type
Tensor
- property sign: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]#
Return the sign of the Jacobian’s determinant.
- class gluonts.mx.distribution.box_cox_transform.BoxCoxTransformOutput(lb_obs: float = 0.0, fix_lambda_2: bool = True)[source]#
Bases:
gluonts.mx.distribution.bijection_output.BijectionOutput
- args_dim: Dict[str, int] = {'box_cox.lambda_1': 1, 'box_cox.lambda_2': 1}#
- bij_cls#
alias of
gluonts.mx.distribution.box_cox_transform.BoxCoxTransform
- domain_map(F, *args: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol]) Tuple[Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], ...] [source]#
- property event_shape: Tuple#
- class gluonts.mx.distribution.box_cox_transform.InverseBoxCoxTransform(lambda_1: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], lambda_2: Union[mxnet.ndarray.ndarray.NDArray, mxnet.symbol.symbol.Symbol], tol_lambda_1: float = 0.01, F=None)[source]#
Bases:
gluonts.mx.distribution.bijection.InverseBijection
Implements the inverse of Box-Cox transformation as a bijection.
- arg_names = ['box_cox.lambda_1', 'box_cox.lambda_2']#
- property event_dim: int#
- class gluonts.mx.distribution.box_cox_transform.InverseBoxCoxTransformOutput(lb_obs: float = 0.0, fix_lambda_2: bool = True)[source]#
Bases:
gluonts.mx.distribution.box_cox_transform.BoxCoxTransformOutput
- args_dim: Dict[str, int] = {'box_cox.lambda_1': 1, 'box_cox.lambda_2': 1}#
- bij_cls#
alias of
gluonts.mx.distribution.box_cox_transform.InverseBoxCoxTransform
- property event_shape: Tuple#