Skip to content

Commit

Permalink
used and modified aeon mini rocket
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramana-Raja committed Nov 27, 2024
1 parent 36a8e27 commit 00e8b89
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 10 deletions.
97 changes: 87 additions & 10 deletions aeon/clustering/_r_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from aeon.transformations.collection.convolution_based import MiniRocket

from aeon.clustering.base import BaseClusterer
from aeon.transformations.collection.convolution_based._minirocket import _fit_dilations,_quantiles,_fit_biases,_static_transform_uni,_static_transform_multi
from aeon.datasets import load_basic_motions
import multiprocessing
from numba import get_num_threads, set_num_threads

class RCluster(BaseClusterer):
"""Time series R Clustering implementation .
Expand Down Expand Up @@ -65,19 +69,90 @@ def __init__(self,
random_state: Optional[Union[int, RandomState]] = None,
max_iter=300,
n_jobs=-1):
self.n_jobs = n_jobs
self.n_kernels = num_kernels
self.max_dilations_per_kernel = max_dilations_per_kernel
self.num_cluster = n_clusters
self.n_init = n_init
self.random_state = random_state
self.max_iter = max_iter
self.mini_rocket = MiniRocket(n_kernels=num_kernels,
max_dilations_per_kernel=max_dilations_per_kernel,
n_jobs=n_jobs)
self.indices = np.array((
1, 3, 6, 1, 2, 7, 1, 2, 3, 0, 2, 3, 1, 4, 5, 0, 1, 3, 3, 5, 6, 0,
1, 2, 2, 5, 8, 1, 3, 7, 0, 1, 8, 4, 6, 7, 0, 1, 4, 3, 4, 6, 0, 4,
5, 2, 6, 7, 5, 6, 7, 0, 1, 6, 4, 5, 7, 4, 7, 8, 1, 6, 8, 0, 2, 6,
5, 6, 8, 2, 5, 7, 0, 1, 7, 0, 7, 8, 0, 3, 5, 0, 3, 7, 2, 3, 8, 2,
3, 4, 1, 4, 6, 3, 4, 5, 0, 3, 8, 4, 5, 8, 0, 4, 6, 1, 4, 8, 6, 7,
8, 4, 6, 8, 0, 3, 4, 1, 3, 4, 1, 5, 7, 1, 4, 7, 1, 2, 8, 0, 6, 7,
1, 6, 7, 1, 3, 5, 0, 1, 5, 0, 4, 8, 4, 5, 6, 0, 2, 5, 3, 5, 7, 0,
2, 4, 2, 6, 8, 2, 3, 7, 2, 5, 6, 2, 4, 8, 0, 2, 7, 3, 6, 8, 2, 3,
6, 3, 7, 8, 0, 5, 8, 1, 2, 6, 2, 3, 5, 1, 5, 8, 3, 6, 7, 3, 4, 7,
0, 4, 7, 3, 5, 8, 2, 4, 5, 1, 2, 5, 2, 7, 8, 2, 4, 6, 0, 5, 6, 3,
4, 8, 0, 6, 8, 2, 4, 7, 0, 2, 8, 0, 3, 6, 5, 7, 8, 1, 5, 6, 1, 2,
4, 0, 5, 7, 1, 3, 8, 1, 7, 8
), dtype = np.int32).reshape(84, 3)
self.fit = False
super().__init__()
def __get_parameterised_data(self,X):
_, n_channels, n_timepoints = X.shape
X = X.astype(np.float32)

dilations, num_features_per_dilation = _fit_dilations(n_timepoints, self.n_kernels , self.max_dilations_per_kernel)

num_features_per_kernel = np.sum(num_features_per_dilation)

quantiles = _quantiles(self.n_kernels * num_features_per_kernel)

#MODIFICATION
quantiles = np.random.permutation(quantiles)

n_dilations = len(dilations)
n_combinations = self.n_kernels * n_dilations
max_n_channels = min(n_channels, 9)
max_exponent = np.log2(max_n_channels + 1)
n_channels_per_combination = (
2 ** np.random.uniform(0, max_exponent, n_combinations)
).astype(np.int32)
channel_indices = np.zeros(n_channels_per_combination.sum(), dtype=np.int32)
n_channels_start = 0
for combination_index in range(n_combinations):
n_channels_this_combination = n_channels_per_combination[combination_index]
n_channels_end = n_channels_start + n_channels_this_combination
channel_indices[n_channels_start:n_channels_end] = np.random.choice(
n_channels, n_channels_this_combination, replace=False
)
n_channels_start = n_channels_end

biases = _fit_biases(X,
n_channels_per_combination,
channel_indices,
dilations,
num_features_per_dilation,
quantiles,
self.indices,
self.random_state,)

return (np.array([_],dtype=np.int32),np.array([_],dtype=np.int32), dilations, num_features_per_dilation, biases)
def __get_transformed_data(self,X):
X = X.astype(np.float32)
_, n_channels, n_timepoints = X.shape
prev_threads = get_num_threads()
if self.n_jobs < 1 or self.n_jobs > multiprocessing.cpu_count():
n_jobs = multiprocessing.cpu_count()
else:
n_jobs = self.n_jobs
set_num_threads(n_jobs)
if n_channels == 1:
X = X.squeeze(1)
X_ = _static_transform_uni(X, self.parameters, self.indices)
else:
X_ = _static_transform_multi(X, self.parameters, self.indices)
set_num_threads(prev_threads)
return X_

def _fit(self, X, y=None):
self.mini_rocket.fit(X=X)
transformed_data = self.mini_rocket.transform(X=X)
self.parameters = self.__get_parameterised_data(X)

transformed_data = self.__get_transformed_data(X=X)

sc = StandardScaler()
X_std = sc.fit_transform(transformed_data)
Expand All @@ -101,8 +176,9 @@ def _predict(self, X, y=None) -> np.ndarray:
if not self.fit:
raise ValueError("Data is not fitted. Please fit the model before using it.")

self.mini_rocket.fit(X=X)
transformed_data = self.mini_rocket.transform(X=X)
self.parameters = self.__get_parameterised_data(X)

transformed_data = self.__get_transformed_data(X=X)

sc = StandardScaler()
X_std = sc.fit_transform(transformed_data)
Expand All @@ -113,8 +189,9 @@ def _predict(self, X, y=None) -> np.ndarray:
return self._r_cluster.predict(transformed_data_pca)

def _fit_predict(self, X, y=None) -> np.ndarray:
self.mini_rocket.fit(X=X)
transformed_data = self.mini_rocket.transform(X=X)
self.parameters = self.__get_parameterised_data(X)

transformed_data = self.__get_transformed_data(X=X)

sc = StandardScaler()
X_std = sc.fit_transform(transformed_data)
Expand Down
34 changes: 34 additions & 0 deletions aeon/clustering/tests/test_r_cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Tests for time series R cluster."""

import numpy as np
import pytest

from aeon.clustering._r_cluster import RCluster
from aeon.datasets import load_basic_motions
from aeon.utils.validation._dependencies import _check_estimator_deps

expected_labels = [0, 2, 1, 2, 0]

expected_iters = 2

expected_results = [0, 0, 0, 0, 0]

@pytest.mark.skipif(
not _check_estimator_deps( RCluster, severity="none"),
reason="skip test if required soft dependencies not available",
)
def test_kernel_k_means():
"""Test implementation of R cluster."""
max_train = 5

X_train, y_train = load_basic_motions(split="train")
X_test, y_test = load_basic_motions(split="test")

r_cluster = RCluster( n_clusters=2)
r_cluster.fit(X_train[0:max_train])
test_shape_result = r_cluster.predict(X_test[0:max_train])


assert np.array_equal(test_shape_result, expected_results)
assert r_cluster.n_iter_ == expected_iters
assert np.array_equal( r_cluster.labels_, expected_labels)

0 comments on commit 00e8b89

Please sign in to comment.