tslearn 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tslearn/.cached_datasets/Trace.npz +0 -0
- tslearn/.cached_datasets/singleTrainTest.csv +86 -0
- tslearn/__init__.py +15 -0
- tslearn/backend/__init__.py +43 -0
- tslearn/backend/backend.py +122 -0
- tslearn/backend/numpy_backend.py +141 -0
- tslearn/backend/pytorch_backend.py +265 -0
- tslearn/barycenters/__init__.py +36 -0
- tslearn/barycenters/dba.py +740 -0
- tslearn/barycenters/euclidean.py +44 -0
- tslearn/barycenters/softdtw.py +113 -0
- tslearn/barycenters/utils.py +13 -0
- tslearn/bases/__init__.py +3 -0
- tslearn/bases/bases.py +337 -0
- tslearn/clustering/__init__.py +24 -0
- tslearn/clustering/kmeans.py +930 -0
- tslearn/clustering/kshape.py +295 -0
- tslearn/clustering/utils.py +220 -0
- tslearn/datasets/__init__.py +14 -0
- tslearn/datasets/cached.py +87 -0
- tslearn/datasets/datasets.py +76 -0
- tslearn/datasets/ucr_uea.py +358 -0
- tslearn/early_classification/__init__.py +19 -0
- tslearn/early_classification/early_classification.py +589 -0
- tslearn/generators/__init__.py +8 -0
- tslearn/generators/generators.py +112 -0
- tslearn/hdftools/__init__.py +3 -0
- tslearn/hdftools/hdftools.py +150 -0
- tslearn/matrix_profile/__init__.py +15 -0
- tslearn/matrix_profile/matrix_profile.py +263 -0
- tslearn/metrics/__init__.py +74 -0
- tslearn/metrics/ctw.py +421 -0
- tslearn/metrics/cycc.py +140 -0
- tslearn/metrics/cysax.py +223 -0
- tslearn/metrics/dtw_variants.py +3058 -0
- tslearn/metrics/frechet.py +693 -0
- tslearn/metrics/sax.py +62 -0
- tslearn/metrics/soft_dtw_fast.py +365 -0
- tslearn/metrics/soft_dtw_loss_pytorch.py +242 -0
- tslearn/metrics/softdtw_variants.py +1153 -0
- tslearn/metrics/utils.py +106 -0
- tslearn/neighbors/__init__.py +16 -0
- tslearn/neighbors/neighbors.py +767 -0
- tslearn/neural_network/__init__.py +15 -0
- tslearn/neural_network/neural_network.py +230 -0
- tslearn/piecewise/__init__.py +14 -0
- tslearn/piecewise/piecewise.py +813 -0
- tslearn/preprocessing/__init__.py +18 -0
- tslearn/preprocessing/preprocessing.py +638 -0
- tslearn/shapelets/__init__.py +24 -0
- tslearn/shapelets/shapelets.py +976 -0
- tslearn/svm/__init__.py +10 -0
- tslearn/svm/svm.py +610 -0
- tslearn/utils/__init__.py +60 -0
- tslearn/utils/cast.py +758 -0
- tslearn/utils/utils.py +674 -0
- tslearn-0.7.0.dist-info/METADATA +190 -0
- tslearn-0.7.0.dist-info/RECORD +61 -0
- tslearn-0.7.0.dist-info/WHEEL +5 -0
- tslearn-0.7.0.dist-info/licenses/LICENSE +25 -0
- tslearn-0.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""The PyTorch backend.
|
|
2
|
+
|
|
3
|
+
Several backend functions are inspired from a python package about Machine Learning
|
|
4
|
+
in Riemannian manifolds named geomstats [JMLR:v21:19-027], also implementing several backends.
|
|
5
|
+
|
|
6
|
+
References
|
|
7
|
+
----------------
|
|
8
|
+
[JMLR:v21:19-027] Nina Miolane, Nicolas Guigui, Alice Le Brigant, Johan Mathe,
|
|
9
|
+
Benjamin Hou, Yann Thanwerdas, Stefan Heyder, Olivier Peltre, Niklas Koep, Hadi Zaatiti,
|
|
10
|
+
Hatem Hajri, Yann Cabanes, Thomas Gerald, Paul Chauchat, Christian Shewmake, Daniel Brooks,
|
|
11
|
+
Bernhard Kainz, Claire Donnat, Susan Holmes and Xavier Pennec.
|
|
12
|
+
Geomstats: A Python Package for Riemannian Geometry in Machine Learning,
|
|
13
|
+
Journal of Machine Learning Research, 2020, volume 21, number 223, pages 1-9,
|
|
14
|
+
http://jmlr.org/papers/v21/19-027.html, https://github.com/geomstats/geomstats/
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import numpy as _np
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
import torch as _torch
|
|
21
|
+
|
|
22
|
+
HAS_TORCH = True
|
|
23
|
+
except ImportError:
|
|
24
|
+
HAS_TORCH = False
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if not HAS_TORCH:
|
|
28
|
+
|
|
29
|
+
class PyTorchBackend:
|
|
30
|
+
def __init__(self):
|
|
31
|
+
raise ValueError(
|
|
32
|
+
"Could not use the PyTorch backend since torch is not installed"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
else:
|
|
36
|
+
|
|
37
|
+
class PyTorchBackend(object):
|
|
38
|
+
"""Class for the PyTorch backend."""
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
self.backend_string = "pytorch"
|
|
42
|
+
|
|
43
|
+
self.linalg = PyTorchLinalg()
|
|
44
|
+
self.random = PyTorchRandom()
|
|
45
|
+
self.testing = PyTorchTesting()
|
|
46
|
+
|
|
47
|
+
self.int8 = _torch.int8
|
|
48
|
+
self.int16 = _torch.int16
|
|
49
|
+
self.int32 = _torch.int32
|
|
50
|
+
self.int64 = _torch.int64
|
|
51
|
+
self.float32 = _torch.float32
|
|
52
|
+
self.float64 = _torch.float64
|
|
53
|
+
self.complex64 = _torch.complex64
|
|
54
|
+
self.complex128 = _torch.complex128
|
|
55
|
+
|
|
56
|
+
self.abs = _torch.abs
|
|
57
|
+
self.any = _torch.any
|
|
58
|
+
self.arange = _torch.arange
|
|
59
|
+
self.argmax = _torch.argmax
|
|
60
|
+
self.argmin = _torch.argmin
|
|
61
|
+
self.dbl_max = _torch.finfo(_torch.double).max
|
|
62
|
+
self.ceil = _torch.ceil
|
|
63
|
+
self.diag = _torch.diag
|
|
64
|
+
self.empty = _torch.empty
|
|
65
|
+
self.exp = _torch.exp
|
|
66
|
+
self.eye = _torch.eye
|
|
67
|
+
self.floor = _torch.floor
|
|
68
|
+
self.full = _torch.full
|
|
69
|
+
self.hstack = _torch.hstack
|
|
70
|
+
self.inf = _torch.inf
|
|
71
|
+
self.is_array = _torch.is_tensor
|
|
72
|
+
self.isfinite = _torch.isfinite
|
|
73
|
+
self.isnan = _torch.isnan
|
|
74
|
+
self.log = _torch.log
|
|
75
|
+
self.max = _torch.max
|
|
76
|
+
self.mean = _torch.mean
|
|
77
|
+
self.median = _torch.median
|
|
78
|
+
self.min = _torch.min
|
|
79
|
+
self.nan = _torch.nan
|
|
80
|
+
self.pairwise_euclidean_distances = _torch.cdist
|
|
81
|
+
self.reshape = _torch.reshape
|
|
82
|
+
self.round = _torch.round
|
|
83
|
+
self.sum = _torch.sum
|
|
84
|
+
self.vstack = _torch.vstack
|
|
85
|
+
self.zeros = _torch.zeros
|
|
86
|
+
self.zeros_like = _torch.zeros_like
|
|
87
|
+
|
|
88
|
+
@staticmethod
|
|
89
|
+
def all(x, axis=None):
|
|
90
|
+
if not _torch.is_tensor(x):
|
|
91
|
+
x = _torch.tensor(x)
|
|
92
|
+
if axis is None:
|
|
93
|
+
return x.bool().all()
|
|
94
|
+
if isinstance(axis, int):
|
|
95
|
+
return _torch.all(x.bool(), axis)
|
|
96
|
+
if len(axis) == 1:
|
|
97
|
+
return _torch.all(x, *axis)
|
|
98
|
+
axis = list(axis)
|
|
99
|
+
for i_axis, one_axis in enumerate(axis):
|
|
100
|
+
if one_axis < 0:
|
|
101
|
+
axis[i_axis] = x.ndim() + one_axis
|
|
102
|
+
new_axis = tuple(k - 1 if k >= 0 else k for k in axis[1:])
|
|
103
|
+
return all(_torch.all(x.bool(), axis[0]), new_axis)
|
|
104
|
+
|
|
105
|
+
def array(self, val, dtype=None):
|
|
106
|
+
if _torch.is_tensor(val):
|
|
107
|
+
if dtype is None or val.dtype == dtype:
|
|
108
|
+
return val.clone()
|
|
109
|
+
return self.cast(val, dtype=dtype)
|
|
110
|
+
|
|
111
|
+
elif isinstance(val, _np.ndarray):
|
|
112
|
+
tensor = self.from_numpy(val)
|
|
113
|
+
if dtype is not None and tensor.dtype != dtype:
|
|
114
|
+
tensor = self.cast(tensor, dtype=dtype)
|
|
115
|
+
|
|
116
|
+
return tensor
|
|
117
|
+
|
|
118
|
+
elif isinstance(val, (list, tuple)) and len(val):
|
|
119
|
+
tensors = [self.array(tensor, dtype=dtype) for tensor in val]
|
|
120
|
+
return _torch.stack(tensors)
|
|
121
|
+
|
|
122
|
+
return _torch.tensor(val, dtype=dtype)
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def belongs_to_backend(x):
|
|
126
|
+
return "torch" in str(type(x)).lower()
|
|
127
|
+
|
|
128
|
+
def cast(self, x, dtype):
|
|
129
|
+
if _torch.is_tensor(x):
|
|
130
|
+
return x.to(dtype=dtype)
|
|
131
|
+
return self.array(x, dtype=dtype)
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def cdist(x, y, metric="euclidean", p=None):
|
|
135
|
+
if metric == "euclidean":
|
|
136
|
+
return _torch.cdist(x, y)
|
|
137
|
+
if metric == "sqeuclidean":
|
|
138
|
+
return _torch.cdist(x, y) ** 2
|
|
139
|
+
if metric == "minkowski":
|
|
140
|
+
return _torch.cdist(x, y, p=p)
|
|
141
|
+
raise ValueError(f"Metric {metric} not implemented in PyTorch backend.")
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def copy(x):
|
|
145
|
+
return x.clone()
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def from_numpy(x):
|
|
149
|
+
return _torch.from_numpy(x)
|
|
150
|
+
|
|
151
|
+
@staticmethod
|
|
152
|
+
def iscomplex(x):
|
|
153
|
+
if isinstance(x, complex):
|
|
154
|
+
return True
|
|
155
|
+
return x.dtype.is_complex
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def is_float(x):
|
|
159
|
+
if isinstance(x, float):
|
|
160
|
+
return True
|
|
161
|
+
return x.dtype.is_floating_point
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def is_float32(x):
|
|
165
|
+
return isinstance(x, _torch.float32)
|
|
166
|
+
|
|
167
|
+
@staticmethod
|
|
168
|
+
def is_float64(x):
|
|
169
|
+
return isinstance(x, _torch.float64)
|
|
170
|
+
|
|
171
|
+
@staticmethod
|
|
172
|
+
def ndim(x):
|
|
173
|
+
return x.dim()
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def pairwise_distances(X, Y=None, metric="euclidean"):
|
|
177
|
+
if Y is None:
|
|
178
|
+
Y = X
|
|
179
|
+
if metric == "euclidean":
|
|
180
|
+
return _torch.cdist(X, Y)
|
|
181
|
+
if metric == "sqeuclidean":
|
|
182
|
+
return _torch.cdist(X, Y) ** 2
|
|
183
|
+
if callable(metric):
|
|
184
|
+
distance_matrix = _torch.zeros(X.shape[0], Y.shape[0])
|
|
185
|
+
for i in range(X.shape[0]):
|
|
186
|
+
for j in range(Y.shape[0]):
|
|
187
|
+
distance_matrix[i, j] = metric(X[i, ...], Y[j, ...])
|
|
188
|
+
return distance_matrix
|
|
189
|
+
raise ValueError(f"Metric {metric} not implemented in PyTorch backend.")
|
|
190
|
+
|
|
191
|
+
@staticmethod
|
|
192
|
+
def pdist(x, metric="euclidean", p=None):
|
|
193
|
+
if metric == "euclidean":
|
|
194
|
+
return _torch.pdist(x)
|
|
195
|
+
if metric == "sqeuclidean":
|
|
196
|
+
return _torch.pdist(x) ** 2
|
|
197
|
+
if metric == "minkowski":
|
|
198
|
+
return _torch.pdist(x, p=p)
|
|
199
|
+
raise ValueError(f"Metric {metric} not implemented in PyTorch backend.")
|
|
200
|
+
|
|
201
|
+
def shape(self, data):
|
|
202
|
+
if not self.is_array(data):
|
|
203
|
+
data = self.array(data)
|
|
204
|
+
return tuple(_torch.Tensor.size(data))
|
|
205
|
+
|
|
206
|
+
def sqrt(self, x, out=None):
|
|
207
|
+
if not self.is_array(x):
|
|
208
|
+
x = self.array(x)
|
|
209
|
+
return _torch.sqrt(x, out=out)
|
|
210
|
+
|
|
211
|
+
@staticmethod
|
|
212
|
+
def to_numpy(x):
|
|
213
|
+
return x.detach().cpu().numpy()
|
|
214
|
+
|
|
215
|
+
@staticmethod
|
|
216
|
+
def tril(mat, k=0):
|
|
217
|
+
return _torch.tril(mat, diagonal=k)
|
|
218
|
+
|
|
219
|
+
@staticmethod
|
|
220
|
+
def tril_indices(n, k=0, m=None):
|
|
221
|
+
if m is None:
|
|
222
|
+
m = n
|
|
223
|
+
x = _torch.tril_indices(row=n, col=m, offset=k)
|
|
224
|
+
return x[0], x[1]
|
|
225
|
+
|
|
226
|
+
@staticmethod
|
|
227
|
+
def triu(mat, k=0):
|
|
228
|
+
return _torch.triu(mat, diagonal=k)
|
|
229
|
+
|
|
230
|
+
@staticmethod
|
|
231
|
+
def triu_indices(n, k=0, m=None):
|
|
232
|
+
if m is None:
|
|
233
|
+
m = n
|
|
234
|
+
x = _torch.triu_indices(row=n, col=m, offset=k)
|
|
235
|
+
return x[0], x[1]
|
|
236
|
+
|
|
237
|
+
class PyTorchLinalg:
|
|
238
|
+
def __init__(self):
|
|
239
|
+
self.inv = _torch.linalg.inv
|
|
240
|
+
self.norm = _torch.linalg.norm
|
|
241
|
+
|
|
242
|
+
class PyTorchRandom:
|
|
243
|
+
def __init__(self):
|
|
244
|
+
self.rand = _torch.rand
|
|
245
|
+
self.randint = _torch.randint
|
|
246
|
+
self.randn = _torch.randn
|
|
247
|
+
|
|
248
|
+
@staticmethod
|
|
249
|
+
def normal(loc=0.0, scale=1.0, size=(1,)):
|
|
250
|
+
if not hasattr(size, "__iter__"):
|
|
251
|
+
size = (size,)
|
|
252
|
+
return _torch.normal(mean=loc, std=scale, size=size)
|
|
253
|
+
|
|
254
|
+
@staticmethod
|
|
255
|
+
def uniform(low=0.0, high=1.0, size=(1,), dtype=None):
|
|
256
|
+
if not hasattr(size, "__iter__"):
|
|
257
|
+
size = (size,)
|
|
258
|
+
if low >= high:
|
|
259
|
+
raise ValueError("Upper bound must be higher than lower bound")
|
|
260
|
+
return (high - low) * _torch.rand(*size, dtype=dtype) + low
|
|
261
|
+
|
|
262
|
+
class PyTorchTesting:
|
|
263
|
+
def __init__(self):
|
|
264
|
+
self.assert_allclose = _torch.allclose
|
|
265
|
+
self.assert_equal = _torch.testing.assert_close
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The :mod:`tslearn.barycenters` module gathers algorithms for time series
|
|
3
|
+
barycenter computation.
|
|
4
|
+
|
|
5
|
+
A barycenter (or *Fréchet mean*) is a time series :math:`b` which minimizes
|
|
6
|
+
the sum of squared distances to the time series of a given data set :math:`x`:
|
|
7
|
+
|
|
8
|
+
.. math:: \\min \\sum_i d( b, x_i )^2
|
|
9
|
+
|
|
10
|
+
Only the methods :func:`dtw_barycenter_averaging` and
|
|
11
|
+
:func:`softdtw_barycenter` can operate on variable-length time-series
|
|
12
|
+
(see :ref:`here<variable-length-barycenter>`).
|
|
13
|
+
|
|
14
|
+
See the :ref:`barycenter examples<sphx_glr_auto_examples_clustering_plot_barycenters.py>`
|
|
15
|
+
for an overview.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Code for soft DTW is by Mathieu Blondel under Simplified BSD license
|
|
19
|
+
|
|
20
|
+
from .utils import _set_weights
|
|
21
|
+
from .euclidean import euclidean_barycenter
|
|
22
|
+
from .dba import dtw_barycenter_averaging, \
|
|
23
|
+
dtw_barycenter_averaging_subgradient, dtw_barycenter_averaging_petitjean
|
|
24
|
+
from .softdtw import softdtw_barycenter
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__author__ = 'Romain Tavenard romain.tavenard[at]univ-rennes2.fr'
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"euclidean_barycenter",
|
|
31
|
+
|
|
32
|
+
"dtw_barycenter_averaging", "dtw_barycenter_averaging_subgradient",
|
|
33
|
+
"dtw_barycenter_averaging_petitjean",
|
|
34
|
+
|
|
35
|
+
"softdtw_barycenter"
|
|
36
|
+
]
|