Repository: sktime/sktime

Issue:
Implement series-to-series transformers
**Describe the solution you'd like**
Here's a simple example of a series-to-series log transformer transformer:

All of these transforms are series-to-series transforms. For an overview of different kinds of transformations, see this [document](https://github.com/sktime/enhancement-proposals/blob/master/steps/03_transformer_api/transform_types.ipynb).

```python
import numpy as np
import pandas as pd

from sktime.transformers.base import _SeriesToSeriesTransformer
from sktime.utils.validation.series import 

class LogTransformer(_SeriesToSeriesTransformer):

    _tags = {"transform-returns-same-time-index": True}

    def transform(self, Z, X=None):
        self.check_is_fitted()
        Z = check_series(Z)
        return np.log(Z)

    def inverse_transform(self, Z, X=None):
        self.check_is_fitted()
        Z = check_series(Z)
        return np.exp(Z)
```

**List of transformations we'd like to include in sktime**
| Transform  | Package/Function |
| ------------- | ------------- |
| FFT/DFT  | https://docs.scipy.org/doc/numpy-1.15.0/reference/routines.fft.html  |
| Autocorrelation function (ACF)  | https://www.statsmodels.org/0.9.0/generated/statsmodels.tsa.stattools.acf.html  |
| Partial autocorrelation function (autoregressive coefficients) (PACF) | https://www.statsmodels.org/0.9.0/generated/statsmodels.tsa.stattools.pacf.html  |
| Auto Regressive Moving Average (ARMA)  | https://www.statsmodels.org/0.9.0/generated/statsmodels.tsa.arima_model.ARMA.html  |
| Power Spectrum  | https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.periodogram.html  |
| Cepstrum  | https://github.com/python-acoustics/python-acoustics/blob/master/acoustics/cepstrum.py  |
| Cosine  | https://docs.scipy.org/doc/numpy/reference/generated/numpy.cos.html  |

**Related issues**
see #6, #224 and #297


Discussion:
Hi @Afzal-Ind, could you tell me which part isn't clear? You can message me here or on Gitter. 
> Could you tell me which part isn't clear?

Thanks. I am not clear about series-to-series log transformer is how it works basically. 

@Afzal-Ind There is an example in the linked [document](https://github.com/sktime/enhancement-proposals/blob/master/steps/03_transformer_api/transform_types.ipynb). Does that make it clearer?
> Does that make it clearer?

Thanks again. It may take some time but I will keep up with this.

Resolving patch:
diff --git a/sktime/transformations/series/acf.py b/sktime/transformations/series/acf.py
new file mode 100644
--- /dev/null
+++ b/sktime/transformations/series/acf.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python3 -u
+# -*- coding: utf-8 -*-
+
+__author__ = ["Afzal Ansari"]
+__all__ = ["AutoCorrelationTransformer", "PartialAutoCorrelationTransformer"]
+
+import pandas as pd
+from statsmodels.tsa.stattools import acf
+from statsmodels.tsa.stattools import pacf
+
+from sktime.transformations.base import _SeriesToSeriesTransformer
+from sktime.utils.validation.series import check_series
+
+
+class AutoCorrelationTransformer(_SeriesToSeriesTransformer):
+    """
+    Auto-correlation transformer.
+    """
+
+    _tags = {"univariate-only": True, "fit-in-transform": True}
+
+    def __init__(
+        self,
+        adjusted=False,
+        n_lags=None,
+        qstat=False,
+        fft=False,
+        missing="none",
+    ):
+        self.adjusted = adjusted
+        self.n_lags = n_lags
+        self.qstat = qstat
+        self.fft = fft
+        self.missing = missing
+        super(AutoCorrelationTransformer, self).__init__()
+
+    def transform(self, Z, X=None):
+        self.check_is_fitted()
+        z = check_series(Z, enforce_univariate=True)
+
+        # Passing an alpha values other than None would return confidence intervals
+        # and break the signature of the series-to-series transformer
+        zt = acf(
+            z,
+            adjusted=self.adjusted,
+            nlags=self.n_lags,
+            qstat=self.qstat,
+            fft=self.fft,
+            alpha=None,
+            missing=self.missing,
+        )
+        return pd.Series(zt)
+
+
+class PartialAutoCorrelationTransformer(_SeriesToSeriesTransformer):
+    """
+    Partial auto-correlation transformer.
+
+    Parameters
+    ----------
+    n_lags : int
+         largest lag for which pacf is returned
+    method : str {'ywunbiased', 'ywmle', 'ols'}
+         specifies which method for the calculations to use:
+        - yw or ywunbiased : yule walker with bias correction in denominator
+          for acovf. Default.
+        - ywm or ywmle : yule walker without bias correction
+        - ols - regression of time series on lags of it and on constant
+        - ld or ldunbiased : Levinson-Durbin recursion with bias correction
+        - ldb or ldbiased : Levinson-Durbin recursion without bias correction
+    """
+
+    _tags = {"univariate-only": True, "fit-in-transform": True}
+
+    def __init__(
+        self,
+        n_lags=None,
+        method="ywunbiased",
+    ):
+        self.n_lags = n_lags
+        self.method = method
+        super(PartialAutoCorrelationTransformer, self).__init__()
+
+    def transform(self, Z, X=None):
+        """
+        pacf : 1d array
+            partial autocorrelations, nlags elements, including lag zero
+        confint : array, optional
+            Confidence intervals for the PACF. Returned if confint is not None.
+        """
+        self.check_is_fitted()
+        z = check_series(Z, enforce_univariate=True)
+
+        # Passing an alpha values other than None would return confidence intervals
+        # and break the signature of the series-to-series transformer
+        zt = pacf(z, nlags=self.n_lags, method=self.method, alpha=None)
+        return pd.Series(zt)
diff --git a/sktime/transformations/series/cos.py b/sktime/transformations/series/cos.py
new file mode 100644
--- /dev/null
+++ b/sktime/transformations/series/cos.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+import numpy as np
+
+from sktime.transformations.base import _SeriesToSeriesTransformer
+from sktime.utils.validation.series import check_series
+
+__author__ = ["Afzal Ansari"]
+__all__ = ["CosineTransformer"]
+
+
+class CosineTransformer(_SeriesToSeriesTransformer):
+    _tags = {"transform-returns-same-time-index": True, "fit-in-transform": True}
+
+    def transform(self, Z, X=None):
+        self.check_is_fitted()
+        Z = check_series(Z)
+        return np.cos(Z)
+
+    # def inverse_transform(self, Z, X=None):
+    # only defined for inputs in (-1, 1) range, requires adding extra input check
+    # self.check_is_fitted()
+    # Z = check_series(Z)
+    # return np.arccos(Z)


Test patch:
diff --git a/sktime/tests/_config.py b/sktime/tests/_config.py
--- a/sktime/tests/_config.py
+++ b/sktime/tests/_config.py
@@ -31,13 +31,13 @@
 from sktime.forecasting.compose import StackingForecaster
 from sktime.forecasting.compose import TransformedTargetForecaster
 from sktime.forecasting.exp_smoothing import ExponentialSmoothing
+from sktime.forecasting.hcrystalball import HCrystalBallForecaster
 from sktime.forecasting.model_selection import ForecastingGridSearchCV
 from sktime.forecasting.model_selection import SingleWindowSplitter
 from sktime.forecasting.naive import NaiveForecaster
 from sktime.forecasting.online_learning import OnlineEnsembleForecaster
 from sktime.forecasting.tbats import TBATS
 from sktime.forecasting.theta import ThetaForecaster
-from sktime.forecasting.hcrystalball import HCrystalBallForecaster
 from sktime.performance_metrics.forecasting import sMAPE
 from sktime.regression.base import BaseRegressor
 from sktime.regression.compose import TimeSeriesForestRegressor
@@ -62,6 +62,8 @@
 from sktime.transformations.panel.tsfresh import (
     TSFreshRelevantFeatureExtractor,
 )
+from sktime.transformations.series.acf import AutoCorrelationTransformer
+from sktime.transformations.series.acf import PartialAutoCorrelationTransformer
 from sktime.transformations.series.adapt import TabularToSeriesAdaptor
 from sktime.transformations.series.detrend import Detrender
 
@@ -202,6 +204,8 @@
         "use_arma_errors": False,
         "n_jobs": 1,
     },
+    PartialAutoCorrelationTransformer: {"n_lags": 1},
+    AutoCorrelationTransformer: {"n_lags": 1},
 }
 
 # These methods should not change the state of the estimator, that is, they should
diff --git a/sktime/utils/_testing/estimator_checks.py b/sktime/utils/_testing/estimator_checks.py
--- a/sktime/utils/_testing/estimator_checks.py
+++ b/sktime/utils/_testing/estimator_checks.py
@@ -23,7 +23,7 @@
     check_get_params_invariance as _check_get_params_invariance,
 )
 from sklearn.utils.estimator_checks import check_set_params as _check_set_params
-from sklearn.utils.testing import set_random_state
+from sklearn.utils._testing import set_random_state
 from sklearn.utils.validation import check_random_state
 
 from sktime.base import BaseEstimator