Skip to content

Commit

Permalink
Replace scikit-learn mixin classes with pyts mixin classes (johannfao…
Browse files Browse the repository at this point in the history
  • Loading branch information
johannfaouzi authored May 26, 2021
1 parent a5a9407 commit 51a55c2
Show file tree
Hide file tree
Showing 31 changed files with 292 additions and 69 deletions.
5 changes: 3 additions & 2 deletions pyts/approximation/dft.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
# License: BSD-3-Clause

import numpy as np
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.base import BaseEstimator
from sklearn.feature_selection import f_classif
from sklearn.utils.validation import check_array, check_is_fitted, check_X_y
from math import ceil
from warnings import warn
from ..base import UnivariateTransformerMixin
from ..preprocessing import StandardScaler


class DiscreteFourierTransform(BaseEstimator, TransformerMixin):
class DiscreteFourierTransform(BaseEstimator, UnivariateTransformerMixin):
"""Discrete Fourier Transform.
Parameters
Expand Down
5 changes: 3 additions & 2 deletions pyts/approximation/mcb.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import numpy as np
from numba import njit, prange
from scipy.stats import norm
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.base import BaseEstimator
from ..base import UnivariateTransformerMixin
from sklearn.tree import DecisionTreeClassifier
from sklearn.utils.validation import check_array, check_is_fitted, check_X_y
from sklearn.utils.multiclass import check_classification_targets
Expand Down Expand Up @@ -47,7 +48,7 @@ def _digitize(X, bins):
return X_binned.astype('int64')


class MultipleCoefficientBinning(BaseEstimator, TransformerMixin):
class MultipleCoefficientBinning(BaseEstimator, UnivariateTransformerMixin):
"""Bin continuous data into intervals column-wise.
Parameters
Expand Down
6 changes: 4 additions & 2 deletions pyts/approximation/paa.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import numpy as np
from math import ceil
from numba import njit, prange
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.base import BaseEstimator
from sklearn.utils.validation import check_array
from ..base import UnivariateTransformerMixin
from ..utils import segmentation


Expand All @@ -20,7 +21,8 @@ def _paa(X, n_samples, n_timestamps, start, end, n_timestamps_new):
return X_paa


class PiecewiseAggregateApproximation(BaseEstimator, TransformerMixin):
class PiecewiseAggregateApproximation(BaseEstimator,
UnivariateTransformerMixin):
"""Piecewise Aggregate Approximation.
Parameters
Expand Down
6 changes: 4 additions & 2 deletions pyts/approximation/sax.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
# License: BSD-3-Clause

import numpy as np
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.base import BaseEstimator
from sklearn.utils.validation import check_array
from ..base import UnivariateTransformerMixin
from ..preprocessing import KBinsDiscretizer


class SymbolicAggregateApproximation(BaseEstimator, TransformerMixin):
class SymbolicAggregateApproximation(BaseEstimator,
UnivariateTransformerMixin):
"""Symbolic Aggregate approXimation.
Parameters
Expand Down
5 changes: 3 additions & 2 deletions pyts/approximation/sfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
# Author: Johann Faouzi <[email protected]>
# License: BSD-3-Clause

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.base import BaseEstimator
from sklearn.pipeline import Pipeline
from sklearn.utils.validation import check_is_fitted
from .dft import DiscreteFourierTransform
from .mcb import MultipleCoefficientBinning
from ..base import UnivariateTransformerMixin


class SymbolicFourierApproximation(BaseEstimator, TransformerMixin):
class SymbolicFourierApproximation(BaseEstimator, UnivariateTransformerMixin):
"""Symbolic Fourier Approximation.
Parameters
Expand Down
3 changes: 2 additions & 1 deletion pyts/bag_of_words/bow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
import warnings
from ..approximation import (
PiecewiseAggregateApproximation, SymbolicAggregateApproximation)
from ..base import UnivariateTransformerMixin
from ..preprocessing import StandardScaler
from ..utils.utils import _windowed_view


class WordExtractor(BaseEstimator, TransformerMixin):
class WordExtractor(BaseEstimator, UnivariateTransformerMixin):
r"""Transform discretized time series into sequences of words.
Parameters
Expand Down
128 changes: 128 additions & 0 deletions pyts/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
"""Base classes for all estimators."""

# Author: Johann Faouzi <[email protected]>
# License: BSD-3-Clause

from sklearn.metrics import accuracy_score


class UnivariateTransformerMixin:
"""Mixin class for all univariate transformers in pyts."""

def fit_transform(self, X, y=None, **fit_params):
"""Fit to data, then transform it.
Fits transformer to `X` and `y` with optional parameters `fit_params`
and returns a transformed version of `X`.
Parameters
----------
X : array-like, shape = (n_samples, n_timestamps)
Univariate time series.
y : None or array-like, shape = (n_samples,) (default = None)
Target values (None for unsupervised transformations).
**fit_params : dict
Additional fit parameters.
Returns
-------
X_new : array
Transformed array.
""" # noqa: E501
if y is None:
# fit method of arity 1 (unsupervised transformation)
return self.fit(X, **fit_params).transform(X)
else:
# fit method of arity 2 (supervised transformation)
return self.fit(X, y, **fit_params).transform(X)


class MultivariateTransformerMixin:
"""Mixin class for all multivariate transformers in pyts."""

def fit_transform(self, X, y=None, **fit_params):
"""Fit to data, then transform it.
Fits transformer to `X` and `y` with optional parameters `fit_params`
and returns a transformed version of `X`.
Parameters
----------
X : array-like, shape = (n_samples, n_features, n_timestamps)
Multivariate time series.
y : None or array-like, shape = (n_samples,) (default = None)
Target values (None for unsupervised transformations).
**fit_params : dict
Additional fit parameters.
Returns
-------
X_new : array
Transformed array.
""" # noqa: E501
if y is None:
# fit method of arity 1 (unsupervised transformation)
return self.fit(X, **fit_params).transform(X)
else:
# fit method of arity 2 (supervised transformation)
return self.fit(X, y, **fit_params).transform(X)


class UnivariateClassifierMixin:
"""Mixin class for all univariate classifiers in pyts."""

def score(self, X, y, sample_weight=None):
"""
Return the mean accuracy on the given test data and labels.
Parameters
----------
X : array-like, shape = (n_samples, n_timestamps)
Univariate time series.
y : array-like, shape = (n_samples,)
True labels for `X`.
sample_weight : None or array-like, shape = (n_samples,) (default = None)
Sample weights.
Returns
-------
score : float
Mean accuracy of ``self.predict(X)`` with regards to `y`.
""" # noqa: E501
return accuracy_score(y, self.predict(X), sample_weight=sample_weight)


class MultivariateClassifierMixin:
"""Mixin class for all multivariate classifiers in pyts."""

def score(self, X, y, sample_weight=None):
"""
Return the mean accuracy on the given test data and labels.
Parameters
----------
X : array-like, shape = (n_samples, n_features, n_timestamps)
Multivariate time series.
y : array-like, shape = (n_samples,)
True labels for `X`.
sample_weight : None or array-like, shape = (n_samples,) (default = None)
Sample weights.
Returns
-------
score : float
Mean accuracy of ``self.predict(X)`` with regards to `y`.
""" # noqa: E501
return accuracy_score(y, self.predict(X), sample_weight=sample_weight)
5 changes: 3 additions & 2 deletions pyts/classification/bossvs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
from math import ceil
from sklearn.utils.validation import check_array, check_X_y, check_is_fitted
from sklearn.utils.multiclass import check_classification_targets
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.base import BaseEstimator
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from ..approximation import SymbolicFourierApproximation
from ..base import UnivariateClassifierMixin
from ..utils.utils import _windowed_view


class BOSSVS(BaseEstimator, ClassifierMixin):
class BOSSVS(BaseEstimator, UnivariateClassifierMixin):
"""Bag-of-SFA Symbols in Vector Space.
Each time series is transformed into an histogram using the
Expand Down
5 changes: 3 additions & 2 deletions pyts/classification/knn.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
# Author: Johann Faouzi <[email protected]>
# License: BSD-3-Clause

from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.base import BaseEstimator
from sklearn.neighbors import KNeighborsClassifier as SklearnKNN
from sklearn.preprocessing import LabelEncoder
from sklearn.utils.validation import check_X_y, check_is_fitted
from ..base import UnivariateClassifierMixin
from ..metrics import boss, dtw, sakoe_chiba_band, itakura_parallelogram
from ..metrics.dtw import (_dtw_classic, _dtw_region, _dtw_fast,
_dtw_multiscale)


class KNeighborsClassifier(BaseEstimator, ClassifierMixin):
class KNeighborsClassifier(BaseEstimator, UnivariateClassifierMixin):
"""k-nearest neighbors classifier.
Parameters
Expand Down
11 changes: 4 additions & 7 deletions pyts/classification/learning_shapelets.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@

from itertools import chain
from math import ceil

from numba import njit, prange
import numpy as np

from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.base import BaseEstimator
from sklearn.cluster import KMeans
from sklearn.exceptions import ConvergenceWarning
from sklearn.multiclass import OneVsOneClassifier, OneVsRestClassifier
Expand All @@ -19,10 +17,9 @@
from sklearn.utils.validation import (
check_is_fitted, check_random_state, check_X_y, _check_sample_weight)
from sklearn.utils.multiclass import check_classification_targets

import warnings

from ..utils.utils import _windowed_view
from ..base import UnivariateClassifierMixin


@njit(fastmath=True)
Expand Down Expand Up @@ -305,7 +302,7 @@ def _grad_shapelets(X, y, n_classes, weights, shapelets, lengths, alpha,
return gradients


class CrossEntropyLearningShapelets(BaseEstimator, ClassifierMixin):
class CrossEntropyLearningShapelets(BaseEstimator, UnivariateClassifierMixin):
"""Learning Shapelets algorithm with cross-entropy loss.
Parameters
Expand Down Expand Up @@ -811,7 +808,7 @@ def _check_params(self, X, y, y_ind, classes, sample_weight):
return n_shapelets_per_size, min_shapelet_length, sample_weight, rng


class LearningShapelets(BaseEstimator, ClassifierMixin):
class LearningShapelets(BaseEstimator, UnivariateClassifierMixin):
"""Learning Shapelets algorithm.
This estimator consists of two steps: computing the distances between the
Expand Down
5 changes: 3 additions & 2 deletions pyts/classification/saxvsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@

from sklearn.utils.validation import check_X_y, check_array, check_is_fitted
from sklearn.utils.multiclass import check_classification_targets
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.base import BaseEstimator
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from ..bag_of_words import BagOfWords
from ..base import UnivariateClassifierMixin


class SAXVSM(BaseEstimator, ClassifierMixin):
class SAXVSM(BaseEstimator, UnivariateClassifierMixin):
"""Classifier based on SAX-VSM representation and tf-idf statistics.
Time series are first transformed into bag of words using Symbolic
Expand Down
9 changes: 5 additions & 4 deletions pyts/classification/time_series_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
from math import ceil
from numba import njit
import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin, TransformerMixin
from sklearn.base import BaseEstimator
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.utils.validation import (
check_array, check_is_fitted, check_random_state)
from ..base import UnivariateClassifierMixin, UnivariateTransformerMixin


@njit()
Expand All @@ -35,7 +36,7 @@ def extract_features(X, n_samples, n_windows, indices):
return X_new


class WindowFeatureExtractor(BaseEstimator, TransformerMixin):
class WindowFeatureExtractor(BaseEstimator, UnivariateTransformerMixin):
"""Feature extractor over a window.
This transformer extracts 3 features from each window: the mean, the
Expand Down Expand Up @@ -174,7 +175,7 @@ def _check_params(self, X):
return n_windows, min_window_size, rng


class TimeSeriesForest(BaseEstimator, ClassifierMixin):
class TimeSeriesForest(BaseEstimator, UnivariateClassifierMixin):
"""A random forest classifier for time series.
A random forest is a meta estimator that fits a number of decision tree
Expand Down Expand Up @@ -376,7 +377,7 @@ class TimeSeriesForest(BaseEstimator, ClassifierMixin):
Forest for Classification and Feature Extraction".
Information Sciences, 239, 142-153 (2013).
.. [2] L. Breiman, "Random Forests", Machine Learning, 45(1), 5-32, 2001.
.. [2] Leo Breiman, "Random Forests", Machine Learning, 45(1), 5-32, 2001.
""" # noqa: E501
def __init__(self,
Expand Down
Loading

0 comments on commit 51a55c2

Please sign in to comment.