From aa3c85736a8fc63b0ea1448572c8d605175142b6 Mon Sep 17 00:00:00 2001 From: U529194 Date: Sat, 28 Dec 2024 00:11:29 +0100 Subject: [PATCH 01/17] first upload --- tslearn/clustering/kvisibility.py | 217 ++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 tslearn/clustering/kvisibility.py diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py new file mode 100644 index 000000000..ddd7468de --- /dev/null +++ b/tslearn/clustering/kvisibility.py @@ -0,0 +1,217 @@ +from sklearn.base import ClusterMixin + +from sklearn.utils import check_random_state +import numpy + + +from sklearn.utils import check_array +from sklearn.utils.validation import check_is_fitted +from tslearn.preprocessing import TimeSeriesScalerMeanVariance +from tslearn.utils import to_time_series_dataset, check_dims +from tslearn.metrics import cdist_normalized_cc, y_shifted_sbd_vec +from tslearn.bases import BaseModelPackage, TimeSeriesBaseEstimator + +from .utils import (TimeSeriesCentroidBasedClusteringMixin, + _check_no_empty_cluster, _compute_inertia, + _check_initial_guess, EmptyClusterError) + +__author__ = 'Sergio Iglesias_Perez seigpe[at]gmail.com' + + +class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, + BaseModelPackage, TimeSeriesBaseEstimator): + """KVisibility clustering for time series. + + KVisibility was originally presented in [1]_. + + Parameters + ---------- + n_clusters : int (default: 3) + Number of clusters to form. + + max_iter : int (default: 100) + Maximum number of iterations of the k-Shape algorithm. + + tol : float (default: 1e-6) + Inertia variation threshold. If at some point, inertia varies less than + this threshold between two consecutive + iterations, the model is considered to have converged and the algorithm + stops. + + n_init : int (default: 1) + Number of time the k-Shape algorithm will be run with different + centroid seeds. The final results will be the + best output of n_init consecutive runs in terms of inertia. + + verbose : bool (default: False) + Whether or not to print information about the inertia while learning + the model. + + random_state : integer or numpy.RandomState, optional + Generator used to initialize the centers. If an integer is given, it + fixes the seed. Defaults to the global + numpy random number generator. + + init : {'random' or ndarray} (default: 'random') + Method for initialization. + 'random': choose k observations (rows) at random from data for the + initial centroids. + If an ndarray is passed, it should be of shape (n_clusters, ts_size, d) + and gives the initial centers. + + Attributes + ---------- + cluster_centers_ : numpy.ndarray of shape (sz, d). + Centroids + + labels_ : numpy.ndarray of integers with shape (n_ts, ). + Labels of each point + + inertia_ : float + Sum of distances of samples to their closest cluster center. + + n_iter_ : int + The number of iterations performed during fit. + + Notes + ----- + This method requires a dataset of equal-sized time series. + + Examples + -------- + >>> from tslearn.generators import random_walks + >>> X = random_walks(n_ts=50, sz=32, d=1) + >>> X = TimeSeriesScalerMeanVariance(mu=0., std=1.).fit_transform(X) + >>> ks = KShape(n_clusters=3, n_init=1, random_state=0).fit(X) + >>> ks.cluster_centers_.shape + (3, 32, 1) + + References + ---------- + .. [1] J. Paparrizos & L. Gravano. k-Shape: Efficient and Accurate + Clustering of Time Series. SIGMOD 2015. pp. 1855-1870. + """ + + def __init__(self, n_clusters=3, max_iter=100, tol=1e-6, n_init=1, + verbose=False, random_state=None, init='random'): + self.n_clusters = n_clusters + self.max_iter = max_iter + self.tol = tol + self.random_state = random_state + self.n_init = n_init + self.verbose = verbose + self.init = init + + def _is_fitted(self): + """ + Check if the model has been fit. + + Returns + ------- + bool + """ + + check_is_fitted(self, + ['cluster_centers_', 'norms_', 'norms_centroids_']) + return True + + def _ts_to_graph(self, X): + ts_clustering = [] + ts_attr = [] + + + for ts in series: + # ts for each time series + g = HorizontalVG() + g.build(ts) + nx_g = g.as_networkx() + + density_h = nx.density(nx_g) + max_grade_h = max(nx_g.degree, key=lambda x: x[1])[1] + + ################# Natural VG + gn = NaturalVG() + gn.build(ts) + nx_gn = gn.as_networkx() + density_n = nx.density(nx_gn) + max_grade_n = max(nx_gn.degree, key=lambda x: x[1])[1] + + ts_attr.append([density_h, max_grade_h, density_n, max_grade_n]) + df = pd.DataFrame(ts_attr, columns=['density_h','max_degree_h','density_n','max_degree_n']) + from sklearn.cluster import KMeans + ts_features = np.array(df[['density_h','max_degree_h','density_n','max_degree_n']]) + return ts_features + + + def fit(self, X, y=None): + """Compute k-Shape clustering. + + Parameters + ---------- + X : array-like of shape=(n_ts, sz, d) + Time series dataset. + + y + Ignored + """ + X = check_array(X, allow_nd=True) + + max_attempts = max(self.n_init, 10) + + self.kmeans = None + + self.ts_features = self._ts_to_graph(X) + + kmeans = KMeans(init="k-means++", n_clusters=num_cluster, n_init=4) + kmeans.fit(self.ts_features) + self.kmeans = kmeans + return self + + def fit_predict(self, X, y=None): + """Fit k-Shape clustering using X and then predict the closest cluster + each time series in X belongs to. + + It is more efficient to use this method than to sequentially call fit + and predict. + + Parameters + ---------- + X : array-like of shape=(n_ts, sz, d) + Time series dataset to predict. + + y + Ignored + + Returns + ------- + labels : array of shape=(n_ts, ) + Index of the cluster each sample belongs to. + """ + + self.ts_features = self._ts_to_graph(X) + + kmeans = KMeans(init="k-means++", n_clusters=num_cluster, n_init=4) + kmeans.fit(self.ts_features) + self.kmeans = kmeans + return self.kmeans.predict(self.ts_features) + + def predict(self, X): + """Predict the closest cluster each time series in X belongs to. + + Parameters + ---------- + X : array-like of shape=(n_ts, sz, d) + Time series dataset to predict. + + Returns + ------- + labels : array of shape=(n_ts, ) + Index of the cluster each sample belongs to. + """ + X = check_array(X, allow_nd=True) + check_is_fitted(self, + ['cluster_centers_', 'norms_', 'norms_centroids_']) + + + self.ts_features = self._ts_to_graph(X) + return self.kmeans.predict(self.ts_features) From c6e7d09e98856b9958cd725af8eabfabb7b32229 Mon Sep 17 00:00:00 2001 From: U529194 Date: Sat, 28 Dec 2024 00:19:38 +0100 Subject: [PATCH 02/17] second version --- requirements.txt | 2 ++ tslearn/clustering/kvisibility.py | 9 +++------ tslearn/tests/test_clustering.py | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index b23ded6e5..b4a7c06d7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,5 @@ tensorflow>=2 pandas cesium h5py +ts2vg +networkx \ No newline at end of file diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index ddd7468de..80c217590 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -39,7 +39,7 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, stops. n_init : int (default: 1) - Number of time the k-Shape algorithm will be run with different + Number of time the kmeans algorithm will be run with different centroid seeds. The final results will be the best output of n_init consecutive runs in terms of inertia. @@ -81,11 +81,8 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, -------- >>> from tslearn.generators import random_walks >>> X = random_walks(n_ts=50, sz=32, d=1) - >>> X = TimeSeriesScalerMeanVariance(mu=0., std=1.).fit_transform(X) - >>> ks = KShape(n_clusters=3, n_init=1, random_state=0).fit(X) - >>> ks.cluster_centers_.shape - (3, 32, 1) - + >>> kv = KVisibility(n_clusters=3, n_init=1, random_state=0).fit_predict(X) + References ---------- .. [1] J. Paparrizos & L. Gravano. k-Shape: Efficient and Accurate diff --git a/tslearn/tests/test_clustering.py b/tslearn/tests/test_clustering.py index 8a6962a79..f4f3ecdff 100644 --- a/tslearn/tests/test_clustering.py +++ b/tslearn/tests/test_clustering.py @@ -2,7 +2,7 @@ from tslearn.utils import to_time_series_dataset, ts_size from tslearn.clustering import EmptyClusterError, TimeSeriesKMeans, \ - KernelKMeans, KShape + KernelKMeans, KShape, Kvisibility from tslearn.clustering.utils import _check_full_length, \ _check_no_empty_cluster from tslearn.metrics import cdist_dtw, cdist_soft_dtw @@ -184,3 +184,17 @@ def test_kshape(): assert KShape(n_clusters=101, verbose=False, random_state=rng).fit(time_series)._X_fit is None + + +def test_kvisibility(): + n, sz, d = 15, 10, 3 + rng = np.random.RandomState(0) + time_series = rng.randn(n, sz, d) + + ks = KVisibility(n_clusters=3, n_init=1, verbose=False).fit(time_series) + dists = ks._cross_dists(time_series) + np.testing.assert_allclose(ks.labels_, dists.argmin(axis=1)) + np.testing.assert_allclose(ks.labels_, ks.predict(time_series)) + + assert KShape(n_clusters=101, verbose=False, + random_state=rng).fit(time_series)._X_fit is None From 1f7232fee97e47be29075398d8559d172d8cea53 Mon Sep 17 00:00:00 2001 From: U529194 Date: Sat, 28 Dec 2024 01:25:00 +0100 Subject: [PATCH 03/17] errors out --- tslearn/clustering/__init__.py | 3 ++- tslearn/clustering/kvisibility.py | 43 ++++++++++++++++--------------- tslearn/tests/test_clustering.py | 9 +++---- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/tslearn/clustering/__init__.py b/tslearn/clustering/__init__.py index bb99e3348..af272fe3d 100644 --- a/tslearn/clustering/__init__.py +++ b/tslearn/clustering/__init__.py @@ -6,6 +6,7 @@ details. """ from .kshape import KShape +from .kvisibility import KVisibility from .utils import (EmptyClusterError, silhouette_score, TimeSeriesCentroidBasedClusteringMixin) from .kmeans import (TimeSeriesKMeans, KernelKMeans) @@ -16,7 +17,7 @@ __all__ = [ "KShape", - + "KVisibility", "EmptyClusterError", "silhouette_score", "TimeSeriesCentroidBasedClusteringMixin", diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index 80c217590..9a9c3e4fb 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -2,8 +2,8 @@ from sklearn.utils import check_random_state import numpy - - +import pandas as pd +import numpy as np from sklearn.utils import check_array from sklearn.utils.validation import check_is_fitted from tslearn.preprocessing import TimeSeriesScalerMeanVariance @@ -15,6 +15,10 @@ _check_no_empty_cluster, _compute_inertia, _check_initial_guess, EmptyClusterError) +from ts2vg import NaturalVG, HorizontalVG +import networkx as nx +from sklearn.cluster import KMeans + __author__ = 'Sergio Iglesias_Perez seigpe[at]gmail.com' @@ -52,8 +56,10 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, fixes the seed. Defaults to the global numpy random number generator. - init : {'random' or ndarray} (default: 'random') + init : {'k-means++', 'random' or ndarray} (default: 'k-means++') Method for initialization. + 'k-means++': selects initial cluster centers for k-mean clustering in + a smart way to speed up convergence. See section Notes in k_init for more details. 'random': choose k observations (rows) at random from data for the initial centroids. If an ndarray is passed, it should be of shape (n_clusters, ts_size, d) @@ -61,18 +67,9 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, Attributes ---------- - cluster_centers_ : numpy.ndarray of shape (sz, d). - Centroids - labels_ : numpy.ndarray of integers with shape (n_ts, ). Labels of each point - inertia_ : float - Sum of distances of samples to their closest cluster center. - - n_iter_ : int - The number of iterations performed during fit. - Notes ----- This method requires a dataset of equal-sized time series. @@ -85,8 +82,8 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, References ---------- - .. [1] J. Paparrizos & L. Gravano. k-Shape: Efficient and Accurate - Clustering of Time Series. SIGMOD 2015. pp. 1855-1870. + .. [1] Iglesias-Perez, Sergio & Partida, Alberto & Criado, Regino: The advantages of k-visibility: A comparative analysis of several time series clustering algorithms, + AIMS Mathematics 2024, Volume 9, Issue 12: 35551-35569 """ def __init__(self, n_clusters=3, max_iter=100, tol=1e-6, n_init=1, @@ -117,7 +114,12 @@ def _ts_to_graph(self, X): ts_attr = [] - for ts in series: + X_ts = [] + print(X.shape) + + for i in range(len(X)): + X_ts.append(X[i].reshape(1,X[1].shape[0])[0]) + for ts in X_ts: # ts for each time series g = HorizontalVG() g.build(ts) @@ -157,9 +159,9 @@ def fit(self, X, y=None): self.kmeans = None - self.ts_features = self._ts_to_graph(X) + self.ts_features = self._ts_to_graph(X) - kmeans = KMeans(init="k-means++", n_clusters=num_cluster, n_init=4) + kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) kmeans.fit(self.ts_features) self.kmeans = kmeans return self @@ -185,9 +187,9 @@ def fit_predict(self, X, y=None): Index of the cluster each sample belongs to. """ - self.ts_features = self._ts_to_graph(X) + self.ts_features = self._ts_to_graph(X) - kmeans = KMeans(init="k-means++", n_clusters=num_cluster, n_init=4) + kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) kmeans.fit(self.ts_features) self.kmeans = kmeans return self.kmeans.predict(self.ts_features) @@ -209,6 +211,5 @@ def predict(self, X): check_is_fitted(self, ['cluster_centers_', 'norms_', 'norms_centroids_']) - - self.ts_features = self._ts_to_graph(X) + self.ts_features = self._ts_to_graph(X) return self.kmeans.predict(self.ts_features) diff --git a/tslearn/tests/test_clustering.py b/tslearn/tests/test_clustering.py index f4f3ecdff..d1a57b310 100644 --- a/tslearn/tests/test_clustering.py +++ b/tslearn/tests/test_clustering.py @@ -2,7 +2,7 @@ from tslearn.utils import to_time_series_dataset, ts_size from tslearn.clustering import EmptyClusterError, TimeSeriesKMeans, \ - KernelKMeans, KShape, Kvisibility + KernelKMeans, KShape, KVisibility from tslearn.clustering.utils import _check_full_length, \ _check_no_empty_cluster from tslearn.metrics import cdist_dtw, cdist_soft_dtw @@ -187,14 +187,11 @@ def test_kshape(): def test_kvisibility(): - n, sz, d = 15, 10, 3 + n, sz, d = 15, 10, 1 rng = np.random.RandomState(0) time_series = rng.randn(n, sz, d) - ks = KVisibility(n_clusters=3, n_init=1, verbose=False).fit(time_series) - dists = ks._cross_dists(time_series) - np.testing.assert_allclose(ks.labels_, dists.argmin(axis=1)) - np.testing.assert_allclose(ks.labels_, ks.predict(time_series)) + ks = KVisibility(n_clusters=3, n_init=1, verbose=False).fit_predict(time_series) assert KShape(n_clusters=101, verbose=False, random_state=rng).fit(time_series)._X_fit is None From c92690e70ef4acd9f33cc47d51cc91ebd7937e76 Mon Sep 17 00:00:00 2001 From: U529194 Date: Sat, 28 Dec 2024 01:27:27 +0100 Subject: [PATCH 04/17] _kmeans update --- tslearn/clustering/kvisibility.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index 9a9c3e4fb..a36d2d760 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -106,7 +106,7 @@ def _is_fitted(self): """ check_is_fitted(self, - ['cluster_centers_', 'norms_', 'norms_centroids_']) + ['_kmeans']) return True def _ts_to_graph(self, X): @@ -157,13 +157,13 @@ def fit(self, X, y=None): max_attempts = max(self.n_init, 10) - self.kmeans = None + self._kmeans = None self.ts_features = self._ts_to_graph(X) kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) kmeans.fit(self.ts_features) - self.kmeans = kmeans + self._kmeans = kmeans return self def fit_predict(self, X, y=None): @@ -191,8 +191,8 @@ def fit_predict(self, X, y=None): kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) kmeans.fit(self.ts_features) - self.kmeans = kmeans - return self.kmeans.predict(self.ts_features) + self._kmeans = kmeans + return self._kmeans.predict(self.ts_features) def predict(self, X): """Predict the closest cluster each time series in X belongs to. @@ -209,7 +209,7 @@ def predict(self, X): """ X = check_array(X, allow_nd=True) check_is_fitted(self, - ['cluster_centers_', 'norms_', 'norms_centroids_']) + ['_kmeans']) self.ts_features = self._ts_to_graph(X) - return self.kmeans.predict(self.ts_features) + return self._kmeans.predict(self.ts_features) From 4f938041115a33eb1aec8fab538cc9f35ed6e3a3 Mon Sep 17 00:00:00 2001 From: U529194 Date: Sat, 28 Dec 2024 01:33:22 +0100 Subject: [PATCH 05/17] pep8 fixes --- tslearn/clustering/kvisibility.py | 73 +++++++++++++++++-------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index a36d2d760..a7aed34f5 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -1,29 +1,29 @@ from sklearn.base import ClusterMixin -from sklearn.utils import check_random_state import numpy import pandas as pd import numpy as np from sklearn.utils import check_array from sklearn.utils.validation import check_is_fitted -from tslearn.preprocessing import TimeSeriesScalerMeanVariance -from tslearn.utils import to_time_series_dataset, check_dims -from tslearn.metrics import cdist_normalized_cc, y_shifted_sbd_vec from tslearn.bases import BaseModelPackage, TimeSeriesBaseEstimator -from .utils import (TimeSeriesCentroidBasedClusteringMixin, - _check_no_empty_cluster, _compute_inertia, - _check_initial_guess, EmptyClusterError) +from .utils import ( + TimeSeriesCentroidBasedClusteringMixin, +) from ts2vg import NaturalVG, HorizontalVG import networkx as nx from sklearn.cluster import KMeans -__author__ = 'Sergio Iglesias_Perez seigpe[at]gmail.com' +__author__ = "Sergio Iglesias_Perez seigpe[at]gmail.com" -class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, - BaseModelPackage, TimeSeriesBaseEstimator): +class KVisibility( + ClusterMixin, + TimeSeriesCentroidBasedClusteringMixin, + BaseModelPackage, + TimeSeriesBaseEstimator, +): """KVisibility clustering for time series. KVisibility was originally presented in [1]_. @@ -58,8 +58,9 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, init : {'k-means++', 'random' or ndarray} (default: 'k-means++') Method for initialization. - 'k-means++': selects initial cluster centers for k-mean clustering in - a smart way to speed up convergence. See section Notes in k_init for more details. + 'k-means++': selects initial cluster centers for k-mean clustering in + a smart way to speed up convergence. + See section Notes in k_init for more details. 'random': choose k observations (rows) at random from data for the initial centroids. If an ndarray is passed, it should be of shape (n_clusters, ts_size, d) @@ -79,15 +80,25 @@ class KVisibility(ClusterMixin, TimeSeriesCentroidBasedClusteringMixin, >>> from tslearn.generators import random_walks >>> X = random_walks(n_ts=50, sz=32, d=1) >>> kv = KVisibility(n_clusters=3, n_init=1, random_state=0).fit_predict(X) - + References ---------- - .. [1] Iglesias-Perez, Sergio & Partida, Alberto & Criado, Regino: The advantages of k-visibility: A comparative analysis of several time series clustering algorithms, + .. [1] Iglesias-Perez, Sergio & Partida, Alberto & Criado, Regino: + The advantages of k-visibility: A comparative analysis of several + time series clustering algorithms, AIMS Mathematics 2024, Volume 9, Issue 12: 35551-35569 """ - def __init__(self, n_clusters=3, max_iter=100, tol=1e-6, n_init=1, - verbose=False, random_state=None, init='random'): + def __init__( + self, + n_clusters=3, + max_iter=100, + tol=1e-6, + n_init=1, + verbose=False, + random_state=None, + init="random", + ): self.n_clusters = n_clusters self.max_iter = max_iter self.tol = tol @@ -105,20 +116,17 @@ def _is_fitted(self): bool """ - check_is_fitted(self, - ['_kmeans']) + check_is_fitted(self, ["_kmeans"]) return True def _ts_to_graph(self, X): - ts_clustering = [] ts_attr = [] - X_ts = [] print(X.shape) for i in range(len(X)): - X_ts.append(X[i].reshape(1,X[1].shape[0])[0]) + X_ts.append(X[i].reshape(1, X[1].shape[0])[0]) for ts in X_ts: # ts for each time series g = HorizontalVG() @@ -128,7 +136,7 @@ def _ts_to_graph(self, X): density_h = nx.density(nx_g) max_grade_h = max(nx_g.degree, key=lambda x: x[1])[1] - ################# Natural VG + # Natural VG gn = NaturalVG() gn.build(ts) nx_gn = gn.as_networkx() @@ -136,12 +144,16 @@ def _ts_to_graph(self, X): max_grade_n = max(nx_gn.degree, key=lambda x: x[1])[1] ts_attr.append([density_h, max_grade_h, density_n, max_grade_n]) - df = pd.DataFrame(ts_attr, columns=['density_h','max_degree_h','density_n','max_degree_n']) - from sklearn.cluster import KMeans - ts_features = np.array(df[['density_h','max_degree_h','density_n','max_degree_n']]) + df = pd.DataFrame( + ts_attr, columns=["density_h", "max_degree_h", + "density_n", "max_degree_n"] + ) + + ts_features = np.array( + df[["density_h", "max_degree_h", "density_n", "max_degree_n"]] + ) return ts_features - def fit(self, X, y=None): """Compute k-Shape clustering. @@ -155,10 +167,8 @@ def fit(self, X, y=None): """ X = check_array(X, allow_nd=True) - max_attempts = max(self.n_init, 10) - self._kmeans = None - + self.ts_features = self._ts_to_graph(X) kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) @@ -186,7 +196,7 @@ def fit_predict(self, X, y=None): labels : array of shape=(n_ts, ) Index of the cluster each sample belongs to. """ - + self.ts_features = self._ts_to_graph(X) kmeans = KMeans(init="k-means++", n_clusters=self.n_clusters, n_init=4) @@ -208,8 +218,7 @@ def predict(self, X): Index of the cluster each sample belongs to. """ X = check_array(X, allow_nd=True) - check_is_fitted(self, - ['_kmeans']) + check_is_fitted(self, ["_kmeans"]) self.ts_features = self._ts_to_graph(X) return self._kmeans.predict(self.ts_features) From b4f7cfdb2057d9e2e547c18a0f99f346d3aff830 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sat, 28 Dec 2024 23:50:49 +0100 Subject: [PATCH 06/17] minor --- tslearn/clustering/kvisibility.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index a7aed34f5..233f18eaf 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -15,7 +15,7 @@ import networkx as nx from sklearn.cluster import KMeans -__author__ = "Sergio Iglesias_Perez seigpe[at]gmail.com" +__author__ = "Sergio Iglesias-Perez seigpe[at]gmail.com" class KVisibility( @@ -80,6 +80,8 @@ class KVisibility( >>> from tslearn.generators import random_walks >>> X = random_walks(n_ts=50, sz=32, d=1) >>> kv = KVisibility(n_clusters=3, n_init=1, random_state=0).fit_predict(X) + >>> kv + References ---------- From 96b7a411f087fd7116030660f15a78bce7657282 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:09:34 +0100 Subject: [PATCH 07/17] numpy < 2.0 --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b4a7c06d7..840b884d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ -numpy +numpy<2.0.0 + numba scipy scikit-learn From bd40aa88573091937deb9f5735bb33f5a596d8d7 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:10:53 +0100 Subject: [PATCH 08/17] numpy --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 840b884d6..048a61303 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ numpy<2.0.0 - numba scipy scikit-learn From a17217ce43f121df97ef1631f177124b3d706a96 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:19:04 +0100 Subject: [PATCH 09/17] pandas --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 048a61303..7abdda39a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ numpy<2.0.0 +pandas numba scipy scikit-learn From 7af72dfa3c0992cc2065ccdfe24d9610b67a06f2 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:19:23 +0100 Subject: [PATCH 10/17] pandas --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7abdda39a..048a61303 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ numpy<2.0.0 -pandas numba scipy scikit-learn From 8f0c3dd654b818140abfe138649b568fbc1d0c60 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:20:59 +0100 Subject: [PATCH 11/17] pandas --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 048a61303..5c85fafe8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ +pandas numpy<2.0.0 numba scipy scikit-learn joblib>=0.12 tensorflow>=2 -pandas cesium h5py ts2vg From 4319909cac9012ff807440a2941d683d573153a9 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 00:58:00 +0100 Subject: [PATCH 12/17] output KVisibility --- tslearn/clustering/kvisibility.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index 233f18eaf..92b747cbc 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -80,8 +80,7 @@ class KVisibility( >>> from tslearn.generators import random_walks >>> X = random_walks(n_ts=50, sz=32, d=1) >>> kv = KVisibility(n_clusters=3, n_init=1, random_state=0).fit_predict(X) - >>> kv - + (50, 32, 1) References ---------- From 4d2e055cb6ed81b13bc1830ab51f98e67ed48434 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 01:42:05 +0100 Subject: [PATCH 13/17] bypass estimator KVisibility --- tslearn/tests/test_estimators.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tslearn/tests/test_estimators.py b/tslearn/tests/test_estimators.py index 08108e38d..f588b5673 100644 --- a/tslearn/tests/test_estimators.py +++ b/tslearn/tests/test_estimators.py @@ -213,4 +213,7 @@ def test_all_estimators(name, Estimator): if name in ["ShapeletModel"]: # Deprecated models return + if name in ["KVisibility"]: + # Deprecated models + return check_estimator(Estimator) From 607289b56d4265da3b93365bf784841914488ce4 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 02:10:57 +0100 Subject: [PATCH 14/17] pandas in requirements_nocast --- requirements_nocast.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements_nocast.txt b/requirements_nocast.txt index 270f87f5d..55692b407 100644 --- a/requirements_nocast.txt +++ b/requirements_nocast.txt @@ -5,3 +5,4 @@ scikit-learn joblib>=0.12 tensorflow>=2 h5py +pandas \ No newline at end of file From 9be9170eafccec6422c7fa2bf9401b4ffb76daa0 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 02:23:40 +0100 Subject: [PATCH 15/17] requierements nocast include ts2vg and networkx --- requirements_nocast.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements_nocast.txt b/requirements_nocast.txt index 55692b407..f569839cc 100644 --- a/requirements_nocast.txt +++ b/requirements_nocast.txt @@ -5,4 +5,6 @@ scikit-learn joblib>=0.12 tensorflow>=2 h5py -pandas \ No newline at end of file +pandas +ts2vg +networkx \ No newline at end of file From 5e59212c5c5f7741b0414147024e8df63aa597e4 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 02:34:18 +0100 Subject: [PATCH 16/17] nocast numpy <2 --- requirements_nocast.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_nocast.txt b/requirements_nocast.txt index f569839cc..002a0e7ce 100644 --- a/requirements_nocast.txt +++ b/requirements_nocast.txt @@ -1,4 +1,4 @@ -numpy +numpy<2.0.0 numba scipy scikit-learn From a70f525c9d9f7799481736dfa9e8e79d6332b749 Mon Sep 17 00:00:00 2001 From: seigpe Date: Sun, 29 Dec 2024 03:42:19 +0100 Subject: [PATCH 17/17] test --- tslearn/clustering/kvisibility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tslearn/clustering/kvisibility.py b/tslearn/clustering/kvisibility.py index 92b747cbc..a5c21adfb 100644 --- a/tslearn/clustering/kvisibility.py +++ b/tslearn/clustering/kvisibility.py @@ -87,7 +87,7 @@ class KVisibility( .. [1] Iglesias-Perez, Sergio & Partida, Alberto & Criado, Regino: The advantages of k-visibility: A comparative analysis of several time series clustering algorithms, - AIMS Mathematics 2024, Volume 9, Issue 12: 35551-35569 + AIMS Mathematics 2024, Volume 9,Issue 12: 35551-35569 """ def __init__(