Repository: sktime/sktime

Issue:
[ENH] offset for `LogTransformer`
It should be possible to specify an offset and scale for `LogTransformer`.

Based on the suggestion of @ilkersigirci here:
https://github.com/alan-turing-institute/sktime/discussions/3275

My approach would be adding `offset` and a `scale` parameter (with defaults 0, 1).


Discussion:
@fkiraly I would like to work on this issue. From what I have understood till now, np.log(data) gives an error for very small values of the data. And after reading your discussion, I got clarity on why offset should be used and how to fix that in code, but the [scale] parameter is what I am not able to understand. Any input from your side would be appreciated.
> I got clarity on why offset should be used and how to fix that in code, but the [scale] parameter is what I am not able to understand. Any input from your side would be appreciated.

the ideas is as follows: the data is being transformed as `scale * (data + offset)`
Thanks, I will work on this.

Resolving patch:
diff --git a/sktime/transformations/series/boxcox.py b/sktime/transformations/series/boxcox.py
--- a/sktime/transformations/series/boxcox.py
+++ b/sktime/transformations/series/boxcox.py
@@ -211,9 +211,18 @@ def _inverse_transform(self, X, y=None):
 class LogTransformer(BaseTransformer):
     """Natural logarithm transformation.
 
-    The natural log transformation can used to make data more normally
+    The Natural logarithm transformation can be used to make the data more normally
     distributed and stabilize its variance.
 
+    Transforms each data point x to log(scale *(x+offset))
+
+    Parameters
+    ----------
+    offset : float , default = 0
+             Additive constant applied to all the data.
+    scale  : float , default = 1
+             Multiplicative scaling constant applied to all the data.
+
     See Also
     --------
     BoxCoxTransformer :
@@ -253,6 +262,11 @@ class LogTransformer(BaseTransformer):
         "capability:inverse_transform": True,
     }
 
+    def __init__(self, offset=0, scale=1):
+        self.offset = offset
+        self.scale = scale
+        super(LogTransformer, self).__init__()
+
     def _transform(self, X, y=None):
         """Transform X and return a transformed version.
 
@@ -265,13 +279,14 @@ def _transform(self, X, y=None):
         y : ignored argument for interface compatibility
             Additional data, e.g., labels for transformation
 
-
         Returns
         -------
         Xt : 2D np.ndarray
             transformed version of X
         """
-        Xt = np.log(X)
+        offset = self.offset
+        scale = self.scale
+        Xt = np.log(scale * (X + offset))
         return Xt
 
     def _inverse_transform(self, X, y=None):
@@ -286,13 +301,14 @@ def _inverse_transform(self, X, y=None):
         y : ignored argument for interface compatibility
             Additional data, e.g., labels for transformation
 
-
         Returns
         -------
         Xt : 2D np.ndarray
             inverse transformed version of X
         """
-        Xt = np.exp(X)
+        offset = self.offset
+        scale = self.scale
+        Xt = (np.exp(X) / scale) - offset
         return Xt
 
 


Test patch: