Esempio n. 1
0
def test_check_soft_dependencies_raises_error():
    """Test the _check_soft_dependencies() function."""
    with pytest.raises(ModuleNotFoundError, match=r".* soft dependency .*"):
        _check_soft_dependencies("unavailable_module")

    with pytest.raises(ModuleNotFoundError, match=r".* soft dependency .*"):
        _check_soft_dependencies("unavailable_module_1",
                                 "unavailable_module_2")
Esempio n. 2
0
__author__ = ["Viktor Kazakov", "Markus Löning", "Aaron Bostrom"]
__all__ = ["Evaluator"]

import itertools

import numpy as np
import pandas as pd
from scipy import stats
from scipy.stats import ranksums
from scipy.stats import ttest_ind

from sktime.benchmarking.base import BaseResults
from sktime.exceptions import NotEvaluatedError
from sktime.utils.check_imports import _check_soft_dependencies

_check_soft_dependencies("matplotlib", "scikit_posthocs")
import matplotlib.pyplot as plt  # noqa: E402

plt.style.use("seaborn-ticks")


class Evaluator:
    """
    Analyze results of machine learning experiments.
    """
    def __init__(self, results):
        if not isinstance(results, BaseResults):
            raise ValueError("`results` must inherit from BaseResults")
        self.results = results
        self._metric_dicts = []
Esempio n. 3
0
#!/usr/bin/env python3 -u
# -*- coding: utf-8 -*-
# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)

__author__ = ["Martin Walter"]
__all__ = ["BATS"]

from sktime.utils.check_imports import _check_soft_dependencies
from sktime.forecasting.base._adapters import _TbatsAdapter

_check_soft_dependencies("tbats")


class BATS(_TbatsAdapter):
    """BATS estimator used to fit and select best performing model.
    BATS (Exponential smoothing state space model with Box-Cox
    transformation, ARMA errors, Trend and Seasonal components.)
    Model has been described in De Livera, Hyndman & Snyder (2011).

    Parameters
    ----------
    use_box_cox: bool or None, optional (default=None)
        If Box-Cox transformation of original series should be applied.
        When None both cases shall be considered and better is selected by AIC.
    box_cox_bounds: tuple, shape=(2,), optional (default=(0, 1))
        Minimal and maximal Box-Cox parameter values.
    use_trend: bool or None, optional (default=None)
        Indicates whether to include a trend or not.
        When None both cases shall be considered and better is selected by AIC.
    use_damped_trend: bool or None, optional (default=None)
        Indicates whether to include a damping parameter in the trend or not.
Esempio n. 4
0
def plot_series(*series, labels=None):
    """Plot one or more time series

    Parameters
    ----------
    series : pd.Series
        One or more time series
    labels : list, optional (default=None)
        Names of series, will be displayed in figure legend

    Returns
    -------
    fig : plt.Figure
    ax : plt.Axis
    """
    _check_soft_dependencies("matplotlib", "seaborn")
    import matplotlib.pyplot as plt
    import seaborn as sns

    n_series = len(series)
    if labels is not None:
        if n_series != len(labels):
            raise ValueError("There must be one label for each time series, "
                             "but found inconsistent numbers of series and "
                             "labels.")
        legend = True
    else:
        labels = ["" for _ in range(n_series)]
        legend = False

    for y in series:
        check_y(y)

    # create combined index
    index = series[0].index
    for y in series[1:]:
        # check types, note that isinstance() does not work here because index
        # types inherit from each other, hence we check for type equality
        if not type(index) is type(y.index):  # noqa
            raise TypeError("Found series with different index types.")
        index = index.union(y.index)

    # generate integer x-values
    xs = [np.argwhere(index.isin(y.index)).ravel() for y in series]

    # create figure
    fig, ax = plt.subplots(1, figsize=plt.figaspect(0.25))
    colors = sns.color_palette("colorblind", n_colors=n_series)

    # plot series
    for x, y, color, label in zip(xs, series, colors, labels):

        # scatter if little data is available or index is not complete
        if len(x) <= 3 or not np.array_equal(np.arange(x[0], x[-1] + 1), x):
            plot_func = sns.scatterplot
        else:
            plot_func = sns.lineplot

        plot_func(x=x, y=y, ax=ax, marker="o", label=label, color=color)

    # set combined index as xticklabels, suppress matplotlib warning
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore")
        ax.set(xticklabels=index)

    if legend:
        ax.legend()

    return fig, ax
Esempio n. 5
0
#!/usr/bin/env python3 -u
# -*- coding: utf-8 -*-
# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)

__author__ = ["Markus Löning"]
__all__ = ["AutoARIMA"]

import pandas as pd

from sktime.forecasting.base._base import DEFAULT_ALPHA
from sktime.forecasting.base._sktime import BaseSktimeForecaster
from sktime.forecasting.base._sktime import OptionalForecastingHorizonMixin
from sktime.utils.check_imports import _check_soft_dependencies

_check_soft_dependencies("pmdarima")


class AutoARIMA(OptionalForecastingHorizonMixin, BaseSktimeForecaster):
    """Automatically discover the optimal order for an ARIMA model.

    The auto-ARIMA process seeks to identify the most optimal parameters
    for an ARIMA model, settling on a single fitted ARIMA model. This
    process is based on the commonly-used R function,
    forecast::auto.arima [3].

    Auto-ARIMA works by conducting differencing tests (i.e.,
    Kwiatkowski–Phillips–Schmidt–Shin, Augmented Dickey-Fuller or
    Phillips–Perron) to determine the order of differencing, d, and then
    fitting models within ranges of defined start_p, max_p, start_q, max_q
    ranges. If the seasonal optional is enabled, auto-ARIMA also seeks to
    identify the optimal P and Q hyper-parameters after conducting the
Esempio n. 6
0
# -*- coding: utf-8 -*-
# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)

__author__ = ["Ayushmaan Seth", "Markus Löning", "Alwin Wang"]
__all__ = ["TSFreshFeatureExtractor", "TSFreshRelevantFeatureExtractor"]

from warnings import warn

from sktime.transformers.series_as_features.base import BaseSeriesAsFeaturesTransformer
from sktime.utils.check_imports import _check_soft_dependencies
from sktime.utils.data_container import from_nested_to_long
from sktime.utils.validation import check_n_jobs
from sktime.utils.validation.series_as_features import check_X
from sktime.utils.validation.series_as_features import check_X_y

_check_soft_dependencies("tsfresh")


class BaseTSFreshFeatureExtractor(BaseSeriesAsFeaturesTransformer):
    """Base adapter class for tsfresh transformers"""
    def __init__(
        self,
        default_fc_parameters="efficient",
        kind_to_fc_parameters=None,
        chunksize=None,
        n_jobs=1,
        show_warnings=True,
        disable_progressbar=False,
        impute_function=None,
        profiling=None,
        profiling_filename=None,
Esempio n. 7
0
# -*- coding: utf-8 -*-
__author__ = "Angus Dempster"
__all__ = ["Rocket"]

import numpy as np
import pandas as pd

from sktime.transformers.base import _PanelToTabularTransformer
from sktime.utils.check_imports import _check_soft_dependencies
from sktime.utils.validation.panel import check_X

_check_soft_dependencies("numba")
from numba import njit  # noqa: E402
from numba import prange  # noqa: E402


class Rocket(_PanelToTabularTransformer):
    """ROCKET

    RandOm Convolutional KErnel Transform

    @article{dempster_etal_2019,
      author  = {Dempster, Angus and Petitjean, Francois and Webb,
      Geoffrey I},
      title   = {ROCKET: Exceptionally fast and accurate time series
      classification using random convolutional kernels},
      year    = {2019},
      journal = {arXiv:1910.13051}
    }

    Parameters
Esempio n. 8
0
# -*- coding: utf-8 -*-
""" catch22 features
A transformer for the catch22 features
"""

__author__ = "Matthew Middlehurst"
__all__ = ["Catch22"]

import numpy as np
import pandas as pd
from sktime.transformers.base import _PanelToTabularTransformer
from sktime.utils.check_imports import _check_soft_dependencies
from sktime.utils.data_container import from_nested_to_2d_array
from sktime.utils.validation.panel import check_X

_check_soft_dependencies("catch22")
import catch22  # noqa: E402


class Catch22(_PanelToTabularTransformer):
    """Canonical Time-series Characteristics (catch22)

    @article{lubba2019catch22,
        title={catch22: CAnonical Time-series CHaracteristics},
        author={Lubba, Carl H and Sethi, Sarab S and Knaute, Philip and
                Schultz, Simon R and Fulcher, Ben D and Jones, Nick S},
        journal={Data Mining and Knowledge Discovery},
        volume={33},
        number={6},
        pages={1821--1852},
        year={2019},
Esempio n. 9
0
def plot_series(*series, labels=None):
    """Plot one or more time series

    Parameters
    ----------
    series : pd.Series
        One or more time series
    labels : list, optional (default=None)
        Names of series, will be displayed in figure legend

    Returns
    -------
    fig : plt.Figure
    ax : plt.Axis
    """
    _check_soft_dependencies("matplotlib", "seaborn")
    import matplotlib.pyplot as plt
    from matplotlib.ticker import FuncFormatter, MaxNLocator
    from matplotlib.cbook import flatten
    import seaborn as sns

    n_series = len(series)
    if labels is not None:
        if n_series != len(labels):
            raise ValueError("There must be one label for each time series, "
                             "but found inconsistent numbers of series and "
                             "labels.")
        legend = True
    else:
        labels = ["" for _ in range(n_series)]
        legend = False

    for y in series:
        check_y(y)

    # create combined index
    index = series[0].index
    for y in series[1:]:
        # check types, note that isinstance() does not work here because index
        # types inherit from each other, hence we check for type equality
        if not type(index) is type(y.index):  # noqa
            raise TypeError("Found series with different index types.")
        index = index.union(y.index)

    # generate integer x-values
    xs = [np.argwhere(index.isin(y.index)).ravel() for y in series]

    # create figure
    fig, ax = plt.subplots(1, figsize=plt.figaspect(0.25))
    colors = sns.color_palette("colorblind", n_colors=n_series)

    # plot series
    for x, y, color, label in zip(xs, series, colors, labels):

        # scatter if little data is available or index is not complete
        if len(x) <= 3 or not np.array_equal(np.arange(x[0], x[-1] + 1), x):
            plot_func = sns.scatterplot
        else:
            plot_func = sns.lineplot

        plot_func(x=x, y=y, ax=ax, marker="o", label=label, color=color)

    # combine data points for all series
    xs_flat = list(flatten(xs))

    # set x label of data point to the matching index
    def format_fn(tick_val, tick_pos):
        if int(tick_val) in xs_flat:
            return index[int(tick_val)]
        else:
            return ""

    # dynamically set x label ticks and spacing from index labels
    ax.xaxis.set_major_formatter(FuncFormatter(format_fn))
    ax.xaxis.set_major_locator(MaxNLocator(integer=True))

    if legend:
        ax.legend()

    return fig, ax
Esempio n. 10
0
# -*- coding: utf-8 -*-

__author__ = ["Markus Löning"]
__all__ = ["MatrixProfileTransformer"]

import pandas as pd
from sktime.transformers.base import _SeriesToSeriesTransformer
from sktime.utils.validation.series import check_series
from sktime.utils.check_imports import _check_soft_dependencies

_check_soft_dependencies("stumpy")

import stumpy  # noqa: E402


class MatrixProfileTransformer(_SeriesToSeriesTransformer):

    _tags = {"univariate-only": True, "fit-in-transform": True}  # for unit test cases

    def __init__(self, window_length=3):
        self.window_length = window_length
        super(MatrixProfileTransformer, self).__init__()

    def transform(self, X, y=None):
        """
        Takes as input a single time series dataset and returns the matrix profile
        for that time series dataset.

        Parameters
        ----------
        X: pandas.Series