tslearn’s documentation

tslearn is a Python package that provides machine learning tools for the analysis of time series. This package builds on (and hence depends on) scikit-learn, numpy and scipy libraries.

This documentation contains a quick-start guide (including installation procedure and basic usage of the toolkit), a complete API Reference, as well as a gallery of examples.

Finally, if you use tslearn in a scientific publication, we would appreciate citations.

Quick-start guide

For a list of functions and classes available in tslearn, please have a look at our API Reference.

Installation

Using conda

The easiest way to install tslearn is probably via conda:

conda install -c conda-forge tslearn

Using PyPI

Using pip should also work fine:

python -m pip install tslearn

In this case, you should have numpy, cython and C++ build tools available at build time.

Using latest github-hosted version

If you want to get tslearn’s latest version, you can refer to the repository hosted at github:

python -m pip install https://github.com/tslearn-team/tslearn/archive/main.zip

In this case, you should have numpy, cython and C++ build tools available at build time.

It seems on some platforms Cython dependency does not install properly. If you experiment such an issue, try installing it with the following command:

python -m pip install cython

before you start installing tslearn. If it still does not work, we suggest you switch to conda installation.

Other requirements

tslearn builds on (and hence depends on) scikit-learn, numpy and scipy libraries.

If you plan to use the tslearn.shapelets module from tslearn, tensorflow (v2) should also be installed. h5py is required for reading or writing models using the hdf5 file format. In order to load multivariate datasets from the UCR/UEA archive using the tslearn.datasets.UCR_UEA_datasets class, installed scipy version should be greater than 1.3.0.

Getting started

This tutorial will guide you to format your first time series data, import standard datasets, and manipulate them using dedicated machine learning algorithms.

Time series format

First, let us have a look at what tslearn time series format is. To do so, we will use the to_time_series utility from tslearn.utils:

>>> from tslearn.utils import to_time_series
>>> my_first_time_series = [1, 3, 4, 2]
>>> formatted_time_series = to_time_series(my_first_time_series)
>>> print(formatted_time_series.shape)
(4, 1)

In tslearn, a time series is nothing more than a two-dimensional numpy array with its first dimension corresponding to the time axis and the second one being the feature dimensionality (1 by default).

Then, if we want to manipulate sets of time series, we can cast them to three-dimensional arrays, using to_time_series_dataset. If time series from the set are not equal-sized, NaN values are appended to the shorter ones and the shape of the resulting array is (n_ts, max_sz, d) where max_sz is the maximum of sizes for time series in the set.

>>> from tslearn.utils import to_time_series_dataset
>>> my_first_time_series = [1, 3, 4, 2]
>>> my_second_time_series = [1, 2, 4, 2]
>>> formatted_dataset = to_time_series_dataset([my_first_time_series, my_second_time_series])
>>> print(formatted_dataset.shape)
(2, 4, 1)
>>> my_third_time_series = [1, 2, 4, 2, 2]
>>> formatted_dataset = to_time_series_dataset([my_first_time_series,
                                                my_second_time_series,
                                                my_third_time_series])
>>> print(formatted_dataset.shape)
(3, 5, 1)

Importing standard time series datasets

If you aim at experimenting with standard time series datasets, you should have a look at the tslearn.datasets.

>>> from tslearn.datasets import UCR_UEA_datasets
>>> X_train, y_train, X_test, y_test = UCR_UEA_datasets().load_dataset("TwoPatterns")
>>> print(X_train.shape)
(1000, 128, 1)
>>> print(y_train.shape)
(1000,)

Note that when working with time series datasets, it can be useful to rescale time series using tools from the tslearn.preprocessing.

If you want to import other time series from text files, the expected format is:

  • each line represents a single time series (and time series from a dataset are not forced to be the same length);

  • in each line, modalities are separated by a | character (useless if you only have one modality in your data);

  • in each modality, observations are separated by a space character.

Here is an example of such a file storing two time series of dimension 2 (the first time series is of length 3 and the second one is of length 2).

1.0 0.0 2.5|3.0 2.0 1.0
1.0 2.0|4.333 2.12

To read from / write to this format, have a look at the tslearn.utils:

>>> from tslearn.utils import save_time_series_txt, load_time_series_txt
>>> time_series_dataset = load_time_series_txt("path/to/your/file.txt")
>>> save_time_series_txt("path/to/another/file.txt", dataset_to_be_saved)

Playing with your data

Once your data is loaded and formatted according to tslearn standards, the next step is to feed machine learning models with it. Most tslearn models inherit from scikit-learn base classes, hence interacting with them is very similar to interacting with a scikit-learn model, except that datasets are not two-dimensional arrays, but rather tslearn time series datasets (i.e. three-dimensional arrays or lists of two-dimensional arrays).

>>> from tslearn.clustering import TimeSeriesKMeans
>>> km = TimeSeriesKMeans(n_clusters=3, metric="dtw")
>>> km.fit(X_train)

As seen above, one key parameter when applying machine learning methods to time series datasets is the metric to be used. You can learn more about it in the dedicated section of this documentation.

Methods for variable-length time series

This page lists machine learning methods in tslearn that are able to deal with datasets containing time series of different lengths. We also provide example usage for these methods using the following variable-length time series dataset:

from tslearn.utils import to_time_series_dataset
X = to_time_series_dataset([[1, 2, 3, 4], [1, 2, 3], [2, 5, 6, 7, 8, 9]])
y = [0, 0, 1]

Classification

Examples
from tslearn.neighbors import KNeighborsTimeSeriesClassifier
knn = KNeighborsTimeSeriesClassifier(n_neighbors=2)
knn.fit(X, y)
from tslearn.svm import TimeSeriesSVC
clf = TimeSeriesSVC(C=1.0, kernel="gak")
clf.fit(X, y)
from tslearn.shapelets import LearningShapelets
clf = LearningShapelets(n_shapelets_per_size={3: 1})
clf.fit(X, y)

Regression

Examples
from tslearn.svm import TimeSeriesSVR
clf = TimeSeriesSVR(C=1.0, kernel="gak")
y_reg = [1.3, 5.2, -12.2]
clf.fit(X, y_reg)

Clustering

Examples
from tslearn.clustering import KernelKMeans
gak_km = KernelKMeans(n_clusters=2, kernel="gak")
labels_gak = gak_km.fit_predict(X)
from tslearn.clustering import TimeSeriesKMeans
km = TimeSeriesKMeans(n_clusters=2, metric="dtw")
labels = km.fit_predict(X)
km_bis = TimeSeriesKMeans(n_clusters=2, metric="softdtw")
labels_bis = km_bis.fit_predict(X)
from tslearn.clustering import TimeSeriesKMeans, silhouette_score
km = TimeSeriesKMeans(n_clusters=2, metric="dtw")
labels = km.fit_predict(X)
silhouette_score(X, labels, metric="dtw")

Barycenter computation

Examples
from tslearn.barycenters import dtw_barycenter_averaging
bar = dtw_barycenter_averaging(X, barycenter_size=3)
from tslearn.barycenters import softdtw_barycenter
from tslearn.utils import ts_zeros
initial_barycenter = ts_zeros(sz=5)
bar = softdtw_barycenter(X, init=initial_barycenter)

Model selection

Also, model selection tools offered by scikit-learn can be used on variable-length data, in a standard way, such as:

from sklearn.model_selection import KFold, GridSearchCV
from tslearn.neighbors import KNeighborsTimeSeriesClassifier

knn = KNeighborsTimeSeriesClassifier(metric="dtw")
p_grid = {"n_neighbors": [1, 5]}

cv = KFold(n_splits=2, shuffle=True, random_state=0)
clf = GridSearchCV(estimator=knn, param_grid=p_grid, cv=cv)
clf.fit(X, y)

Resampling

Finally, if you want to use a method that cannot run on variable-length time series, one option would be to first resample your data so that all your time series have the same length and then run your method on this resampled version of your dataset.

Note however that resampling will introduce temporal distortions in your data. Use with great care!

from tslearn.preprocessing import TimeSeriesResampler

resampled_X = TimeSeriesResampler(sz=X.shape[1]).fit_transform(X)

Backend selection and use

tslearn proposes different backends (NumPy and PyTorch) to compute time series metrics such as DTW and Soft-DTW. The PyTorch backend can be used to compute gradients of metric functions thanks to automatic differentiation.

Backend selection

A backend can be instantiated using the function instantiate_backend. To specify which backend should be instantiated (NumPy or PyTorch), this function accepts four different kind of input parameters:

  • a string equal to "numpy" or "pytorch".

  • a NumPy array or a Torch tensor.

  • a Backend instance. The input backend is then returned.

  • None or anything else than mentioned previously. The backend NumPy is then instantiated.

Examples

If the input is the string "numpy", the NumPyBackend is instantiated.

>>> from tslearn.backend import instantiate_backend
>>> be = instantiate_backend("numpy")
>>> print(be.backend_string)
"numpy"

If the input is the string "pytorch", the PyTorchBackend is instantiated.

>>> be = instantiate_backend("pytorch")
>>> print(be.backend_string)
"pytorch"

If the input is a NumPy array, the NumPyBackend is instantiated.

>>> import numpy as np
>>> be = instantiate_backend(np.array([0]))
>>> print(be.backend_string)
"numpy"

If the input is a Torch tensor, the PyTorchBackend is instantiated.

>>> import torch
>>> be = instantiate_backend(torch.tensor([0]))
>>> print(be.backend_string)
"pytorch"

If the input is a Backend instance, the input backend is returned.

>>> print(be.backend_string)
"pytorch"
>>> be = instantiate_backend(be)
>>> print(be.backend_string)
"pytorch"

If the input is None, the NumPyBackend is instantiated.

>>> be = instantiate_backend(None)
>>> print(be.backend_string)
"numpy"

If the input is anything else, the NumPyBackend is instantiated.

>>> be = instantiate_backend("Hello, World!")
>>> print(be.backend_string)
"numpy"

The function instantiate_backend accepts any number of input parameters, including zero. To select which backend should be instantiated (NumPy or PyTorch), a for loop is performed on the inputs until a backend is selected.

>>> be = instantiate_backend(1, None, "Hello, World!", torch.tensor([0]), "numpy")
>>> print(be.backend_string)
"pytorch"

If none of the inputs are related to NumPy or PyTorch, the NumPyBackend is instantiated.

>>> be = instantiate_backend(1, None, "Hello, World!")
>>> print(be.backend_string)
"numpy"

Use the backends

The names of the attributes and methods of the backends are inspired by the NumPy backend.

Examples

Create backend objects.

>>> be = instantiate_backend("pytorch")
>>> mat = be.array([[0 , 1], [2, 3]], dtype=float)
>>> print(mat)
tensor([[0., 1.],
        [2., 3.]], dtype=torch.float64)

Use backend functions.

>>> norm = be.linalg.norm(mat)
>>> print(norm)
tensor(3.7417, dtype=torch.float64)

Choose the backend used by metric functions

tslearn’s metric functions have an optional input parameter “be” to specify the backend to use to compute the metric.

Examples
>>> import torch
>>> from tslearn.metrics import dtw
>>> s1 = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True)
>>> s2 = torch.tensor([[3.0], [4.0], [-3.0]])
>>> sim = dtw(s1, s2, be="pytorch")
>>> print(sim)
sim tensor(6.4807, grad_fn=<SqrtBackward0>)

By default, the optional input parameter be is equal to None. Note that the first line of the function dtw is:

be = instantiate_backend(be, s1, s2)

Therefore, even if be=None, the PyTorchBackend is instantiated and used to compute the DTW metric since s1 and s2 are Torch tensors.

>>> sim = dtw(s1, s2)
>>> print(sim)
sim tensor(6.4807, grad_fn=<SqrtBackward0>)

Automatic differentiation

The PyTorch backend can be used to compute the gradients of the metric functions thanks to automatic differentiation.

Examples

Compute the gradient of the Dynamic Time Warping similarity measure.

>>> s1 = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True)
>>> s2 = torch.tensor([[3.0], [4.0], [-3.0]])
>>> sim = dtw(s1, s2, be="pytorch")
>>> sim.backward()
>>> d_s1 = s1.grad
>>> print(d_s1)
tensor([[-0.3086],
        [-0.1543],
        [ 0.7715]])

Compute the gradient of the Soft-DTW similarity measure.

>>> from tslearn.metrics import soft_dtw
>>> ts1 = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True)
>>> ts2 = torch.tensor([[3.0], [4.0], [-3.0]])
>>> sim = soft_dtw(ts1, ts2, gamma=1.0, be="pytorch", compute_with_backend=True)
>>> print(sim)
tensor(41.1876, dtype=torch.float64, grad_fn=<SelectBackward0>)
>>> sim.backward()
>>> d_ts1 = ts1.grad
>>> print(d_ts1)
tensor([[-4.0001],
        [-2.2852],
        [10.1643]])

Integration with other Python packages

tslearn is a general-purpose Python machine learning library for time series that offers tools for pre-processing and feature extraction as well as dedicated models for clustering, classification and regression. To ensure compatibility with more specific Python packages, we provide utilities to convert data sets from and to other formats.

tslearn.utils.to_time_series_dataset() is a general function that transforms an array-like object into a three-dimensional array of shape (n_ts, sz, d) with the following conventions:

  • the fist axis is the sample axis, n_ts being the number of time series;

  • the second axis is the time axis, sz being the maximum number of time points;

  • the third axis is the dimension axis, d being the number of dimensions.

This is how a data set of time series is represented in tslearn.

The following sections briefly explain how to transform a data set from tslearn to another supported Python package and vice versa.

scikit-learn

scikit-learn is a popular Python package for machine learning. tslearn.utils.to_sklearn_dataset() converts a data set from tslearn format to scikit-learn format. To convert a data set from scikit-learn, you can use tslearn.utils.to_time_series_dataset().

>>> from tslearn.utils import to_sklearn_dataset
>>> to_sklearn_dataset([[1, 2], [1, 4, 3]])
array([[ 1.,  2., nan],
       [ 1.,  4.,  3.]])
>>> to_time_series_dataset([[ 1.,  2., None], [ 1.,  4.,  3.]])
array([[[ 1.],
    [ 2.],
    [nan]],

   [[ 1.],
    [ 4.],
    [ 3.]]])

pyts

pyts is a Python package dedicated to time series classification. tslearn.utils.to_pyts_dataset() and tslearn.utils.from_pyts_dataset() allow users to convert a data set from tslearn format to pyts format and vice versa.

>>> from tslearn.utils import from_pyts_dataset, to_pyts_dataset
>>> from_pyts_dataset([[1, 2], [1, 4]])
array([[[1],
        [2]],

       [[1],
        [4]]])

>>> to_pyts_dataset([[[1], [2]], [[1], [4]]])
array([[1., 2.],
       [1., 4.]])

seglearn

seglearn is a python package for machine learning time series or sequences. tslearn.utils.to_seglearn_dataset() and tslearn.utils.from_seglearn_dataset() allow users to convert a data set from tslearn format to seglearn format and vice versa.

>>> from tslearn.utils import from_seglearn_dataset, to_seglearn_dataset
>>> from_seglearn_dataset([[1, 2], [1, 4, 3]])
array([[[ 1.],
        [ 2.],
        [nan]],

       [[ 1.],
        [ 4.],
        [ 3.]]])
>>> to_seglearn_dataset([[[1], [2], [None]], [[1], [4], [3]]])
array([array([[1.],
       [2.]]),
       array([[1.],
       [4.],
       [3.]])], dtype=object)

stumpy

stumpy is a powerful and scalable Python library for computing a Matrix Profile, which can be used for a variety of time series data mining tasks. tslearn.utils.to_stumpy_dataset() and tslearn.utils.from_stumpy_dataset() allow users to convert a data set from tslearn format to stumpy format and vice versa.

>>> import numpy as np
>>> from tslearn.utils import from_stumpy_dataset, to_stumpy_dataset
>>> from_stumpy_dataset([np.array([1, 2]), np.array([1, 4, 3])])
array([[[ 1.],
        [ 2.],
        [nan]],

       [[ 1.],
        [ 4.],
        [ 3.]]])
>>> to_stumpy_dataset([[[1], [2], [None]], [[1], [4], [3]]])
[array([1., 2.]), array([1., 4., 3.])]

sktime

sktime is a scikit-learn compatible Python toolbox for learning with time series. tslearn.utils.to_sktime_dataset() and tslearn.utils.from_sktime_dataset() allow users to convert a data set from tslearn format to sktime format and vice versa. pandas is a required dependency to use these functions.

>>> import pandas as pd
>>> from tslearn.utils import from_sktime_dataset, to_sktime_dataset
>>> df = pd.DataFrame()
>>> df["dim_0"] = [pd.Series([1, 2]), pd.Series([1, 4, 3])]
>>> from_sktime_dataset(df)
array([[[ 1.],
        [ 2.],
        [nan]],

       [[ 1.],
        [ 4.],
        [ 3.]]])
>>> to_sktime_dataset([[[1], [2], [None]], [[1], [4], [3]]]).shape
(2, 1)

pyflux

pyflux is a library for time series analysis and prediction. tslearn.utils.to_pyflux_dataset() and tslearn.utils.from_pyflux_dataset() allow users to convert a data set from tslearn format to pyflux format and vice versa. pandas is a required dependency to use these functions.

>>> import pandas as pd
>>> from tslearn.utils import from_pyflux_dataset, to_pyflux_dataset
>>> df = pd.DataFrame([1, 2], columns=["dim_0"])
>>> from_pyflux_dataset(df)
array([[[1.],
        [2.]]])
>>> to_pyflux_dataset([[[1], [2]]]).shape
(2, 1)

tsfresh

tsfresh is a python package automatically calculating a large number of time series characteristics. tslearn.utils.to_tsfresh_dataset() and tslearn.utils.from_tsfresh_dataset() allow users to convert a data set from tslearn format to tsfresh format and vice versa. pandas is a required dependency to use these functions.

>>> import pandas as pd
>>> from tslearn.utils import from_tsfresh_dataset, to_tsfresh_dataset
>>> df = pd.DataFrame([[0, 0, 1.0],
...                    [0, 1, 2.0],
...                    [1, 0, 1.0],
...                    [1, 1, 4.0],
...                    [1, 2, 3.0]], columns=['id', 'time', 'dim_0'])
>>> from_tsfresh_dataset(df)
array([[[ 1.],
    [ 2.],
    [nan]],

   [[ 1.],
    [ 4.],
    [ 3.]]])
>>> to_tsfresh_dataset([[[1], [2], [None]], [[1], [4], [3]]]).shape
(5, 3)

cesium

cesium is an open-source platform for time series inference. tslearn.utils.to_cesium_dataset() and tslearn.utils.from_cesium_dataset() allow users to convert a data set from tslearn format to cesium format and vice versa. cesium is a required dependency to use these functions.

>>> from tslearn.utils import from_cesium_dataset, to_cesium_dataset
>>> from cesium.data_management import TimeSeries
>>> from_cesium_dataset([TimeSeries(m=[1, 2]), TimeSeries(m=[1, 4, 3])])
array([[[ 1.],
        [ 2.],
        [nan]],

       [[ 1.],
        [ 4.],
        [ 3.]]])
>>> len(to_cesium_dataset([[[1], [2], [None]], [[1], [4], [3]]]))
2

Contributing

First of all, thank you for considering contributing to tslearn. It’s people like you that will help make tslearn a great toolkit.

Contributions are managed through GitHub Issues and Pull Requests.

We are welcoming contributions in the following forms:

  • Bug reports: when filing an issue to report a bug, please use the search tool to ensure the bug hasn’t been reported yet;

  • New feature suggestions: if you think tslearn should include a new algorithm, please open an issue to ask for it (of course, you should always check that the feature has not been asked for yet :). Think about linking to a pdf version of the paper that first proposed the method when suggesting a new algorithm.

  • Bug fixes and new feature implementations: if you feel you can fix a reported bug/implement a suggested feature yourself, do not hesitate to:

    1. fork the project;

    2. implement your bug fix;

    3. submit a pull request referencing the ID of the issue in which the bug was reported / the feature was suggested;

If you would like to contribute by implementing a new feature reported in the Issues, maybe starting with Issues that are attached the “good first issue” label would be a good idea.

When submitting code, please think about code quality, adding proper docstrings including doctests with high code coverage.

More details on Pull requests

The preferred workflow for contributing to tslearn is to fork the main repository on GitHub, clone, and develop on a branch. Steps:

  1. Fork the project repository by clicking on the ‘Fork’ button near the top right of the page. This creates a copy of the code under your GitHub user account. For more details on how to fork a repository see this guide.

  2. Clone your fork of the tslearn repo from your GitHub account to your local disk:

    $ git clone git@github.com:YourLogin/tslearn.git
    $ cd tslearn
    
  3. Create a my-feature branch to hold your development changes. Always use a my-feature branch. It’s good practice to never work on the master branch:

    $ git checkout -b my-feature
    
  4. Develop the feature on your feature branch. To record your changes in git, add changed files using git add and then git commit files:

    $ git add modified_files
    $ git commit
    
  5. Push the changes to your GitHub account with:

    $ git push -u origin my-feature
    
  6. Follow these instructions to create a pull request from your fork. This will send an email to the committers.

(If any of the above seems like magic to you, please look up the Git documentation on the web, or ask a friend or another contributor for help.)

Pull Request Checklist

We recommended that your contribution complies with the following rules before you submit a pull request:

  • Follow the PEP8 Guidelines.

  • If your pull request addresses an issue, please use the pull request title to describe the issue and mention the issue number in the pull request description. This will make sure a link back to the original issue is created.

  • All public methods should have informative docstrings with sample usage presented as doctests when appropriate.

  • Please prefix the title of your pull request with [MRG] (Ready for Merge), if the contribution is complete and ready for a detailed review. An incomplete contribution – where you expect to do more work before receiving a full review – should be prefixed [WIP] (to indicate a work in progress) and changed to [MRG] when it matures. WIPs may be useful to: indicate you are working on something to avoid duplicated work, request broad review of functionality or API, or seek collaborators. WIPs often benefit from the inclusion of a task list in the PR description.

  • When adding additional functionality, provide at least one example script in the tslearn/docs/examples/ folder. Have a look at other examples for reference. Examples should demonstrate why the new functionality is useful in practice and, if possible, compare it to other methods available in tslearn.

  • Documentation and high-coverage tests are necessary for enhancements to be accepted. Bug-fixes or new features should be provided with non-regression tests. These tests verify the correct behavior of the fix or feature. In this manner, further modifications on the code base are granted to be consistent with the desired behavior. For the Bug-fixes case, at the time of the PR, this tests should fail for the code base in master and pass for the PR code.

  • At least one paragraph of narrative documentation with links to references in the literature (with PDF links when possible) and the example.

Here is a description of useful tools to check your code locally:

  • No PEP8 or PEP257 errors; check with the flake8 Python package:

    $ pip install flake8
    $ flake8 path/to/module.py  # check for errors in one file
    $ flake8 path/to/folder  # check for errors in all the files in a folder
    $ git diff -u | flake8 --diff  # check for errors in the modified code only
    
  • To run the tests locally and get code coverage, use the pytest and pytest-cov Python packages:

    $ pip install pytest pytest-cov
    $ pytest --cov tslearn
    
  • To build the documentation locally, install the following packages and run the make html command in the tslearn/docs folder:

    $ pip install sphinx==1.8.5 sphinx-gallery sphinx-bootstrap-theme nbsphinx
    $ pip install numpydoc matplotlib
    $ cd tslearn/docs
    $ make html
    

    The documentation will be generated in the _build/html. You can double click on index.html to open the index page, which will look like the first page that you see on the online documentation. Then you can move to the pages that you modified and have a look at your changes.

Bonus points for contributions that include a performance analysis with a benchmark script and profiling output.

User Guide

Dynamic Time Warping

Dynamic Time Warping (DTW) [1] is a similarity measure between time series. Let us consider two time series \(x = (x_0, \dots, x_{n-1})\) and \(y = (y_0, \dots, y_{m-1})\) of respective lengths \(n\) and \(m\). Here, all elements \(x_i\) and \(y_j\) are assumed to lie in the same \(d\)-dimensional space. In tslearn, such time series would be represented as arrays of respective shapes (n, d) and (m, d) and DTW can be computed using the following code:

from tslearn.metrics import dtw, dtw_path

dtw_score = dtw(x, y)
# Or, if the path is also an important information:
optimal_path, dtw_score = dtw_path(x, y)

Optimization problem

DTW between \(x\) and \(y\) is formulated as the following optimization problem:

\[DTW(x, y) = \min_\pi \sqrt{ \sum_{(i, j) \in \pi} d(x_i, y_j)^2 }\]

where \(\pi = [\pi_0, \dots , \pi_K]\) is a path that satisfies the following properties:

  • it is a list of index pairs \(\pi_k = (i_k, j_k)\) with \(0 \leq i_k < n\) and \(0 \leq j_k < m\)

  • \(\pi_0 = (0, 0)\) and \(\pi_K = (n - 1, m - 1)\)

  • for all \(k > 0\) , \(\pi_k = (i_k, j_k)\) is related to \(\pi_{k-1} = (i_{k-1}, j_{k-1})\) as follows:

    • \(i_{k-1} \leq i_k \leq i_{k-1} + 1\)

    • \(j_{k-1} \leq j_k \leq j_{k-1} + 1\)

Here, a path can be seen as a temporal alignment of time series such that Euclidean distance between aligned (ie. resampled) time series is minimal.

The following image exhibits the DTW path (in white) for a given pair of time series, on top of the cross-similarity matrix that stores \(d(x_i, y_j)\) values.

../_images/sphx_glr_plot_dtw_thumb.svg

Code to produce such visualization is available in our Gallery of examples.

Algorithmic solution

There exists an \(O(mn)\) algorithm to compute the exact optimum for this problem (pseudo-code is provided for time series indexed from 1 for simplicity):

def dtw(x, y):
    # Initialization
    for i = 1..n
        for j = 1..m
            C[i, j] = inf

    C[0, 0] = 0.

   # Main loop
   for i = 1..n
        for j = 1..m
            dist = d(x_i, y_j) ** 2
            C[i, j] = dist + min(C[i-1, j], C[i, j-1], C[i-1, j-1])

   return sqrt(C[n, m])

Using a different ground metric

By default, tslearn uses squared Euclidean distance as the base metric (i.e. \(d(\cdot, \cdot)\) in the optimization problem above is the Euclidean distance). If one wants to use another ground metric, the code would then be:

from tslearn.metrics import dtw_path_from_metric
path, cost = dtw_path_from_metric(x, y, metric=compatible_metric)

in which case the optimization problem that would be solved would be:

\[DTW(x, y) = \min_\pi \sum_{(i, j) \in \pi} \tilde{d}(x_i, y_j)\]

where \(\tilde{d}(\cdot, \cdot)\) is the user-defined ground metric, denoted compatible_metric in the code snippet above.

Properties

Dynamic Time Warping holds the following properties:

  • \(\forall x, y, DTW(x, y) \geq 0\)

  • \(\forall x, DTW(x, x) = 0\)

However, mathematically speaking, DTW is not a valid distance since it does not satisfy the triangular inequality.

Additional constraints

The set of temporal deformations to which DTW is invariant can be reduced by setting additional constraints on the set of acceptable paths. These constraints typically consists in forcing paths to lie close to the diagonal.

First, the Sakoe-Chiba band is parametrized by a radius \(r\) (number of off-diagonal elements to consider, also called warping window size sometimes), as illustrated below:

_images/sakoe_chiba.png

\(n = m = 10, r = 3\). Diagonal is marked in grey for better readability.

The corresponding code would be:

from tslearn.metrics import dtw
cost = dtw(x, y, global_constraint="sakoe_chiba", sakoe_chiba_radius=3)

Second, the Itakura parallelogram sets a maximum slope \(s\) for alignment paths, which leads to a parallelogram-shaped constraint:

_images/itakura.png

\(n = m = 10, s = 2\). Diagonal is marked in grey for better readability.

The corresponding code would be:

from tslearn.metrics import dtw
cost = dtw(x, y, global_constraint="itakura", itakura_max_slope=2.)

Alternatively, one can put an upper bound on the warping path length so as to discard complex paths, as described in [2]:

from tslearn.metrics import dtw_limited_warping_length
cost = dtw_limited_warping_length(x, y, max_length)

Barycenters

Computing barycenter (also known as Fréchet means) of a set \(\mathcal{D}\) for DTW corresponds to the following optimization problem:

\[\min_\mu \sum_{x \in \mathcal{D}} DTW(\mu, x)^2\]

Optimizing this quantity can be done through the DTW Barycenter Averaging (DBA) algorithm presented in [3].

from tslearn.barycenters import dtw_barycenter_averaging
b = dtw_barycenter_averaging(dataset)

This is the algorithm at stake when invoking tslearn.clustering.TimeSeriesKMeans with metric="dtw".

soft-DTW

DTW is not differentiable with respect to its inputs because of the non-differentiability of the min operation. A differentiable extension has been presented in [4] in which the min operator is replaced by soft-min, using the log-sum-exp formulation:

\[\text{soft-min}_\gamma(a_1, \dots, a_n) = - \gamma \log \sum_i e^{-a_i / \gamma}\]

soft-DTW hence depends on a hyper-parameter \(\gamma\) that controls the smoothing of the resulting metric (squared DTW corresponds to the limit case \(\gamma \rightarrow 0\)).

from tslearn.metrics import soft_dtw
soft_dtw_score = soft_dtw(x, y, gamma=.1)

When a strictly positive value is set for \(\gamma\), the corresponding alignment matrix corresponds to a blurred version of the DTW one:

_images/softdtw_alignment.png

Also, barycenters for soft-DTW can be estimated through gradient descent:

from tslearn.barycenters import softdtw_barycenter
b = softdtw_barycenter(dataset, gamma=.1)

This is the algorithm at stake when invoking tslearn.clustering.TimeSeriesKMeans with metric="softdtw".

Examples Involving DTW variants

Longest Common Subsequence

Longest Common Subsequence

Canonical Time Warping

Canonical Time Warping

Dynamic Time Warping

Dynamic Time Warping

Soft Dynamic Time Warping

Soft Dynamic Time Warping

DTW computation with a custom distance metric

DTW computation with a custom distance metric

Barycenters

Barycenters

Soft-DTW weighted barycenters

Soft-DTW weighted barycenters

References

Longest Common Subsequence

Longest Common Subsequence (LCSS) [1] is a similarity measure between time series. Let us consider two time series \(x = (x_0, \dots, x_{n-1})\) and \(y = (y_0, \dots, y_{m-1})\) of respective lengths \(n\) and \(m\). Here, all elements \(x_i\) and \(y_j\) are assumed to lie in the same \(d\)-dimensional space. In tslearn, such time series would be represented as arrays of respective shapes (n, d) and (m, d) and LCSS can be computed using the following code:

from tslearn.metrics import lcss, lcss_path

lcss_score = lcss(x, y)
# Or, if the path is also an important information:
path, lcss_score = lcss_path(x, y)

Problem

The similarity \(S\) between \(x\) and \(y\), given a positive real number \(\epsilon\), is formulated as follows:

\[S(x, y, \epsilon) = \frac{LCSS_{\epsilon} (x, y)}{\min(n, m)}\]

The constant \(\epsilon\) is the matching threshold.

Here, a path can be seen as the parts of the time series where the Euclidean distance between them does not exceed a given threshold, i.e., they are close/similar.

To retrieve a meaningful similarity value from the length of the longest common subsequence, the percentage of that value regarding the length of the shortest time series is returned.

Algorithmic solution

There exists an \(O(n^2)\) algorithm to compute the solution for this problem (pseudo-code is provided for time series indexed from 1 for simplicity):

def lcss(x, y):
   # Initialization
   for i = 0..n
       C[i, 0] = 0
   for j = 0..m
       C[0, j] = 0

   # Main loop
   for i = 1..n
        for j = 1..m
            if dist(x_i, x_j) <= epsilon:
                C[i, j] = C[i-1, j-1] + 1
            else:
                C[i, j] = max(C[i, j-1], C[i-1, j])

   return C[n, m] / min(n, m)

Using a different ground metric

By default, tslearn uses squared Euclidean distance as the base metric (i.e. \(dist()\) in the problem above is the Euclidean distance). If one wants to use another ground metric, the code would then be:

from tslearn.metrics import lcss_path_from_metric
path, cost = lcss_path_from_metric(x, y, metric=compatible_metric)

Properties

The Longest Common Subsequence holds the following properties:

  • \(\forall x, y, LCSS(x, y) \in \left[0, 1\right]\)

  • \(\forall x, y, LCSS(x, y) = LCSS(y, x)\)

  • \(\forall x, LCSS(x, x) = 1\)

The values returned by LCSS range from 0 to 1, the value 1 being taken when the two time series completely match.

Additional constraints

One can set additional constraints to the set of acceptable paths. These constraints typically consists in forcing paths to lie close to the diagonal.

First, the Sakoe-Chiba band is parametrized by a radius \(r\) (number of off-diagonal elements to consider, also called warping window size sometimes), as illustrated below:

_images/sakoe_chiba.png

\(n = m = 10, r = 3\). Diagonal is marked in grey for better readability.

The corresponding code would be:

from tslearn.metrics import lcss
cost = lcss(x, y, global_constraint="sakoe_chiba", sakoe_chiba_radius=3)

The Sakoe-Chiba radius corresponds to the parameter \(\delta\) mentioned in [1], it controls how far in time we can go in order to match a given point from one time series to a point in another time series.

Second, the Itakura parallelogram sets a maximum slope \(s\) for alignment paths, which leads to a parallelogram-shaped constraint:

_images/itakura.png

\(n = m = 10, s = 2\). Diagonal is marked in grey for better readability.

The corresponding code would be:

from tslearn.metrics import lcss
cost = lcss(x, y, global_constraint="itakura", itakura_max_slope=2.)

Examples Involving LCSS variants

Longest Common Subsequence

Longest Common Subsequence

Longest Commom Subsequence with a custom distance metric

Longest Commom Subsequence with a custom distance metric

References

Kernel Methods

In the following, we will discuss the use of kernels to compare time series. A kernel \(k(\cdot, \cdot)\) is such that there exists an unknown map \(\Phi\) such that:

\[k(\mathbf{x}, \mathbf{y}) = \left\langle \Phi(\mathbf{x}), \Phi(\mathbf{y}) \right\rangle_{\mathcal{H}}\]

i.e. \(k(\cdot, \cdot)\) is the inner product between \(\mathbf{x}\) and \(\mathbf{y}\) in some (unknown) embedding space \(\mathcal{H}\). In practice, \(k(\mathbf{x}, \mathbf{y})\) will be large when \(\mathbf{x}\) and \(\mathbf{y}\) are similar and close to 0 when they are very dissimilar.

A large number of kernel methods from the machine learning literature rely on the so-called kernel trick, that consists in performing computations in the embedding space \(\mathcal{H}\) without ever actually performing any embedding. As an example, one can compute distance between \(\mathbf{x}\) and \(\mathbf{y}\) in \(\mathcal{H}\) via:

\[\begin{split}\| \Phi(\mathbf{x}) - \Phi(\mathbf{y})\|_\mathcal{H}^2 &= \left\langle \Phi(\mathbf{x}) - \Phi(\mathbf{y}), \Phi(\mathbf{x}) - \Phi(\mathbf{y}) \right\rangle_{\mathcal{H}} \\ &= \left\langle \Phi(\mathbf{x}), \Phi(\mathbf{x}) \right\rangle_{\mathcal{H}} + \left\langle \Phi(\mathbf{y}), \Phi(\mathbf{y}) \right\rangle_{\mathcal{H}} - 2 \left\langle \Phi(\mathbf{x}), \Phi(\mathbf{y}) \right\rangle_{\mathcal{H}} \\ &= k(\mathbf{x}, \mathbf{x}) + k(\mathbf{y}, \mathbf{y}) - 2 k(\mathbf{x}, \mathbf{y})\end{split}\]

Such computations are used, for example, in the kernel-\(k\)-means algorithm (see below).

Global Alignment Kernel

The Global Alignment Kernel (GAK) is a kernel that operates on time series.

It is defined, for a given bandwidth \(\sigma\), as:

\[k(\mathbf{x}, \mathbf{y}) = \sum_{\pi \in \mathcal{A}(\mathbf{x}, \mathbf{y})} \prod_{i=1}^{ | \pi | } \exp \left( - \frac{ \left\| x_{\pi_1(i)} - y_{\pi_2{j}} \right\|^2}{2 \sigma^2} \right)\]

where \(\mathcal{A}(\mathbf{x}, \mathbf{y})\) is the set of all possible alignments between series \(\mathbf{x}\) and \(\mathbf{y}\).

It is advised in [1] to set the bandwidth \(\sigma\) as a multiple of a simple estimate of the median distance of different points observed in different time-series of your training set, scaled by the square root of the median length of time-series in the set. This estimate is made available in tslearn through tslearn.metrics.sigma_gak:

from tslearn.metrics import gak, sigma_gak

sigma = sigma_gak(X)
k_01 = gak(X[0], X[1], sigma=sigma)

Note however that, on long time series, this estimate can lead to numerical overflows, which smaller values can avoid.

Finally, GAK is related to softDTW [3] through the following formula:

\[k(\mathbf{x}, \mathbf{y}) = \exp \left(- \frac{\text{softDTW}_\gamma(\mathbf{x}, \mathbf{y})}{\gamma} \right)\]

where \(\gamma\) is the hyper-parameter controlling softDTw smoothness, which is related to the bandwidth parameter of GAK through \(\gamma = 2 \sigma^2\).

Clustering and Classification

Kernel \(k\)-means [2] is a method that uses the kernel trick to implicitly perform \(k\)-means clustering in the embedding space associated to a kernel. This method is discussed in our User Guide section dedicated to clustering.

Kernels can also be used in classification settings. tslearn.svm offers implementations of Support Vector Machines (SVM) that accept GAK as a kernel. This implementation heavily relies on scikit-learn and libsvm. One implication is that predict_proba and predict_log_proba methods are computed based on cross-validation probability estimates, which has two main implications, as discussed in more details in scikit-learn’s user guide:

1. setting the constructor option probability to True makes the fit step longer since it then relies on an expensive five-fold cross-validation;

2. the probability estimates obtained through predict_proba may be inconsistent with the scores provided by decision_function and the predicted class output by predict.

Examples Using Kernel Methods

SVM and GAK

SVM and GAK

Kernel k-means

Kernel k-means

References

Time Series Clustering

Clustering is the task of grouping together similar objects. This task hence heavily relies on the notion of similarity one relies on.

The following Figure illustrates why choosing an adequate similarity function is key (code to reproduce is available in the Gallery of Examples).

_images/kmeans.svg

\(k\)-means clustering with Euclidean distance. Each subfigure represents series from a given cluster and their centroid (in red).

This Figure is the result of a \(k\)-means clustering that uses Euclidean distance as a base metric. One issue with this metric is that it is not invariant to time shifts, while the dataset at stake clearly holds such invariants.

\(k\)-means and Dynamic Time Warping

To overcome the previously illustrated issue, distance metrics dedicated to time series, such as Dynamic Time Warping (DTW), are required. As can be seen in the Figure below, the use of such metrics produce more meaningful results.

The tslearn.clustering module in tslearn offers an option to use DTW as the core metric in a \(k\)-means algorithm, which leads to better clusters and centroids:

_images/kmeans_dtw.svg

\(k\)-means clustering with Dynamic Time Warping. Each subfigure represents series from a given cluster and their centroid (in red).

First, clusters gather time series of similar shapes, which is due to the ability of Dynamic Time Warping (DTW) to deal with time shifts, as explained above. Second, cluster centers (aka centroids) are computed as the barycenters with respect to DTW, hence they allow to retrieve a sensible average shape whatever the temporal shifts in the cluster (see our dedicated User Guide section for more details on how these barycenters are computed).

In tslearn, clustering a time series dataset with \(k\)-means and a dedicated time series metric is as easy as

from tslearn.clustering import TimeSeriesKMeans

model = TimeSeriesKMeans(n_clusters=3, metric="dtw",
                         max_iter=10, random_state=seed)
model.fit(X_train)

where X_train is the considered unlabelled dataset of time series. The metric parameter can also be set to "softdtw" as an alternative time series metric (cf. our User Guide section on soft-DTW).

Kernel \(k\)-means and Time Series Kernels

Another option to deal with such time shifts is to rely on the kernel trick. Indeed, [1] introduces a positive semidefinite kernel for time series, inspired from DTW. Then, the kernel \(k\)-means algorithm [2], that is equivalent to a \(k\)-means that would operate in the Reproducing Kernel Hilbert Space associated to the chosen kernel, can be used:

_images/kernel_kmeans.svg

Kernel \(k\)-means clustering with Global Alignment Kernel. Each subfigure represents series from a given cluster.

A first significant difference (when compared to \(k\)-means) is that cluster centers are never computed explicitly, hence time series assignments to cluster are the only kind of information available once the clustering is performed.

Second, one should note that the clusters generated by kernel-\(k\)-means are phase dependent (see clusters 2 and 3 that differ in phase rather than in shape). This is because Global Alignment Kernel is not invariant to time shifts, as demonstrated in [3] for the closely related soft-DTW [4].

Examples Using Clustering Estimators

k-means

k-means

Kernel k-means

Kernel k-means

References

Shapelets

Shapelets are defined in [1] as “subsequences that are in some sense maximally representative of a class”. Informally, if we assume a binary classification setting, a shapelet is discriminant if it is present in most series of one class and absent from series of the other class. To assess the level of presence, one uses shapelet matches:

\[d(\mathbf{x}, \mathbf{s}) = \min_t \| \mathbf{x}_{t\rightarrow t+L} - \mathbf{s} \|_2\]

where \(L\) is the length (number of timestamps) of shapelet \(\mathbf{s}\) and \(\mathbf{x}_{t\rightarrow t+L}\) is the subsequence extracted from time series \(\mathbf{x}\) that starts at time index \(t\) and stops at \(t+L\). If the above-defined distance is small enough, then shapelet \(\textbf{s}\) is supposed to be present in time series \(\mathbf{x}\).

../_images/sphx_glr_plot_shapelet_locations_001.svg

The distance from a time series to a shapelet is done by sliding the shorter shapelet over the longer time series and calculating the point-wise distances. The minimal distance found is returned.

In a classification setting, the goal is then to find the most discriminant shapelets given some labeled time series data. Shapelets can be mined from the training set [1] or learned using gradient-descent.

Learning Time-series Shapelets

tslearn provides an implementation of “Learning Time-series Shapelets”, introduced in [2], that is an instance of the latter category. In Learning Shapelets, shapelets are learned such that time series represented in their shapelet-transform space (i.e. their distances to each of the shapelets) are linearly separable. A shapelet-transform representation of a time series \(\mathbf{x}\) given a set of shapelets \(\{\mathbf{s}_i\}_{i \leq k}\) is the feature vector: \([d(\mathbf{x}, \mathbf{s}_1), \cdots, d(\mathbf{x}, \mathbf{s}_k)]\). This is illustrated below with a two-dimensional example.

../_images/sphx_glr_plot_shapelet_distances_001.svg

An example of how time series are transformed into linearly separable distances.

In tslearn, in order to learn shapelets and transform timeseries to their corresponding shapelet-transform space, the following code can be used:

from tslearn.shapelets import LearningShapelets

model = LearningShapelets(n_shapelets_per_size={3: 2})
model.fit(X_train, y_train)
train_distances = model.transform(X_train)
test_distances = model.transform(X_test)
shapelets = model.shapelets_as_time_series_

A tslearn.shapelets.LearningShapelets model has several hyper-parameters, such as the maximum number of iterations and the batch size. One important hyper-parameters is the n_shapelets_per_size which is a dictionary where the keys correspond to the desired lengths of the shapelets and the values to the desired number of shapelets per length. When set to None, this dictionary will be determined by a heuristic. After creating the model, we can fit the optimal shapelets using our training data. After a fitting phase, the distances can be calculated using the transform function. Moreover, you can easily access the learned shapelets by using the shapelets_as_time_series_ attribute.

It is important to note that due to the fact that a technique based on gradient-descent is used to learn the shapelets, our model can be prone to numerical issues (e.g. exploding and vanishing gradients). For that reason, it is important to normalize your data. This can be done before passing the data to the fit and transform methods, by using our tslearn.preprocessing module but this can be done internally by the algorithm itself by setting the scale parameter.

Examples Involving Shapelet-based Estimators

Learning Shapelets

Learning Shapelets

Aligning discovered shapelets with timeseries

Aligning discovered shapelets with timeseries

Learning Shapelets: decision boundaries in 2D distance space

Learning Shapelets: decision boundaries in 2D distance space

References

Matrix Profile

The Matrix Profile, \(MP\), is a new time series that can be calculated based on an input time series \(T\) and a subsequence length \(m\). \(MP_i\) corresponds to the minimal distance from the query subsequence \(T_{i\rightarrow i+m}\) to any subsequence in \(T\) [1]. As the distance from the query subsequence to itself will be equal to zero, \(T_{i-\frac{m}{4}\rightarrow i+\frac{m}{4}}\) is considered as an exclusion zone. In order to construct the Matrix Profile, a distance profile which is similar to the distance calculation used to transform time series into their shapelet-transform space, is calculated for each subsequence, as illustrated below:

../_images/sphx_glr_plot_distance_and_matrix_profile_001.svg

For each segment, the distances to all subsequences of the time series are calculated and the minimal distance that does not correspond to the original location of the segment (where the distance is zero) is returned.

Implementation

The Matrix Profile implementation provided in tslearn uses numpy or wraps around STUMPY [2]. Three different versions are available:

  • numpy: a slow implementation

  • stump: a fast CPU version, which requires STUMPY to be installed

  • gpu_stump: the fastest version, which requires STUMPY to be installed and a GPU

Possible Applications

The Matrix Profile allows for many possible applications, which are well documented on the page created by the original authors [3]. Some of these applications include: motif and shapelet extraction, discord detection, earthquake detection, and many more.

Examples Involving Matrix Profile

Matrix Profile

Matrix Profile

Distance and Matrix Profiles

Distance and Matrix Profiles

References

Early Classification of Time Series

Early classification of time series is the task of performing a classification as early as possible for an incoming time series, and decision about when to trigger the decision is part of the prediction process.

Early Classification Cost Function

Dachraoui et al. [1] introduces a composite loss function for early classification of time series that balances earliness and accuracy.

The cost function is of the following form:

\[\mathcal{L}(\mathbf{x}_{\rightarrow t}, y, t, \boldsymbol{\theta}) = \mathcal{L}_c(\mathbf{x}_{\rightarrow t}, y, \boldsymbol{\theta}) + \alpha t\]

where \(\mathcal{L}_c(\cdot,\cdot,\cdot)\) is a classification loss and \(t\) is the time at which a decision is triggered by the system (\(\mathbf{x}_{\rightarrow t}\) is time series \(\mathbf{x}\) observed up to time \(t\)). In this setting, \(\alpha\) drives the tradeoff between accuracy and earliness and is supposed to be a hyper-parameter of the method.

The authors rely on (i) a clustering of the training time series and (ii) individual classifiers \(m_t(\cdot)\) trained at all possible timestamps, so as to be able to predict, at time \(t\), an expected cost for all future times \(t + \tau\) with \(\tau \geq 0\):

\[f_\tau(\mathbf{x}_{\rightarrow t}, y) = \sum_k \left[ P(C_k | \mathbf{x}_{\rightarrow t}) \sum_i \left( P(y=i | C_k) \left( \sum_{j \neq i} P_{t+\tau}(\hat{y} = j | y=i, C_k) \right) \right) \right] + \alpha t\]

where:

  • \(P(C_k | \mathbf{x}_{\rightarrow t})\) is a soft-assignment weight of \(\mathbf{x}_{\rightarrow t}\) to cluster \(C_k\);

  • \(P(y=i | C_k)\) is obtained from a contingency table that stores the number of training time series of each class in each cluster;

  • \(P_{t+\tau}(\hat{y} = j | y=i, C_k)\) is obtained through training time confusion matrices built on time series from cluster \(C_k\) using classifier \(m_{t+\tau}(\cdot)\).

At test time, if a series is observed up to time \(t\) and if, for all positive \(\tau\) we have \(f_\tau(\mathbf{x}_{\rightarrow t}, y) \geq f_0(\mathbf{x}_{\rightarrow t}, y)\), then a decision is made using classifier \(m_t(\cdot)\).

../_images/sphx_glr_plot_early_classification_002.svg

Early classification. At test time, prediction is made at a timestamp such that the expected earliness-accuracy is optimized, which can hence vary between time series.

To use this early classifier in tslearn, one can rely on the tslearn.early_classification.NonMyopicEarlyClassifier class:

from tslearn.early_classification import NonMyopicEarlyClassifier

early_clf = NonMyopicEarlyClassifier(n_clusters=3,
                                     cost_time_parameter=1e-3,
                                     lamb=1e2,
                                     random_state=0)
early_clf.fit(X_train, y_train)
preds, times = early_clf.predict_class_and_earliness(X_test)

where cost_time_parameter is the \(\alpha\) parameter presented above and lamb is a trade-off parameter for the soft-assignment of partial series to clusters \(P(C_k | \mathbf{x}_{\rightarrow t})\) (when lamb tends to infinity, the assignment tends to hard-assignment, and when lamb is set to 0, equal probabilities are obtained for all clusters).

Examples Involving Early Classification Estimators

Early Classification

Early Classification

References

API Reference

The complete tslearn project is automatically documented for every module.

tslearn.barycenters

The tslearn.barycenters module gathers algorithms for time series barycenter computation.

tslearn.clustering

The tslearn.clustering module gathers time series specific clustering algorithms.

tslearn.datasets

The tslearn.datasets module provides simplified access to standard time series datasets.

tslearn.early_classification

The tslearn.early_classification module gathers early classifiers for time series.

tslearn.generators

The tslearn.generators module gathers synthetic time series dataset generation routines.

tslearn.matrix_profile

The tslearn.matrix_profile module gathers methods for the computation of Matrix Profiles from time series.

tslearn.metrics

The tslearn.metrics module delivers time-series specific metrics to be used at the core of machine learning algorithms.

tslearn.neural_network

The tslearn.neural_network module contains multi-layer perceptron models for time series classification and regression.

tslearn.neighbors

The tslearn.neighbors module gathers nearest neighbor algorithms using time series metrics.

tslearn.piecewise

The tslearn.piecewise module gathers time series piecewise approximation algorithms.

tslearn.preprocessing

The tslearn.preprocessing module gathers time series scalers and resamplers.

tslearn.shapelets

The tslearn.shapelets module gathers Shapelet-based algorithms.

tslearn.svm

The tslearn.svm module contains Support Vector Classifier (SVC) and Support Vector Regressor (SVR) models for time series.

tslearn.utils

The tslearn.utils module includes various utilities.

Citing tslearn

If you use tslearn in a scientific publication, we would appreciate citations:

Bibtex entry:

@article{JMLR:v21:20-091,
  author  = {Romain Tavenard and Johann Faouzi and Gilles Vandewiele and
             Felix Divo and Guillaume Androz and Chester Holtz and
             Marie Payne and Roman Yurchak and Marc Ru{\ss}wurm and
             Kushal Kolar and Eli Woods},
  title   = {Tslearn, A Machine Learning Toolkit for Time Series Data},
  journal = {Journal of Machine Learning Research},
  year    = {2020},
  volume  = {21},
  number  = {118},
  pages   = {1-6},
  url     = {http://jmlr.org/papers/v21/20-091.html}
}