From 1646895bc931f5e47553da51c1b533461cafb688 Mon Sep 17 00:00:00 2001 From: baraline Date: Wed, 4 Dec 2024 22:47:52 +0100 Subject: [PATCH 01/18] WIP remake module structure --- aeon/similarity_search/__init__.py | 6 +- aeon/similarity_search/_commons.py | 504 -------------- aeon/similarity_search/base.py | 209 ++---- .../distance_profiles/__init__.py | 18 - .../euclidean_distance_profile.py | 102 --- .../squared_distance_profile.py | 319 --------- .../distance_profiles/tests/__init__.py | 1 - .../tests/test_euclidean_distance.py | 208 ------ .../tests/test_squared_distance.py | 200 ------ .../matrix_profiles/__init__.py | 14 - .../matrix_profiles/stomp.py | 633 ------------------ .../matrix_profiles/tests/test_stomp.py | 205 ------ aeon/similarity_search/query_search.py | 428 ------------ aeon/similarity_search/series_search.py | 436 ------------ .../series_search/__init__.py | 7 + aeon/similarity_search/series_search/base.py | 22 + .../subsequence_search/__init__.py | 5 + .../subsequence_search/_brute_force.py | 284 ++++++++ .../subsequence_search/_commons.py | 138 ++++ .../subsequence_search/_stomp.py | 596 +++++++++++++++++ .../subsequence_search/base.py | 358 ++++++++++ .../tests/__init__.py | 0 .../subsequence_search/tests/test__commons.py | 64 ++ .../subsequence_search/tests/test_stomp.py | 238 +++++++ aeon/similarity_search/tests/test__commons.py | 49 -- .../tests/test_query_search.py | 176 ----- .../tests/test_series_search.py | 74 -- aeon/utils/numba/general.py | 3 + 28 files changed, 1785 insertions(+), 3512 deletions(-) delete mode 100644 aeon/similarity_search/_commons.py delete mode 100644 aeon/similarity_search/distance_profiles/__init__.py delete mode 100644 aeon/similarity_search/distance_profiles/euclidean_distance_profile.py delete mode 100644 aeon/similarity_search/distance_profiles/squared_distance_profile.py delete mode 100644 aeon/similarity_search/distance_profiles/tests/__init__.py delete mode 100644 aeon/similarity_search/distance_profiles/tests/test_euclidean_distance.py delete mode 100644 aeon/similarity_search/distance_profiles/tests/test_squared_distance.py delete mode 100644 aeon/similarity_search/matrix_profiles/__init__.py delete mode 100644 aeon/similarity_search/matrix_profiles/stomp.py delete mode 100644 aeon/similarity_search/matrix_profiles/tests/test_stomp.py delete mode 100644 aeon/similarity_search/query_search.py delete mode 100644 aeon/similarity_search/series_search.py create mode 100644 aeon/similarity_search/series_search/__init__.py create mode 100644 aeon/similarity_search/series_search/base.py create mode 100644 aeon/similarity_search/subsequence_search/__init__.py create mode 100644 aeon/similarity_search/subsequence_search/_brute_force.py create mode 100644 aeon/similarity_search/subsequence_search/_commons.py create mode 100644 aeon/similarity_search/subsequence_search/_stomp.py create mode 100644 aeon/similarity_search/subsequence_search/base.py rename aeon/similarity_search/{matrix_profiles => subsequence_search}/tests/__init__.py (100%) create mode 100644 aeon/similarity_search/subsequence_search/tests/test__commons.py create mode 100644 aeon/similarity_search/subsequence_search/tests/test_stomp.py delete mode 100644 aeon/similarity_search/tests/test__commons.py delete mode 100644 aeon/similarity_search/tests/test_query_search.py delete mode 100644 aeon/similarity_search/tests/test_series_search.py diff --git a/aeon/similarity_search/__init__.py b/aeon/similarity_search/__init__.py index f576c41f03..53f80b2cdf 100644 --- a/aeon/similarity_search/__init__.py +++ b/aeon/similarity_search/__init__.py @@ -1,7 +1,3 @@ """Similarity search module.""" -__all__ = ["BaseSimilaritySearch", "QuerySearch", "SeriesSearch"] - -from aeon.similarity_search.base import BaseSimilaritySearch -from aeon.similarity_search.query_search import QuerySearch -from aeon.similarity_search.series_search import SeriesSearch +__all__ = [] diff --git a/aeon/similarity_search/_commons.py b/aeon/similarity_search/_commons.py deleted file mode 100644 index 1d20a6a5b0..0000000000 --- a/aeon/similarity_search/_commons.py +++ /dev/null @@ -1,504 +0,0 @@ -"""Helper and common function for similarity search estimators and functions.""" - -__maintainer__ = ["baraline"] - -import warnings - -import numpy as np -from numba import njit, prange -from numba.typed import List -from scipy.signal import convolve - -from aeon.utils.numba.general import ( - get_all_subsequences, - normalise_subsequences, - sliding_mean_std_one_series, - z_normalise_series_2d, -) - - -@njit(cache=True, fastmath=True) -def _compute_dist_profile(X_subs, q): - """ - Compute the distance profile between subsequences and a query. - - Parameters - ---------- - X_subs : array, shape=(n_samples, n_channels, query_length) - Input subsequences extracted from a time series. - q : array, shape=(n_channels, query_length) - Query used for the distance computation - - Returns - ------- - dist_profile : np.ndarray, 1D array of shape (n_samples) - The distance between the query all subsequences. - - """ - n_candidates, n_channels, q_length = X_subs.shape - dist_profile = np.zeros(n_candidates) - for i in range(n_candidates): - for j in range(n_channels): - for k in range(q_length): - dist_profile[i] += (X_subs[i, j, k] - q[j, k]) ** 2 - return dist_profile - - -@njit(cache=True, fastmath=True) -def naive_squared_distance_profile( - X, - q, - mask, - normalise=False, - X_means=None, - X_stds=None, -): - """ - Compute a squared euclidean distance profile. - - Parameters - ---------- - X : array, shape=(n_samples, n_channels, n_timepoints) - Input time series dataset to search in. - q : array, shape=(n_channels, query_length) - Query used during the search. - mask : array, shape=(n_samples, n_timepoints - query_length + 1) - Boolean mask indicating candidates for which the distance - profiles computed for each query should be set to infinity. - normalise : bool - Wheter to use a z-normalised distance. - X_means : array, shape=(n_samples, n_channels, n_timepoints - query_length + 1) - Mean of each candidate (subsequence) of length query_length in X. The - default is None, meaning that these values will be computed if normalise - is True. If provided, the computations will be skipped. - X_stds : array, shape=(n_samples, n_channels, n_timepoints - query_length + 1) - Standard deviation of each candidate (subsequence) of length query_length - in X. The default is None, meaning that these values will be computed if - normalise is True. If provided, the computations will be skipped. - - Returns - ------- - out : np.ndarray, 1D array of shape (n_samples, n_timepoints_t - query_length + 1) - The distance between the query and all candidates in X. - - """ - query_length = q.shape[1] - dist_profiles = List() - # Init distance profile array with unequal length support - for i in range(len(X)): - dist_profiles.append(np.zeros(X[i].shape[1] - query_length + 1)) - if normalise: - q = z_normalise_series_2d(q) - else: - q = q.astype(np.float64) - for i in range(len(X)): - # Numba don't support strides with integers ? - - X_subs = get_all_subsequences(X[i].astype(np.float64), query_length, 1) - if normalise: - if X_means is None and X_stds is None: - _X_means, _X_stds = sliding_mean_std_one_series(X[i], query_length, 1) - else: - _X_means, _X_stds = X_means[i], X_stds[i] - X_subs = normalise_subsequences(X_subs, _X_means, _X_stds) - dist_profile = _compute_dist_profile(X_subs, q) - dist_profile[~mask[i]] = np.inf - dist_profiles[i] = dist_profile - return dist_profiles - - -@njit(cache=True, fastmath=True) -def naive_squared_matrix_profile(X, T, query_length, mask, normalise=False): - """ - Compute a squared euclidean matrix profile. - - Parameters - ---------- - X : array, shape=(n_samples, n_channels, n_timepoints_x) - Input time series dataset to search in. - T : array, shape=(n_channels, n_timepoints_t) - Time series from which queries are extracted. - query_length : int - Length of the queries to extract from T. - mask : array, shape=(n_samples, n_timepoints_x - query_length + 1) - Boolean mask indicating candidates for which the distance - profiles computed for each query should be set to infinity. - normalise : bool - Wheter to use a z-normalised distance. - - Returns - ------- - out : np.ndarray, 1D array of shape (n_timepoints_t - query_length + 1) - The minimum distance between each query in T and all candidates in X. - """ - X_subs = List() - for i in range(len(X)): - i_subs = get_all_subsequences(X[i].astype(np.float64), query_length, 1) - if normalise: - X_means, X_stds = sliding_mean_std_one_series(X[i], query_length, 1) - i_subs = normalise_subsequences(i_subs, X_means, X_stds) - X_subs.append(i_subs) - - n_candidates = T.shape[1] - query_length + 1 - mp = np.full(n_candidates, np.inf) - - for i in range(n_candidates): - q = T[:, i : i + query_length] - if normalise: - q = z_normalise_series_2d(q) - for id_sample in range(len(X)): - dist_profile = _compute_dist_profile(X_subs[id_sample], q) - dist_profile[~mask[id_sample]] = np.inf - mp[i] = min(mp[i], dist_profile.min()) - return mp - - -def fft_sliding_dot_product(X, q): - """ - Use FFT convolution to calculate the sliding window dot product. - - This function applies the Fast Fourier Transform (FFT) to efficiently compute - the sliding dot product between the input time series `X` and the query `q`. - The dot product is computed for each channel individually. The sliding window - approach ensures that the dot product is calculated for every possible subsequence - of `X` that matches the length of `q` - - Parameters - ---------- - X : array, shape=(n_channels, n_timepoints) - Input time series - q : array, shape=(n_channels, query_length) - Input query - - Returns - ------- - out : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - Sliding dot product between q and X. - """ - n_channels, n_timepoints = X.shape - query_length = q.shape[1] - out = np.zeros((n_channels, n_timepoints - query_length + 1)) - for i in range(n_channels): - out[i, :] = convolve(np.flipud(q[i, :]), X[i, :], mode="valid").real - return out - - -def get_ith_products(X, T, L, ith): - """ - Compute dot products between X and the i-th subsequence of size L in T. - - Parameters - ---------- - X : array, shape = (n_channels, n_timepoints_X) - Input data. - T : array, shape = (n_channels, n_timepoints_T) - Data containing the query. - L : int - Overall query length. - ith : int - Query starting index in T. - - Returns - ------- - np.ndarray, 2D array of shape (n_channels, n_timepoints_X - L + 1) - Sliding dot product between the i-th subsequence of size L in T and X. - - """ - return fft_sliding_dot_product(X, T[:, ith : ith + L]) - - -@njit(cache=True) -def numba_roll_1D_no_warparound(array, shift, warparound_value): - """ - Roll the rows of an array. - - Wheter to allow values at the end of the array to appear at the start after - being rolled out of the array length. - - Parameters - ---------- - array : np.ndarray of shape (n_columns) - Array to roll. - shift : int - The amount of indexes the values will be rolled on each row of the array. - Must be inferior or equal to n_columns. - warparound_value : any type - A value of the type of array to insert instead of the value that got rolled - over the array length - - Returns - ------- - rolled_array : np.ndarray of shape (n_rows, n_columns) - The rolled array. Can also be a TypedList in the case where n_columns changes - between rows. - - """ - length = array.shape[0] - _a1 = array[: length - shift] - array[shift:] = _a1 - array[:shift] = warparound_value - return array - - -@njit(cache=True) -def numba_roll_2D_no_warparound(array, shift, warparound_value): - """ - Roll the rows of an array. - - Wheter to allow values at the end of the array to appear at the start after - being rolled out of the array length. - - Parameters - ---------- - array : np.ndarray of shape (n_rows, n_columns) - Array to roll. Can also be a TypedList in the case where n_columns changes - between rows. - shift : int - The amount of indexes the values will be rolled on each row of the array. - Must be inferior or equal to n_columns. - warparound_value : any type - A value of the type of array to insert instead of the value that got rolled - over the array length - - Returns - ------- - rolled_array : np.ndarray of shape (n_rows, n_columns) - The rolled array. Can also be a TypedList in the case where n_columns changes - between rows. - - """ - for i in prange(len(array)): - length = len(array[i]) - _a1 = array[i][: length - shift] - array[i][shift:] = _a1 - array[i][:shift] = warparound_value - return array - - -@njit(cache=True) -def extract_top_k_and_threshold_from_distance_profiles_one_series( - distance_profiles, - id_x, - k=1, - threshold=np.inf, - exclusion_size=None, - inverse_distance=False, -): - """ - Extract the top-k smallest values from distance profiles and apply threshold. - - This function processes a distance profile and extracts the top-k smallest - distance values, optionally applying a threshold to exclude distances above - a given value. It also optionally handles exclusion zones to avoid selecting - neighboring timestamps. - - Parameters - ---------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) - Precomputed distance profile. Can be a TypedList if n_candidates vary between - cases. - id_x : int - Identifier of the series or subsequence from which the distance profile - is computed. - k : int - Number of matches to returns - threshold : float - All matches below this threshold will be returned - exclusion_size : int or None, optional, default=None - Size of the exclusion zone around the current subsequence. This prevents - selecting neighboring subsequences within the specified range, useful for - avoiding trivial matches in time series data. If set to `None`, no - exclusion zone is applied. - inverse_distance : bool, optional - Wheter to return the worst matches instead of the bests. The default is False. - - Returns - ------- - top_k_dist : np.ndarray - Array of the top-k smallest distance values, potentially excluding values above - the threshold or those within the exclusion zone. - top_k : np.ndarray - Array of shape (k, 2) where each row contains the `id_x` identifier and the - index of the corresponding subsequence (or timestamp) with the top-k smallest - distances. - """ - if inverse_distance: - # To avoid div by 0 case - distance_profiles += 1e-8 - distance_profiles[distance_profiles != np.inf] = ( - 1 / distance_profiles[distance_profiles != np.inf] - ) - - if threshold != np.inf: - distance_profiles[distance_profiles > threshold] = np.inf - - _argsort = np.argsort(distance_profiles) - - if distance_profiles[distance_profiles <= threshold].shape[0] < k: - _k = distance_profiles[distance_profiles <= threshold].shape[0] - elif _argsort.shape[0] < k: - _k = _argsort.shape[0] - else: - _k = k - - if exclusion_size is None: - indexes = np.zeros((_k, 2), dtype=np.int_) - for i in range(_k): - indexes[i, 0] = id_x - indexes[i, 1] = _argsort[i] - return distance_profiles[_argsort[:_k]], indexes - else: - # Apply exclusion zone to avoid neighboring matches - top_k = np.zeros((_k, 2), dtype=np.int_) - exclusion_size - top_k_dist = np.zeros((_k), dtype=np.float64) - - top_k[0, 0] = id_x - top_k[0, 1] = _argsort[0] - - top_k_dist[0] = distance_profiles[_argsort[0]] - - n_inserted = 1 - i_current = 1 - - while n_inserted < _k and i_current < _argsort.shape[0]: - candidate_timestamp = _argsort[i_current] - - insert = True - LB = candidate_timestamp >= (top_k[:, 1] - exclusion_size) - UB = candidate_timestamp <= (top_k[:, 1] + exclusion_size) - if np.any(UB & LB): - insert = False - - if insert: - top_k[n_inserted, 0] = id_x - top_k[n_inserted, 1] = _argsort[i_current] - top_k_dist[n_inserted] = distance_profiles[_argsort[i_current]] - n_inserted += 1 - i_current += 1 - return top_k_dist[:n_inserted], top_k[:n_inserted] - - -def extract_top_k_and_threshold_from_distance_profiles( - distance_profiles, - k=1, - threshold=np.inf, - exclusion_size=None, - inverse_distance=False, -): - """ - Extract the best matches from a distance profile given k and threshold parameters. - - Parameters - ---------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) - Precomputed distance profile. Can be a TypedList if n_candidates vary between - cases. - k : int - Number of matches to returns - threshold : float - All matches below this threshold will be returned - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - inverse_distance : bool, optional - Wheter to return the worst matches instead of the bests. The default is False. - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(n_matches)``, contains the distance between - the query and its best matches in X_. The second array, of shape - ``(n_matches, 2)``, contains the indexes of these matches as - ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - # This whole function could be optimized and maybe made in numba to avoid stepping - # out of numba mode during distance computations - - n_cases_ = len(distance_profiles) - - id_timestamps = np.concatenate( - [np.arange(distance_profiles[i].shape[0]) for i in range(n_cases_)] - ) - id_samples = np.concatenate( - [[i] * distance_profiles[i].shape[0] for i in range(n_cases_)] - ) - - distance_profiles = np.concatenate(distance_profiles) - - if inverse_distance: - # To avoid div by 0 case - distance_profiles += 1e-8 - distance_profiles[distance_profiles != np.inf] = ( - 1 / distance_profiles[distance_profiles != np.inf] - ) - - if threshold != np.inf: - distance_profiles[distance_profiles > threshold] = np.inf - - _argsort_1d = np.argsort(distance_profiles) - _argsort = np.asarray( - [ - [id_samples[_argsort_1d[i]], id_timestamps[_argsort_1d[i]]] - for i in range(len(_argsort_1d)) - ], - dtype=int, - ) - - if distance_profiles[distance_profiles <= threshold].shape[0] < k: - _k = distance_profiles[distance_profiles <= threshold].shape[0] - warnings.warn( - f"Only {_k} matches are bellow the threshold of {threshold}, while" - f" k={k}. The number of returned match will be {_k}.", - stacklevel=2, - ) - elif _argsort.shape[0] < k: - _k = _argsort.shape[0] - warnings.warn( - f"The number of possible match is {_argsort.shape[0]}, but got" - f" k={k}. The number of returned match will be {_k}.", - stacklevel=2, - ) - else: - _k = k - - if exclusion_size is None: - return distance_profiles[_argsort_1d[:_k]], _argsort[:_k] - else: - # Apply exclusion zone to avoid neighboring matches - top_k = np.zeros((_k, 2), dtype=int) - top_k_dist = np.zeros((_k), dtype=float) - - top_k[0] = _argsort[0, :] - top_k_dist[0] = distance_profiles[_argsort_1d[0]] - - n_inserted = 1 - i_current = 1 - - while n_inserted < _k and i_current < _argsort.shape[0]: - candidate_sample, candidate_timestamp = _argsort[i_current] - - insert = True - is_from_same_sample = top_k[:, 0] == candidate_sample - if np.any(is_from_same_sample): - LB = candidate_timestamp >= ( - top_k[is_from_same_sample, 1] - exclusion_size - ) - UB = candidate_timestamp <= ( - top_k[is_from_same_sample, 1] + exclusion_size - ) - if np.any(UB & LB): - insert = False - - if insert: - top_k[n_inserted] = _argsort[i_current] - top_k_dist[n_inserted] = distance_profiles[_argsort_1d[i_current]] - n_inserted += 1 - i_current += 1 - return top_k_dist[:n_inserted], top_k[:n_inserted] diff --git a/aeon/similarity_search/base.py b/aeon/similarity_search/base.py index 5b0ce8c555..8a9e9547d7 100644 --- a/aeon/similarity_search/base.py +++ b/aeon/similarity_search/base.py @@ -3,15 +3,13 @@ __maintainer__ = ["baraline"] from abc import abstractmethod -from collections.abc import Iterable -from typing import Optional, final +from typing import Optional, Union, final import numpy as np from numba import get_num_threads, set_num_threads from numba.typed import List from aeon.base import BaseCollectionEstimator -from aeon.utils.numba.general import sliding_mean_std_one_series class BaseSimilaritySearch(BaseCollectionEstimator): @@ -20,36 +18,10 @@ class BaseSimilaritySearch(BaseCollectionEstimator): Parameters ---------- - distance : str, default="euclidean" - Name of the distance function to use. A list of valid strings can be found in - the documentation for :func:`aeon.distances.get_distance_function`. - If a callable is passed it must either be a python function or numba function - with nopython=True, that takes two 1d numpy arrays as input and returns a float. - distance_args : dict, default=None - Optional keyword arguments for the distance function. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - normalise : bool, default=False - Whether the distance function should be z-normalised. - speed_up : str, default='fastest' - Which speed up technique to use with for the selected distance - function. By default, the fastest algorithm is used. A list of available - algorithm for each distance can be obtained by calling the - `get_speedup_function_names` function of the child classes. - n_jobs : int, default=1 - Number of parallel jobs to use. - - Attributes - ---------- - X_ : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input time series stored during the fit method. - - Notes - ----- - For now, the multivariate case is only treated as independent. - Distances are computed for each channel independently and then - summed together. + normalize : bool, optional + Whether the inputs should be z-normalized. The default is False. + n_jobs : int, optional + Number of parallel jobs to use. The default is 1. """ _tags = { @@ -63,30 +35,27 @@ class BaseSimilaritySearch(BaseCollectionEstimator): @abstractmethod def __init__( self, - distance: str = "euclidean", - distance_args: Optional[dict] = None, - inverse_distance: bool = False, - normalise: bool = False, - speed_up: str = "fastest", - n_jobs: int = 1, + normalize: Optional[bool] = False, + n_jobs: Optional[int] = 1, ): - self.distance = distance - self.distance_args = distance_args - self.inverse_distance = inverse_distance - self.normalise = normalise self.n_jobs = n_jobs - self.speed_up = speed_up + self.normalize = normalize super().__init__() @final - def fit(self, X: np.ndarray, y=None): + def fit( + self, + X: Union[np.ndarray, List], + y=None, + ): """ Fit method: data preprocessing and storage. Parameters ---------- X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Input array to be used as database for the similarity search + Input array to be used as database for the similarity search. If it is an + unequal length collection, it should be a list of 2d numpy arrays. y : optional Not used. @@ -113,120 +82,80 @@ def fit(self, X: np.ndarray, y=None): self.is_fitted = True return self - def _store_mean_std_from_inputs(self, query_length: int) -> None: + @abstractmethod + def find_motifs( + self, + k: int, + threshold: float, + X: Optional[np.ndarray] = None, + allow_overlap: Optional[bool] = True, + ): """ - Store the mean and std of each subsequence of size query_length in X_. + Find the top-k motifs in the training data. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif + sets. We define a motif set as a set of candidates which all are at a distance + of at most ``threshold`` from each other. The top-k motifs sets are the + motif sets with the most candidates. Parameters ---------- - query_length : int - Length of the query. + X : np.ndarray, optional + The query in which we want to indentify motifs. If provided, the motifs + extracted should appear in X and in the database given in fit. If not + provided, the motifs will be extracted only from the database given in fit. + k : int, optional + Number of motifs to return + threshold : int, optional + A threshold on the similarity measure to determine which candidates will be + part of a motif set. + allow_overlap: bool, optional + Wheter a candidate can be part of multiple motif sets (True), or if motif + sets should be mutually exclusive (False). Returns ------- - None + list of ndarray, shape=(k,) + A list of at most ``k`` numpy arrays containing the indexes of the + candidates in each motif. """ - means = [] - stds = [] - - for i in range(len(self.X_)): - _mean, _std = sliding_mean_std_one_series(self.X_[i], query_length, 1) - - stds.append(_std) - means.append(_mean) - - self.X_means_ = List(means) - self.X_stds_ = List(stds) + ... - def _init_X_index_mask( + @abstractmethod + def find_neighbors( self, - X_index: Optional[Iterable[int]], - query_length: int, - exclusion_factor: Optional[float] = 2.0, - ) -> np.ndarray: + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + ): """ - Initiliaze the mask indicating the candidates to be evaluated in the search. + Find the top-k neighbors of X in the database. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k + neighbors of X, such as each of the ``k`` neighbors as a distance inferior or + equal to ``threshold``. By default, ``threshold`` is set to infinity. It is + possible for this method to return less than ``k`` neighbors, either if there + is less than ``k`` admissible candidate in the database, or if in the top-k + candidates, some do not meet the ``threshold`` condition. Parameters ---------- - X_index : Iterable - Any Iterable (tuple, list, array) of length two used to specify the index of - the query X if it was extracted from the input data X given during the fit - method. Given the tuple (id_sample, id_timestamp), the similarity search - will define an exclusion zone around the X_index in order to avoid matching - X with itself. If None, it is considered that the query is not extracted - from X_ (the training data). - query_length : int - Length of the queries. - exclusion_factor : float, optional - The exclusion factor is used to prevent candidates close or equal to the - query sample point to be returned as best matches. It is used to define a - region between :math:`id_timestamp - query_length//exclusion_factor` and - :math:`id_timestamp + query_length//exclusion_factor` which cannot be used - in the search. The default is 2.0. - - Raises - ------ - ValueError - If the length of the q_index iterable is not two, will raise a ValueError. - TypeError - If q_index is not an iterable, will raise a TypeError. + X: np.ndarray + The query for which we want to identify nearest neighbors in the database. + k : int, optional + Number of neighbors to return. + threshold : int, optional + A threshold on the distance to determine which candidates will be returned. Returns ------- - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean array which indicates the candidates that should be evaluated in the - similarity search. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + candidates in each motif. """ - if self.metadata_["unequal_length"]: - mask = List( - [ - np.ones(self.X_[i].shape[1] - query_length + 1, dtype=bool) - for i in range(self.n_cases_) - ] - ) - else: - mask = np.ones( - (self.n_cases_, self.min_timepoints_ - query_length + 1), - dtype=bool, - ) - if X_index is not None: - if isinstance(X_index, Iterable): - if len(X_index) != 2: - raise ValueError( - "The X_index should contain an interable of size 2 such as " - "(id_sample, id_timestamp), but got an iterable of " - "size {}".format(len(X_index)) - ) - else: - raise TypeError( - "If not None, the X_index parameter should be an iterable, here " - "X_index is of type {}".format(type(X_index)) - ) - - if exclusion_factor <= 0: - raise ValueError( - "The value of exclusion_factor should be superior to 0, but got " - "{}".format(len(exclusion_factor)) - ) - - i_instance, i_timestamp = X_index - profile_length = self.X_[i_instance].shape[1] - query_length + 1 - exclusion_LB = max(0, int(i_timestamp - query_length // exclusion_factor)) - exclusion_UB = min( - profile_length, - int(i_timestamp + query_length // exclusion_factor), - ) - mask[i_instance][exclusion_LB:exclusion_UB] = False - - return mask + ... @abstractmethod def _fit(self, X, y=None): ... - - @abstractmethod - def get_speedup_function_names(self): - """Return a dictionnary containing the name of the speedup functions.""" - ... diff --git a/aeon/similarity_search/distance_profiles/__init__.py b/aeon/similarity_search/distance_profiles/__init__.py deleted file mode 100644 index 4be73f9d8e..0000000000 --- a/aeon/similarity_search/distance_profiles/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Distance profiles.""" - -__all__ = [ - "euclidean_distance_profile", - "normalised_euclidean_distance_profile", - "squared_distance_profile", - "normalised_squared_distance_profile", -] - - -from aeon.similarity_search.distance_profiles.euclidean_distance_profile import ( - euclidean_distance_profile, - normalised_euclidean_distance_profile, -) -from aeon.similarity_search.distance_profiles.squared_distance_profile import ( - normalised_squared_distance_profile, - squared_distance_profile, -) diff --git a/aeon/similarity_search/distance_profiles/euclidean_distance_profile.py b/aeon/similarity_search/distance_profiles/euclidean_distance_profile.py deleted file mode 100644 index 1dd781e467..0000000000 --- a/aeon/similarity_search/distance_profiles/euclidean_distance_profile.py +++ /dev/null @@ -1,102 +0,0 @@ -"""Optimized distance profile for euclidean distance.""" - -__maintainer__ = ["baraline"] - - -from typing import Union - -import numpy as np -from numba.typed import List - -from aeon.similarity_search.distance_profiles.squared_distance_profile import ( - normalised_squared_distance_profile, - squared_distance_profile, -) - - -def euclidean_distance_profile( - X: Union[np.ndarray, List], q: np.ndarray, mask: np.ndarray -) -> np.ndarray: - """ - Compute a distance profile using the squared Euclidean distance. - - It computes the distance profiles between the input time series and the query using - the squared Euclidean distance. The distance between the query and a candidate is - comptued using a dot product and a rolling sum to avoid recomputing parts of the - operation. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - of 2D arrays of shape (n_channels, n_timepoints) - q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - - Returns - ------- - distance_profiles : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between q and the input time series X. - - """ - distance_profiles = squared_distance_profile(X, q, mask) - # Need loop as we can return a list of np array in the unequal length case - for i in range(len(distance_profiles)): - distance_profiles[i] = distance_profiles[i] ** 0.5 - return distance_profiles - - -def normalised_euclidean_distance_profile( - X: Union[np.ndarray, List], - q: np.ndarray, - mask: np.ndarray, - X_means: Union[np.ndarray, List], - X_stds: Union[np.ndarray, List], - q_means: np.ndarray, - q_stds: np.ndarray, -) -> np.ndarray: - """ - Compute a distance profile in a brute force way. - - It computes the distance profiles between the input time series and the query using - the specified distance. The search is made in a brute force way without any - optimizations and can thus be slow. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - of 2D arrays of shape (n_channels, n_timepoints) - q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Means of each subsequences of X of size query_length. Should be a numba - TypedList if X is unequal length. - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Stds of each subsequences of X of size query_length. Should be a numba - TypedList if X is unequal length. - q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - q_stds : np.ndarray, 1D array of shape (n_channels) - - Returns - ------- - distance_profiles : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between q and the input time series X. - - """ - distance_profiles = normalised_squared_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - # Need loop as we can return a list of np array in the unequal length case - for i in range(len(distance_profiles)): - distance_profiles[i] = distance_profiles[i] ** 0.5 - return distance_profiles diff --git a/aeon/similarity_search/distance_profiles/squared_distance_profile.py b/aeon/similarity_search/distance_profiles/squared_distance_profile.py deleted file mode 100644 index a42beeac2f..0000000000 --- a/aeon/similarity_search/distance_profiles/squared_distance_profile.py +++ /dev/null @@ -1,319 +0,0 @@ -"""Optimized distance profile for euclidean distance.""" - -__maintainer__ = ["baraline"] - - -from typing import Union - -import numpy as np -from numba import njit, prange -from numba.typed import List - -from aeon.similarity_search._commons import fft_sliding_dot_product -from aeon.utils.numba.general import AEON_NUMBA_STD_THRESHOLD - - -def squared_distance_profile( - X: Union[np.ndarray, List], q: np.ndarray, mask: np.ndarray -) -> np.ndarray: - """ - Compute a distance profile using the squared Euclidean distance. - - It computes the distance profiles between the input time series and the query using - the squared Euclidean distance. The distance between the query and a candidate is - comptued using a dot product and a rolling sum to avoid recomputing parts of the - operation. - - Parameters - ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - 2D array of shape (n_channels, n_timepoints) - q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - - Returns - ------- - distance_profile : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between q and the input time series X. - - """ - QX = [fft_sliding_dot_product(X[i], q) for i in range(len(X))] - if isinstance(X, np.ndarray): - QX = np.asarray(QX) - elif isinstance(X, List): - QX = List(QX) - distance_profiles = _squared_distance_profile(QX, X, q, mask) - if isinstance(X, np.ndarray): - distance_profiles = np.asarray(distance_profiles) - return distance_profiles - - -def normalised_squared_distance_profile( - X: Union[np.ndarray, List], - q: np.ndarray, - mask: np.ndarray, - X_means: np.ndarray, - X_stds: np.ndarray, - q_means: np.ndarray, - q_stds: np.ndarray, -) -> np.ndarray: - """ - Compute a distance profile in a brute force way. - - It computes the distance profiles between the input time series and the query using - the specified distance. The search is made in a brute force way without any - optimizations and can thus be slow. - - Parameters - ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - 2D array of shape (n_channels, n_timepoints) - q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Means of each subsequences of X of size query_length - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Stds of each subsequences of X of size query_length - q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - q_stds : np.ndarray, 1D array of shape (n_channels) - Stds of the query q - - Returns - ------- - distance_profiles : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between q and the input time series X. - - """ - query_length = q.shape[1] - QX = [fft_sliding_dot_product(X[i], q) for i in range(len(X))] - if isinstance(X, np.ndarray): - QX = np.asarray(QX) - elif isinstance(X, List): - QX = List(QX) - - distance_profiles = _normalised_squared_distance_profile( - QX, mask, X_means, X_stds, q_means, q_stds, query_length - ) - if isinstance(X, np.ndarray): - distance_profiles = np.asarray(distance_profiles) - return distance_profiles - - -@njit(cache=True, fastmath=True, parallel=True) -def _squared_distance_profile(QX, X, q, mask): - """ - Compute squared distance profiles between query subsequence and time series. - - Parameters - ---------- - QX : List of np.ndarray - List of precomputed dot products between queries and time series, with each - element corresponding to a different time series. - Shape of each array is (n_channels, n_timepoints - query_length + 1). - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - 2D array of shape (n_channels, n_timepoints) - q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - - Returns - ------- - distance_profiles : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between q and the input time series X. - - """ - distance_profiles = List() - query_length = q.shape[1] - - # Init distance profile array with unequal length support - for i_instance in range(len(X)): - profile_length = X[i_instance].shape[1] - query_length + 1 - distance_profiles.append(np.full((profile_length), np.inf)) - - for _i_instance in prange(len(QX)): - # prange cast iterator to unit64 with parallel=True - i_instance = np.int_(_i_instance) - - distance_profiles[i_instance][mask[i_instance]] = ( - _squared_dist_profile_one_series(QX[i_instance], X[i_instance], q)[ - mask[i_instance] - ] - ) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _squared_dist_profile_one_series(QT, T, Q): - """ - Compute squared distance profile between query subsequence and a single time series. - - This function calculates the squared distance profile for a single time series by - leveraging the dot product of the query and time series as well as precomputed sums - of squares to efficiently compute the squared distances. - - Parameters - ---------- - QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - The dot product between the query and the time series. - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - Q : np.ndarray - 2D array of shape (n_channels, query_length) representing query subsequence. - - Returns - ------- - distance_profile : np.ndarray - 2D array of shape (n_channels, n_timepoints - query_length + 1) - The squared distance profile between the query and the input time series. - """ - n_channels, profile_length = QT.shape - query_length = Q.shape[1] - _QT = -2 * QT - distance_profile = np.zeros(profile_length) - for k in prange(n_channels): - _sum = 0 - _qsum = 0 - for j in prange(query_length): - _sum += T[k, j] ** 2 - _qsum += Q[k, j] ** 2 - - distance_profile += _qsum + _QT[k] - distance_profile[0] += _sum - for i in prange(1, profile_length): - _sum += T[k, i + (query_length - 1)] ** 2 - T[k, i - 1] ** 2 - distance_profile[i] += _sum - return distance_profile - - -@njit(cache=True, fastmath=True, parallel=True) -def _normalised_squared_distance_profile( - QX, mask, X_means, X_stds, q_means, q_stds, query_length -): - """ - Compute the normalised squared distance profiles between query subsequence and input time series. - - Parameters - ---------- - QX : List of np.ndarray - List of precomputed dot products between queries and time series, with each element - corresponding to a different time series. - Shape of each array is (n_channels, n_timepoints - query_length + 1). - mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Means of each subsequences of X of size query_length - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Stds of each subsequences of X of size query_length - q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - q_stds : np.ndarray, 1D array of shape (n_channels) - Stds of the query q - query_length : int - The length of the query subsequence used for the distance profile computation. - - Returns - ------- - List of np.ndarray - List of 2D arrays, each of shape (n_channels, n_timepoints - query_length + 1). - Each array contains the normalised squared distance profile between the query subsequence and the corresponding time series. - Entries in the array are set to infinity where the mask is False. - """ - distance_profiles = List() - Q_is_constant = q_stds <= AEON_NUMBA_STD_THRESHOLD - # Init distance profile array with unequal length support - for i_instance in range(len(QX)): - profile_length = QX[i_instance].shape[1] - distance_profiles.append(np.full((profile_length), np.inf)) - - for _i_instance in prange(len(QX)): - # prange cast iterator to unit64 with parallel=True - i_instance = np.int_(_i_instance) - - distance_profiles[i_instance][mask[i_instance]] = ( - _normalised_squared_dist_profile_one_series( - QX[i_instance], - X_means[i_instance], - X_stds[i_instance], - q_means, - q_stds, - query_length, - Q_is_constant, - )[mask[i_instance]] - ) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _normalised_squared_dist_profile_one_series( - QT, T_means, T_stds, Q_means, Q_stds, query_length, Q_is_constant -): - """ - Compute the z-normalised squared Euclidean distance profile for one time series. - - Parameters - ---------- - QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - The dot product between the query and the time series. - T_means : np.ndarray, 1D array of length n_channels - The mean values of the time series for each channel. - - T_stds : np.ndarray, 2D array of shape (n_channels, profile_length) - The standard deviations of the time series for each channel and position. - Q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - Q_stds : np.ndarray, 1D array of shape (n_channels) - Stds of the query q - query_length : int - The length of the query subsequence used for the distance profile computation. - Q_is_constant : np.ndarray - 1D array of shape (n_channels,) where each element is a Boolean indicating - whether the query standard deviation for that channel is less than or equal - to a specified threshold. - - Returns - ------- - np.ndarray - 2D array of shape (n_channels, n_timepoints - query_length + 1) containing the - z-normalised squared distance profile between the query subsequence and the time - series. Entries are computed based on the z-normalised values, with special - handling for constant values. - """ - n_channels, profile_length = QT.shape - distance_profile = np.zeros(profile_length) - - for i in prange(profile_length): - Sub_is_constant = T_stds[:, i] <= AEON_NUMBA_STD_THRESHOLD - for k in prange(n_channels): - # Two Constant case - if Q_is_constant[k] and Sub_is_constant[k]: - _val = 0 - # One Constant case - elif Q_is_constant[k] or Sub_is_constant[k]: - _val = query_length - else: - denom = query_length * Q_stds[k] * T_stds[k, i] - - p = (QT[k, i] - query_length * (Q_means[k] * T_means[k, i])) / denom - p = min(p, 1.0) - - _val = abs(2 * query_length * (1.0 - p)) - distance_profile[i] += _val - - return distance_profile diff --git a/aeon/similarity_search/distance_profiles/tests/__init__.py b/aeon/similarity_search/distance_profiles/tests/__init__.py deleted file mode 100644 index 566dda7367..0000000000 --- a/aeon/similarity_search/distance_profiles/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for distance profiles.""" diff --git a/aeon/similarity_search/distance_profiles/tests/test_euclidean_distance.py b/aeon/similarity_search/distance_profiles/tests/test_euclidean_distance.py deleted file mode 100644 index 2eafff78bb..0000000000 --- a/aeon/similarity_search/distance_profiles/tests/test_euclidean_distance.py +++ /dev/null @@ -1,208 +0,0 @@ -"""Tests for naive Euclidean distance profile.""" - -__maintainer__ = [] - - -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import assert_array_almost_equal, assert_array_equal - -from aeon.similarity_search._commons import naive_squared_distance_profile -from aeon.similarity_search.distance_profiles.euclidean_distance_profile import ( - euclidean_distance_profile, - normalised_euclidean_distance_profile, -) -from aeon.utils.numba.general import sliding_mean_std_one_series - -DATATYPES = ["float64", "int64"] - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_distance(dtype): - """Test Euclidean distance.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - expected = [T**0.5 for T in naive_squared_distance_profile(X, q, mask)] - dist_profile = euclidean_distance_profile(X, q, mask) - - assert_array_almost_equal(dist_profile, expected) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_constant_case(dtype): - """Test Euclidean distance profile calculation.""" - X = np.ones((2, 1, 10), dtype=dtype) - q = np.zeros((1, 3), dtype=dtype) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - expected = [T**0.5 for T in naive_squared_distance_profile(X, q, mask)] - dist_profile = euclidean_distance_profile(X, q, mask) - - assert_array_almost_equal(dist_profile, expected) - - -def test_non_alteration_of_inputs_euclidean(): - """Test if input is altered during Euclidean distance profile.""" - X = np.asarray([[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]]) - X_copy = np.copy(X) - q = np.asarray([[3, 4, 5]]) - q_copy = np.copy(q) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - _ = euclidean_distance_profile(X, q, mask) - assert_array_equal(q, q_copy) - assert_array_equal(X, X_copy) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_distance(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - - dist_profile = normalised_euclidean_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = [ - T**0.5 for T in naive_squared_distance_profile(X, q, mask, normalise=True) - ] - - assert_array_almost_equal(dist_profile, expected) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_distance_unequal_length(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = List( - [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6]], dtype=dtype), - ] - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - X_means = List() - X_stds = List() - - for i in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds.append(_std) - X_means.append(_mean) - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - mask = List( - [np.ones(X[i].shape[1] - q.shape[1] + 1, dtype=bool) for i in range(len(X))] - ) - - dist_profile = normalised_euclidean_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = [ - T**0.5 - for T in naive_squared_distance_profile( - X, q, mask, normalise=True, X_means=X_means, X_stds=X_stds - ) - ] - for i in range(len(X)): - assert_array_almost_equal(dist_profile[i], expected[i]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_distance_unequal_length(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = List( - [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6]], dtype=dtype), - ] - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - mask = List( - [np.ones(X[i].shape[1] - q.shape[1] + 1, dtype=bool) for i in range(len(X))] - ) - expected = [T**0.5 for T in naive_squared_distance_profile(X, q, mask)] - dist_profile = euclidean_distance_profile(X, q, mask) - for i in range(len(X)): - assert_array_almost_equal(dist_profile[i], expected[i]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_constant_case(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = np.ones((2, 2, 10), dtype=dtype) - q = np.zeros((2, 3), dtype=dtype) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - - dist_profile = normalised_euclidean_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = [ - T**0.5 for T in naive_squared_distance_profile(X, q, mask, normalise=True) - ] - - assert_array_almost_equal(dist_profile, expected) - - -def test_non_alteration_of_inputs_normalised_euclidean(): - """Test if input is altered during normalised Euclidean distance profile.""" - X = np.asarray([[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]]) - X_copy = np.copy(X) - q = np.asarray([[3, 4, 5]]) - q_copy = np.copy(q) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - _ = normalised_euclidean_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - - assert_array_equal(q, q_copy) - assert_array_equal(X, X_copy) diff --git a/aeon/similarity_search/distance_profiles/tests/test_squared_distance.py b/aeon/similarity_search/distance_profiles/tests/test_squared_distance.py deleted file mode 100644 index cdb7b35cbc..0000000000 --- a/aeon/similarity_search/distance_profiles/tests/test_squared_distance.py +++ /dev/null @@ -1,200 +0,0 @@ -"""Tests for naive Euclidean distance profile.""" - -__maintainer__ = [] - - -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import assert_array_almost_equal, assert_array_equal - -from aeon.similarity_search._commons import naive_squared_distance_profile -from aeon.similarity_search.distance_profiles.squared_distance_profile import ( - normalised_squared_distance_profile, - squared_distance_profile, -) -from aeon.utils.numba.general import sliding_mean_std_one_series - -DATATYPES = ["float64", "int64"] - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_distance(dtype): - """Test Euclidean distance.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - expected = naive_squared_distance_profile(X, q, mask) - dist_profile = squared_distance_profile(X, q, mask) - - assert_array_almost_equal(dist_profile, expected) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_constant_case(dtype): - """Test Euclidean distance profile calculation.""" - X = np.ones((2, 1, 10), dtype=dtype) - q = np.zeros((1, 3), dtype=dtype) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - expected = naive_squared_distance_profile(X, q, mask) - dist_profile = squared_distance_profile(X, q, mask) - - assert_array_almost_equal(dist_profile, expected) - - -def test_non_alteration_of_inputs_euclidean(): - """Test if input is altered during Euclidean distance profile.""" - X = np.asarray([[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]]) - X_copy = np.copy(X) - q = np.asarray([[3, 4, 5]]) - q_copy = np.copy(q) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - _ = squared_distance_profile(X, q, mask) - assert_array_equal(q, q_copy) - assert_array_equal(X, X_copy) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_distance(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - - dist_profile = normalised_squared_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = naive_squared_distance_profile(X, q, mask, normalise=True) - - assert_array_almost_equal(dist_profile, expected) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_distance_unequal_length(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = List( - [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6]], dtype=dtype), - ] - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - X_means = List() - X_stds = List() - - for i in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds.append(_std) - X_means.append(_mean) - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - mask = List( - [np.ones(X[i].shape[1] - q.shape[1] + 1, dtype=bool) for i in range(len(X))] - ) - - dist_profile = normalised_squared_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = naive_squared_distance_profile(X, q, mask, normalise=True) - for i in range(len(X)): - assert_array_almost_equal(dist_profile[i], expected[i]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_euclidean_distance_unequal_length(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = List( - [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6]], dtype=dtype), - ] - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - mask = List( - [np.ones(X[i].shape[1] - q.shape[1] + 1, dtype=bool) for i in range(len(X))] - ) - - expected = naive_squared_distance_profile(X, q, mask) - dist_profile = squared_distance_profile(X, q, mask) - for i in range(len(X)): - assert_array_almost_equal(dist_profile[i], expected[i]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_normalised_euclidean_constant_case(dtype): - """Test normalised Euclidean distance profile calculation.""" - X = np.ones((2, 2, 10), dtype=dtype) - q = np.zeros((2, 3), dtype=dtype) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - - dist_profile = normalised_squared_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - expected = naive_squared_distance_profile(X, q, mask, normalise=True) - - assert_array_almost_equal(dist_profile, expected) - - -def test_non_alteration_of_inputs_normalised_euclidean(): - """Test if input is altered during normalised Euclidean distance profile.""" - X = np.asarray([[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]]) - X_copy = np.copy(X) - q = np.asarray([[3, 4, 5]]) - q_copy = np.copy(q) - - search_space_size = X.shape[-1] - q.shape[-1] + 1 - - X_means = np.zeros((X.shape[0], X.shape[1], search_space_size)) - X_stds = np.zeros((X.shape[0], X.shape[1], search_space_size)) - - for i in range(X.shape[0]): - _mean, _std = sliding_mean_std_one_series(X[i], q.shape[-1], 1) - X_stds[i] = _std - X_means[i] = _mean - - q_means = q.mean(axis=-1) - q_stds = q.std(axis=-1) - - mask = np.ones((X.shape[0], X.shape[2] - q.shape[1] + 1), dtype=bool) - _ = normalised_squared_distance_profile( - X, q, mask, X_means, X_stds, q_means, q_stds - ) - - assert_array_equal(q, q_copy) - assert_array_equal(X, X_copy) diff --git a/aeon/similarity_search/matrix_profiles/__init__.py b/aeon/similarity_search/matrix_profiles/__init__.py deleted file mode 100644 index d04f1cbfd3..0000000000 --- a/aeon/similarity_search/matrix_profiles/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Distance profiles.""" - -__all__ = [ - "stomp_normalised_euclidean_matrix_profile", - "stomp_euclidean_matrix_profile", - "stomp_normalised_squared_matrix_profile", - "stomp_squared_matrix_profile", -] -from aeon.similarity_search.matrix_profiles.stomp import ( - stomp_euclidean_matrix_profile, - stomp_normalised_euclidean_matrix_profile, - stomp_normalised_squared_matrix_profile, - stomp_squared_matrix_profile, -) diff --git a/aeon/similarity_search/matrix_profiles/stomp.py b/aeon/similarity_search/matrix_profiles/stomp.py deleted file mode 100644 index 509e68ad49..0000000000 --- a/aeon/similarity_search/matrix_profiles/stomp.py +++ /dev/null @@ -1,633 +0,0 @@ -"""Implementation of stomp for euclidean and squared euclidean distance profile.""" - -from typing import Optional - -__maintainer__ = ["baraline"] - - -from typing import Union - -import numpy as np -from numba import njit -from numba.typed import List - -from aeon.similarity_search._commons import ( - extract_top_k_and_threshold_from_distance_profiles_one_series, - get_ith_products, - numba_roll_1D_no_warparound, -) -from aeon.similarity_search.distance_profiles.squared_distance_profile import ( - _normalised_squared_dist_profile_one_series, - _squared_dist_profile_one_series, -) -from aeon.utils.numba.general import AEON_NUMBA_STD_THRESHOLD - - -def stomp_euclidean_matrix_profile( - X: Union[np.ndarray, List], - T: np.ndarray, - L: int, - mask: np.ndarray, - k: int = 1, - threshold: float = np.inf, - inverse_distance: bool = False, - exclusion_size: Optional[int] = None, -): - """ - Compute a euclidean euclidean matrix profile using STOMP [1]_. - - This improves on the naive matrix profile by updating the dot products for each - sucessive query in T instead of recomputing them. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for the - first query of size L in T. This mask will be updated during the algorithm. - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - - References - ---------- - .. [1] Matrix Profile II: Exploiting a Novel Algorithm and GPUs to break the one - Hundred Million Barrier for Time Series Motifs and Joins. Yan Zhu, Zachary - Zimmerman, Nader Shakibay Senobari, Chin-Chia Michael Yeh, Gareth Funning, Abdullah - Mueen, Philip Berisk and Eamonn Keogh. IEEE ICDM 2016 - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - MP, IP = stomp_squared_matrix_profile( - X, - T, - L, - mask, - k=k, - threshold=threshold, - exclusion_size=exclusion_size, - inverse_distance=inverse_distance, - ) - for i in range(len(MP)): - MP[i] = MP[i] ** 0.5 - return MP, IP - - -def stomp_squared_matrix_profile( - X: Union[np.ndarray, List], - T: np.ndarray, - L: int, - mask: np.ndarray, - k: int = 1, - threshold: float = np.inf, - inverse_distance: bool = False, - exclusion_size: Optional[int] = None, -): - """ - Compute a squared euclidean matrix profile using STOMP [1]_. - - This improves on the naive matrix profile by updating the dot products for each - sucessive query in T instead of recomputing them. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for the - first query of size L in T. This mask will be updated during the algorithm. - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - - References - ---------- - .. [1] Matrix Profile II: Exploiting a Novel Algorithm and GPUs to break the one - Hundred Million Barrier for Time Series Motifs and Joins. Yan Zhu, Zachary - Zimmerman, Nader Shakibay Senobari, Chin-Chia Michael Yeh, Gareth Funning, Abdullah - Mueen, Philip Berisk and Eamonn Keogh. IEEE ICDM 2016 - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - XdotT = [get_ith_products(X[i], T, L, 0) for i in range(len(X))] - if isinstance(X, np.ndarray): - XdotT = np.asarray(XdotT) - elif isinstance(X, List): - XdotT = List(XdotT) - - MP, IP = _stomp( - X, - T, - XdotT, - L, - mask, - k, - threshold, - exclusion_size, - inverse_distance, - ) - return MP, IP - - -def stomp_normalised_euclidean_matrix_profile( - X: Union[np.ndarray, List], - T: np.ndarray, - L: int, - X_means: Union[np.ndarray, List], - X_stds: Union[np.ndarray, List], - T_means: np.ndarray, - T_stds: np.ndarray, - mask: np.ndarray, - k: int = 1, - threshold: float = np.inf, - inverse_distance: bool = False, - exclusion_size: Optional[int] = None, -): - """ - Compute a euclidean matrix profile using STOMP [1]_. - - This improves on the naive matrix profile by updating the dot products for each - sucessive query in T instead of recomputing them. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Means of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Stds of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - T_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Means of each subsequences of T of size L. - T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Stds of each subsequences of T of size L. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for the - first query of size L in T. This mask will be updated during the algorithm. - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - - References - ---------- - .. [1] Matrix Profile II: Exploiting a Novel Algorithm and GPUs to break the one - Hundred Million Barrier for Time Series Motifs and Joins. Yan Zhu, Zachary - Zimmerman, Nader Shakibay Senobari, Chin-Chia Michael Yeh, Gareth Funning, Abdullah - Mueen, Philip Berisk and Eamonn Keogh. IEEE ICDM 2016 - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - MP, IP = stomp_normalised_squared_matrix_profile( - X, - T, - L, - X_means, - X_stds, - T_means, - T_stds, - mask, - k=k, - threshold=threshold, - exclusion_size=exclusion_size, - inverse_distance=inverse_distance, - ) - for i in range(len(MP)): - MP[i] = MP[i] ** 0.5 - return MP, IP - - -def stomp_normalised_squared_matrix_profile( - X: Union[np.ndarray, List], - T: np.ndarray, - L: int, - X_means: Union[np.ndarray, List], - X_stds: Union[np.ndarray, List], - T_means: np.ndarray, - T_stds: np.ndarray, - mask: np.ndarray, - k: int = 1, - threshold: float = np.inf, - inverse_distance: bool = False, - exclusion_size: Optional[int] = None, -): - """ - Compute a squared euclidean matrix profile using STOMP [1]_. - - This improves on the naive matrix profile by updating the dot products for each - sucessive query in T instead of recomputing them. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Means of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Stds of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - T_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Means of each subsequences of T of size L. - T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Stds of each subsequences of T of size L. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for the - first query of size L in T. This mask will be updated during the algorithm. - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - - References - ---------- - .. [1] Matrix Profile II: Exploiting a Novel Algorithm and GPUs to break the one - Hundred Million Barrier for Time Series Motifs and Joins. Yan Zhu, Zachary - Zimmerman, Nader Shakibay Senobari, Chin-Chia Michael Yeh, Gareth Funning, Abdullah - Mueen, Philip Berisk and Eamonn Keogh. IEEE ICDM 2016 - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - XdotT = [get_ith_products(X[i], T, L, 0) for i in range(len(X))] - if isinstance(X, np.ndarray): - XdotT = np.asarray(XdotT) - elif isinstance(X, List): - XdotT = List(XdotT) - - MP, IP = _stomp_normalised( - X, - T, - XdotT, - X_means, - X_stds, - T_means, - T_stds, - L, - mask, - k, - threshold, - exclusion_size, - inverse_distance, - ) - return MP, IP - - -def _stomp_normalised( - X, - T, - XdotT, - X_means, - X_stds, - T_means, - T_stds, - L, - mask, - k, - threshold, - exclusion_size, - inverse_distance, -): - """ - Compute the Matrix Profile using the STOMP algorithm with normalised distances. - - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - Length of the subsequences used for the distance computation. - XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Precomputed dot products between each time series in X and the query series T. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Means of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Stds of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - T_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Means of each subsequences of T of size L. - T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Stds of each subsequences of T of size L. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for the - first query of size L in T. This mask will be updated during the algorithm. - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - - Returns - ------- - tuple of np.ndarray - - MP : array of shape (n_queries,) - Matrix profile distances for each query subsequence. - - IP : array of shape (n_queries,) - Indexes of the top matches for each query subsequence. - """ - n_queries = T.shape[1] - L + 1 - MP = np.empty(n_queries, dtype=object) - IP = np.empty(n_queries, dtype=object) - for i_x in range(len(X)): - for i in range(n_queries): - dist_profiles = _normalised_squared_dist_profile_one_series( - XdotT[i_x], - X_means[i_x], - X_stds[i_x], - T_means[:, i], - T_stds[:, i], - L, - T_stds[:, i] <= AEON_NUMBA_STD_THRESHOLD, - ) - dist_profiles[~mask[i_x]] = np.inf - if i + 1 < n_queries: - XdotT[i_x] = _update_dot_products_one_series( - X[i_x], T, XdotT[i_x], L, i + 1 - ) - - mask[i_x] = numba_roll_1D_no_warparound(mask[i_x], 1, True) - ( - top_dists, - top_indexes, - ) = extract_top_k_and_threshold_from_distance_profiles_one_series( - dist_profiles, - i_x, - k=k, - threshold=threshold, - exclusion_size=exclusion_size, - inverse_distance=inverse_distance, - ) - if i_x > 0: - top_dists, top_indexes = _sort_out_tops( - top_dists, MP[i], top_indexes, IP[i], k - ) - MP[i] = top_dists - IP[i] = top_indexes - else: - MP[i] = top_dists - IP[i] = top_indexes - - return MP, IP - - -def _stomp( - X, - T, - XdotT, - L, - mask, - k, - threshold, - exclusion_size, - inverse_distance, -): - n_queries = T.shape[1] - L + 1 - MP = np.empty(n_queries, dtype=object) - IP = np.empty(n_queries, dtype=object) - for i_x in range(len(X)): - for i in range(n_queries): - Q = T[:, i : i + L] - dist_profiles = _squared_dist_profile_one_series(XdotT[i_x], X[i_x], Q) - dist_profiles[~mask[i_x]] = np.inf - if i + 1 < n_queries: - XdotT[i_x] = _update_dot_products_one_series( - X[i_x], T, XdotT[i_x], L, i + 1 - ) - - mask[i_x] = numba_roll_1D_no_warparound(mask[i_x], 1, True) - ( - top_dists, - top_indexes, - ) = extract_top_k_and_threshold_from_distance_profiles_one_series( - dist_profiles, - i_x, - k=k, - threshold=threshold, - exclusion_size=exclusion_size, - inverse_distance=inverse_distance, - ) - if i_x > 0: - top_dists, top_indexes = _sort_out_tops( - top_dists, MP[i], top_indexes, IP[i], k - ) - MP[i] = top_dists - IP[i] = top_indexes - else: - MP[i] = top_dists - IP[i] = top_indexes - - return MP, IP - - -def _sort_out_tops(top_dists, prev_top_dists, top_indexes, prev_to_indexes, k): - """ - Sort and combine top distance results from previous and current computations. - - Parameters - ---------- - top_dists : np.ndarray - Array of distances from the current computation. Shape should be (n,). - prev_top_dists : np.ndarray - Array of distances from previous computations. Shape should be (n,). - top_indexes : np.ndarray - Array of indexes corresponding to the top distances from current computation. - Shape should be (n,). - prev_to_indexes : np.ndarray - Array of indexes corresponding to the top distances from previous computations. - Shape should be (n,). - k : int, default=1 - The number of best matches to return during predict for each subsequence. - - Returns - ------- - tuple - A tuple containing two elements: - - A 1D numpy array of sorted distances, of length min(k, - total number of distances). - - A 1D numpy array of indexes corresponding to the sorted distances, - of length min(k, total number of distances). - """ - all_dists = np.concatenate((prev_top_dists, top_dists)) - all_indexes = np.concatenate((prev_to_indexes, top_indexes)) - if k == np.inf: - return all_dists, all_indexes - else: - idx = np.argsort(all_dists)[:k] - return all_dists[idx], all_indexes[idx] - - -@njit(cache=True, fastmath=True) -def _update_dot_products_one_series( - X, - T, - XT_products, - L, - i_query, -): - """ - Update dot products of the i-th query of size L in T from the dot products of i-1. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Input time series on which the sliding dot product is computed. - T: np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - i_query : int - Query starting index in T. - - Returns - ------- - XT_products : np.ndarray of shape (n_cases, n_channels, n_timepoints - L + 1) - Sliding dot product between the i-th subsequence of size L in T and X. - - """ - n_channels = T.shape[0] - Q = T[:, i_query : i_query + L] - n_candidates = X.shape[1] - L + 1 - - for i_ft in range(n_channels): - # first element of all 0 to n-1 candidates * first element of previous query - _a1 = X[i_ft, : n_candidates - 1] * T[i_ft, i_query - 1] - # last element of all 1 to n candidates * last element of current query - _a2 = X[i_ft, L : L - 1 + n_candidates] * T[i_ft, i_query + L - 1] - - XT_products[i_ft, 1:] = XT_products[i_ft, :-1] - _a1 + _a2 - - # Compute first dot product - XT_products[i_ft, 0] = np.sum(Q[i_ft] * X[i_ft, :L]) - return XT_products diff --git a/aeon/similarity_search/matrix_profiles/tests/test_stomp.py b/aeon/similarity_search/matrix_profiles/tests/test_stomp.py deleted file mode 100644 index ffcf7d0b6a..0000000000 --- a/aeon/similarity_search/matrix_profiles/tests/test_stomp.py +++ /dev/null @@ -1,205 +0,0 @@ -"""Tests for stomp algorithm.""" - -__maintainer__ = ["baraline"] - -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import assert_almost_equal, assert_array_almost_equal, assert_equal - -from aeon.distances import get_distance_function -from aeon.similarity_search._commons import get_ith_products -from aeon.similarity_search.matrix_profiles.stomp import ( - _update_dot_products_one_series, - stomp_normalised_squared_matrix_profile, - stomp_squared_matrix_profile, -) -from aeon.utils.numba.general import sliding_mean_std_one_series - -DATATYPES = ["int64", "float64"] -K_VALUES = [1] - - -def test__update_dot_products_one_series(): - """Test the _update_dot_product function.""" - X = np.random.rand(1, 50) - T = np.random.rand(1, 25) - L = 10 - current_product = get_ith_products(X, T, L, 0) - for i_query in range(1, T.shape[1] - L + 1): - new_product = get_ith_products( - X, - T, - L, - i_query, - ) - current_product = _update_dot_products_one_series( - X, - T, - current_product, - L, - i_query, - ) - assert_array_almost_equal(new_product, current_product) - - -@pytest.mark.parametrize("dtype", DATATYPES) -@pytest.mark.parametrize("k", K_VALUES) -def test_stomp_squared_matrix_profile(dtype, k): - """Test stomp series search.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - - S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype) - L = 3 - mask = np.ones((X.shape[0], X.shape[2] - L + 1), dtype=bool) - distance = get_distance_function("squared") - mp, ip = stomp_squared_matrix_profile(X, S, L, mask, k=k) - for i in range(S.shape[-1] - L + 1): - q = S[:, i : i + L] - - expected = np.array( - [ - [distance(q, X[j, :, _i : _i + L]) for _i in range(X.shape[-1] - L + 1)] - for j in range(X.shape[0]) - ] - ) - id_bests = np.vstack( - np.unravel_index( - np.argsort(expected.ravel(), kind="stable"), expected.shape - ) - ).T - - for j in range(k): - assert_almost_equal(mp[i][j], expected[id_bests[j, 0], id_bests[j, 1]]) - assert_equal(ip[i][j], id_bests[j]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -@pytest.mark.parametrize("k", K_VALUES) -def test_stomp_normalised_squared_matrix_profile(dtype, k): - """Test stomp series search.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - - S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype) - L = 3 - mask = np.ones((X.shape[0], X.shape[2] - L + 1), dtype=bool) - distance = get_distance_function("squared") - X_means = [] - X_stds = [] - - for i in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i], L, 1) - - X_stds.append(_std) - X_means.append(_mean) - X_means = np.asarray(X_means) - X_stds = np.asarray(X_stds) - - S_means, S_stds = sliding_mean_std_one_series(S, L, 1) - - mp, ip = stomp_normalised_squared_matrix_profile( - X, S, L, X_means, X_stds, S_means, S_stds, mask, k=k - ) - - for i in range(S.shape[-1] - L + 1): - q = (S[:, i : i + L] - S_means[:, i]) / S_stds[:, i] - - expected = np.array( - [ - [ - distance( - q, - (X[j, :, _i : _i + L] - X_means[j, :, _i]) / X_stds[j, :, _i], - ) - for _i in range(X.shape[-1] - L + 1) - ] - for j in range(X.shape[0]) - ] - ) - id_bests = np.vstack( - np.unravel_index(np.argsort(expected.ravel()), expected.shape) - ).T - - for j in range(k): - assert_almost_equal(mp[i][j], expected[id_bests[j, 0], id_bests[j, 1]]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_stomp_squared_matrix_profile_unequal_length(dtype): - """Test stomp with unequal length.""" - X = List( - [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6]], dtype=dtype), - ] - ) - L = 3 - mask = List( - [ - np.ones(X[0].shape[1] - L + 1, dtype=bool), - np.ones(X[1].shape[1] - L + 1, dtype=bool), - ] - ) - S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype) - - distance = get_distance_function("squared") - mp, ip = stomp_squared_matrix_profile(X, S, L, mask) - - for i in range(S.shape[-1] - L + 1): - q = S[:, i : i + L] - - expected = [ - [ - distance(q, X[j][:, _i : _i + q.shape[-1]]) - for _i in range(X[j].shape[-1] - q.shape[-1] + 1) - ] - for j in range(len(X)) - ] - assert_almost_equal(mp[i][0], np.concatenate(expected).min()) - - -@pytest.mark.parametrize("dtype", DATATYPES) -@pytest.mark.parametrize("k", K_VALUES) -def test_stomp_squared_matrix_profile_inverse(dtype, k): - """Test stomp series search for inverse distance.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype) - L = 3 - mask = np.ones((X.shape[0], X.shape[2] - L + 1), dtype=bool) - distance = get_distance_function("squared") - mp, ip = stomp_squared_matrix_profile( - X, - S, - L, - mask, - k=k, - inverse_distance=True, - ) - - for i in range(S.shape[-1] - L + 1): - q = S[:, i : i + L] - - expected = np.array( - [ - [ - distance(q, X[j, :, _i : _i + q.shape[-1]]) - for _i in range(X.shape[-1] - q.shape[-1] + 1) - ] - for j in range(X.shape[0]) - ] - ) - expected += 1e-8 - expected = 1 / expected - id_bests = np.vstack( - np.unravel_index(np.argsort(expected.ravel()), expected.shape) - ).T - - for j in range(k): - assert_almost_equal(mp[i][j], expected[id_bests[j, 0], id_bests[j, 1]]) - assert_equal(ip[i][j], id_bests[j]) diff --git a/aeon/similarity_search/query_search.py b/aeon/similarity_search/query_search.py deleted file mode 100644 index 393439148d..0000000000 --- a/aeon/similarity_search/query_search.py +++ /dev/null @@ -1,428 +0,0 @@ -"""Base class for query search.""" - -__maintainer__ = ["baraline"] - -from typing import Optional, final - -import numpy as np -from numba import get_num_threads, set_num_threads - -from aeon.similarity_search._commons import ( - extract_top_k_and_threshold_from_distance_profiles, -) -from aeon.similarity_search.base import BaseSimilaritySearch -from aeon.similarity_search.distance_profiles.euclidean_distance_profile import ( - euclidean_distance_profile, - normalised_euclidean_distance_profile, -) -from aeon.similarity_search.distance_profiles.squared_distance_profile import ( - normalised_squared_distance_profile, - squared_distance_profile, -) - - -class QuerySearch(BaseSimilaritySearch): - """ - Query search estimator. - - The query search estimator will return a set of matches of a query in a search space - , which is defined by a time series dataset given during fit. Depending on the `k` - and/or `threshold` parameters, which condition what is considered a valid match - during the search, the number of matches will vary. If `k` is used, at most `k` - matches (the `k` best) will be returned, if `threshold` is used and `k` is set to - `np.inf`, all the candidates which distance to the query is inferior or equal to - `threshold` will be returned. If both are used, the `k` best matches to the query - with distance inferior to `threshold` will be returned. - - - Parameters - ---------- - k : int, default=1 - The number of best matches to return during predict for a given query. - threshold : float, default=np.inf - The number of best matches to return during predict for a given query. - distance : str, default="euclidean" - Name of the distance function to use. A list of valid strings can be found in - the documentation for :func:`aeon.distances.get_distance_function`. - If a callable is passed it must either be a python function or numba function - with nopython=True, that takes two 1d numpy arrays as input and returns a float. - distance_args : dict, default=None - Optional keyword arguments for the distance function. - normalise : bool, default=False - Whether the distance function should be z-normalised. - speed_up : str, default='fastest' - Which speed up technique to use with for the selected distance - function. By default, the fastest algorithm is used. A list of available - algorithm for each distance can be obtained by calling the - `get_speedup_function_names` function. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - n_jobs : int, default=1 - Number of parallel jobs to use. - store_distance_profiles : bool, default=False. - Whether to store the computed distance profiles in the attribute - "distance_profiles_" after calling the predict method. It will store the raw - distance profile, meaning without potential inversion or thresholding applied. - - Attributes - ---------- - X_ : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input time series stored during the fit method. This is the - database we search in when given a query. - distance_profile_function : function - The function used to compute the distance profile. This is determined - during the fit method based on the distance and normalise - parameters. - - Notes - ----- - For now, the multivariate case is only treated as independent. - Distances are computed for each channel independently and then - summed together. - """ - - def __init__( - self, - k: int = 1, - threshold: float = np.inf, - distance: str = "euclidean", - distance_args: Optional[dict] = None, - inverse_distance: bool = False, - normalise: bool = False, - speed_up: str = "fastest", - n_jobs: int = 1, - store_distance_profiles: bool = False, - ): - self.k = k - self.threshold = threshold - self.store_distance_profiles = store_distance_profiles - self._previous_query_length = -1 - self.axis = 1 - - super().__init__( - distance=distance, - distance_args=distance_args, - inverse_distance=inverse_distance, - normalise=normalise, - speed_up=speed_up, - n_jobs=n_jobs, - ) - - def _fit(self, X: np.ndarray, y=None): - """ - Check input format and store it to be used as search space during predict. - - Parameters - ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Input array to used as database for the similarity search - y : optional - Not used. - - Raises - ------ - TypeError - If the input X array is not 3D raise an error. - - Returns - ------- - self - - """ - self.X_ = X - self.distance_profile_function_ = self._get_distance_profile_function() - return self - - @final - def predict( - self, - X: np.ndarray, - axis=1, - X_index=None, - exclusion_factor=2.0, - apply_exclusion_to_result=False, - ) -> np.ndarray: - """ - Predict method : Check the shape of X and call _predict to perform the search. - - If the distance profile function is normalised, it stores the mean and stds - from X and X_, with X_ the training data. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, query_length) - Input query used for similarity search. - axis : int - The time point axis of the input series if it is 2D. If ``axis==0``, it is - assumed each column is a time series and each row is a time point. i.e. the - shape of the data is ``(n_timepoints,n_channels)``. ``axis==1`` indicates - the time series are in rows, i.e. the shape of the data is - ``(n_channels,n_timepoints)``. - X_index : Iterable - An Interable (tuple, list, array) of length two used to specify the index of - the query X if it was extracted from the input data X given during the fit - method. Given the tuple (id_sample, id_timestamp), the similarity search - will define an exclusion zone around the X_index in order to avoid matching - X with itself. If None, it is considered that the query is not extracted - from X_. - exclusion_factor : float, default=2. - The factor to apply to the query length to define the exclusion zone. The - exclusion zone is define from - :math:`id_timestamp - query_length//exclusion_factor` to - :math:`id_timestamp + query_length//exclusion_factor`. This also applies to - the matching conditions defined by child classes. For example, with - TopKSimilaritySearch, the k best matches are also subject to the exclusion - zone, but with :math:`id_timestamp` the index of one of the k matches. - apply_exclusion_to_result : bool, default=False - Wheter to apply the exclusion factor to the output of the similarity search. - This means that two matches of the query from the same sample must be at - least spaced by +/- :math:`query_length//exclusion_factor`. - This can avoid pathological matching where, for example if we extract the - best two matches, there is a high chance that if the best match is located - at :math:`id_timestamp`, the second best match will be located at - :math:`id_timestamp` +/- 1, as they both share all their values except one. - - Raises - ------ - TypeError - If the input X array is not 2D raise an error. - ValueError - If the length of the query is greater - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(n_matches)``, contains the distance between - the query and its best matches in X_. The second array, of shape - ``(n_matches, 2)``, contains the indexes of these matches as - ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - self._check_is_fitted() - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) - - query_dim, query_length = self._check_query_format(X, axis) - - mask = self._init_X_index_mask( - X_index, - query_length, - exclusion_factor=exclusion_factor, - ) - - if self.normalise: - self.query_means_ = np.mean(X, axis=-1) - self.query_stds_ = np.std(X, axis=-1) - if self._previous_query_length != query_length: - self._store_mean_std_from_inputs(query_length) - - if apply_exclusion_to_result: - exclusion_size = query_length // exclusion_factor - else: - exclusion_size = None - - self._previous_query_length = query_length - - X_preds = self._predict( - self._call_distance_profile(X, mask), - exclusion_size=exclusion_size, - ) - set_num_threads(prev_threads) - return X_preds - - def _predict( - self, distance_profiles: np.ndarray, exclusion_size: Optional[int] = None - ) -> np.ndarray: - """ - Private predict method for QuerySearch. - - It takes the distance profiles and apply the `k` and `threshold` conditions to - return the set of best matches. - - Parameters - ---------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_timepoints - query_length + 1) # noqa: E501 - Precomputed distance profile. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(n_matches)``, contains the distance between - the query and its best matches in X_. The second array, of shape - ``(n_matches, 2)``, contains the indexes of these matches as - ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - - """ - if self.store_distance_profiles: - self.distance_profiles_ = distance_profiles - # Define id sample and timestamp to not "loose" them due to concatenation - return extract_top_k_and_threshold_from_distance_profiles( - distance_profiles, - k=self.k, - threshold=self.threshold, - exclusion_size=exclusion_size, - inverse_distance=self.inverse_distance, - ) - - def _check_query_format(self, X, axis): - if axis not in [0, 1]: - raise ValueError("The axis argument is expected to be either 1 or 0") - if self.axis != axis: - X = X.T - if not isinstance(X, np.ndarray) or X.ndim != 2: - raise TypeError( - "Error, only supports 2D numpy for now. If the query X is univariate " - "do X = X[np.newaxis, :]." - ) - - query_dim, query_length = X.shape - if query_length >= self.min_timepoints_: - raise ValueError( - "The length of the query should be inferior or equal to the length of " - "data (X_) provided during fit, but got {} for X and {} for X_".format( - query_length, self.min_timepoints_ - ) - ) - - if query_dim != self.n_channels_: - raise ValueError( - "The number of feature should be the same for the query X and the data " - "(X_) provided during fit, but got {} for X and {} for X_".format( - query_dim, self.n_channels_ - ) - ) - return query_dim, query_length - - def _get_distance_profile_function(self): - """ - Given distance and speed_up parameters, return the distance profile function. - - Raises - ------ - ValueError - If the distance parameter given at initialization is not a string nor a - numba function or a callable, or if the speedup parameter is unknow or - unsupported, raisea ValueError. - - Returns - ------- - function - The distance profile function matching the distance argument. - - """ - if isinstance(self.distance, str): - distance_dict = _QUERY_SEARCH_SPEED_UP_DICT.get(self.distance) - if distance_dict is None: - raise NotImplementedError( - f"No distance profile have been implemented for {self.distance}." - ) - else: - speed_up_profile = distance_dict.get(self.normalise).get(self.speed_up) - - if speed_up_profile is None: - raise ValueError( - f"Unknown or unsupported speed up {self.speed_up} for " - f"{self.distance} distance function with" - ) - self.speed_up_ = self.speed_up - return speed_up_profile - else: - raise ValueError( - f"Expected distance argument to be str but got {type(self.distance)}" - ) - - def _call_distance_profile(self, X: np.ndarray, mask: np.ndarray) -> np.ndarray: - """ - Obtain the distance profile function and call it with the query and the mask. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, query_length) - Input query used for similarity search. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean array which indicates the candidates that should be evaluated in - the similarity search. - - Returns - ------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_timepoints - query_length + 1) # noqa: E501 - The distance profiles between the input time series and the query. - - """ - if self.normalise: - distance_profiles = self.distance_profile_function_( - self.X_, - X, - mask, - self.X_means_, - self.X_stds_, - self.query_means_, - self.query_stds_, - ) - else: - distance_profiles = self.distance_profile_function_(self.X_, X, mask) - - return distance_profiles - - @classmethod - def get_speedup_function_names(self) -> dict: - """ - Get available speedup for query search in aeon. - - The returned structure is a dictionnary that contains the names of all - avaialble speedups for normalised and non-normalised distance functions. - - Returns - ------- - dict - The available speedups name that can be used as parameters in - similarity search classes. - - """ - speedups = {} - for dist_name in _QUERY_SEARCH_SPEED_UP_DICT.keys(): - for normalise in _QUERY_SEARCH_SPEED_UP_DICT[dist_name].keys(): - speedups_names = list( - _QUERY_SEARCH_SPEED_UP_DICT[dist_name][normalise].keys() - ) - if normalise: - speedups.update({f"normalised {dist_name}": speedups_names}) - else: - speedups.update({f"{dist_name}": speedups_names}) - return speedups - - -_QUERY_SEARCH_SPEED_UP_DICT = { - "euclidean": { - True: { - "fastest": normalised_euclidean_distance_profile, - "Mueen": normalised_euclidean_distance_profile, - }, - False: { - "fastest": euclidean_distance_profile, - "Mueen": euclidean_distance_profile, - }, - }, - "squared": { - True: { - "fastest": normalised_squared_distance_profile, - "Mueen": normalised_squared_distance_profile, - }, - False: { - "fastest": squared_distance_profile, - "Mueen": squared_distance_profile, - }, - }, -} diff --git a/aeon/similarity_search/series_search.py b/aeon/similarity_search/series_search.py deleted file mode 100644 index 3c36cf9c4a..0000000000 --- a/aeon/similarity_search/series_search.py +++ /dev/null @@ -1,436 +0,0 @@ -"""Base class for series search.""" - -__maintainer__ = ["baraline"] - -from typing import Union, final - -import numpy as np -from numba import get_num_threads, set_num_threads - -from aeon.similarity_search.base import BaseSimilaritySearch -from aeon.similarity_search.matrix_profiles.stomp import ( - stomp_euclidean_matrix_profile, - stomp_normalised_euclidean_matrix_profile, - stomp_normalised_squared_matrix_profile, - stomp_squared_matrix_profile, -) -from aeon.utils.numba.general import sliding_mean_std_one_series - - -class SeriesSearch(BaseSimilaritySearch): - """ - Series search estimator. - - The series search estimator will return a set of matches for each subsequence of - size L in a time series given during predict. The matching of each subsequence will - be made against all subsequence of size L inside the time series given during fit, - which will represent the search space. - - Depending on the `k` and/or `threshold` parameters, which condition what is - considered a valid match during the search, the number of matches will vary. If `k` - is used, at most `k` matches (the `k` best) will be returned, if `threshold` is used - and `k` is set to `np.inf`, all the candidates which distance to the query is - inferior or equal to `threshold` will be returned. If both are used, the `k` best - matches to the query with distance inferior to `threshold` will be returned. - - - Parameters - ---------- - k : int, default=1 - The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf - The number of best matches to return during predict for each subsequence. - distance : str, default="euclidean" - Name of the distance function to use. A list of valid strings can be found in - the documentation for :func:`aeon.distances.get_distance_function`. - If a callable is passed it must either be a python function or numba function - with nopython=True, that takes two 1d numpy arrays as input and returns a float. - distance_args : dict, default=None - Optional keyword arguments for the distance function. - normalise : bool, default=False - Whether the distance function should be z-normalised. - speed_up : str, default='fastest' - Which speed up technique to use with for the selected distance - function. By default, the fastest algorithm is used. A list of available - algorithm for each distance can be obtained by calling the - `get_speedup_function_names` function. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - n_jobs : int, default=1 - Number of parallel jobs to use. - - Attributes - ---------- - X_ : array, shape (n_cases, n_channels, n_timepoints) - The input time series stored during the fit method. This is the - database we search in when given a query. - distance_profile_function : function - The function used to compute the distance profile. This is determined - during the fit method based on the distance and normalise - parameters. - - Notes - ----- - For now, the multivariate case is only treated as independent. - Distances are computed for each channel independently and then - summed together. - """ - - def __init__( - self, - k: int = 1, - threshold: float = np.inf, - distance: str = "euclidean", - distance_args: Union[None, dict] = None, - inverse_distance: bool = False, - normalise: bool = False, - speed_up: str = "fastest", - n_jobs: int = 1, - ): - self.k = k - self.threshold = threshold - self._previous_query_length = -1 - self.axis = 1 - - super().__init__( - distance=distance, - distance_args=distance_args, - inverse_distance=inverse_distance, - normalise=normalise, - speed_up=speed_up, - n_jobs=n_jobs, - ) - - def _fit(self, X, y=None): - """ - Check input format and store it to be used as search space during predict. - - Parameters - ---------- - X : array, shape (n_cases, n_channels, n_timepoints) - Input array to used as database for the similarity search - y : optional - Not used. - - Raises - ------ - TypeError - If the input X array is not 3D raise an error. - - Returns - ------- - self - - """ - self.X_ = X - self.matrix_profile_function_ = self._get_series_method_function() - return self - - @final - def predict( - self, - X: np.ndarray, - length: int, - axis: int = 1, - X_index=None, - exclusion_factor=2.0, - apply_exclusion_to_result=False, - ): - """ - Predict method : Check the shape of X and call _predict to perform the search. - - If the distance profile function is normalised, it stores the mean and stds - from X and X_, with X_ the training data. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, series_length) - Input time series used for the search. - length : int - The length parameter that will be used to extract queries from X. - axis : int - The time point axis of the input series if it is 2D. If ``axis==0``, it is - assumed each column is a time series and each row is a time point. i.e. the - shape of the data is ``(n_timepoints,n_channels)``. ``axis==1`` indicates - the time series are in rows, i.e. the shape of the data is - ``(n_channels,n_timepoints)``. - X_index : int - An integer indicating if X was extracted is part of the dataset that was - given during the fit method. If so, this integer should be the sample id. - The search will define an exclusion zone for the queries extarcted from X - in order to avoid matching with themself. If None, it is considered that - the query is not extracted from X_. - exclusion_factor : float, default=2. - The factor to apply to the query length to define the exclusion zone. The - exclusion zone is define from - ``id_timestamp - query_length//exclusion_factor`` to - ``id_timestamp + query_length//exclusion_factor``. This also applies to - the matching conditions defined by child classes. For example, with - TopKSimilaritySearch, the k best matches are also subject to the exclusion - zone, but with :math:`id_timestamp` the index of one of the k matches. - apply_exclusion_to_result : bool, default=False - Wheter to apply the exclusion factor to the output of the similarity search. - This means that two matches of the query from the same sample must be at - least spaced by +/- ``query_length//exclusion_factor``. - This can avoid pathological matching where, for example if we extract the - best two matches, there is a high chance that if the best match is located - at ``id_timestamp``, the second best match will be located at - ``id_timestamp`` +/- 1, as they both share all their values except one. - - Raises - ------ - TypeError - If the input X array is not 2D raise an error. - ValueError - If the length of the query is greater - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - self._check_is_fitted() - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) - series_dim, series_length = self._check_series_format(X, length, axis) - - mask = self._init_X_index_mask( - None if X_index is None else [X_index, 0], - length, - exclusion_factor=exclusion_factor, - ) - - if self.normalise: - _mean, _std = sliding_mean_std_one_series(X, length, 1) - self.T_means_ = _mean - self.T_stds_ = _std - if self._previous_query_length != length: - self._store_mean_std_from_inputs(length) - - if apply_exclusion_to_result: - exclusion_size = length // exclusion_factor - else: - exclusion_size = None - - self._previous_query_length = length - - X_preds = self._predict( - X, - length, - mask, - exclusion_size, - X_index, - exclusion_factor, - apply_exclusion_to_result, - ) - set_num_threads(prev_threads) - return X_preds - - def _predict( - self, - X, - length, - mask, - exclusion_size, - X_index, - exclusion_factor, - apply_exclusion_to_result, - ): - """ - Private predict method for SeriesSearch. - - This method calculates the matrix profile for a given time series dataset by - comparing all possible subsequences of a specified length against a reference - time series. It handles exclusion zones to prevent nearby matches from being - selected and supports normalization. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, series_length) - Input time series used for the search. - length : int - The length parameter that will be used to extract queries from X. - axis : int - The time point axis of the input series if it is 2D. If ``axis==0``, it is - assumed each column is a time series and each row is a time point. i.e. the - shape of the data is ``(n_timepoints,n_channels)``. ``axis==1`` indicates - the time series are in rows, i.e. the shape of the data is - ``(n_channels,n_timepoints)``. - mask : np.ndarray, 2D array of shape (n_cases, n_timepoints - length + 1) - Boolean mask of the shape of the distance profiles indicating for which part - of it the distance should be computed. In this context, it is the mask for - the first query of size L in T. This mask will be updated during the - algorithm. - exclusion_size : int, optional - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - - Returns - ------- - Tuple(ndarray, ndarray) - The first array, of shape ``(series_length - length + 1, n_matches)``, - contains the distance between all the queries of size length and their best - matches in X_. The second array, of shape - ``(series_length - L + 1, n_matches, 2)``, contains the indexes of these - matches as ``(id_sample, id_timepoint)``. The corresponding match can be - retrieved as ``X_[id_sample, :, id_timepoint : id_timepoint + length]``. - - """ - if self.normalise: - return self.matrix_profile_function_( - self.X_, - X, - length, - self.X_means_, - self.X_stds_, - self.T_means_, - self.T_stds_, - mask, - k=self.k, - threshold=self.threshold, - inverse_distance=self.inverse_distance, - exclusion_size=exclusion_size, - ) - else: - return self.matrix_profile_function_( - self.X_, - X, - length, - mask, - k=self.k, - threshold=self.threshold, - inverse_distance=self.inverse_distance, - exclusion_size=exclusion_size, - ) - - def _check_series_format(self, X, length, axis): - if axis not in [0, 1]: - raise ValueError("The axis argument is expected to be either 1 or 0") - if self.axis != axis: - X = X.T - if not isinstance(X, np.ndarray) or X.ndim != 2: - raise TypeError( - "Error, only supports 2D numpy for now. If the series X is univariate " - "do X = X[np.newaxis, :]." - ) - - series_dim, series_length = X.shape - if series_length < length: - raise ValueError( - "The length of the series should be superior or equal to the length " - "parameter given during predict, but got {} < {}".format( - series_length, length - ) - ) - - if series_dim != self.n_channels_: - raise ValueError( - "The number of feature should be the same for the series X and the data" - " (X_) provided during fit, but got {} for X and {} for X_".format( - series_dim, self.n_channels_ - ) - ) - return series_dim, series_length - - def _get_series_method_function(self): - """ - Given distance and speed_up parameters, return the series method function. - - Raises - ------ - ValueError - If the distance parameter given at initialization is not a string nor a - numba function or a callable, or if the speedup parameter is unknow or - unsupported, raisea ValueError. - - Returns - ------- - function - The series method function matching the distance argument. - - """ - if isinstance(self.distance, str): - distance_dict = _SERIES_SEARCH_SPEED_UP_DICT.get(self.distance) - if distance_dict is None: - raise NotImplementedError( - f"No distance profile have been implemented for {self.distance}." - ) - else: - speed_up_series_method = distance_dict.get(self.normalise).get( - self.speed_up - ) - - if speed_up_series_method is None: - raise ValueError( - f"Unknown or unsupported speed up {self.speed_up} for " - f"{self.distance} distance function with" - ) - self.speed_up_ = self.speed_up - return speed_up_series_method - else: - raise ValueError( - f"Expected distance argument to be str but got {type(self.distance)}" - ) - - @classmethod - def get_speedup_function_names(self): - """ - Get available speedup for series search in aeon. - - The returned structure is a dictionnary that contains the names of all - avaialble speedups for normalised and non-normalised distance functions. - - Returns - ------- - dict - The available speedups name that can be used as parameters in - similarity search classes. - - """ - speedups = {} - for dist_name in _SERIES_SEARCH_SPEED_UP_DICT.keys(): - for normalise in _SERIES_SEARCH_SPEED_UP_DICT[dist_name].keys(): - speedups_names = list( - _SERIES_SEARCH_SPEED_UP_DICT[dist_name][normalise].keys() - ) - if normalise: - speedups.update({f"normalised {dist_name}": speedups_names}) - else: - speedups.update({f"{dist_name}": speedups_names}) - return speedups - - -_SERIES_SEARCH_SPEED_UP_DICT = { - "euclidean": { - True: { - "fastest": stomp_normalised_euclidean_matrix_profile, - "STOMP": stomp_normalised_euclidean_matrix_profile, - }, - False: { - "fastest": stomp_euclidean_matrix_profile, - "STOMP": stomp_euclidean_matrix_profile, - }, - }, - "squared": { - True: { - "fastest": stomp_normalised_squared_matrix_profile, - "STOMP": stomp_normalised_squared_matrix_profile, - }, - False: { - "fastest": stomp_squared_matrix_profile, - "STOMP": stomp_squared_matrix_profile, - }, - }, -} diff --git a/aeon/similarity_search/series_search/__init__.py b/aeon/similarity_search/series_search/__init__.py new file mode 100644 index 0000000000..f576c41f03 --- /dev/null +++ b/aeon/similarity_search/series_search/__init__.py @@ -0,0 +1,7 @@ +"""Similarity search module.""" + +__all__ = ["BaseSimilaritySearch", "QuerySearch", "SeriesSearch"] + +from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search.query_search import QuerySearch +from aeon.similarity_search.series_search import SeriesSearch diff --git a/aeon/similarity_search/series_search/base.py b/aeon/similarity_search/series_search/base.py new file mode 100644 index 0000000000..db83519c04 --- /dev/null +++ b/aeon/similarity_search/series_search/base.py @@ -0,0 +1,22 @@ +"""Base class for whole series search.""" + +__maintainer__ = ["baraline"] + +from aeon.similarity_search.base import BaseSimilaritySearch + + +class BaseSeriesSearch(BaseSimilaritySearch): + """.""" + + ... + + +class BaseIndexSearch(BaseSimilaritySearch): + """.""" + + ... + + def batch_fit(sourcefiles, batch_size): + """.""" + # fit + # and then update diff --git a/aeon/similarity_search/subsequence_search/__init__.py b/aeon/similarity_search/subsequence_search/__init__.py new file mode 100644 index 0000000000..dfca8ee18c --- /dev/null +++ b/aeon/similarity_search/subsequence_search/__init__.py @@ -0,0 +1,5 @@ +"""Similarity search module.""" + +__all__ = ["StompMatrixProfile"] + +from aeon.similarity_search.subsequence_search._stomp import StompMatrixProfile diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py new file mode 100644 index 0000000000..7f95083f3b --- /dev/null +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -0,0 +1,284 @@ +"""Implementation of matrix profile with brute force.""" + +from typing import Optional + +__maintainer__ = ["baraline"] + + +import numpy as np +from numba import njit, prange +from numba.typed import List + +from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile_list, +) +from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile +from aeon.utils.numba.general import ( + get_all_subsequences, + z_normalise_series_3d, + z_normalize_series_2d, +) + +# TODO : check function params and make docstrings +# TODO : make tests + + +class BruteForceMatrixProfile(BaseMatrixProfile): + """.""" + + def compute_matrix_profile( + self, + k, + threshold, + exclusion_size, + inverse_distance, + allow_overlap, + X: Optional[np.ndarray] = None, + X_index: Optional[int] = None, + ): + """ + . + + Parameters + ---------- + k : TYPE + DESCRIPTION. + threshold : TYPE + DESCRIPTION. + exclusion_size : TYPE + DESCRIPTION. + inverse_distance : TYPE + DESCRIPTION. + X : Optional[np.ndarray], optional + DESCRIPTION. The default is None. + X_index : Optional[int], optional + DESCRIPTION. The default is None. + : TYPE + DESCRIPTION. + + Returns + ------- + MP : TYPE + DESCRIPTION. + IP : TYPE + DESCRIPTION. + + """ + # pairwise if none + if X is None: + MP = [] + IP = [] + for i in range(len(self.X_)): + _MP, _IP = self.compute_matrix_profile( + k, + threshold, + exclusion_size, + inverse_distance, + X=self.X_[i], + X_index=i, + ) + MP.append(_MP) + IP.append(_IP) + else: + MP, IP = _naive_squared_matrix_profile( + self.X_, + X, + self.length, + X_index, + k, + allow_overlap, + threshold, + exclusion_size, + inverse_distance, + normalize=self.normalize, + ) + + return MP, IP + + def compute_distance_profile(self, X: np.ndarray): + """ + Compute the distance profile of X to all samples in X_. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The query to use to compute the distance profiles. + + Returns + ------- + distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) + The distance profile of X to all samples in X_. The ``n_candidates`` value + is equal to ``n_timepoins - length + 1``. If X_ is an unequal length + collection, returns a numba typed list instead of an ndarray. + + """ + distance_profiles = _naive_squared_distance_profile( + self.X_, X, normalize=self.normalize + ) + + if not self.metadata_["unequal_length"]: + distance_profiles = np.asarray(distance_profiles) + return distance_profiles + + +@njit(cache=True, fastmath=True) +def _compute_dist_profile(X_subs, q): + """ + Compute the distance profile between subsequences and a query. + + Parameters + ---------- + X_subs : array, shape=(n_samples, n_channels, query_length) + Input subsequences extracted from a time series. + q : array, shape=(n_channels, query_length) + Query used for the distance computation + + Returns + ------- + dist_profile : np.ndarray, 1D array of shape (n_samples) + The distance between the query all subsequences. + + """ + n_candidates, n_channels, q_length = X_subs.shape + dist_profile = np.zeros(n_candidates) + for i in range(n_candidates): + for j in range(n_channels): + for k in range(q_length): + dist_profile[i] += (X_subs[i, j, k] - q[j, k]) ** 2 + return dist_profile + + +@njit(cache=True, fastmath=True, parallel=True) +def _naive_squared_distance_profile( + X, + Q, + normalize=False, +): + """ + Compute a squared euclidean distance profile. + + Parameters + ---------- + X : array, shape=(n_samples, n_channels, n_timepoints) + Input time series dataset to search in. + Q : array, shape=(n_channels, query_length) + Query used during the search. + normalize : bool + Wheter to use a z-normalized distance. + + Returns + ------- + out : np.ndarray, 1D array of shape (n_samples, n_timepoints_t - query_length + 1) + The distance between the query and all candidates in X. + + """ + query_length = Q.shape[1] + dist_profiles = List() + # Init distance profile array with unequal length support + for i in range(len(X)): + dist_profiles.append(np.zeros(X[i].shape[1] - query_length + 1)) + if normalize: + Q = z_normalize_series_2d(Q) + else: + Q = Q.astype(np.float64) + + for i in prange(len(X)): + X_subs = get_all_subsequences(X[i], query_length, 1) + if normalize: + X_subs = z_normalise_series_3d(X_subs) + + dist_profile = _compute_dist_profile(X_subs, Q) + dist_profiles[i] = dist_profile + return dist_profiles + + +@njit(cache=True, fastmath=True, parallel=True) +def _naive_squared_matrix_profile( + X, + T, + L, + k, + T_index, + threshold, + inverse_distance, + allow_overlap, + exclusion_size, + normalize=False, +): + """ + Compute a squared euclidean matrix profile. + + Parameters + ---------- + X : array, shape=(n_samples, n_channels, n_timepoints_x) + Input time series dataset to search in. + T : array, shape=(n_channels, n_timepoints_t) + Time series from which queries are extracted. + query_length : int + Length of the queries to extract from T. + T_index : int, + If ``X`` is a subsequence of the database given in fit, specify its starting + index as (i_case, i_timestamp). If specified, this subsequence and the + neighboring ones (according to ``exclusion_factor``) won't be considered as + admissible candidates. + normalize : bool + Wheter to use a z-normalized distance. + + Returns + ------- + out : np.ndarray, 1D array of shape (n_timepoints_t - query_length + 1) + The minimum distance between each query in T and all candidates in X. + """ + n_queries = T.shape[1] - L + 1 + MP = List() + IP = List() + + # Init List to allow parallel, we'll re-use it for all dist profiles + dist_profiles = List() + for i_x in range(len(X)): + dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) + + X_subs = List() + for i in range(len(X)): + i_subs = get_all_subsequences(X[i], L, 1) + if normalize: + i_subs = z_normalise_series_3d(X_subs) + X_subs.append(i_subs) + + for i_q in range(n_queries): + Q = T[:, i : i + L] + if normalize: + Q = z_normalize_series_2d(Q) + for i_x in prange(len(X)): + dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = _compute_dist_profile( + X_subs[i_x], Q + ) + + if T_index is not None: + _max_timestamp = X[T_index].shape[1] - L + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profiles[T_index][lb:ub] = np.inf + + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + + # Deal with self-matches + if T_index is not None: + _max_timestamp = X[T_index].shape[1] - L + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profiles[T_index][lb:ub] = np.inf + + top_dists, top_indexes = _extract_top_k_from_dist_profile( + dist_profiles, + k, + threshold, + allow_overlap, + exclusion_size, + ) + + MP.append(top_dists) + IP.append(top_indexes) + return MP, IP diff --git a/aeon/similarity_search/subsequence_search/_commons.py b/aeon/similarity_search/subsequence_search/_commons.py new file mode 100644 index 0000000000..e2e0aa54df --- /dev/null +++ b/aeon/similarity_search/subsequence_search/_commons.py @@ -0,0 +1,138 @@ +"""Helper and common function for similarity search estimators and functions.""" + +__maintainer__ = ["baraline"] + +import numpy as np +from numba import njit, prange +from scipy.signal import convolve + + +def fft_sliding_dot_product(X, q): + """ + Use FFT convolution to calculate the sliding window dot product. + + This function applies the Fast Fourier Transform (FFT) to efficiently compute + the sliding dot product between the input time series `X` and the query `q`. + The dot product is computed for each channel individually. The sliding window + approach ensures that the dot product is calculated for every possible subsequence + of `X` that matches the length of `q` + + Parameters + ---------- + X : array, shape=(n_channels, n_timepoints) + Input time series + q : array, shape=(n_channels, query_length) + Input query + + Returns + ------- + out : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + Sliding dot product between q and X. + """ + n_channels, n_timepoints = X.shape + query_length = q.shape[1] + out = np.zeros((n_channels, n_timepoints - query_length + 1)) + for i in range(n_channels): + out[i, :] = convolve(np.flipud(q[i, :]), X[i, :], mode="valid").real + return out + + +def get_ith_products(X, T, L, ith): + """ + Compute dot products between X and the i-th subsequence of size L in T. + + Parameters + ---------- + X : array, shape = (n_channels, n_timepoints_X) + Input data. + T : array, shape = (n_channels, n_timepoints_T) + Data containing the query. + L : int + Overall query length. + ith : int + Query starting index in T. + + Returns + ------- + np.ndarray, 2D array of shape (n_channels, n_timepoints_X - L + 1) + Sliding dot product between the i-th subsequence of size L in T and X. + + """ + return fft_sliding_dot_product(X, T[:, ith : ith + L]) + + +@njit(cache=True, fastmath=True, parallel=True) +def _inverse_distance_profile_list(dist_profiles): + for i in prange(len(dist_profiles)): + dist_profiles[i] = 1 / (dist_profiles[i] + 1e-8) + return dist_profiles + + +@njit(cache=True) +def _extract_top_k_from_dist_profile( + dist_profiles, + k, + threshold, + allow_overlap, + exclusion_size, +): + top_k_indexes = np.zeros((2 * k, 2), dtype=np.int64) - 1 + top_k_distances = np.full(2 * k, np.inf) + for i_profile in range(len(dist_profiles)): + # Extract top-k without neighboring matches + if not allow_overlap: + _sorted_indexes = np.argsort(dist_profiles[i_profile]) + _top_k_indexes = np.zeros(k, dtype=np.int64) - 1 + _current_k = 1 + _top_k_indexes[0] = _sorted_indexes[0] + _current_j = 1 + # Until we extract k value or explore all the array + while _current_k < k and _current_j < len(_sorted_indexes): + _insert = True + # Check for validity with each previously inserted + for i_k in range(_current_k): + ub = min(_top_k_indexes[i_k] + exclusion_size, len(dist_profiles)) + lb = max(_top_k_indexes[i_k] - exclusion_size, 0) + if ( + _sorted_indexes[_current_j] < lb + or _sorted_indexes[_current_j] > ub + ): + _insert = False + break + + if _insert: + _top_k_indexes[_current_k] = _sorted_indexes[_current_j] + _current_k += 1 + _current_j += 1 + + _top_k_indexes = _top_k_indexes[:_current_k] + _top_k_distances = dist_profiles[i_profile][_top_k_indexes] + # Extract top-k with neighboring matches + else: + _top_k_indexes = np.argpartition(dist_profiles[i_profile], k)[:k] + _top_k_distances = dist_profiles[i_profile][_top_k_indexes] + + # Select overall top k by using the buffer array of size 2*k + # Inset top from current sample + top_k_distances[k : k + len(_top_k_distances)] = _top_k_distances + top_k_indexes[k : k + len(_top_k_distances), 1] = _top_k_indexes + top_k_indexes[k : k + len(_top_k_distances), 0] = i_profile + + # Sort overall + idx = np.argsort(top_k_distances) + # Keep top k overall + top_k_distances[:k] = top_k_distances[idx[:k]] + top_k_indexes[:k] = top_k_indexes[idx[:k]] + + top_k_distances[k:] = np.inf + + # get the actual number of extracted values and apply threshold + true_k = 0 + for i in range(k): + # if top_k is inf, it means that no value was extracted + if top_k_distances[i] != np.inf and top_k_distances[i] <= threshold: + true_k += 1 + else: + break + + return top_k_indexes[:true_k], top_k_distances[:true_k] diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py new file mode 100644 index 0000000000..8986a41926 --- /dev/null +++ b/aeon/similarity_search/subsequence_search/_stomp.py @@ -0,0 +1,596 @@ +"""Implementation of STOMP with squared euclidean distance.""" + +from typing import Optional + +__maintainer__ = ["baraline"] + + +import numpy as np +from numba import njit, prange +from numba.typed import List + +from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile_list, + fft_sliding_dot_product, + get_ith_products, +) +from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile +from aeon.utils.numba.general import AEON_NUMBA_STD_THRESHOLD + +# TODO : check and order parameters of functions in base and here +# TODO : check function params and make docstrings to be consistent with brute force +# TODO : validate tests + + +class StompMatrixProfile(BaseMatrixProfile): + """.""" + + def compute_matrix_profile( + self, + k, + threshold, + exclusion_size, + inverse_distance, + allow_overlap, + X: Optional[np.ndarray] = None, + X_index: Optional[int] = None, + ): + """ + . + + Parameters + ---------- + k : TYPE + DESCRIPTION. + threshold : TYPE + DESCRIPTION. + exclusion_size : TYPE + DESCRIPTION. + inverse_distance : TYPE + DESCRIPTION. + X : Optional[np.ndarray], optional + DESCRIPTION. The default is None. + X_index : Optional[int], optional + If ``X`` is a series of the database given in fit, specify its index in + ``X_``. If specified, each query of this series won't be able to match with + its neighboring subsequences. + : TYPE + DESCRIPTION. + + Returns + ------- + MP : TYPE + DESCRIPTION. + IP : TYPE + DESCRIPTION. + + """ + # pairwise if none + if X is None: + MP = [] + IP = [] + for i in range(len(self.X_)): + _MP, _IP = self.compute_matrix_profile( + k, + threshold, + exclusion_size, + inverse_distance, + X=self.X_[i], + X_index=i, + ) + MP.append(_MP) + IP.append(_IP) + else: + XdotT = [ + get_ith_products(self.X[i], X, self.length, 0) + for i in range(len(self.X_)) + ] + if isinstance(X, np.ndarray): + XdotT = np.asarray(XdotT) + elif isinstance(X, List): + XdotT = List(XdotT) + if X_index is None: + X_means, X_stds = 0 + else: + X_means, X_stds = self.X_means_[i], self.X_stds_[i] + if self.normalize: + MP, IP = _stomp_normalized( + self.X_, + X, + XdotT, + self.X_means_, + self.X_stds_, + X_means, + X_stds, + self.length, + X_index, + k, + threshold, + allow_overlap, + exclusion_size, + inverse_distance, + ) + + else: + MP, IP = _stomp( + self.X_, + X, + XdotT, + self.length, + X_index, + k, + allow_overlap, + threshold, + exclusion_size, + inverse_distance, + ) + + return MP, IP + + def compute_distance_profile(self, X: np.ndarray): + """ + Compute the distance profile of X to all samples in X_. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The query to use to compute the distance profiles. + + Returns + ------- + distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) + The distance profile of X to all samples in X_. The ``n_candidates`` value + is equal to ``n_timepoins - length + 1``. If X_ is an unequal length + collection, returns a numba typed list instead of an ndarray. + + """ + QX = [fft_sliding_dot_product(self.X_[i], X) for i in range(len(self.X_))] + if self.metadata_["unequal_length"]: + QX = List(QX) + else: + QX = np.asarray(QX) + + if self.normalize: + distance_profiles = _normalized_squared_distance_profile( + QX, + self.X_means_, + self.X_stds_, + X.mean(axis=1), + X.std(axis=1), + self.length, + ) + else: + distance_profiles = _squared_distance_profile( + QX, + self.X_, + X, + ) + + if not self.metadata_["unequal_length"]: + distance_profiles = np.asarray(distance_profiles) + return distance_profiles + + +@njit(cache=True, parallel=True, fastmath=True) +def _stomp_normalized( + X, + T, + XdotT, + X_means, + X_stds, + T_means, + T_stds, + L, + T_index, + k, + threshold, + allow_overlap, + exclusion_size, + inverse_distance, +): + """ + Compute the Matrix Profile using the STOMP algorithm with normalized distances. + + X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + The input samples. If X is an unquel length collection, expect a TypedList + of 2D arrays of shape (n_channels, n_timepoints) + T : np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + L : int + Length of the subsequences used for the distance computation. + XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) + Precomputed dot products between each time series in X and the query series T. + X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) + Means of each subsequences of X of size L. Should be a numba TypedList if X is + unequal length. + X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) + Stds of each subsequences of X of size L. Should be a numba TypedList if X is + unequal length. + T_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) + Means of each subsequences of T of size L. + T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) + Stds of each subsequences of T of size L. + T_index : int, + If ``T`` is a series of the database given in fit, specify its index + in ``X_``. If specified, each query of this series won't be able to + match with its neighboring subsequences. + k : int, default=1 + The number of best matches to return during predict for each subsequence. + threshold : float, default=np.inf + The number of best matches to return during predict for each subsequence. + inverse_distance : bool, default=False + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. + exclusion_size : int, optional + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestomp - exclusion_size` and + :math:`id_timestomp + exclusion_size` which cannot be returned + as best match if :math:`id_timestomp` was already selected. By default, + the value None means that this is not used. + + Returns + ------- + tuple of np.ndarray + - MP : array of shape (series_length - L + 1,) + Matrix profile distances for each query subsequence. + - IP : array of shape (series_length - L + 1,) + Indexes of the top matches for each query subsequence. + """ + n_queries = T.shape[1] - L + 1 + MP = List() + IP = List() + + # Init List to allow parallel, we'll re-use it for all dist profiles + dist_profiles = List() + for i_x in range(len(X)): + dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) + + for i_q in range(n_queries): + for i_x in prange(len(X)): + dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = ( + _normalized_squared_dist_profile_one_series( + XdotT[i_x], + X_means[i_x], + X_stds[i_x], + T_means[:, i_q], + T_stds[:, i_q], + L, + T_stds[:, i_q] <= AEON_NUMBA_STD_THRESHOLD, + ) + ) + if i_q + 1 < n_queries: + XdotT[i_x] = _update_dot_products_one_series( + X[i_x], T, XdotT[i_x], L, i_q + 1 + ) + + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + + # Deal with self-matches + if T_index is not None: + _max_timestamp = X[T_index].shape[1] - L + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profiles[T_index][lb:ub] = np.inf + + top_indexes, top_dists = _extract_top_k_from_dist_profile( + dist_profiles, + k, + threshold, + allow_overlap, + exclusion_size, + ) + + MP.append(top_dists) + IP.append(top_indexes) + + return MP, IP + + +@njit(cache=True, parallel=True, fastmath=True) +def _stomp( + X, + T, + XdotT, + L, + T_index, + k, + allow_overlap, + threshold, + exclusion_size, + inverse_distance, +): + n_queries = T.shape[1] - L + 1 + MP = List() + IP = List() + + # Init List to allow parallel, we'll re-use it for all dist profiles + dist_profiles = List() + for i_x in range(len(X)): + dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) + # For each query of size L in T + for i_q in range(n_queries): + Q = T[:, i_q : i_q + L] + # For each series in X compute distance profile to the query + for i_x in prange(len(X)): + dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = ( + _squared_dist_profile_one_series(XdotT[i_x], X[i_x], Q) + ) + if i_q + 1 < n_queries: + XdotT[i_x] = _update_dot_products_one_series( + X[i_x], T, XdotT[i_x], L, i_q + 1 + ) + + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + + # Deal with self-matches + if T_index is not None: + _max_timestamp = X[T_index].shape[1] - L + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profiles[T_index][lb:ub] = np.inf + + top_indexes, top_dists = _extract_top_k_from_dist_profile( + dist_profiles, + k, + threshold, + allow_overlap, + exclusion_size, + ) + + MP.append(top_dists) + IP.append(top_indexes) + + return MP, IP + + +@njit(cache=True, fastmath=True) +def _update_dot_products_one_series( + X, + T, + XT_products, + L, + i_query, +): + """ + Update dot products of the i-th query of size L in T from the dot products of i-1. + + Parameters + ---------- + X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + Input time series on which the sliding dot product is computed. + T: np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + L : int + The length of the subsequences considered during the search. This parameter + cannot be larger than n_timepoints and series_length. + i_query : int + Query starting index in T. + + Returns + ------- + XT_products : np.ndarray of shape (n_cases, n_channels, n_timepoints - L + 1) + Sliding dot product between the i-th subsequence of size L in T and X. + + """ + n_channels = T.shape[0] + Q = T[:, i_query : i_query + L] + n_candidates = X.shape[1] - L + 1 + + for i_ft in range(n_channels): + # first element of all 0 to n-1 candidates * first element of previous query + _a1 = X[i_ft, : n_candidates - 1] * T[i_ft, i_query - 1] + # last element of all 1 to n candidates * last element of current query + _a2 = X[i_ft, L : L - 1 + n_candidates] * T[i_ft, i_query + L - 1] + + XT_products[i_ft, 1:] = XT_products[i_ft, :-1] - _a1 + _a2 + + # Compute first dot product + XT_products[i_ft, 0] = np.sum(Q[i_ft] * X[i_ft, :L]) + return XT_products + + +@njit(cache=True, fastmath=True, parallel=True) +def _squared_distance_profile(QX, X, Q): + """ + Compute squared distance profiles between query subsequence and time series. + + Parameters + ---------- + QX : List of np.ndarray + List of precomputed dot products between queries and time series, with each + element corresponding to a different time series. + Shape of each array is (n_channels, n_timepoints - query_length + 1). + X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + The input samples. If X is an unquel length collection, expect a numba TypedList + 2D array of shape (n_channels, n_timepoints) + Q : np.ndarray, 2D array of shape (n_channels, query_length) + The query used for similarity search. + mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) + Boolean mask of the shape of the distance profile indicating for which part + of it the distance should be computed. + + Returns + ------- + distance_profiles : np.ndarray + 3D array of shape (n_cases, n_timepoints - query_length + 1) + The distance profile between Q and the input time series X. + + """ + distance_profiles = List() + query_length = Q.shape[1] + + # Init distance profile array with unequal length support + for i_instance in range(len(X)): + profile_length = X[i_instance].shape[1] - query_length + 1 + distance_profiles.append(np.full((profile_length), np.inf)) + + for _i_instance in prange(len(QX)): + # prange cast iterator to unit64 with parallel=True + i_instance = np.int_(_i_instance) + + distance_profiles[i_instance] = _squared_dist_profile_one_series( + QX[i_instance], X[i_instance], Q + ) + return distance_profiles + + +@njit(cache=True, fastmath=True) +def _squared_dist_profile_one_series(QT, T, Q): + """ + Compute squared distance profile between query subsequence and a single time series. + + This function calculates the squared distance profile for a single time series by + leveraging the dot product of the query and time series as well as precomputed sums + of squares to efficiently compute the squared distances. + + Parameters + ---------- + QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + The dot product between the query and the time series. + T : np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + Q : np.ndarray + 2D array of shape (n_channels, query_length) representing query subsequence. + + Returns + ------- + distance_profile : np.ndarray + 2D array of shape (n_channels, n_timepoints - query_length + 1) + The squared distance profile between the query and the input time series. + """ + n_channels, profile_length = QT.shape + query_length = Q.shape[1] + _QT = -2 * QT + distance_profile = np.zeros(profile_length) + for k in prange(n_channels): + _sum = 0 + _qsum = 0 + for j in prange(query_length): + _sum += T[k, j] ** 2 + _qsum += Q[k, j] ** 2 + + distance_profile += _qsum + _QT[k] + distance_profile[0] += _sum + for i in prange(1, profile_length): + _sum += T[k, i + (query_length - 1)] ** 2 - T[k, i - 1] ** 2 + distance_profile[i] += _sum + return distance_profile + + +@njit(cache=True, fastmath=True, parallel=True) +def _normalized_squared_distance_profile( + QX, X_means, X_stds, Q_means, Q_stds, query_length +): + """ + Compute the normalized squared distance profiles between query subsequence and input time series. + + Parameters + ---------- + QX : List of np.ndarray + List of precomputed dot products between queries and time series, with each element + corresponding to a different time series. + Shape of each array is (n_channels, n_timepoints - query_length + 1). + X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 + Means of each subsequences of X of size query_length + X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 + Stds of each subsequences of X of size query_length + Q_means : np.ndarray, 1D array of shape (n_channels) + Means of the query q + Q_stds : np.ndarray, 1D array of shape (n_channels) + Stds of the query q + query_length : int + The length of the query subsequence used for the distance profile computation. + + Returns + ------- + List of np.ndarray + List of 2D arrays, each of shape (n_channels, n_timepoints - query_length + 1). + Each array contains the normalized squared distance profile between the query subsequence and the corresponding time series. + Entries in the array are set to infinity where the mask is False. + """ + distance_profiles = List() + Q_is_constant = Q_stds <= AEON_NUMBA_STD_THRESHOLD + # Init distance profile array with unequal length support + for i_instance in range(len(QX)): + profile_length = QX[i_instance].shape[1] + distance_profiles.append(np.zeros(profile_length)) + + for _i_instance in prange(len(QX)): + # iterator is uint64 with prange and parallel so cast to int to avoid warnings + i_instance = np.int64(_i_instance) + distance_profiles[i_instance] = _normalized_squared_dist_profile_one_series( + QX[i_instance], + X_means[i_instance], + X_stds[i_instance], + Q_means, + Q_stds, + query_length, + Q_is_constant, + ) + return distance_profiles + + +@njit(cache=True, fastmath=True) +def _normalized_squared_dist_profile_one_series( + QT, T_means, T_stds, Q_means, Q_stds, query_length, Q_is_constant +): + """ + Compute the z-normalized squared Euclidean distance profile for one time series. + + Parameters + ---------- + QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + The dot product between the query and the time series. + T_means : np.ndarray, 1D array of length n_channels + The mean values of the time series for each channel. + T_stds : np.ndarray, 2D array of shape (n_channels, profile_length) + The standard deviations of the time series for each channel and position. + Q_means : np.ndarray, 1D array of shape (n_channels) + Means of the query q + Q_stds : np.ndarray, 1D array of shape (n_channels) + Stds of the query q + query_length : int + The length of the query subsequence used for the distance profile computation. + Q_is_constant : np.ndarray + 1D array of shape (n_channels,) where each element is a Boolean indicating + whether the query standard deviation for that channel is less than or equal + to a specified threshold. + + Returns + ------- + np.ndarray + 2D array of shape (n_channels, n_timepoints - query_length + 1) containing the + z-normalized squared distance profile between the query subsequence and the time + series. Entries are computed based on the z-normalized values, with special + handling for constant values. + """ + n_channels, profile_length = QT.shape + distance_profile = np.zeros(profile_length) + + for i in prange(profile_length): + Sub_is_constant = T_stds[:, i] <= AEON_NUMBA_STD_THRESHOLD + for k in prange(n_channels): + # Two Constant case + if Q_is_constant[k] and Sub_is_constant[k]: + _val = 0 + # One Constant case + elif Q_is_constant[k] or Sub_is_constant[k]: + _val = query_length + else: + denom = query_length * Q_stds[k] * T_stds[k, i] + + p = (QT[k, i] - query_length * (Q_means[k] * T_means[k, i])) / denom + p = min(p, 1.0) + + _val = abs(2 * query_length * (1.0 - p)) + distance_profile[i] += _val + + return distance_profile diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py new file mode 100644 index 0000000000..1d49004472 --- /dev/null +++ b/aeon/similarity_search/subsequence_search/base.py @@ -0,0 +1,358 @@ +"""Base class for subsequence search.""" + +__maintainer__ = ["baraline"] + +import warnings +from abc import abstractmethod +from typing import Optional, final + +import numpy as np +from numba import get_num_threads, set_num_threads +from numba.typed import List + +from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile_list, +) +from aeon.utils.numba.general import sliding_mean_std_one_series + + +# We can define a BaseVariableLengthSubsequenceSearch later for VALMOD and the likes. +class BaseSubsequenceSearch(BaseSimilaritySearch): + """ + Base class for similarity search on time series subsequences. + + Parameters + ---------- + length : int + The length of the subsequence to be considered. + normalize : bool, optional + Whether the inputs should be z-normalized. The default is False. + n_jobs : int, optional + Number of parallel jobs to use. The default is 1. + """ + + @abstractmethod + def __init__( + self, + length: int, + normalize: Optional[bool] = False, + n_jobs: Optional[int] = 1, + ): + self.length = length + super().__init__(n_jobs=n_jobs, normalize=normalize) + + @final + def find_motifs( + self, + k: int, + threshold: float, + X: Optional[np.ndarray] = None, + allow_overlap: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): + """ + Find the top-k motifs in the training data. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif + sets. We define a motif set as a set of candidates which all are at a distance + of at most ``threshold`` from each other. The top-k motifs sets are the + motif sets with the most candidates. + + Parameters + ---------- + k : int, optional + Number of motifs to return + threshold : int, optional + A threshold on the similarity measure to determine which candidates will be + part of a motif set. + X : np.ndarray, 2D array of shape (n_channels, n_timestamps), optional + A series in which we want to indentify motifs. If provided, the motifs + extracted should appear in X and in the database given in fit. If not + provided, the motifs will be extracted only from the database given in fit. + allow_overlap: bool, optional + Wheter a candidate can be part of multiple motif sets (True), or if motif + sets should be mutually exclusive (False). + exclusion_factor : float, default=2. + A factor of the query length used to define the exclusion zone when + ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone + starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + :math:`id_timestamp + query_length//exclusion_factor`. + + Returns + ------- + list of ndarray, shape=(k,) + A list of at most ``k`` numpy arrays containing the indexes of the + candidates in each motif. + + """ + self._check_is_fitted() + + @final + def find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index: Optional[np.ndarray] = None, + allow_overlap: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): + """ + Find the top-k neighbors of X in the database. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k + neighbors of X, such as each of the ``k`` neighbors as a distance inferior or + equal to ``threshold``. By default, ``threshold`` is set to infinity. It is + possible for this method to return less than ``k`` neighbors, either if there + is less than ``k`` admissible candidate in the database, or if in the top-k + candidates, some do not meet the ``threshold`` condition. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The subsequence for which we want to identify nearest neighbors in the + database. + k : int, optional + Number of neighbors to return. + threshold : int, optional + A threshold on the distance to determine which candidates will be returned. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the k most dissimilar neighbors instead of the k most similar. + X_index : np.ndarray, shape=(2,), optional + If ``X`` is a subsequence of the database given in fit, specify its starting + index as (i_case, i_timestamp). If specified, this subsequence and the + neighboring ones (according to ``exclusion_factor``) won't be considered as + admissible candidates. + allow_overlap: bool, optional + Wheter the top-k candidates can be neighboring subsequences. + exclusion_factor : float, default=2. + A factor of the query length used to define the exclusion zone when + ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone + starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + :math:`id_timestamp + query_length//exclusion_factor`. + + Returns + ------- + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + neighbors. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the distances of the + neighbors to X. + + """ + self._check_is_fitted() + if self.length != X.shape[1] or self.n_channels_ != X.shape[0]: + raise ValueError( + f"Expected a subsequence of shape {(self.n_channels_, self.length)} but" + f" got {X.shape}" + ) + self._check_X_index(X_index) + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) + neighbors, distances = self._find_neighbors( + X, + k=k, + threshold=threshold, + inverse_distance=inverse_distance, + X_index=X_index, + allow_overlap=allow_overlap, + exclusion_factor=exclusion_factor, + ) + set_num_threads(prev_threads) + if len(neighbors) < k: + warnings.warn( + f"The number of admissible neighbors found is {len(neighbors)}, instead" + f" of {k}", + stacklevel=2, + ) + return neighbors, distances + + def _check_X_index(self, X_index: np.ndarray): + """ + Check wheter the X_index parameter is correctly formated and is admissible. + + Parameters + ---------- + X_index : np.ndarray, 1D array of shape (2) + Array of integer containing the sample and timestamp identifiers of the + starting point of a subsequence in X_. + + Returns + ------- + X_index : np.ndarray, 1D array of shape (2) + Array of integer containing the sample and timestamp identifiers of the + starting point of a subsequence in X_. + + """ + if X_index is not None: + if ( + isinstance(X_index, list) + and len(X_index) == 2 + and isinstance(X_index[0], int) + and isinstance(X_index[1], int) + ): + X_index = np.asarray(X_index, dtype=int) + elif len(X_index) != 2: + raise ValueError( + "Expected a numpy array or list of integers with 2 elements " + f"for X_index but got {X_index}" + ) + elif ( + not (isinstance(X_index[0], int) and isinstance(X_index[1], int)) + or X_index.dtype != int + ): + raise TypeError( + "Expected a numpy array or list of integers for X_index but got " + f"{X_index}" + ) + + if X_index[0] >= self.n_cases_: + raise ValueError( + "The sample ID (first element) of X_index cannot exced the number " + "of series in the collection given during fit. Expected a value " + f"between [0, {self.n_cases_ - 1}] but got {X_index[0]}" + ) + _max_timestamp = self.X_[X_index[0]].shape[1] - self.length + 1 + if X_index[1] >= _max_timestamp: + raise ValueError( + "The timestamp ID (second element) of X_index cannot exced the " + "number of timestamps minus the length parameter plus one. Expected" + f" a value between [0, {_max_timestamp - 1}] but got {X_index[1]}" + ) + return X_index + + def _compute_mean_std_from_collection(self, X: np.ndarray): + """ + Compute the mean and std of each subsequence of size ``length`` in X. + + Parameters + ---------- + X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + Collection of series from which we extract mean and stds. If it is an + unequal length collection, it should be a list of 2d numpy arrays. + + Returns + ------- + Tuple(np.ndarray, np.ndarray) + Both array are of shape (n_cases, n_timepoints-length+1, n_channels), + the first contains the means and the second the stds for each subsequence + of size ``length`` in X. + + """ + means = [] + stds = [] + + for i_x in range(len(X)): + _mean, _std = sliding_mean_std_one_series(X[i_x], self.length, 1) + stds.append(_std) + means.append(_mean) + + if self.metadata_["unequal_length"]: + return List(means), List(stds) + else: + return np.asarray(means), np.asarray(stds) + + @abstractmethod + def _fit(self, X, y=None): ... + + +class BaseMatrixProfile(BaseSubsequenceSearch): + """Base class for Matrix Profile methods using a length parameter.""" + + def _fit(self, X, y=None): + if self.length >= self.min_timepoints_: + raise ValueError( + "The length of the query should be inferior or equal to the length of " + "data (X_) provided during fit, but got {} for X and {} for X_".format( + self.length, self.min_timepoints_ + ) + ) + + if self.normalize: + self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) + self.X_ = X + return self + + def _find_motifs(): + raise NotImplementedError() + + def _find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + allow_overlap: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): + """ + Find the top-k neighbors of X in the database. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k + neighbors of X, such as each of the ``k`` neighbors as a distance inferior or + equal to ``threshold``. By default, ``threshold`` is set to infinity. It is + possible for this method to return less than ``k`` neighbors, either if there + is less than ``k`` admissible candidate in the database, or if in the top-k + candidates, some do not meet the ``threshold`` condition. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The subsequence for which we want to identify nearest neighbors in the + database. + k : int, optional + Number of neighbors to return. + threshold : int, optional + A threshold on the distance to determine which candidates will be returned. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the k most dissimilar neighbors instead of the k most similar. + X_index : np.ndarray, shape=(2,), optional + If ``X`` is a subsequence of the database given in fit, specify its starting + index as (i_case, i_timestamp). If specified, this subsequence and the + neighboring ones (according to ``exclusion_factor``) won't be considered as + admissible candidates. + allow_overlap: bool, optional + Wheter the top-k candidates can be neighboring subsequences. + exclusion_factor : float, default=2. + A factor of the query length used to define the exclusion zone when + ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone + starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + :math:`id_timestamp + query_length//exclusion_factor`. + """ + exclusion_size = self.length // exclusion_factor + dist_profiles = self.compute_distance_profile(X) + + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + + # Deal with self-matches + if X_index is not None: + _max_timestamp = self.X_[X_index[0]].shape[1] - self.length + ub = min(X_index[1] + exclusion_size, _max_timestamp) + lb = max(0, X_index[1] - exclusion_size) + dist_profiles[X_index[0]][lb:ub] = np.inf + + return _extract_top_k_from_dist_profile( + dist_profiles, + k, + threshold, + allow_overlap, + exclusion_size, + ) + + @abstractmethod + def compute_matrix_profile(X: Optional[np.ndarray] = None): + """Compute matrix profiles between X_ and X or between all series in X_.""" + ... + + @abstractmethod + def compute_distance_profile(X: np.ndarray): + """Compute distrance profiles between X_ and X (a series of size length).""" + ... diff --git a/aeon/similarity_search/matrix_profiles/tests/__init__.py b/aeon/similarity_search/subsequence_search/tests/__init__.py similarity index 100% rename from aeon/similarity_search/matrix_profiles/tests/__init__.py rename to aeon/similarity_search/subsequence_search/tests/__init__.py diff --git a/aeon/similarity_search/subsequence_search/tests/test__commons.py b/aeon/similarity_search/subsequence_search/tests/test__commons.py new file mode 100644 index 0000000000..23b07d78f7 --- /dev/null +++ b/aeon/similarity_search/subsequence_search/tests/test__commons.py @@ -0,0 +1,64 @@ +"""Test _commons.py functions.""" + +__maintainer__ = ["baraline"] + +import numpy as np +from numba.typed import List +from numpy.testing import assert_array_almost_equal + +from aeon.similarity_search.subsequence_search._commons import ( + _inverse_distance_profile_list, + fft_sliding_dot_product, + get_ith_products, +) +from aeon.testing.data_generation import ( + make_example_2d_numpy_list, + make_example_2d_numpy_series, +) + + +def test_fft_sliding_dot_product(): + """Test the fft_sliding_dot_product function.""" + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=4) + + values = fft_sliding_dot_product(X, Q) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0], X[0, i : i + 5]) for i in range(X.shape[1] - 5 + 1)], + ) + + +def test_get_ith_products(): + """Test i-th dot product of a subsequence of size L.""" + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + L = 5 + + values = get_ith_products(X, Q, L, 0) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0, 0:L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], + ) + + values = get_ith_products(X, Q, L, 4) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0, 4 : 4 + L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], + ) + + +def test__inverse_distance_profile_list(): + """Test method to inverse a TypedList of distance profiles.""" + X = make_example_2d_numpy_list(n_cases=2, return_y=False) + T = _inverse_distance_profile_list(List(X)) + assert_array_almost_equal(1 / (X[0] + 1e-8), T[0]) + assert_array_almost_equal(1 / (X[1] + 1e-8), T[1]) + + +def test__extract_top_k_from_dist_profile(): + """Test method to esxtract the top k candidates from a list of distance profiles.""" + ... diff --git a/aeon/similarity_search/subsequence_search/tests/test_stomp.py b/aeon/similarity_search/subsequence_search/tests/test_stomp.py new file mode 100644 index 0000000000..169eee135e --- /dev/null +++ b/aeon/similarity_search/subsequence_search/tests/test_stomp.py @@ -0,0 +1,238 @@ +"""Tests for stomp algorithm.""" + +__maintainer__ = ["baraline"] + +import numpy as np +import pytest +from numba.typed import List +from numpy.testing import assert_almost_equal, assert_array_almost_equal + +from aeon.similarity_search.subsequence_search._commons import get_ith_products +from aeon.similarity_search.subsequence_search._stomp import ( + _normalized_squared_dist_profile_one_series, + _normalized_squared_distance_profile, + _squared_dist_profile_one_series, + _squared_distance_profile, + _stomp, + _stomp_normalized, + _update_dot_products_one_series, +) +from aeon.testing.data_generation import ( + make_example_2d_numpy_series, + make_example_3d_numpy, + make_example_3d_numpy_list, +) +from aeon.utils.numba.general import ( + sliding_mean_std_one_series, + z_normalise_series_2d_with_mean_std, +) + +K_VALUES = [1, 3] + + +def _get_mean_sdts_inputs(X, Q, L): + X_means = [] + X_stds = [] + + for i_x in range(len(X)): + _mean, _std = sliding_mean_std_one_series(X[i_x], L, 1) + X_stds.append(_std) + X_means.append(_mean) + + Q_means = Q.mean(axis=1) + Q_stds = Q.std(axis=1) + + return X_means, X_stds, Q_means, Q_stds + + +def test__update_dot_products_one_series(): + """Test the _update_dot_product function.""" + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=20) + T = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + L = 7 + current_product = get_ith_products(X, T, L, 0) + for i_query in range(1, T.shape[1] - L + 1): + new_product = get_ith_products( + X, + T, + L, + i_query, + ) + current_product = _update_dot_products_one_series( + X, + T, + current_product, + L, + i_query, + ) + assert_array_almost_equal(new_product, current_product) + + +def test__squared_dist_profile_one_series(): + """Test Euclidean distance.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = get_ith_products(X, Q, L, 0) + dist_profile = _squared_dist_profile_one_series(QX, X, Q) + for i_t in range(X.shape[1] - L + 1): + assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) + + +def test__normalized_squared_dist_profile_one_series(): + """Test Euclidean distance.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = get_ith_products(X, Q, L, 0) + X_mean, X_std = sliding_mean_std_one_series(X, L, 1) + Q_mean = Q.mean(axis=1) + Q_std = Q.std(axis=1) + + dist_profile = _normalized_squared_dist_profile_one_series( + QX, X_mean, X_std, Q_mean, Q_std, L, Q.std(axis=1) <= 0 + ) + Q = z_normalise_series_2d_with_mean_std(Q, Q_mean, Q_std) + for i_t in range(X.shape[1] - L + 1): + S = z_normalise_series_2d_with_mean_std( + X[:, i_t : i_t + L], X_mean[:, i_t], X_std[:, i_t] + ) + assert_almost_equal(dist_profile[i_t], np.sum((S - Q) ** 2)) + + +def test__squared_distance_profile(): + """Test Euclidean distance profile calculation.""" + L = 3 + X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = np.asarray([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) + dist_profiles = _squared_distance_profile(QX, X, Q) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X[i_x, :, i_t : i_t + L] - Q) ** 2) + ) + + # test unequal length and multivariate + X = List( + make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=10, + max_n_timepoints=20, + return_y=False, + ) + ) + + Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) + QX = List([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) + dist_profiles = _squared_distance_profile(QX, X, Q) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X[i_x][:, i_t : i_t + L] - Q) ** 2) + ) + + +def test__normalized_squared_distance_profile(): + """Test Euclidean distance profile calculation.""" + L = 3 + X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = np.asarray([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) + + X_means, X_stds, Q_means, Q_stds = _get_mean_sdts_inputs(X, Q, L) + + X_means = np.asarray(X_means) + X_stds = np.asarray(X_stds) + + dist_profiles = _normalized_squared_distance_profile( + QX, X_means, X_stds, Q_means, Q_stds, L + ) + + Q_norm = z_normalise_series_2d_with_mean_std(Q, Q_means, Q_stds) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + X_sub_norm = z_normalise_series_2d_with_mean_std( + X[i_x, :, i_t : i_t + L], X_means[i_x][:, i_t], X_stds[i_x][:, i_t] + ) + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X_sub_norm - Q_norm) ** 2) + ) + + # test unequal length and multivariate + X = List( + make_example_3d_numpy_list( + n_cases=5, + n_channels=2, + min_n_timepoints=10, + max_n_timepoints=20, + return_y=False, + ) + ) + Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) + + QX = List([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) + + X_means, X_stds, Q_means, Q_stds = _get_mean_sdts_inputs(X, Q, L) + # Convert to numba typed list + X_means = List(X_means) + X_stds = List(X_stds) + + dist_profiles = _normalized_squared_distance_profile( + QX, X_means, X_stds, Q_means, Q_stds, L + ) + + Q_norm = z_normalise_series_2d_with_mean_std(Q, Q_means, Q_stds) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + X_sub_norm = z_normalise_series_2d_with_mean_std( + X[i_x][:, i_t : i_t + L], X_means[i_x][:, i_t], X_stds[i_x][:, i_t] + ) + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X_sub_norm - Q_norm) ** 2) + ) + + +# K_VALUES = [1, 3] +@pytest.mark.parametrize("k", K_VALUES) +def test__stomp(k): + """Test STOMP method.""" + L = 3 + X = np.array([[[1, 2, 3, 2, 1, 2, 3, 4, 5, 2, 1, 2, 2]]]) + T = np.array([[1, 1, 3, 2, 2]]) + XdotT = np.asarray([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) + + T_index = None + allow_overlap = False + threshold = np.inf + exclusion_size = L + inverse_distance = False + + MP, IP = _stomp( + X, + T, + XdotT, + L, + T_index, + k, + allow_overlap, + threshold, + exclusion_size, + inverse_distance, + ) + Expected_MP = [[1, 6], [1, 2], [1, 2, 5]] + Expected_IP = [[[0, 0], [0, 1]], [[0, 1], [0, 0]], [[0, 2], [0, 1], [0, 0]]] + for i in range(len(Expected_MP)): + assert_array_almost_equal(Expected_IP[i], IP[i]) + assert_array_almost_equal(Expected_MP[i], MP[i]) + + +@pytest.mark.parametrize("k", K_VALUES) +def test__stomp_normalized(k): + """Test STOMP normalized method.""" + _stomp_normalized + ... + + +# TODO : add tests for StompMatrixProfile diff --git a/aeon/similarity_search/tests/test__commons.py b/aeon/similarity_search/tests/test__commons.py deleted file mode 100644 index a97519ad31..0000000000 --- a/aeon/similarity_search/tests/test__commons.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Test _commons.py functions.""" - -__maintainer__ = ["baraline"] - -import numpy as np -from numpy.testing import assert_array_almost_equal - -from aeon.similarity_search._commons import ( - fft_sliding_dot_product, - naive_squared_distance_profile, - naive_squared_matrix_profile, -) - - -def test_fft_sliding_dot_product(): - """Test the fft_sliding_dot_product function.""" - X = np.random.rand(1, 10) - q = np.random.rand(1, 5) - - values = fft_sliding_dot_product(X, q) - - assert_array_almost_equal( - values[0], - [np.dot(q[0], X[0, i : i + 5]) for i in range(X.shape[1] - 5 + 1)], - ) - - -def test_naive_squared_distance_profile(): - """Test naive squared distance profile computation is correct.""" - X = np.zeros((1, 1, 6)) - X[0, 0] = np.arange(6) - Q = np.array([[1, 2, 3]]) - query_length = Q.shape[1] - mask = np.ones((X.shape[0], X.shape[2] - query_length + 1), dtype=bool) - dist_profile = naive_squared_distance_profile(X, Q, mask) - assert_array_almost_equal(dist_profile[0], np.array([3.0, 0.0, 3.0, 12.0])) - - -def test_naive_squared_matrix_profile(): - """Test naive squared matrix profile computation is correct.""" - X = np.zeros((1, 1, 6)) - X[0, 0] = np.arange(6) - Q = np.zeros((1, 6)) - - Q[0] = np.arange(6, 12) - query_length = 3 - mask = np.ones((X.shape[0], X.shape[2] - query_length + 1), dtype=bool) - matrix_profile = naive_squared_matrix_profile(X, Q, query_length, mask) - assert_array_almost_equal(matrix_profile, np.array([27.0, 48.0, 75.0, 108.0])) diff --git a/aeon/similarity_search/tests/test_query_search.py b/aeon/similarity_search/tests/test_query_search.py deleted file mode 100644 index f97f6a50bf..0000000000 --- a/aeon/similarity_search/tests/test_query_search.py +++ /dev/null @@ -1,176 +0,0 @@ -"""Tests for QuerySearch.""" - -__maintainer__ = ["baraline"] - -import numpy as np -import pytest -from numpy.testing import assert_almost_equal, assert_array_equal - -from aeon.similarity_search.query_search import QuerySearch - -DATATYPES = ["int64", "float64"] - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_mean_std_equal_length(dtype): - """Test the mean and std computation of QuerySearch.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(normalise=True) - search.fit(X) - _ = search.predict(q, X_index=(1, 2)) - for i in range(len(X)): - for j in range(X[i].shape[1] - q.shape[1] + 1): - subsequence = X[i, :, j : j + q.shape[1]] - assert_almost_equal(search.X_means_[i][:, j], subsequence.mean(axis=-1)) - assert_almost_equal(search.X_stds_[i][:, j], subsequence.std(axis=-1)) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_mean_std_unequal_length(dtype): - """Test the mean and std computation of QuerySearch on unequal length data.""" - X = [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6, 5]], dtype=dtype), - ] - - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(normalise=True) - search.fit(X) - _ = search.predict(q, X_index=(1, 2)) - for i in range(len(X)): - for j in range(X[i].shape[1] - q.shape[1] + 1): - subsequence = X[i][:, j : j + q.shape[1]] - assert_almost_equal(search.X_means_[i][:, j], subsequence.mean(axis=-1)) - assert_almost_equal(search.X_stds_[i][:, j], subsequence.std(axis=-1)) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_threshold_and_k(dtype): - """Test the k and threshold combination of QuerySearch.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(k=3, threshold=1) - search.fit(X) - dist, idx = search.predict(q) - assert_array_equal(idx, [(0, 2), (1, 2)]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_inverse_distance(dtype): - """Test the inverse distance parameter of QuerySearch.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(k=1, inverse_distance=True) - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 5)]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_euclidean(dtype): - """Test the functionality of QuerySearch with Euclidean distance.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(k=1) - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 2)]) - - search = QuerySearch(k=3) - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 2), (1, 2), (1, 1)]) - - _, idx = search.predict(q, apply_exclusion_to_result=True) - assert_array_equal(idx, [(0, 2), (1, 2), (1, 4)]) - - search = QuerySearch(k=1, normalise=True) - search.fit(X) - q = np.asarray([[8, 8, 10]], dtype=dtype) - _, idx = search.predict(q) - assert_array_equal(idx, [(1, 2)]) - - _, idx = search.predict(q, apply_exclusion_to_result=True) - assert_array_equal(idx, [(1, 2)]) - - search = QuerySearch(k=1, normalise=True) - search.fit(X) - _, idx = search.predict(q, X_index=(1, 2)) - assert_array_equal(idx, [(1, 0)]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_euclidean_unequal_length(dtype): - """Test the functionality of QuerySearch on unequal length data.""" - X = [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6, 5]], dtype=dtype), - ] - - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(k=1) - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 2)]) - - search = QuerySearch(k=3) - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 2), (1, 2), (1, 1)]) - - _, idx = search.predict(q, apply_exclusion_to_result=True) - assert_array_equal(idx, [(0, 2), (1, 2), (1, 4)]) - - search = QuerySearch(k=1, normalise=True) - search.fit(X) - q = np.asarray([[8, 8, 10]], dtype=dtype) - _, idx = search.predict(q) - assert_array_equal(idx, [(1, 2)]) - - _, idx = search.predict(q, apply_exclusion_to_result=True) - assert_array_equal(idx, [(1, 2)]) - - search = QuerySearch(k=1, normalise=True) - search.fit(X) - _, idx = search.predict(q, X_index=(1, 2)) - assert_array_equal(idx, [(1, 0)]) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_QuerySearch_speedup(dtype): - """Test the speedup functionality of QuerySearch.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - q = np.asarray([[3, 4, 5]], dtype=dtype) - - search = QuerySearch(k=1, speed_up="fastest") - search.fit(X) - _, idx = search.predict(q) - assert_array_equal(idx, [(0, 2)]) - - search = QuerySearch( - k=1, - distance="euclidean", - speed_up="fastest", - normalise=True, - ) - search.fit(X) - q = np.asarray([[8, 8, 10]], dtype=dtype) - _, idx = search.predict(q) - assert_array_equal(idx, [(1, 2)]) diff --git a/aeon/similarity_search/tests/test_series_search.py b/aeon/similarity_search/tests/test_series_search.py deleted file mode 100644 index a10109359c..0000000000 --- a/aeon/similarity_search/tests/test_series_search.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Tests for SeriesSearch similarity search algorithm.""" - -__maintainer__ = ["baraline"] - - -import numpy as np -import pytest - -from aeon.similarity_search.series_search import SeriesSearch - -DATATYPES = ["int64", "float64"] -K_VALUES = [1, 3] -normalise = [True, False] - -# See #2236 -# @pytest.mark.parametrize("k", K_VALUES) -# @pytest.mark.parametrize("normalise", normalise) -# def test_SeriesSearch_k(k, normalise): -# """Test the k and threshold combination of SeriesSearch.""" -# X = np.asarray([[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]]) -# S = np.asarray([[3, 4, 5, 4, 3, 4]]) -# L = 3 -# -# search = SeriesSearch(k=k, normalise=normalise) -# search.fit(X) -# mp, ip = search.predict(S, L) -# -# assert mp[0].shape[0] == ip[0].shape[0] == k -# assert len(mp) == len(ip) == S.shape[1] - L + 1 -# assert ip[0].shape[1] == 2 - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_SeriesSearch_error_predict(dtype): - """Test the functionality of SeriesSearch with Euclidean distance.""" - X = np.asarray( - [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype - ) - S = np.asarray([[3, 4, 5, 4, 3, 4, 5]], dtype=dtype) - L = 100 - - search = SeriesSearch() - search.fit(X) - with pytest.raises(ValueError): - mp, ip = search.predict(S, L) - L = 3 - S = np.asarray( - [ - [3, 4, 5, 4, 3, 4], - [6, 5, 3, 2, 4, 5], - ], - dtype=dtype, - ) - with pytest.raises(ValueError): - mp, ip = search.predict(S, L) - - S = [6, 5, 3, 2, 4, 5] - with pytest.raises(TypeError): - mp, ip = search.predict(S, L) - - -@pytest.mark.parametrize("dtype", DATATYPES) -def test_SeriesSearch_process_unequal_length(dtype): - """Test the functionality of SeriesSearch on unequal length data.""" - X = [ - np.array([[1, 2, 3, 4, 5, 6, 7, 8]], dtype=dtype), - np.array([[1, 2, 4, 4, 5, 6, 5]], dtype=dtype), - ] - S = np.asarray([[3, 4, 5, 4, 3, 4]], dtype=dtype) - L = 3 - - search = SeriesSearch() - search.fit(X) - mp, ip = search.predict(S, L) diff --git a/aeon/utils/numba/general.py b/aeon/utils/numba/general.py index 10e96abde6..b398a8414b 100644 --- a/aeon/utils/numba/general.py +++ b/aeon/utils/numba/general.py @@ -8,7 +8,9 @@ "first_order_differences_3d", "z_normalise_series_with_mean", "z_normalise_series", + "z_normalise_series_with_mean_std", "z_normalise_series_2d", + "z_normalise_series_2d_with_mean_std", "z_normalise_series_3d", "set_numba_random_seed", "choice_log", @@ -20,6 +22,7 @@ "slope_derivative_2d", "slope_derivative_3d", "generate_combinations", + "get_all_subsequences", ] From 52b0692a26353f302570323d9b6d4498e09071db Mon Sep 17 00:00:00 2001 From: Antoine Guillaume Date: Thu, 5 Dec 2024 17:20:47 +0100 Subject: [PATCH 02/18] Update _brute_force.py --- aeon/similarity_search/subsequence_search/_brute_force.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py index 7f95083f3b..691b81367a 100644 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -264,13 +264,6 @@ def _naive_squared_matrix_profile( if inverse_distance: dist_profiles = _inverse_distance_profile_list(dist_profiles) - # Deal with self-matches - if T_index is not None: - _max_timestamp = X[T_index].shape[1] - L - ub = min(i_q + exclusion_size, _max_timestamp) - lb = max(0, i_q - exclusion_size) - dist_profiles[T_index][lb:ub] = np.inf - top_dists, top_indexes = _extract_top_k_from_dist_profile( dist_profiles, k, From 7973a306c98c7c0b38fff56abd01e415732ca31d Mon Sep 17 00:00:00 2001 From: Antoine Guillaume Date: Thu, 5 Dec 2024 17:47:19 +0100 Subject: [PATCH 03/18] Update test__commons.py --- .../subsequence_search/tests/test__commons.py | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/aeon/similarity_search/subsequence_search/tests/test__commons.py b/aeon/similarity_search/subsequence_search/tests/test__commons.py index 23b07d78f7..b0e2764b0b 100644 --- a/aeon/similarity_search/subsequence_search/tests/test__commons.py +++ b/aeon/similarity_search/subsequence_search/tests/test__commons.py @@ -4,7 +4,7 @@ import numpy as np from numba.typed import List -from numpy.testing import assert_array_almost_equal +from numpy.testing import assert_array_almost_equal, assert_array_equal from aeon.similarity_search.subsequence_search._commons import ( _inverse_distance_profile_list, @@ -61,4 +61,57 @@ def test__inverse_distance_profile_list(): def test__extract_top_k_from_dist_profile(): """Test method to esxtract the top k candidates from a list of distance profiles.""" - ... + X = List([ + [5,4,3,3,1,3,2,5,1,4,1,0,1,2,2,7,8,1,5], + [5,1,0,1,0,0,5,4,3,5,6,1,4,2], + ]) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, + 1, + np.inf, + False, + 3 + ) + assert_array_equal(top_k_indexes, [[0,11]]) + assert_array_equal(top_k_indexes, [0]) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, + 5, + np.inf, + False, + 3 + ) + assert_array_equal(top_k_indexes, [[0,11],[1,2],[0,4],[0,17],[1,11]]) + assert_array_equal(top_k_indexes, [0,0,1,1,1]) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, + 5, + np.inf, + True, + 3 + ) + assert_array_equal(top_k_indexes, [[0,11],[1,2],[1,4],[1,5],[0,4]]) + assert_array_equal(top_k_indexes, [0,0,0,0,1]) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, + 5, + 0.5, + True, + 3 + ) + assert_array_equal(top_k_indexes, [[0,11],[1,2],[1,4],[1,5]]) + assert_array_equal(top_k_indexes, [0,0,0,0]) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, + 5, + 0.5, + False, + 3 + ) + assert_array_equal(top_k_indexes, [[0,11],[1,2]]) + assert_array_equal(top_k_indexes, [0,0]) From ad02b8466fb51e2fde63f1bcfec43166d5026116 Mon Sep 17 00:00:00 2001 From: baraline Date: Fri, 27 Dec 2024 09:05:05 +0100 Subject: [PATCH 04/18] WIP mock and test --- .../series_search/__init__.py | 8 +- .../subsequence_search/__init__.py | 8 +- .../subsequence_search/_brute_force.py | 140 +++++++----- .../subsequence_search/_commons.py | 48 +++- .../subsequence_search/_stomp.py | 211 ++++++++++-------- .../subsequence_search/base.py | 172 +++++++++++--- .../tests/test_brute_force.py | 155 +++++++++++++ .../{test__commons.py => test_commons.py} | 84 +++---- .../subsequence_search/tests/test_stomp.py | 166 +++++++++++--- aeon/testing/mock_estimators/__init__.py | 3 - .../_mock_similarity_search.py | 21 -- .../_mock_similarity_searchers.py | 72 ++++++ aeon/utils/base/_register.py | 14 +- docs/api_reference/utils.rst | 1 - 14 files changed, 807 insertions(+), 296 deletions(-) create mode 100644 aeon/similarity_search/subsequence_search/tests/test_brute_force.py rename aeon/similarity_search/subsequence_search/tests/{test__commons.py => test_commons.py} (59%) delete mode 100644 aeon/testing/mock_estimators/_mock_similarity_search.py create mode 100644 aeon/testing/mock_estimators/_mock_similarity_searchers.py diff --git a/aeon/similarity_search/series_search/__init__.py b/aeon/similarity_search/series_search/__init__.py index f576c41f03..2f69dab51a 100644 --- a/aeon/similarity_search/series_search/__init__.py +++ b/aeon/similarity_search/series_search/__init__.py @@ -1,7 +1,5 @@ -"""Similarity search module.""" +"""Series search module.""" -__all__ = ["BaseSimilaritySearch", "QuerySearch", "SeriesSearch"] +__all__ = ["BaseSeriesSearch", "BaseIndexSearch"] -from aeon.similarity_search.base import BaseSimilaritySearch -from aeon.similarity_search.query_search import QuerySearch -from aeon.similarity_search.series_search import SeriesSearch +from aeon.similarity_search.series_search.base import BaseIndexSearch, BaseSeriesSearch diff --git a/aeon/similarity_search/subsequence_search/__init__.py b/aeon/similarity_search/subsequence_search/__init__.py index dfca8ee18c..c5de805eb6 100644 --- a/aeon/similarity_search/subsequence_search/__init__.py +++ b/aeon/similarity_search/subsequence_search/__init__.py @@ -1,5 +1,9 @@ -"""Similarity search module.""" +"""Subsequence search module.""" -__all__ = ["StompMatrixProfile"] +__all__ = ["BaseSubsequenceSearch", "BaseMatrixProfile", "StompMatrixProfile"] from aeon.similarity_search.subsequence_search._stomp import StompMatrixProfile +from aeon.similarity_search.subsequence_search.base import ( + BaseMatrixProfile, + BaseSubsequenceSearch, +) diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py index 691b81367a..6c26925a32 100644 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -16,8 +16,8 @@ from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile from aeon.utils.numba.general import ( get_all_subsequences, + z_normalise_series_2d, z_normalise_series_3d, - z_normalize_series_2d, ) # TODO : check function params and make docstrings @@ -25,7 +25,7 @@ class BruteForceMatrixProfile(BaseMatrixProfile): - """.""" + """Estimator to compute matrix profile and distance profile using brute force.""" def compute_matrix_profile( self, @@ -33,37 +33,51 @@ def compute_matrix_profile( threshold, exclusion_size, inverse_distance, - allow_overlap, + allow_neighboring_matches, X: Optional[np.ndarray] = None, X_index: Optional[int] = None, ): """ - . + Compute matrix profiles. + + The matrix profiles are computed on the collection given in fit. If ``X`` is + not given, computes the matrix profile of each series in the collection. If it + is given, only computes it for ``X``. Parameters ---------- - k : TYPE - DESCRIPTION. - threshold : TYPE - DESCRIPTION. - exclusion_size : TYPE - DESCRIPTION. - inverse_distance : TYPE - DESCRIPTION. + k : int + The number of best matches to return during predict for each subsequence. + threshold : float + The number of best matches to return during predict for each subsequence. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the worst matches to the query will be returned instead of the best ones. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestomp - exclusion_size` and + :math:`id_timestomp + exclusion_size` which cannot be returned + as best match if :math:`id_timestomp` was already selected. By default, + the value None means that this is not used. X : Optional[np.ndarray], optional - DESCRIPTION. The default is None. + The time series on which the matrix profile will be compute. + The default is None, meaning that the series in the collection given in fit + will be used instead. X_index : Optional[int], optional - DESCRIPTION. The default is None. - : TYPE - DESCRIPTION. + If ``X`` is a series of the database given in fit, specify its index in + ``X_``. If specified, each query of this series won't be able to match with + its neighboring subsequences. Returns ------- - MP : TYPE - DESCRIPTION. - IP : TYPE - DESCRIPTION. - + MP : array of shape (series_length - L + 1,) + Matrix profile distances for each query subsequence. If X is none, this + will be a list of MP for each series in X_. + IP : array of shape (series_length - L + 1,) + Indexes of the top matches for each query subsequence. If X is none, this + will be a list of MP for each series in X_. """ # pairwise if none if X is None: @@ -87,11 +101,11 @@ def compute_matrix_profile( self.length, X_index, k, - allow_overlap, threshold, + allow_neighboring_matches, exclusion_size, inverse_distance, - normalize=self.normalize, + normalise=self.normalise, ) return MP, IP @@ -114,7 +128,7 @@ def compute_distance_profile(self, X: np.ndarray): """ distance_profiles = _naive_squared_distance_profile( - self.X_, X, normalize=self.normalize + self.X_, X, normalise=self.normalise ) if not self.metadata_["unequal_length"]: @@ -153,7 +167,7 @@ def _compute_dist_profile(X_subs, q): def _naive_squared_distance_profile( X, Q, - normalize=False, + normalise=False, ): """ Compute a squared euclidean distance profile. @@ -164,8 +178,8 @@ def _naive_squared_distance_profile( Input time series dataset to search in. Q : array, shape=(n_channels, query_length) Query used during the search. - normalize : bool - Wheter to use a z-normalized distance. + normalise : bool + Wheter to use a z-normalised distance. Returns ------- @@ -178,14 +192,16 @@ def _naive_squared_distance_profile( # Init distance profile array with unequal length support for i in range(len(X)): dist_profiles.append(np.zeros(X[i].shape[1] - query_length + 1)) - if normalize: - Q = z_normalize_series_2d(Q) + if normalise: + Q = z_normalise_series_2d(Q) else: Q = Q.astype(np.float64) - for i in prange(len(X)): + for _i in prange(len(X)): + # cast uint64 due to parallel prange + i = np.int64(_i) X_subs = get_all_subsequences(X[i], query_length, 1) - if normalize: + if normalise: X_subs = z_normalise_series_3d(X_subs) dist_profile = _compute_dist_profile(X_subs, Q) @@ -198,32 +214,50 @@ def _naive_squared_matrix_profile( X, T, L, - k, T_index, + k, threshold, - inverse_distance, - allow_overlap, + allow_neighboring_matches, exclusion_size, - normalize=False, + inverse_distance, + normalise=False, ): """ Compute a squared euclidean matrix profile. Parameters ---------- - X : array, shape=(n_samples, n_channels, n_timepoints_x) - Input time series dataset to search in. - T : array, shape=(n_channels, n_timepoints_t) - Time series from which queries are extracted. - query_length : int - Length of the queries to extract from T. + X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + The input samples. If X is an unquel length collection, expect a TypedList + of 2D arrays of shape (n_channels, n_timepoints) + T : np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + L : int + Length of the subsequences used for the distance computation. T_index : int, - If ``X`` is a subsequence of the database given in fit, specify its starting - index as (i_case, i_timestamp). If specified, this subsequence and the - neighboring ones (according to ``exclusion_factor``) won't be considered as - admissible candidates. - normalize : bool - Wheter to use a z-normalized distance. + If ``T`` is a series of ``X``, specify its index + in ``X``. If specified, each query of this series won't be able to + match with its neighboring subsequences. + k : int + The number of best matches to return during predict for each subsequence. + threshold : float + The number of best matches to return during predict for each subsequence. + allow_neighboring_matches : bool + Wheter the top-k candidates can be neighboring subsequences. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestomp - exclusion_size` and + :math:`id_timestomp + exclusion_size` which cannot be returned + as best match if :math:`id_timestomp` was already selected. By default, + the value None means that this is not used. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. + normalise : bool + Wheter to use a z-normalised distance. Returns ------- @@ -242,14 +276,14 @@ def _naive_squared_matrix_profile( X_subs = List() for i in range(len(X)): i_subs = get_all_subsequences(X[i], L, 1) - if normalize: - i_subs = z_normalise_series_3d(X_subs) + if normalise: + i_subs = z_normalise_series_3d(i_subs) X_subs.append(i_subs) for i_q in range(n_queries): Q = T[:, i : i + L] - if normalize: - Q = z_normalize_series_2d(Q) + if normalise: + Q = z_normalise_series_2d(Q) for i_x in prange(len(X)): dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = _compute_dist_profile( X_subs[i_x], Q @@ -264,11 +298,11 @@ def _naive_squared_matrix_profile( if inverse_distance: dist_profiles = _inverse_distance_profile_list(dist_profiles) - top_dists, top_indexes = _extract_top_k_from_dist_profile( + top_indexes, top_dists = _extract_top_k_from_dist_profile( dist_profiles, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, ) diff --git a/aeon/similarity_search/subsequence_search/_commons.py b/aeon/similarity_search/subsequence_search/_commons.py index e2e0aa54df..03e0ee1ac3 100644 --- a/aeon/similarity_search/subsequence_search/_commons.py +++ b/aeon/similarity_search/subsequence_search/_commons.py @@ -73,29 +73,61 @@ def _extract_top_k_from_dist_profile( dist_profiles, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, ): + """ + Given an array (or list) of distance profiles, extract the top k lower distances. + + Parameters + ---------- + dist_profiles : np.ndarray, shape = (n_samples, n_timepoints - length + 1) + A collection of distance profiles computed from ``n_samples`` time series of + size ``n_timepoints``, giving distance profiles of length + ``n_timepoints - length + 1``, with ``length`` the size of the query used to + compute the distance profiles. + k : int + Number of best matches to return + threshold : float + A threshold on the distances of the best matches. To be returned, a candidate + must have a distance bellow this threshold. This can reduce the number of + returned matches to be bellow ``k`` + allow_neighboring_matches : bool + Wheter to allow returning matches that are in the same neighborhood. + exclusion_size : int + The size of the exlusion size to apply when ``allow_neighboring_matches`` is + False. It is applied on both side of existing matches (+/- their indexes). + + Returns + ------- + top_k_indexes : np.ndarray, shape = (k, 2) + The indexes of the best matches in ``distance_profiles``. + top_k_distances : np.ndarray, shape = (k) + The distances of the best matches. + + """ top_k_indexes = np.zeros((2 * k, 2), dtype=np.int64) - 1 top_k_distances = np.full(2 * k, np.inf) for i_profile in range(len(dist_profiles)): # Extract top-k without neighboring matches - if not allow_overlap: + if not allow_neighboring_matches: _sorted_indexes = np.argsort(dist_profiles[i_profile]) _top_k_indexes = np.zeros(k, dtype=np.int64) - 1 - _current_k = 1 - _top_k_indexes[0] = _sorted_indexes[0] - _current_j = 1 + _current_k = 0 + _current_j = 0 # Until we extract k value or explore all the array while _current_k < k and _current_j < len(_sorted_indexes): _insert = True # Check for validity with each previously inserted for i_k in range(_current_k): - ub = min(_top_k_indexes[i_k] + exclusion_size, len(dist_profiles)) + ub = min( + _top_k_indexes[i_k] + exclusion_size, + len(dist_profiles[i_profile]), + ) lb = max(_top_k_indexes[i_k] - exclusion_size, 0) if ( - _sorted_indexes[_current_j] < lb - or _sorted_indexes[_current_j] > ub + _sorted_indexes[_current_j] >= lb + and _sorted_indexes[_current_j] <= ub ): _insert = False break diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py index 8986a41926..0dd75971f8 100644 --- a/aeon/similarity_search/subsequence_search/_stomp.py +++ b/aeon/similarity_search/subsequence_search/_stomp.py @@ -1,10 +1,10 @@ """Implementation of STOMP with squared euclidean distance.""" -from typing import Optional - __maintainer__ = ["baraline"] +from typing import Optional + import numpy as np from numba import njit, prange from numba.typed import List @@ -16,15 +16,14 @@ get_ith_products, ) from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile -from aeon.utils.numba.general import AEON_NUMBA_STD_THRESHOLD - -# TODO : check and order parameters of functions in base and here -# TODO : check function params and make docstrings to be consistent with brute force -# TODO : validate tests +from aeon.utils.numba.general import ( + AEON_NUMBA_STD_THRESHOLD, + sliding_mean_std_one_series, +) class StompMatrixProfile(BaseMatrixProfile): - """.""" + """Estimator to compute matrix profile and distance profile using STOMP.""" def compute_matrix_profile( self, @@ -32,41 +31,53 @@ def compute_matrix_profile( threshold, exclusion_size, inverse_distance, - allow_overlap, + allow_neighboring_matches, X: Optional[np.ndarray] = None, X_index: Optional[int] = None, ): """ - . + Compute matrix profiles. + + The matrix profiles are computed on the collection given in fit. If ``X`` is + not given, computes the matrix profile of each series in the collection. If it + is given, only computes it for ``X``. Parameters ---------- - k : TYPE - DESCRIPTION. - threshold : TYPE - DESCRIPTION. - exclusion_size : TYPE - DESCRIPTION. - inverse_distance : TYPE - DESCRIPTION. + k : int + The number of best matches to return during predict for each subsequence. + threshold : float + The number of best matches to return during predict for each subsequence. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the worst matches to the query will be returned instead of the best ones. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestomp - exclusion_size` and + :math:`id_timestomp + exclusion_size` which cannot be returned + as best match if :math:`id_timestomp` was already selected. By default, + the value None means that this is not used. X : Optional[np.ndarray], optional - DESCRIPTION. The default is None. + The time series on which the matrix profile will be compute. + The default is None, meaning that the series in the collection given in fit + will be used instead. X_index : Optional[int], optional If ``X`` is a series of the database given in fit, specify its index in ``X_``. If specified, each query of this series won't be able to match with its neighboring subsequences. - : TYPE - DESCRIPTION. Returns ------- - MP : TYPE - DESCRIPTION. - IP : TYPE - DESCRIPTION. - + MP : array of shape (series_length - L + 1,) + Matrix profile distances for each query subsequence. If X is none, this + will be a list of MP for each series in X_. + IP : array of shape (series_length - L + 1,) + Indexes of the top matches for each query subsequence. If X is none, this + will be a list of MP for each series in X_. """ - # pairwise if none + # If we compute matrix profiles for each series in X_ if X is None: MP = [] IP = [] @@ -81,6 +92,7 @@ def compute_matrix_profile( ) MP.append(_MP) IP.append(_IP) + # else we compute matrix profiles using X on the series in X_ else: XdotT = [ get_ith_products(self.X[i], X, self.length, 0) @@ -90,12 +102,13 @@ def compute_matrix_profile( XdotT = np.asarray(XdotT) elif isinstance(X, List): XdotT = List(XdotT) + if X_index is None: - X_means, X_stds = 0 + X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) else: X_means, X_stds = self.X_means_[i], self.X_stds_[i] - if self.normalize: - MP, IP = _stomp_normalized( + if self.normalise: + MP, IP = _stomp_normalised( self.X_, X, XdotT, @@ -107,11 +120,10 @@ def compute_matrix_profile( X_index, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, inverse_distance, ) - else: MP, IP = _stomp( self.X_, @@ -120,12 +132,11 @@ def compute_matrix_profile( self.length, X_index, k, - allow_overlap, threshold, + allow_neighboring_matches, exclusion_size, inverse_distance, ) - return MP, IP def compute_distance_profile(self, X: np.ndarray): @@ -151,8 +162,8 @@ def compute_distance_profile(self, X: np.ndarray): else: QX = np.asarray(QX) - if self.normalize: - distance_profiles = _normalized_squared_distance_profile( + if self.normalise: + distance_profiles = _normalised_squared_distance_profile( QX, self.X_means_, self.X_stds_, @@ -172,8 +183,8 @@ def compute_distance_profile(self, X: np.ndarray): return distance_profiles -@njit(cache=True, parallel=True, fastmath=True) -def _stomp_normalized( +@njit(cache=True, fastmath=True) +def _stomp_normalised( X, T, XdotT, @@ -185,12 +196,12 @@ def _stomp_normalized( T_index, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, inverse_distance, ): """ - Compute the Matrix Profile using the STOMP algorithm with normalized distances. + Compute the Matrix Profile using the STOMP algorithm with normalised distances. X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) The input samples. If X is an unquel length collection, expect a TypedList @@ -198,8 +209,6 @@ def _stomp_normalized( T : np.ndarray, 2D array of shape (n_channels, series_length) The series used for similarity search. Note that series_length can be equal, superior or inferior to n_timepoints, it doesn't matter. - L : int - Length of the subsequences used for the distance computation. XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) Precomputed dot products between each time series in X and the query series T. X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) @@ -212,18 +221,19 @@ def _stomp_normalized( Means of each subsequences of T of size L. T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) Stds of each subsequences of T of size L. + L : int + Length of the subsequences used for the distance computation. T_index : int, If ``T`` is a series of the database given in fit, specify its index in ``X_``. If specified, each query of this series won't be able to match with its neighboring subsequences. - k : int, default=1 + k : int, The number of best matches to return during predict for each subsequence. - threshold : float, default=np.inf + threshold : float The number of best matches to return during predict for each subsequence. - inverse_distance : bool, default=False - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - exclusion_size : int, optional + allow_neighboring_matches : bool + Wheter the top-k candidates can be neighboring subsequences. + exclusion_size : int The size of the exclusion zone used to prevent returning as top k candidates the ones that are close to each other (for example i and i+1). It is used to define a region between @@ -231,6 +241,9 @@ def _stomp_normalized( :math:`id_timestomp + exclusion_size` which cannot be returned as best match if :math:`id_timestomp` was already selected. By default, the value None means that this is not used. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. Returns ------- @@ -244,25 +257,12 @@ def _stomp_normalized( MP = List() IP = List() - # Init List to allow parallel, we'll re-use it for all dist profiles - dist_profiles = List() - for i_x in range(len(X)): - dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) - for i_q in range(n_queries): - for i_x in prange(len(X)): - dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = ( - _normalized_squared_dist_profile_one_series( - XdotT[i_x], - X_means[i_x], - X_stds[i_x], - T_means[:, i_q], - T_stds[:, i_q], - L, - T_stds[:, i_q] <= AEON_NUMBA_STD_THRESHOLD, - ) - ) - if i_q + 1 < n_queries: + dist_profiles = _normalised_squared_distance_profile( + XdotT, X_means, X_stds, T_means[:, i_q], T_stds[:, i_q], L + ) + if i_q + 1 < n_queries: + for i_x in range(len(X)): XdotT[i_x] = _update_dot_products_one_series( X[i_x], T, XdotT[i_x], L, i_q + 1 ) @@ -281,7 +281,7 @@ def _stomp_normalized( dist_profiles, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, ) @@ -291,7 +291,7 @@ def _stomp_normalized( return MP, IP -@njit(cache=True, parallel=True, fastmath=True) +@njit(cache=True, fastmath=True) def _stomp( X, T, @@ -299,28 +299,65 @@ def _stomp( L, T_index, k, - allow_overlap, threshold, + allow_neighboring_matches, exclusion_size, inverse_distance, ): + """ + Compute the Matrix Profile using the STOMP algorithm with non-normalised distances. + + X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + The input samples. If X is an unquel length collection, expect a TypedList + of 2D arrays of shape (n_channels, n_timepoints) + T : np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) + Precomputed dot products between each time series in X and the query series T. + L : int + Length of the subsequences used for the distance computation. + T_index : int, + If ``T`` is a series of the database given in fit, specify its index + in ``X_``. If specified, each query of this series won't be able to + match with its neighboring subsequences. + k : int, + The number of best matches to return during predict for each subsequence. + threshold : float + The number of best matches to return during predict for each subsequence. + allow_neighboring_matches : bool + Wheter the top-k candidates can be neighboring subsequences. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestomp - exclusion_size` and + :math:`id_timestomp + exclusion_size` which cannot be returned + as best match if :math:`id_timestomp` was already selected. By default, + the value None means that this is not used. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. + + Returns + ------- + tuple of np.ndarray + - MP : array of shape (series_length - L + 1,) + Matrix profile distances for each query subsequence. + - IP : array of shape (series_length - L + 1,) + Indexes of the top matches for each query subsequence. + """ n_queries = T.shape[1] - L + 1 MP = List() IP = List() - # Init List to allow parallel, we'll re-use it for all dist profiles - dist_profiles = List() - for i_x in range(len(X)): - dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) # For each query of size L in T for i_q in range(n_queries): Q = T[:, i_q : i_q + L] + dist_profiles = _squared_distance_profile(XdotT, X, Q) # For each series in X compute distance profile to the query - for i_x in prange(len(X)): - dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = ( - _squared_dist_profile_one_series(XdotT[i_x], X[i_x], Q) - ) - if i_q + 1 < n_queries: + if i_q + 1 < n_queries: + for i_x in range(len(X)): XdotT[i_x] = _update_dot_products_one_series( X[i_x], T, XdotT[i_x], L, i_q + 1 ) @@ -339,7 +376,7 @@ def _stomp( dist_profiles, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, ) @@ -486,11 +523,11 @@ def _squared_dist_profile_one_series(QT, T, Q): @njit(cache=True, fastmath=True, parallel=True) -def _normalized_squared_distance_profile( +def _normalised_squared_distance_profile( QX, X_means, X_stds, Q_means, Q_stds, query_length ): """ - Compute the normalized squared distance profiles between query subsequence and input time series. + Compute the normalised squared distance profiles between query subsequence and input time series. Parameters ---------- @@ -513,7 +550,7 @@ def _normalized_squared_distance_profile( ------- List of np.ndarray List of 2D arrays, each of shape (n_channels, n_timepoints - query_length + 1). - Each array contains the normalized squared distance profile between the query subsequence and the corresponding time series. + Each array contains the normalised squared distance profile between the query subsequence and the corresponding time series. Entries in the array are set to infinity where the mask is False. """ distance_profiles = List() @@ -526,7 +563,7 @@ def _normalized_squared_distance_profile( for _i_instance in prange(len(QX)): # iterator is uint64 with prange and parallel so cast to int to avoid warnings i_instance = np.int64(_i_instance) - distance_profiles[i_instance] = _normalized_squared_dist_profile_one_series( + distance_profiles[i_instance] = _normalised_squared_dist_profile_one_series( QX[i_instance], X_means[i_instance], X_stds[i_instance], @@ -539,11 +576,11 @@ def _normalized_squared_distance_profile( @njit(cache=True, fastmath=True) -def _normalized_squared_dist_profile_one_series( +def _normalised_squared_dist_profile_one_series( QT, T_means, T_stds, Q_means, Q_stds, query_length, Q_is_constant ): """ - Compute the z-normalized squared Euclidean distance profile for one time series. + Compute the z-normalised squared Euclidean distance profile for one time series. Parameters ---------- @@ -568,8 +605,8 @@ def _normalized_squared_dist_profile_one_series( ------- np.ndarray 2D array of shape (n_channels, n_timepoints - query_length + 1) containing the - z-normalized squared distance profile between the query subsequence and the time - series. Entries are computed based on the z-normalized values, with special + z-normalised squared distance profile between the query subsequence and the time + series. Entries are computed based on the z-normalised values, with special handling for constant values. """ n_channels, profile_length = QT.shape diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py index 1d49004472..7df358e5ec 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/base.py @@ -17,8 +17,9 @@ ) from aeon.utils.numba.general import sliding_mean_std_one_series - # We can define a BaseVariableLengthSubsequenceSearch later for VALMOD and the likes. + + class BaseSubsequenceSearch(BaseSimilaritySearch): """ Base class for similarity search on time series subsequences. @@ -27,8 +28,8 @@ class BaseSubsequenceSearch(BaseSimilaritySearch): ---------- length : int The length of the subsequence to be considered. - normalize : bool, optional - Whether the inputs should be z-normalized. The default is False. + normalise : bool, optional + Whether the inputs should be z-normalised. The default is False. n_jobs : int, optional Number of parallel jobs to use. The default is 1. """ @@ -37,19 +38,21 @@ class BaseSubsequenceSearch(BaseSimilaritySearch): def __init__( self, length: int, - normalize: Optional[bool] = False, + normalise: Optional[bool] = False, n_jobs: Optional[int] = 1, ): self.length = length - super().__init__(n_jobs=n_jobs, normalize=normalize) + super().__init__(n_jobs=n_jobs, normalise=normalise) @final def find_motifs( self, - k: int, - threshold: float, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, X: Optional[np.ndarray] = None, - allow_overlap: Optional[bool] = False, + X_index: Optional[int] = None, + inverse_distance: Optional[bool] = False, + allow_neighboring_matches: Optional[bool] = False, exclusion_factor: Optional[float] = 2.0, ): """ @@ -71,13 +74,21 @@ def find_motifs( A series in which we want to indentify motifs. If provided, the motifs extracted should appear in X and in the database given in fit. If not provided, the motifs will be extracted only from the database given in fit. - allow_overlap: bool, optional + X_index : Optional[int], optional + If ``X`` is a series of the database given in fit, specify its index in + ``X_``. If specified, each query of this series won't be able to match with + its neighboring subsequences. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the anomalies instead of motifs. + allow_neighboring_matches: bool, optional Wheter a candidate can be part of multiple motif sets (True), or if motif sets should be mutually exclusive (False). exclusion_factor : float, default=2. A factor of the query length used to define the exclusion zone when - ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone - starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + ``allow_neighboring_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - query_length//exclusion_factor` and end at :math:`id_timestamp + query_length//exclusion_factor`. Returns @@ -88,6 +99,19 @@ def find_motifs( """ self._check_is_fitted() + prev_threads = get_num_threads() + X_index = self._check_X_index_int(X_index) + motifs = self._find_motifs( + k=k, + threshold=threshold, + exclusion_factor=exclusion_factor, + inverse_distance=inverse_distance, + allow_neighboring_matches=allow_neighboring_matches, + X=X, + X_index=X_index, + ) + set_num_threads(prev_threads) + return motifs @final def find_neighbors( @@ -97,7 +121,7 @@ def find_neighbors( threshold: Optional[float] = np.inf, inverse_distance: Optional[bool] = False, X_index: Optional[np.ndarray] = None, - allow_overlap: Optional[bool] = False, + allow_neighboring_matches: Optional[bool] = False, exclusion_factor: Optional[float] = 2.0, ): """ @@ -127,12 +151,13 @@ def find_neighbors( index as (i_case, i_timestamp). If specified, this subsequence and the neighboring ones (according to ``exclusion_factor``) won't be considered as admissible candidates. - allow_overlap: bool, optional + allow_neighboring_matches: bool, optional Wheter the top-k candidates can be neighboring subsequences. exclusion_factor : float, default=2. A factor of the query length used to define the exclusion zone when - ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone - starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + ``allow_neighboring_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - query_length//exclusion_factor` and end at :math:`id_timestamp + query_length//exclusion_factor`. Returns @@ -151,7 +176,7 @@ def find_neighbors( f"Expected a subsequence of shape {(self.n_channels_, self.length)} but" f" got {X.shape}" ) - self._check_X_index(X_index) + X_index = self._check_X_index_array(X_index) prev_threads = get_num_threads() set_num_threads(self._n_jobs) neighbors, distances = self._find_neighbors( @@ -160,7 +185,7 @@ def find_neighbors( threshold=threshold, inverse_distance=inverse_distance, X_index=X_index, - allow_overlap=allow_overlap, + allow_neighboring_matches=allow_neighboring_matches, exclusion_factor=exclusion_factor, ) set_num_threads(prev_threads) @@ -172,10 +197,41 @@ def find_neighbors( ) return neighbors, distances - def _check_X_index(self, X_index: np.ndarray): + def _check_X_index_int(self, X_index: int): """ Check wheter the X_index parameter is correctly formated and is admissible. + This check is made for motif search functions. + + Parameters + ---------- + X_index : int + Index of a series in X_. + + Returns + ------- + X_index : int + Index of a series in X_ + + """ + if X_index is not None: + if not isinstance(X_index, int): + raise TypeError("Expected an integer for X_index but got {X_index}") + + if X_index >= self.n_cases_ or X_index < 0: + raise ValueError( + "The value of X_index cannot exced the number " + "of series in the collection given during fit. Expected a value " + f"between [0, {self.n_cases_ - 1}] but got {X_index}" + ) + return X_index + + def _check_X_index_array(self, X_index: np.ndarray): + """ + Check wheter the X_index parameter is correctly formated and is admissible. + + This check is made for neighbour search functions. + Parameters ---------- X_index : np.ndarray, 1D array of shape (2) @@ -198,12 +254,12 @@ def _check_X_index(self, X_index: np.ndarray): ): X_index = np.asarray(X_index, dtype=int) elif len(X_index) != 2: - raise ValueError( + raise TypeError( "Expected a numpy array or list of integers with 2 elements " f"for X_index but got {X_index}" ) elif ( - not (isinstance(X_index[0], int) and isinstance(X_index[1], int)) + not (isinstance(X_index[0], int) or not isinstance(X_index[1], int)) or X_index.dtype != int ): raise TypeError( @@ -211,7 +267,7 @@ def _check_X_index(self, X_index: np.ndarray): f"{X_index}" ) - if X_index[0] >= self.n_cases_: + if X_index[0] >= self.n_cases_ or X_index[0] < 0: raise ValueError( "The sample ID (first element) of X_index cannot exced the number " "of series in the collection given during fit. Expected a value " @@ -260,6 +316,30 @@ def _compute_mean_std_from_collection(self, X: np.ndarray): @abstractmethod def _fit(self, X, y=None): ... + @abstractmethod + def _find_motifs( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + allow_neighboring_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): ... + + @abstractmethod + def _find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + allow_neighboring_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): ... + class BaseMatrixProfile(BaseSubsequenceSearch): """Base class for Matrix Profile methods using a length parameter.""" @@ -273,13 +353,33 @@ def _fit(self, X, y=None): ) ) - if self.normalize: + if self.normalise: self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) self.X_ = X return self - def _find_motifs(): - raise NotImplementedError() + def _find_motifs( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + allow_neighboring_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): + exclusion_size = self.length // exclusion_factor + + MP, IP = self.compute_matrix_profile( + k, + threshold, + exclusion_size, + inverse_distance, + allow_neighboring_matches, + X=X, + X_index=X_index, + ) + # TODO : implement logic here def _find_neighbors( self, @@ -288,7 +388,7 @@ def _find_neighbors( threshold: Optional[float] = np.inf, inverse_distance: Optional[bool] = False, X_index=None, - allow_overlap: Optional[bool] = False, + allow_neighboring_matches: Optional[bool] = False, exclusion_factor: Optional[float] = 2.0, ): """ @@ -318,12 +418,13 @@ def _find_neighbors( index as (i_case, i_timestamp). If specified, this subsequence and the neighboring ones (according to ``exclusion_factor``) won't be considered as admissible candidates. - allow_overlap: bool, optional + allow_neighboring_matches: bool, optional Wheter the top-k candidates can be neighboring subsequences. exclusion_factor : float, default=2. A factor of the query length used to define the exclusion zone when - ``allow_overlap`` is set to False. For a given timestamp, the exclusion zone - starts from :math:`id_timestamp - query_length//exclusion_factor` and end at + ``allow_neighboring_matches`` is set to False. For a given timestamp, the + exclusion zone starts from + :math:`id_timestamp - query_length//exclusion_factor` and end at :math:`id_timestamp + query_length//exclusion_factor`. """ exclusion_size = self.length // exclusion_factor @@ -343,16 +444,25 @@ def _find_neighbors( dist_profiles, k, threshold, - allow_overlap, + allow_neighboring_matches, exclusion_size, ) @abstractmethod - def compute_matrix_profile(X: Optional[np.ndarray] = None): + def compute_matrix_profile( + self, + k, + threshold, + exclusion_size, + inverse_distance, + allow_neighboring_matches, + X: Optional[np.ndarray] = None, + X_index: Optional[int] = None, + ): """Compute matrix profiles between X_ and X or between all series in X_.""" ... @abstractmethod - def compute_distance_profile(X: np.ndarray): + def compute_distance_profile(self, X: np.ndarray): """Compute distrance profiles between X_ and X (a series of size length).""" ... diff --git a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py new file mode 100644 index 0000000000..3c92138b3d --- /dev/null +++ b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py @@ -0,0 +1,155 @@ +""" +Tests for stomp algorithm. + +We do not test equality for returned indexes due to the unstable nature of argsort +and the fact that the "kind=stable" parameter is not yet supported in numba. We instead +test that the returned index match the expected distance value. +""" + +__maintainer__ = ["baraline"] + +import numpy as np +import pytest +from numba.typed import List +from numpy.testing import assert_almost_equal, assert_array_almost_equal + +from aeon.similarity_search.subsequence_search._brute_force import ( + _compute_dist_profile, + _naive_squared_distance_profile, + _naive_squared_matrix_profile, +) +from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile_list, +) +from aeon.testing.data_generation import ( + make_example_2d_numpy_series, + make_example_3d_numpy, + make_example_3d_numpy_list, +) +from aeon.utils.numba.general import sliding_mean_std_one_series + +K_VALUES = [1, 3, 5] +NN_MATCHES = [True, False] +INVERSE = [True, False] +NORMALISE = [True, False] + + +def _get_mean_sdts_inputs(X, Q, L): + X_means = [] + X_stds = [] + + for i_x in range(len(X)): + _mean, _std = sliding_mean_std_one_series(X[i_x], L, 1) + X_stds.append(_std) + X_means.append(_mean) + + Q_means = Q.mean(axis=1) + Q_stds = Q.std(axis=1) + + return X_means, X_stds, Q_means, Q_stds + + +def test__compute_dist_profile(): + """Test Euclidean distance.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + dist_profile = _compute_dist_profile(X, Q) + for i_t in range(X.shape[1] - L + 1): + assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) + + +def test__naive_squared_distance_profile(normalise): + """Test Euclidean distance profile calculation.""" + L = 3 + X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + dist_profiles = _naive_squared_distance_profile(X, Q) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X[i_x, :, i_t : i_t + L] - Q) ** 2) + ) + + # test unequal length and multivariate + X = List( + make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=10, + max_n_timepoints=20, + return_y=False, + ) + ) + + Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) + dist_profiles = _naive_squared_distance_profile(X, Q) + for i_x in range(len(X)): + for i_t in range(X[i_x].shape[1] - L + 1): + assert_almost_equal( + dist_profiles[i_x][i_t], np.sum((X[i_x][:, i_t : i_t + L] - Q) ** 2) + ) + + +@pytest.mark.parametrize( + [ + ("k", K_VALUES), + ("allow_neighboring_matches", NN_MATCHES), + ("inverse_distance", INVERSE), + ("normalise", NORMALISE), + ] +) +def test__naive_squared_matrix_profile( + k, allow_neighboring_matches, inverse_distance, normalise +): + """Test STOMP method.""" + L = 3 + + X = make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=6, + max_n_timepoints=8, + return_y=False, + ) + T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) + + T_index = None + threshold = np.inf + exclusion_size = L + # MP : distances to best matches for each query + # IP : Indexes of best matches for each query + MP, IP = _naive_squared_matrix_profile( + X, + T, + L, + T_index, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + inverse_distance, + normalise=normalise, + ) + # For each query of size L in T + for i in range(T.shape[1] - L + 1): + dist_profiles = _naive_squared_distance_profile( + X, T[:, i : i + L], normalise=normalise + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + assert_array_almost_equal(MP[i], top_k_distances) + + # Check that the index in IP correspond to a distance profile point + # with value equal to the corresponding MP point. + for j, index in enumerate(top_k_indexes): + assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) diff --git a/aeon/similarity_search/subsequence_search/tests/test__commons.py b/aeon/similarity_search/subsequence_search/tests/test_commons.py similarity index 59% rename from aeon/similarity_search/subsequence_search/tests/test__commons.py rename to aeon/similarity_search/subsequence_search/tests/test_commons.py index b0e2764b0b..70e443a78c 100644 --- a/aeon/similarity_search/subsequence_search/tests/test__commons.py +++ b/aeon/similarity_search/subsequence_search/tests/test_commons.py @@ -1,12 +1,13 @@ """Test _commons.py functions.""" __maintainer__ = ["baraline"] - import numpy as np +import pytest from numba.typed import List -from numpy.testing import assert_array_almost_equal, assert_array_equal +from numpy.testing import assert_, assert_array_almost_equal from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, _inverse_distance_profile_list, fft_sliding_dot_product, get_ith_products, @@ -59,59 +60,38 @@ def test__inverse_distance_profile_list(): assert_array_almost_equal(1 / (X[1] + 1e-8), T[1]) -def test__extract_top_k_from_dist_profile(): - """Test method to esxtract the top k candidates from a list of distance profiles.""" - X = List([ - [5,4,3,3,1,3,2,5,1,4,1,0,1,2,2,7,8,1,5], - [5,1,0,1,0,0,5,4,3,5,6,1,4,2], - ]) - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, - 1, - np.inf, - False, - 3 - ) - assert_array_equal(top_k_indexes, [[0,11]]) - assert_array_equal(top_k_indexes, [0]) - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, - 5, - np.inf, - False, - 3 - ) - assert_array_equal(top_k_indexes, [[0,11],[1,2],[0,4],[0,17],[1,11]]) - assert_array_equal(top_k_indexes, [0,0,1,1,1]) +K_VALUES = [1, 3, 5] +THRESHOLDS = [np.inf, 0.7] +NN_MATCHES = [False, True] - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, - 5, - np.inf, - True, - 3 - ) - assert_array_equal(top_k_indexes, [[0,11],[1,2],[1,4],[1,5],[0,4]]) - assert_array_equal(top_k_indexes, [0,0,0,0,1]) - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, - 5, - 0.5, - True, - 3 +@pytest.mark.parametrize( + [("k", K_VALUES), ("threshold", THRESHOLDS), ("allow_nn_matches", NN_MATCHES)] +) +def test__extract_top_k_from_dist_profile(k, threshold, allow_nn_matches): + """Test method to esxtract the top k candidates from a list of distance profiles.""" + X = make_example_2d_numpy_list( + n_cases=2, min_n_timepoints=5, max_n_timepoints=7, return_y=False ) - assert_array_equal(top_k_indexes, [[0,11],[1,2],[1,4],[1,5]]) - assert_array_equal(top_k_indexes, [0,0,0,0]) + X_sort = [X[i][np.argsort(X[i])] for i in range(len(X))] top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, - 5, - 0.5, - False, - 3 + X, k, threshold, allow_nn_matches, 3 ) - assert_array_equal(top_k_indexes, [[0,11],[1,2]]) - assert_array_equal(top_k_indexes, [0,0]) + for i, index in enumerate(top_k_indexes): + assert_(X[index[0]][index[1]] == top_k_distances[i]) + assert_(np.all(top_k_distances <= threshold)) + if allow_nn_matches: + for i in range(len(X)): + assert_(np.all(top_k_distances <= X_sort[i][k - 1])) + if not allow_nn_matches: + for i_x in range(len(X)): + # test same index X respect exclusion + same_X = [ + top_k_indexes[i][1] + for i in range(len(top_k_indexes)) + if top_k_indexes[i][0] == i_x + ] + same_X = np.sort(same_X) + if len(same_X) > 1: + assert_(np.all(np.diff(same_X) >= 3)) diff --git a/aeon/similarity_search/subsequence_search/tests/test_stomp.py b/aeon/similarity_search/subsequence_search/tests/test_stomp.py index 169eee135e..7a655035a5 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_stomp.py +++ b/aeon/similarity_search/subsequence_search/tests/test_stomp.py @@ -1,4 +1,10 @@ -"""Tests for stomp algorithm.""" +""" +Tests for stomp algorithm. + +We do not test equality for returned indexes due to the unstable nature of argsort +and the fact that the "kind=stable" parameter is not yet supported in numba. We instead +test that the returned index match the expected distance value. +""" __maintainer__ = ["baraline"] @@ -7,14 +13,18 @@ from numba.typed import List from numpy.testing import assert_almost_equal, assert_array_almost_equal -from aeon.similarity_search.subsequence_search._commons import get_ith_products +from aeon.similarity_search.subsequence_search._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile_list, + get_ith_products, +) from aeon.similarity_search.subsequence_search._stomp import ( - _normalized_squared_dist_profile_one_series, - _normalized_squared_distance_profile, + _normalised_squared_dist_profile_one_series, + _normalised_squared_distance_profile, _squared_dist_profile_one_series, _squared_distance_profile, _stomp, - _stomp_normalized, + _stomp_normalised, _update_dot_products_one_series, ) from aeon.testing.data_generation import ( @@ -27,7 +37,9 @@ z_normalise_series_2d_with_mean_std, ) -K_VALUES = [1, 3] +K_VALUES = [1, 3, 5] +NN_MATCHES = [True, False] +INVERSE = [True, False] def _get_mean_sdts_inputs(X, Q, L): @@ -79,7 +91,7 @@ def test__squared_dist_profile_one_series(): assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) -def test__normalized_squared_dist_profile_one_series(): +def test__normalised_squared_dist_profile_one_series(): """Test Euclidean distance.""" L = 3 X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) @@ -89,7 +101,7 @@ def test__normalized_squared_dist_profile_one_series(): Q_mean = Q.mean(axis=1) Q_std = Q.std(axis=1) - dist_profile = _normalized_squared_dist_profile_one_series( + dist_profile = _normalised_squared_dist_profile_one_series( QX, X_mean, X_std, Q_mean, Q_std, L, Q.std(axis=1) <= 0 ) Q = z_normalise_series_2d_with_mean_std(Q, Q_mean, Q_std) @@ -134,7 +146,7 @@ def test__squared_distance_profile(): ) -def test__normalized_squared_distance_profile(): +def test__normalised_squared_distance_profile(): """Test Euclidean distance profile calculation.""" L = 3 X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) @@ -146,7 +158,7 @@ def test__normalized_squared_distance_profile(): X_means = np.asarray(X_means) X_stds = np.asarray(X_stds) - dist_profiles = _normalized_squared_distance_profile( + dist_profiles = _normalised_squared_distance_profile( QX, X_means, X_stds, Q_means, Q_stds, L ) @@ -179,7 +191,7 @@ def test__normalized_squared_distance_profile(): X_means = List(X_means) X_stds = List(X_stds) - dist_profiles = _normalized_squared_distance_profile( + dist_profiles = _normalised_squared_distance_profile( QX, X_means, X_stds, Q_means, Q_stds, L ) @@ -194,21 +206,32 @@ def test__normalized_squared_distance_profile(): ) -# K_VALUES = [1, 3] -@pytest.mark.parametrize("k", K_VALUES) -def test__stomp(k): +@pytest.mark.parametrize( + [ + ("k", K_VALUES), + ("allow_neighboring_matches", NN_MATCHES), + ("inverse_distance", INVERSE), + ] +) +def test__stomp(k, allow_neighboring_matches, inverse_distance): """Test STOMP method.""" L = 3 - X = np.array([[[1, 2, 3, 2, 1, 2, 3, 4, 5, 2, 1, 2, 2]]]) - T = np.array([[1, 1, 3, 2, 2]]) - XdotT = np.asarray([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) + + X = make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=6, + max_n_timepoints=8, + return_y=False, + ) + T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) + XdotT = List([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) T_index = None - allow_overlap = False threshold = np.inf exclusion_size = L - inverse_distance = False - + # MP : distances to best matches for each query + # IP : Indexes of best matches for each query MP, IP = _stomp( X, T, @@ -216,23 +239,102 @@ def test__stomp(k): L, T_index, k, - allow_overlap, threshold, + allow_neighboring_matches, exclusion_size, inverse_distance, ) - Expected_MP = [[1, 6], [1, 2], [1, 2, 5]] - Expected_IP = [[[0, 0], [0, 1]], [[0, 1], [0, 0]], [[0, 2], [0, 1], [0, 0]]] - for i in range(len(Expected_MP)): - assert_array_almost_equal(Expected_IP[i], IP[i]) - assert_array_almost_equal(Expected_MP[i], MP[i]) + # For each query of size L in T + for i in range(T.shape[1] - L + 1): + dist_profiles = _squared_distance_profile( + List([get_ith_products(X[i_x], T, L, i) for i_x in range(len(X))]), + X, + T[:, i : i + L], + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + assert_array_almost_equal(MP[i], top_k_distances) + + # Check that the index in IP correspond to a distance profile point + # with value equal to the corresponding MP point. + for j, index in enumerate(top_k_indexes): + assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) + + +@pytest.mark.parametrize( + [ + ("k", K_VALUES), + ("allow_neighboring_matches", NN_MATCHES), + ("inverse_distance", INVERSE), + ] +) +def test__stomp_normalised(k, allow_neighboring_matches, inverse_distance): + """Test STOMP normalised method.""" + L = 3 + X = make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=6, + max_n_timepoints=8, + return_y=False, + ) + T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) -@pytest.mark.parametrize("k", K_VALUES) -def test__stomp_normalized(k): - """Test STOMP normalized method.""" - _stomp_normalized - ... + XdotT = List([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) + T_index = None + threshold = np.inf + exclusion_size = L + X_means, X_stds, _, _ = _get_mean_sdts_inputs(X, T, L) + T_means, T_stds = sliding_mean_std_one_series(T, L, 1) + # MP : distances to best matches for each query + # IP : Indexes of best matches for each query + MP, IP = _stomp_normalised( + X, + T, + XdotT, + X_means, + X_stds, + T_means, + T_stds, + L, + T_index, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + inverse_distance, + ) + # For each query of size L in T + for i in range(T.shape[1] - L + 1): + dist_profiles = _normalised_squared_distance_profile( + List([get_ith_products(X[i_x], T, L, i) for i_x in range(len(X))]), + X_means, + X_stds, + T_means[:, i], + T_stds[:, i], + L, + ) + + if inverse_distance: + dist_profiles = _inverse_distance_profile_list(dist_profiles) -# TODO : add tests for StompMatrixProfile + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + assert_array_almost_equal(MP[i], top_k_distances) + + # Check that the index in IP correspond to a distance profile point + # with value equal to the corresponding MP point. + for j, index in enumerate(top_k_indexes): + assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) diff --git a/aeon/testing/mock_estimators/__init__.py b/aeon/testing/mock_estimators/__init__.py index 219fc3e987..e517e07ca0 100644 --- a/aeon/testing/mock_estimators/__init__.py +++ b/aeon/testing/mock_estimators/__init__.py @@ -29,8 +29,6 @@ "MockUnivariateSeriesTransformer", "MockMultivariateSeriesTransformer", "MockSeriesTransformerNoFit", - # similarity search - "MockSimilaritySearch", ] from aeon.testing.mock_estimators._mock_anomaly_detectors import ( @@ -64,4 +62,3 @@ MockSeriesTransformerNoFit, MockUnivariateSeriesTransformer, ) -from aeon.testing.mock_estimators._mock_similarity_search import MockSimilaritySearch diff --git a/aeon/testing/mock_estimators/_mock_similarity_search.py b/aeon/testing/mock_estimators/_mock_similarity_search.py deleted file mode 100644 index 55c9c435c7..0000000000 --- a/aeon/testing/mock_estimators/_mock_similarity_search.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Mock similarity searchers useful for testing and debugging.""" - -__maintainer__ = ["baraline"] -__all__ = [ - "MockSimilaritySearch", -] - -from aeon.similarity_search.base import BaseSimilaritySearch - - -class MockSimilaritySearch(BaseSimilaritySearch): - """Mock similarity search for testing base class predict.""" - - def _fit(self, X, y=None): - """_fit dummy.""" - self.X_ = X - return self - - def predict(self, X): - """Predict dummy.""" - return [(0, 0)] diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py new file mode 100644 index 0000000000..f7c0acfc98 --- /dev/null +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -0,0 +1,72 @@ +"""Mock series transformers useful for testing and debugging.""" + +__maintainer__ = [] +__all__ = [ + "MockSubsequenceSearch", + "MockMatrixProfile", +] + +import numpy as np + +from aeon.similarity_search.subsequence_search.base import ( + BaseMatrixProfile, + BaseSubsequenceSearch, +) + + +class MockMatrixProfile(BaseMatrixProfile): + def __init__(self, length=3): + super().__init__(length=length) + + def compute_matrix_profile( + self, + k, + threshold, + exclusion_size, + inverse_distance, + allow_neighboring_matches, + X=None, + X_index=None, + ): + """Compute matrix profiles between X_ and X or between all series in X_.""" + return np.zeros((X.shape[1] - self.length + 1, k)), np.zeros( + (X.shape[1] - self.length + 1, k, 2) + ) + + def compute_distance_profile(self, X): + """Compute distrance profiles between X_ and X (a series of size length).""" + return np.zeros(X.shape[1] - self.length + 1) + + +class MockSubsequenceSearch(BaseSubsequenceSearch): + """MockSeriesTransformer to set tags.""" + + def __init__(self, length=3): + super().__init__(length=length) + + def _fit(self, X, y=None): + return self + + def _find_motifs( + self, + X, + k=1, + threshold=np.inf, + inverse_distance=False, + X_index=None, + allow_neighboring_matches=False, + exclusion_factor=2.0, + ): + return [[0, 0]], self.X_[0][0:1] # TODO: update after logic is implemented + + def _find_neighbors( + self, + X, + k=1, + threshold=np.inf, + inverse_distance=False, + X_index=None, + allow_neighboring_matches=False, + exclusion_factor=2.0, + ): + return [[0, 0]], self.X_[0][0:1] diff --git a/aeon/utils/base/_register.py b/aeon/utils/base/_register.py index 1d81c2512c..5bf4045ad5 100644 --- a/aeon/utils/base/_register.py +++ b/aeon/utils/base/_register.py @@ -25,6 +25,10 @@ from aeon.regression.base import BaseRegressor from aeon.segmentation.base import BaseSegmenter from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search.subsequence_search.base import ( + BaseMatrixProfile, + BaseSubsequenceSearch, +) from aeon.transformations.base import BaseTransformer from aeon.transformations.collection import BaseCollectionTransformer from aeon.transformations.series import BaseSeriesTransformer @@ -45,6 +49,8 @@ "regressor": BaseRegressor, "segmenter": BaseSegmenter, "similarity_searcher": BaseSimilaritySearch, + "subsequence_searcher": BaseSubsequenceSearch, + "matrixprofile_searcher": BaseMatrixProfile, "series-transformer": BaseSeriesTransformer, "forecaster": BaseForecaster, } @@ -53,5 +59,11 @@ VALID_ESTIMATOR_BASES = { k: BASE_CLASS_REGISTER[k] for k in BASE_CLASS_REGISTER.keys() - - {"estimator", "collection-estimator", "series-estimator", "transformer"} + - { + "estimator", + "collection-estimator", + "series-estimator", + "transformer", + "similarity_searcher", + } } diff --git a/docs/api_reference/utils.rst b/docs/api_reference/utils.rst index 40dea9f67c..6f43398a44 100644 --- a/docs/api_reference/utils.rst +++ b/docs/api_reference/utils.rst @@ -87,7 +87,6 @@ Mock Estimators MockUnivariateSeriesTransformer MockMultivariateSeriesTransformer MockSeriesTransformerNoFit - MockSimilaritySearch Utilities ^^^^^^^^^ From bb2aa33820b914b8a5dd390e4f087c61925c7a0c Mon Sep 17 00:00:00 2001 From: baraline Date: Wed, 1 Jan 2025 09:36:10 +0100 Subject: [PATCH 05/18] Add test for base subsequence --- aeon/similarity_search/__init__.py | 4 +- aeon/similarity_search/base.py | 59 ++++- .../similarity_search/series_search/_r_lsh.py | 239 ++++++++++++++++++ .../subsequence_search/_stomp.py | 145 +++++------ .../subsequence_search/base.py | 89 ++++--- .../subsequence_search/tests/test_base.py | 78 ++++++ aeon/similarity_search/tests/test_base.py | 1 + .../_mock_similarity_searchers.py | 15 +- 8 files changed, 487 insertions(+), 143 deletions(-) create mode 100644 aeon/similarity_search/series_search/_r_lsh.py create mode 100644 aeon/similarity_search/subsequence_search/tests/test_base.py create mode 100644 aeon/similarity_search/tests/test_base.py diff --git a/aeon/similarity_search/__init__.py b/aeon/similarity_search/__init__.py index 53f80b2cdf..cdf5cebd84 100644 --- a/aeon/similarity_search/__init__.py +++ b/aeon/similarity_search/__init__.py @@ -1,3 +1,5 @@ """Similarity search module.""" -__all__ = [] +__all__ = ["BaseSimilaritySearch"] + +from aeon.similarity_search.base import BaseSimilaritySearch diff --git a/aeon/similarity_search/base.py b/aeon/similarity_search/base.py index 8a9e9547d7..d486491fa4 100644 --- a/aeon/similarity_search/base.py +++ b/aeon/similarity_search/base.py @@ -18,8 +18,8 @@ class BaseSimilaritySearch(BaseCollectionEstimator): Parameters ---------- - normalize : bool, optional - Whether the inputs should be z-normalized. The default is False. + normalise : bool, optional + Whether the inputs should be z-normalised. The default is False. n_jobs : int, optional Number of parallel jobs to use. The default is 1. """ @@ -35,11 +35,11 @@ class BaseSimilaritySearch(BaseCollectionEstimator): @abstractmethod def __init__( self, - normalize: Optional[bool] = False, + normalise: Optional[bool] = False, n_jobs: Optional[int] = 1, ): self.n_jobs = n_jobs - self.normalize = normalize + self.normalise = normalise super().__init__() @final @@ -68,7 +68,9 @@ def fit( ------- self """ + self.reset() prev_threads = get_num_threads() + self._check_fit_format(X) X = self._preprocess_collection(X) # Store minimum number of n_timepoints for unequal length collections self.min_timepoints_ = min([X[i].shape[-1] for i in range(len(X))]) @@ -85,9 +87,9 @@ def fit( @abstractmethod def find_motifs( self, + X: np.ndarray, k: int, threshold: float, - X: Optional[np.ndarray] = None, allow_overlap: Optional[bool] = True, ): """ @@ -100,10 +102,8 @@ def find_motifs( Parameters ---------- - X : np.ndarray, optional - The query in which we want to indentify motifs. If provided, the motifs - extracted should appear in X and in the database given in fit. If not - provided, the motifs will be extracted only from the database given in fit. + X : np.ndarray, + A series in which we want to indentify motifs. k : int, optional Number of motifs to return threshold : int, optional @@ -115,9 +115,12 @@ def find_motifs( Returns ------- - list of ndarray, shape=(k,) - A list of at most ``k`` numpy arrays containing the indexes of the - candidates in each motif. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + motifs. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the distances of the + motifs to . """ ... @@ -157,5 +160,37 @@ def find_neighbors( """ ... + def _check_fit_format(self, X): + if isinstance(X, np.ndarray): # "numpy3D" or numpy2D + if X.ndim != 3: + raise TypeError( + f"A np.ndarray given in fit must be 3D but found {X.ndim}D" + ) + elif isinstance(X, list): # np-list or df-list + if isinstance(X[0], np.ndarray): # if one a numpy they must all be 2D numpy + for a in X: + if not (isinstance(a, np.ndarray) and a.ndim == 2): + raise TypeError( + "A np-list given in fit must contain 2D np.ndarray but" + f" found {a.ndim}D" + ) + + def _check_find_neighbors_motif_format(self, X): + if isinstance(X, np.ndarray): + if X.ndim != 2: + raise TypeError( + "A np.ndarray given in find_neighbors must be 2D" + f"(n_channels, n_timepoints) but found {X.ndim}D." + ) + else: + raise TypeError( + "Expected a 2D np.ndarray in find_neighbors but found" f" {type(X)}." + ) + if self.n_channels_ != X.shape[0]: + raise ValueError( + f"Expected X to have {self.n_channels_} channels but" + f" got {X.shape[0]} channels." + ) + @abstractmethod def _fit(self, X, y=None): ... diff --git a/aeon/similarity_search/series_search/_r_lsh.py b/aeon/similarity_search/series_search/_r_lsh.py new file mode 100644 index 0000000000..9921aeeba1 --- /dev/null +++ b/aeon/similarity_search/series_search/_r_lsh.py @@ -0,0 +1,239 @@ +"""Random projection LSH index.""" + +import numpy as np +from numba import njit, prange + +TPB = 16 + + +@njit(cache=True) +def _hamming_dist(X, Y): + d = 0 + for i in prange(X.shape[0]): + d += X[i] ^ Y[i] + return d + + +@njit(cache=True, parallel=True) +def _hamming_dist_matrix(bool_hashes_value_list, bool_hashes): + n_hashes = bool_hashes.shape[0] + res = np.zeros((n_hashes, bool_hashes_value_list.shape[0]), dtype=np.int64) + for i in prange(n_hashes): + for j in prange(bool_hashes_value_list.shape[0]): + res[i, j] = _hamming_dist(bool_hashes_value_list[j], bool_hashes[i]) + return res + + +@njit(cache=True, fastmath=True, parallel=True) +def _series_to_bool(X, hash_funcs, start_points, length): + n_hash_funcs = hash_funcs.shape[0] + res = np.empty(n_hash_funcs, dtype=np.bool_) + for j in prange(n_hash_funcs): + res[j] = ( + np.dot(X[start_points[j] : start_points[j] + length], hash_funcs[j]) >= 0 + ) + return res + + +@njit(cache=True, fastmath=True, parallel=True) +def _collection_to_bool(X, hash_funcs, start_points, length): + n_hash_funcs = hash_funcs.shape[0] + n_samples = X.shape[0] + res = np.empty((n_samples, n_hash_funcs), dtype=np.bool_) + for i in prange(n_samples): + for j in prange(n_hash_funcs): + res[i, j] = ( + np.dot(X[i, start_points[j] : start_points[j] + length], hash_funcs[j]) + >= 0 + ) + return res + + +class LSH: + """ + . + + Parameters + ---------- + n_vectors : TYPE + DESCRIPTION. + custom_table : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + None. + + """ + + def __init__(self, n_hash_funcs=128, window_length=1.0, seed=None): + self.n_hash_funcs = n_hash_funcs + self.window_length = window_length + self.seed = seed + + def fit(self, X): + """ + . + + Parameters + ---------- + X : TYPE + DESCRIPTION. + + Returns + ------- + TYPE + DESCRIPTION. + + """ + self.rng_ = np.random.default_rng(self.seed) + self.X_ = np.array( + [X[i].flatten() for i in range(len(X))] + ) # n_samples, n_channels * n_timepoints + + self.window_length_ = max(1, int(self.X_.shape[1] * self.window_length)) + # Can replace with choice [-1, 1] + self.hash_funcs_ = self.rng_.uniform( + low=-1, high=1.0, size=(self.n_hash_funcs, self.window_length_) + ) + self.start_points_ = self.rng_.choice( + self.X_.shape[1] - self.window_length_ + 1, + size=self.n_hash_funcs, + replace=True, + ) + + bool_hashes = _collection_to_bool( + self.X_, self.hash_funcs_, self.start_points_, self.window_length_ + ) + # could yield this + str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] + self.dict_X_index = {} + self.dict_bool_hashes = {} + for i in range(len(str_hashes)): + if str_hashes[i] in self.dict_X_index: + self.dict_X_index[str_hashes[i]].append(i) + else: + self.dict_X_index[str_hashes[i]] = [i] + self.dict_bool_hashes[str_hashes[i]] = bool_hashes[i] + + self.bool_hashes_value_list = np.asarray(list(self.dict_bool_hashes.values())) + self.bool_hashes_key_list = np.asarray(list(self.dict_bool_hashes.keys())) + + return self + + def update(self, X): + """ + . + + Parameters + ---------- + X : TYPE + DESCRIPTION. + + Returns + ------- + TYPE + DESCRIPTION. + + """ + X_ = np.array( + [X[i].flatten() for i in range(len(X))] + ) # n_samples, n_channels * n_timepoints + bool_hashes = _collection_to_bool( + X_, self.hash_funcs_, self.start_points_, self.window_length_ + ) + + str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] + base_index = self.X_.shape[0] + for i in range(len(str_hashes)): + if str_hashes[i] in self.dict_X_index: + self.dict_X_index[str_hashes[i]].append(i + base_index) + else: + self.dict_X_index[str_hashes[i]] = [i + base_index] + self.dict_bool_hashes[str_hashes[i]] = bool_hashes[i] + self.X_ = np.concatenate((self.X_, X_)) + + self.bool_hashes_value_list = np.asarray(list(self.dict_bool_hashes.values())) + self.bool_hashes_key_list = np.asarray(list(self.dict_bool_hashes.keys())) + return self + + def get_bucket_collection_indexes(self, X): + """ + . + + Parameters + ---------- + X : TYPE + DESCRIPTION. + + Returns + ------- + TYPE + DESCRIPTION. + + """ + bool_hash = _series_to_bool( + X.flatten(), self.hash_funcs_, self.start_points_, self.window_length_ + ) + str_hash = hash(bool_hash.tobytes()) + if str_hash in self.dict_X_index: + return self.dict_X_index[str_hash] + else: + return [] + + def predict(self, X, k=1): + """ + . + + Parameters + ---------- + X : TYPE + DESCRIPTION. + k : TYPE, optional + DESCRIPTION. The default is 1. + + Returns + ------- + top_k : TYPE + DESCRIPTION. + + """ + X_ = np.array([X[i].flatten() for i in range(len(X))]) + bool_hashes = _collection_to_bool( + X_, self.hash_funcs_, self.start_points_, self.window_length_ + ) + top_k = np.zeros((len(X), k), dtype=int) + dists = _hamming_dist_matrix(self.bool_hashes_value_list, bool_hashes) + self.h_dists = dists + # Deal with equality by merging bucket contents ? + for i_x in range(len(X)): + ids = np.argsort(dists[i_x]) + _i = 0 + c = k + while c > 0: + candidates = self.dict_X_index[self.bool_hashes_key_list[ids[_i]]] + # Can do exact search by computing distances here + if len(candidates) > c: + candidates = candidates[:c] + top_k[i_x, k - c : k - c + len(candidates)] = candidates + c -= len(candidates) + _i += 1 + return top_k + + def find_motif(Index, X=None): + """ + . + + Parameters + ---------- + Index : TYPE + DESCRIPTION. + X : TYPE, optional + DESCRIPTION. The default is None. + + Returns + ------- + None. + + """ + pass diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py index 0dd75971f8..21fdacdfcd 100644 --- a/aeon/similarity_search/subsequence_search/_stomp.py +++ b/aeon/similarity_search/subsequence_search/_stomp.py @@ -2,9 +2,6 @@ __maintainer__ = ["baraline"] - -from typing import Optional - import numpy as np from numba import njit, prange from numba.typed import List @@ -27,13 +24,13 @@ class StompMatrixProfile(BaseMatrixProfile): def compute_matrix_profile( self, - k, - threshold, - exclusion_size, - inverse_distance, - allow_neighboring_matches, - X: Optional[np.ndarray] = None, - X_index: Optional[int] = None, + X: np.ndarray, + k: int, + threshold: float, + exclusion_size: int, + inverse_distance: bool, + allow_neighboring_matches: bool, + X_index=None, ): """ Compute matrix profiles. @@ -44,6 +41,8 @@ def compute_matrix_profile( Parameters ---------- + X : np.ndarray, shape = (n_channels, n_timepoints) + A 2D array time series on which the matrix profile will be computed. k : int The number of best matches to return during predict for each subsequence. threshold : float @@ -55,14 +54,10 @@ def compute_matrix_profile( The size of the exclusion zone used to prevent returning as top k candidates the ones that are close to each other (for example i and i+1). It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, the value None means that this is not used. - X : Optional[np.ndarray], optional - The time series on which the matrix profile will be compute. - The default is None, meaning that the series in the collection given in fit - will be used instead. X_index : Optional[int], optional If ``X`` is a series of the database given in fit, specify its index in ``X_``. If specified, each query of this series won't be able to match with @@ -70,73 +65,55 @@ def compute_matrix_profile( Returns ------- - MP : array of shape (series_length - L + 1,) + MP : array of shape (n_timepoints - L + 1,) Matrix profile distances for each query subsequence. If X is none, this will be a list of MP for each series in X_. - IP : array of shape (series_length - L + 1,) + IP : array of shape (n_timepoints - L + 1,) Indexes of the top matches for each query subsequence. If X is none, this will be a list of MP for each series in X_. """ - # If we compute matrix profiles for each series in X_ - if X is None: - MP = [] - IP = [] - for i in range(len(self.X_)): - _MP, _IP = self.compute_matrix_profile( - k, - threshold, - exclusion_size, - inverse_distance, - X=self.X_[i], - X_index=i, - ) - MP.append(_MP) - IP.append(_IP) - # else we compute matrix profiles using X on the series in X_ + XdotT = [ + get_ith_products(self.X[i], X, self.length, 0) for i in range(len(self.X_)) + ] + if isinstance(X, np.ndarray): + XdotT = np.asarray(XdotT) + elif isinstance(X, List): + XdotT = List(XdotT) + + if X_index is None: + X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) else: - XdotT = [ - get_ith_products(self.X[i], X, self.length, 0) - for i in range(len(self.X_)) - ] - if isinstance(X, np.ndarray): - XdotT = np.asarray(XdotT) - elif isinstance(X, List): - XdotT = List(XdotT) - - if X_index is None: - X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) - else: - X_means, X_stds = self.X_means_[i], self.X_stds_[i] - if self.normalise: - MP, IP = _stomp_normalised( - self.X_, - X, - XdotT, - self.X_means_, - self.X_stds_, - X_means, - X_stds, - self.length, - X_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) - else: - MP, IP = _stomp( - self.X_, - X, - XdotT, - self.length, - X_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) + X_means, X_stds = self.X_means_[X_index], self.X_stds_[X_index] + if self.normalise: + MP, IP = _stomp_normalised( + self.X_, + X, + XdotT, + self.X_means_, + self.X_stds_, + X_means, + X_stds, + self.length, + X_index, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + inverse_distance, + ) + else: + MP, IP = _stomp( + self.X_, + X, + XdotT, + self.length, + X_index, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + inverse_distance, + ) return MP, IP def compute_distance_profile(self, X: np.ndarray): @@ -237,9 +214,9 @@ def _stomp_normalised( The size of the exclusion zone used to prevent returning as top k candidates the ones that are close to each other (for example i and i+1). It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, the value None means that this is not used. inverse_distance : bool If True, the matching will be made on the inverse of the distance, and thus, the @@ -331,9 +308,9 @@ def _stomp( The size of the exclusion zone used to prevent returning as top k candidates the ones that are close to each other (for example i and i+1). It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, the value None means that this is not used. inverse_distance : bool If True, the matching will be made on the inverse of the distance, and thus, the diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py index 7df358e5ec..dcc3f17dc8 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/base.py @@ -47,9 +47,9 @@ def __init__( @final def find_motifs( self, + X: np.ndarray, k: Optional[int] = 1, threshold: Optional[float] = np.inf, - X: Optional[np.ndarray] = None, X_index: Optional[int] = None, inverse_distance: Optional[bool] = False, allow_neighboring_matches: Optional[bool] = False, @@ -65,15 +65,13 @@ def find_motifs( Parameters ---------- + X : np.ndarray, 2D array of shape (n_channels, n_timestamps) + A series in which we want to indentify motifs. k : int, optional Number of motifs to return threshold : int, optional A threshold on the similarity measure to determine which candidates will be part of a motif set. - X : np.ndarray, 2D array of shape (n_channels, n_timestamps), optional - A series in which we want to indentify motifs. If provided, the motifs - extracted should appear in X and in the database given in fit. If not - provided, the motifs will be extracted only from the database given in fit. X_index : Optional[int], optional If ``X`` is a series of the database given in fit, specify its index in ``X_``. If specified, each query of this series won't be able to match with @@ -93,25 +91,30 @@ def find_motifs( Returns ------- - list of ndarray, shape=(k,) - A list of at most ``k`` numpy arrays containing the indexes of the - candidates in each motif. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + motifs in X. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the distances of the + motifs macthes to the motif in X. """ self._check_is_fitted() + if X is not None: + self._check_find_neighbors_motif_format(X) prev_threads = get_num_threads() X_index = self._check_X_index_int(X_index) - motifs = self._find_motifs( + motifs_indexes, distances = self._find_motifs( + X, k=k, threshold=threshold, exclusion_factor=exclusion_factor, inverse_distance=inverse_distance, allow_neighboring_matches=allow_neighboring_matches, - X=X, X_index=X_index, ) set_num_threads(prev_threads) - return motifs + return motifs_indexes, distances @final def find_neighbors( @@ -171,11 +174,14 @@ def find_neighbors( """ self._check_is_fitted() - if self.length != X.shape[1] or self.n_channels_ != X.shape[0]: + + self._check_find_neighbors_motif_format(X) + if self.length != X.shape[1]: raise ValueError( - f"Expected a subsequence of shape {(self.n_channels_, self.length)} but" - f" got {X.shape}" + f"Expected X to be of shape {(self.n_channels_, self.length)} but" + f" got {X.shape} in find_neighbors." ) + X_index = self._check_X_index_array(X_index) prev_threads = get_num_threads() set_num_threads(self._n_jobs) @@ -313,8 +319,19 @@ def _compute_mean_std_from_collection(self, X: np.ndarray): else: return np.asarray(means), np.asarray(stds) - @abstractmethod - def _fit(self, X, y=None): ... + def _fit(self, X, y=None): + if self.length >= self.min_timepoints_ or self.length < 1: + raise ValueError( + "The length of the query should be inferior or equal to the length of " + "data (X_) provided during fit, but got {} for X and {} for X_".format( + self.length, self.min_timepoints_ + ) + ) + + if self.normalise: + self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) + self.X_ = X + return self @abstractmethod def _find_motifs( @@ -322,8 +339,8 @@ def _find_motifs( X: np.ndarray, k: Optional[int] = 1, threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, inverse_distance: Optional[bool] = False, - X_index=None, allow_neighboring_matches: Optional[bool] = False, exclusion_factor: Optional[float] = 2.0, ): ... @@ -344,27 +361,13 @@ def _find_neighbors( class BaseMatrixProfile(BaseSubsequenceSearch): """Base class for Matrix Profile methods using a length parameter.""" - def _fit(self, X, y=None): - if self.length >= self.min_timepoints_: - raise ValueError( - "The length of the query should be inferior or equal to the length of " - "data (X_) provided during fit, but got {} for X and {} for X_".format( - self.length, self.min_timepoints_ - ) - ) - - if self.normalise: - self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) - self.X_ = X - return self - def _find_motifs( self, X: np.ndarray, k: Optional[int] = 1, threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, inverse_distance: Optional[bool] = False, - X_index=None, allow_neighboring_matches: Optional[bool] = False, exclusion_factor: Optional[float] = 2.0, ): @@ -379,7 +382,15 @@ def _find_motifs( X=X, X_index=X_index, ) - # TODO : implement logic here + # TODO check motif extraction logic, sure its not this one + MP_avg = np.array([np.mean(MP[i]) for i in range(len(MP))]) + return _extract_top_k_from_dist_profile( + MP_avg, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + ) def _find_neighbors( self, @@ -451,12 +462,12 @@ def _find_neighbors( @abstractmethod def compute_matrix_profile( self, - k, - threshold, - exclusion_size, - inverse_distance, - allow_neighboring_matches, - X: Optional[np.ndarray] = None, + X: np.ndarray, + k: int, + threshold: float, + exclusion_size: int, + inverse_distance: bool, + allow_neighboring_matches: bool, X_index: Optional[int] = None, ): """Compute matrix profiles between X_ and X or between all series in X_.""" diff --git a/aeon/similarity_search/subsequence_search/tests/test_base.py b/aeon/similarity_search/subsequence_search/tests/test_base.py new file mode 100644 index 0000000000..a037879992 --- /dev/null +++ b/aeon/similarity_search/subsequence_search/tests/test_base.py @@ -0,0 +1,78 @@ +"""Test for subsequence search base class.""" + +import pytest + +from aeon.testing.mock_estimators._mock_similarity_searchers import ( + MockMatrixProfile, + MockSubsequenceSearch, +) +from aeon.testing.testing_data import ( + make_example_1d_numpy, + make_example_2d_numpy_series, + make_example_3d_numpy, + make_example_3d_numpy_list, +) + +BASES = [MockMatrixProfile, MockSubsequenceSearch] + + +@pytest.mark.parametrize("base", BASES) +def test_input_shape_fit_neighbord_motifs(base): + """Test input shapes.""" + estimator = base() + # dummy data to pass to fit when testing predict/predict_proba + X_3D_uni = make_example_3d_numpy(n_channels=1, return_y=False) + X_3D_multi = make_example_3d_numpy(n_channels=2, return_y=False) + X_3D_uni_list = make_example_3d_numpy_list(n_channels=1, return_y=False) + X_3D_multi_list = make_example_3d_numpy_list(n_channels=2, return_y=False) + X_2D_uni = make_example_2d_numpy_series(n_channels=1) + X_2D_multi = make_example_2d_numpy_series(n_channels=2) + X_1D = make_example_1d_numpy() + + valid_inputs_fit = [X_3D_uni, X_3D_multi, X_3D_uni_list, X_3D_multi_list] + # Valid inputs + for _input in valid_inputs_fit: + estimator.fit(_input) + + invalid_inputs_fit = [X_2D_uni, X_2D_multi, X_1D] + for _input in invalid_inputs_fit: + with pytest.raises(TypeError): + estimator.fit(_input) + + valid_inputs_neighboord_motifs_uni = [X_2D_uni] + invalid_inputs_neighboord_motifs_uni = [ + X_1D, + X_3D_uni, + X_3D_uni_list, + ] + invalid_inputs_neighboord_motifs_multi = [ + X_3D_multi, + X_3D_multi_list, + ] + L = 5 + estimator_multi = base(length=L).fit(X_3D_multi) + estimator_uni = base(length=L).fit(X_3D_uni) + + for _input in valid_inputs_neighboord_motifs_uni: + estimator_uni.find_neighbors(_input[:, :L]) + estimator_uni.find_motifs(X=_input) + with pytest.raises(ValueError): + # Wrong number of channels + estimator_multi.find_neighbors(_input) + estimator_multi.find_motifs(X=_input) + # X length not of size L + estimator_uni.find_neighbors(X=_input[:, : L + 2]) + + for _input in invalid_inputs_neighboord_motifs_uni: + with pytest.raises(TypeError): + estimator_uni.find_neighbors(_input) + estimator_uni.find_motifs(X=_input) + estimator_multi.find_neighbors(_input) + estimator_multi.find_motifs(X=_input) + + for _input in invalid_inputs_neighboord_motifs_multi: + with pytest.raises(TypeError): + estimator_uni.find_neighbors(_input) + estimator_uni.find_motifs(X=_input) + estimator_multi.find_neighbors(_input) + estimator_multi.find_motifs(X=_input) diff --git a/aeon/similarity_search/tests/test_base.py b/aeon/similarity_search/tests/test_base.py new file mode 100644 index 0000000000..e066e14680 --- /dev/null +++ b/aeon/similarity_search/tests/test_base.py @@ -0,0 +1 @@ +"""Tests for base similarity search.""" diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index f7c0acfc98..89c6121c38 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -15,6 +15,8 @@ class MockMatrixProfile(BaseMatrixProfile): + """Mock estimator for BaseMatrixProfile.""" + def __init__(self, length=3): super().__init__(length=length) @@ -35,25 +37,24 @@ def compute_matrix_profile( def compute_distance_profile(self, X): """Compute distrance profiles between X_ and X (a series of size length).""" - return np.zeros(X.shape[1] - self.length + 1) + return [ + np.zeros(self.X_[i].shape[1] - self.length + 1) for i in range(len(self.X_)) + ] class MockSubsequenceSearch(BaseSubsequenceSearch): - """MockSeriesTransformer to set tags.""" + """Mock estimator for BaseSubsequenceSearch.""" def __init__(self, length=3): super().__init__(length=length) - def _fit(self, X, y=None): - return self - def _find_motifs( self, - X, k=1, threshold=np.inf, - inverse_distance=False, + X=None, X_index=None, + inverse_distance=False, allow_neighboring_matches=False, exclusion_factor=2.0, ): From f23c7203f9cc6ba295c187d1d227c8af1329daa4 Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 2 Jan 2025 11:23:49 +0100 Subject: [PATCH 06/18] Fix subsequence_search tests --- aeon/similarity_search/__init__.py | 2 +- aeon/similarity_search/{base.py => _base.py} | 0 aeon/similarity_search/series_search/base.py | 2 +- .../subsequence_search/__init__.py | 10 ++++- .../subsequence_search/base.py | 6 +-- .../subsequence_search/tests/__init__.py | 2 +- .../subsequence_search/tests/test_base.py | 24 +++++++---- .../tests/test_brute_force.py | 42 ++++++++++--------- .../subsequence_search/tests/test_commons.py | 15 ++++--- .../subsequence_search/tests/test_stomp.py | 10 ++--- .../_mock_similarity_searchers.py | 4 +- aeon/testing/utils/estimator_checks.py | 2 +- aeon/utils/base/_register.py | 14 +++---- aeon/utils/discovery.py | 1 + 14 files changed, 73 insertions(+), 61 deletions(-) rename aeon/similarity_search/{base.py => _base.py} (100%) diff --git a/aeon/similarity_search/__init__.py b/aeon/similarity_search/__init__.py index cdf5cebd84..26b79c7da2 100644 --- a/aeon/similarity_search/__init__.py +++ b/aeon/similarity_search/__init__.py @@ -2,4 +2,4 @@ __all__ = ["BaseSimilaritySearch"] -from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search._base import BaseSimilaritySearch diff --git a/aeon/similarity_search/base.py b/aeon/similarity_search/_base.py similarity index 100% rename from aeon/similarity_search/base.py rename to aeon/similarity_search/_base.py diff --git a/aeon/similarity_search/series_search/base.py b/aeon/similarity_search/series_search/base.py index db83519c04..bcbc92c042 100644 --- a/aeon/similarity_search/series_search/base.py +++ b/aeon/similarity_search/series_search/base.py @@ -2,7 +2,7 @@ __maintainer__ = ["baraline"] -from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search._base import BaseSimilaritySearch class BaseSeriesSearch(BaseSimilaritySearch): diff --git a/aeon/similarity_search/subsequence_search/__init__.py b/aeon/similarity_search/subsequence_search/__init__.py index c5de805eb6..5d64f901bd 100644 --- a/aeon/similarity_search/subsequence_search/__init__.py +++ b/aeon/similarity_search/subsequence_search/__init__.py @@ -1,7 +1,15 @@ """Subsequence search module.""" -__all__ = ["BaseSubsequenceSearch", "BaseMatrixProfile", "StompMatrixProfile"] +__all__ = [ + "BaseSubsequenceSearch", + "BaseMatrixProfile", + "StompMatrixProfile", + "BruteForceMatrixProfile", +] +from aeon.similarity_search.subsequence_search._brute_force import ( + BruteForceMatrixProfile, +) from aeon.similarity_search.subsequence_search._stomp import StompMatrixProfile from aeon.similarity_search.subsequence_search.base import ( BaseMatrixProfile, diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py index dcc3f17dc8..238b749b5f 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/base.py @@ -10,7 +10,7 @@ from numba import get_num_threads, set_num_threads from numba.typed import List -from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search._base import BaseSimilaritySearch from aeon.similarity_search.subsequence_search._commons import ( _extract_top_k_from_dist_profile, _inverse_distance_profile_list, @@ -34,7 +34,6 @@ class BaseSubsequenceSearch(BaseSimilaritySearch): Number of parallel jobs to use. The default is 1. """ - @abstractmethod def __init__( self, length: int, @@ -383,7 +382,8 @@ def _find_motifs( X_index=X_index, ) # TODO check motif extraction logic, sure its not this one - MP_avg = np.array([np.mean(MP[i]) for i in range(len(MP))]) + MP_avg = np.array([[np.mean(MP[i]) for i in range(len(MP))]]) + # TODO: appening IP of identified motifs to return to get motifs matches in X_ return _extract_top_k_from_dist_profile( MP_avg, k, diff --git a/aeon/similarity_search/subsequence_search/tests/__init__.py b/aeon/similarity_search/subsequence_search/tests/__init__.py index 3feb8d4ca5..0287f2ee04 100644 --- a/aeon/similarity_search/subsequence_search/tests/__init__.py +++ b/aeon/similarity_search/subsequence_search/tests/__init__.py @@ -1 +1 @@ -"""Tests for series methods.""" +"""Tests for subsequence search methods.""" diff --git a/aeon/similarity_search/subsequence_search/tests/test_base.py b/aeon/similarity_search/subsequence_search/tests/test_base.py index a037879992..e1a314f38a 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_base.py +++ b/aeon/similarity_search/subsequence_search/tests/test_base.py @@ -55,24 +55,32 @@ def test_input_shape_fit_neighbord_motifs(base): for _input in valid_inputs_neighboord_motifs_uni: estimator_uni.find_neighbors(_input[:, :L]) - estimator_uni.find_motifs(X=_input) + estimator_uni.find_motifs(_input) with pytest.raises(ValueError): # Wrong number of channels estimator_multi.find_neighbors(_input) - estimator_multi.find_motifs(X=_input) - # X length not of size L - estimator_uni.find_neighbors(X=_input[:, : L + 2]) + with pytest.raises(ValueError): + estimator_multi.find_motifs(_input) + # X length not of size L + with pytest.raises(ValueError): + estimator_uni.find_neighbors(_input[:, : L + 2]) for _input in invalid_inputs_neighboord_motifs_uni: with pytest.raises(TypeError): estimator_uni.find_neighbors(_input) - estimator_uni.find_motifs(X=_input) + with pytest.raises(TypeError): + estimator_uni.find_motifs(_input) + with pytest.raises(TypeError): estimator_multi.find_neighbors(_input) - estimator_multi.find_motifs(X=_input) + with pytest.raises(TypeError): + estimator_multi.find_motifs(_input) for _input in invalid_inputs_neighboord_motifs_multi: with pytest.raises(TypeError): estimator_uni.find_neighbors(_input) - estimator_uni.find_motifs(X=_input) + with pytest.raises(TypeError): + estimator_uni.find_motifs(_input) + with pytest.raises(TypeError): estimator_multi.find_neighbors(_input) - estimator_multi.find_motifs(X=_input) + with pytest.raises(TypeError): + estimator_multi.find_motifs(_input) diff --git a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py index 3c92138b3d..cc87b34a9f 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py +++ b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py @@ -27,7 +27,7 @@ make_example_3d_numpy, make_example_3d_numpy_list, ) -from aeon.utils.numba.general import sliding_mean_std_one_series +from aeon.utils.numba.general import sliding_mean_std_one_series, z_normalise_series_2d K_VALUES = [1, 3, 5] NN_MATCHES = [True, False] @@ -60,17 +60,22 @@ def test__compute_dist_profile(): assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) +@pytest.mark.parametrize("normalise", NORMALISE) def test__naive_squared_distance_profile(normalise): """Test Euclidean distance profile calculation.""" L = 3 X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - dist_profiles = _naive_squared_distance_profile(X, Q) + dist_profiles = _naive_squared_distance_profile(X, Q, normalise=normalise) + + if normalise: + Q = z_normalise_series_2d(Q) for i_x in range(len(X)): for i_t in range(X[i_x].shape[1] - L + 1): - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X[i_x, :, i_t : i_t + L] - Q) ** 2) - ) + _x = X[i_x, :, i_t : i_t + L] + if normalise: + _x = z_normalise_series_2d(_x) + assert_almost_equal(dist_profiles[i_x][i_t], np.sum((_x - Q) ** 2)) # test unequal length and multivariate X = List( @@ -84,22 +89,21 @@ def test__naive_squared_distance_profile(normalise): ) Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) - dist_profiles = _naive_squared_distance_profile(X, Q) + dist_profiles = _naive_squared_distance_profile(X, Q, normalise=normalise) + if normalise: + Q = z_normalise_series_2d(Q) for i_x in range(len(X)): for i_t in range(X[i_x].shape[1] - L + 1): - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X[i_x][:, i_t : i_t + L] - Q) ** 2) - ) - - -@pytest.mark.parametrize( - [ - ("k", K_VALUES), - ("allow_neighboring_matches", NN_MATCHES), - ("inverse_distance", INVERSE), - ("normalise", NORMALISE), - ] -) + _x = X[i_x][:, i_t : i_t + L] + if normalise: + _x = z_normalise_series_2d(_x) + assert_almost_equal(dist_profiles[i_x][i_t], np.sum((_x - Q) ** 2)) + + +@pytest.mark.parametrize("k", K_VALUES) +@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) +@pytest.mark.parametrize("inverse_distance", INVERSE) +@pytest.mark.parametrize("normalise", NORMALISE) def test__naive_squared_matrix_profile( k, allow_neighboring_matches, inverse_distance, normalise ): diff --git a/aeon/similarity_search/subsequence_search/tests/test_commons.py b/aeon/similarity_search/subsequence_search/tests/test_commons.py index 70e443a78c..50c5cfad31 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_commons.py +++ b/aeon/similarity_search/subsequence_search/tests/test_commons.py @@ -17,6 +17,10 @@ make_example_2d_numpy_series, ) +K_VALUES = [1, 3, 5] +THRESHOLDS = [np.inf, 0.7] +NN_MATCHES = [False, True] + def test_fft_sliding_dot_product(): """Test the fft_sliding_dot_product function.""" @@ -60,14 +64,9 @@ def test__inverse_distance_profile_list(): assert_array_almost_equal(1 / (X[1] + 1e-8), T[1]) -K_VALUES = [1, 3, 5] -THRESHOLDS = [np.inf, 0.7] -NN_MATCHES = [False, True] - - -@pytest.mark.parametrize( - [("k", K_VALUES), ("threshold", THRESHOLDS), ("allow_nn_matches", NN_MATCHES)] -) +@pytest.mark.parametrize("k", K_VALUES) +@pytest.mark.parametrize("threshold", THRESHOLDS) +@pytest.mark.parametrize("allow_nn_matches", NN_MATCHES) def test__extract_top_k_from_dist_profile(k, threshold, allow_nn_matches): """Test method to esxtract the top k candidates from a list of distance profiles.""" X = make_example_2d_numpy_list( diff --git a/aeon/similarity_search/subsequence_search/tests/test_stomp.py b/aeon/similarity_search/subsequence_search/tests/test_stomp.py index 7a655035a5..12d7738eaf 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_stomp.py +++ b/aeon/similarity_search/subsequence_search/tests/test_stomp.py @@ -206,13 +206,9 @@ def test__normalised_squared_distance_profile(): ) -@pytest.mark.parametrize( - [ - ("k", K_VALUES), - ("allow_neighboring_matches", NN_MATCHES), - ("inverse_distance", INVERSE), - ] -) +@pytest.mark.parametrize("k", K_VALUES) +@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) +@pytest.mark.parametrize("inverse_distance", INVERSE) def test__stomp(k, allow_neighboring_matches, inverse_distance): """Test STOMP method.""" L = 3 diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index 89c6121c38..824a627d7a 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -32,7 +32,7 @@ def compute_matrix_profile( ): """Compute matrix profiles between X_ and X or between all series in X_.""" return np.zeros((X.shape[1] - self.length + 1, k)), np.zeros( - (X.shape[1] - self.length + 1, k, 2) + (X.shape[1] - self.length + 1, k, 2), dtype=np.int64 ) def compute_distance_profile(self, X): @@ -50,9 +50,9 @@ def __init__(self, length=3): def _find_motifs( self, + X, k=1, threshold=np.inf, - X=None, X_index=None, inverse_distance=False, allow_neighboring_matches=False, diff --git a/aeon/testing/utils/estimator_checks.py b/aeon/testing/utils/estimator_checks.py index b2e0973dbf..d556ff0249 100644 --- a/aeon/testing/utils/estimator_checks.py +++ b/aeon/testing/utils/estimator_checks.py @@ -7,7 +7,7 @@ import numpy as np -from aeon.similarity_search.base import BaseSimilaritySearch +from aeon.similarity_search import BaseSimilaritySearch from aeon.testing.testing_data import FULL_TEST_DATA_DICT from aeon.utils.validation import get_n_cases diff --git a/aeon/utils/base/_register.py b/aeon/utils/base/_register.py index 5bf4045ad5..9c576c350a 100644 --- a/aeon/utils/base/_register.py +++ b/aeon/utils/base/_register.py @@ -24,15 +24,13 @@ from aeon.forecasting.base import BaseForecaster from aeon.regression.base import BaseRegressor from aeon.segmentation.base import BaseSegmenter -from aeon.similarity_search.base import BaseSimilaritySearch -from aeon.similarity_search.subsequence_search.base import ( - BaseMatrixProfile, - BaseSubsequenceSearch, -) +from aeon.similarity_search.subsequence_search.base import BaseSubsequenceSearch from aeon.transformations.base import BaseTransformer from aeon.transformations.collection import BaseCollectionTransformer from aeon.transformations.series import BaseSeriesTransformer +# from aeon.similarity_search.series_search.base import BaseSeriesSearch + # all base classes BASE_CLASS_REGISTER = { # abstract - no estimator directly inherits from these @@ -48,11 +46,10 @@ "early_classifier": BaseEarlyClassifier, "regressor": BaseRegressor, "segmenter": BaseSegmenter, - "similarity_searcher": BaseSimilaritySearch, - "subsequence_searcher": BaseSubsequenceSearch, - "matrixprofile_searcher": BaseMatrixProfile, "series-transformer": BaseSeriesTransformer, "forecaster": BaseForecaster, + "subsequence_searcher": BaseSubsequenceSearch, + # "series_searcher": BaseSeriesSearch, } # base classes which are valid for estimator to directly inherit from @@ -64,6 +61,5 @@ "collection-estimator", "series-estimator", "transformer", - "similarity_searcher", } } diff --git a/aeon/utils/discovery.py b/aeon/utils/discovery.py index 8fd4a05efe..d6e5ce61fc 100644 --- a/aeon/utils/discovery.py +++ b/aeon/utils/discovery.py @@ -92,6 +92,7 @@ def all_estimators( # ignore test modules and base classes "base", "tests", + "similarity_search" # ignore these submodules "benchmarking", "datasets", From c372969a92257da14ea40a8f238d9f6160b331e4 Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 2 Jan 2025 13:56:20 +0100 Subject: [PATCH 07/18] debug brute force mp --- .../subsequence_search/_brute_force.py | 2 +- .../subsequence_search/_commons.py | 2 +- .../tests/test_brute_force.py | 41 ++++++++++++------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py index 6c26925a32..a7227499b6 100644 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -281,7 +281,7 @@ def _naive_squared_matrix_profile( X_subs.append(i_subs) for i_q in range(n_queries): - Q = T[:, i : i + L] + Q = T[:, i_q : i_q + L] if normalise: Q = z_normalise_series_2d(Q) for i_x in prange(len(X)): diff --git a/aeon/similarity_search/subsequence_search/_commons.py b/aeon/similarity_search/subsequence_search/_commons.py index 03e0ee1ac3..c13a7381bc 100644 --- a/aeon/similarity_search/subsequence_search/_commons.py +++ b/aeon/similarity_search/subsequence_search/_commons.py @@ -141,7 +141,7 @@ def _extract_top_k_from_dist_profile( _top_k_distances = dist_profiles[i_profile][_top_k_indexes] # Extract top-k with neighboring matches else: - _top_k_indexes = np.argpartition(dist_profiles[i_profile], k)[:k] + _top_k_indexes = np.argsort(dist_profiles[i_profile])[:k] _top_k_distances = dist_profiles[i_profile][_top_k_indexes] # Select overall top k by using the buffer array of size 2*k diff --git a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py index cc87b34a9f..9ef0eb44e8 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py +++ b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py @@ -11,7 +11,11 @@ import numpy as np import pytest from numba.typed import List -from numpy.testing import assert_almost_equal, assert_array_almost_equal +from numpy.testing import ( + assert_almost_equal, + assert_array_almost_equal, + assert_array_equal, +) from aeon.similarity_search.subsequence_search._brute_force import ( _compute_dist_profile, @@ -27,7 +31,11 @@ make_example_3d_numpy, make_example_3d_numpy_list, ) -from aeon.utils.numba.general import sliding_mean_std_one_series, z_normalise_series_2d +from aeon.utils.numba.general import ( + get_all_subsequences, + sliding_mean_std_one_series, + z_normalise_series_2d, +) K_VALUES = [1, 3, 5] NN_MATCHES = [True, False] @@ -51,18 +59,18 @@ def _get_mean_sdts_inputs(X, Q, L): def test__compute_dist_profile(): - """Test Euclidean distance.""" + """Test Euclidean distance with brute force.""" L = 3 X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - dist_profile = _compute_dist_profile(X, Q) + dist_profile = _compute_dist_profile(get_all_subsequences(X, L, 1), Q) for i_t in range(X.shape[1] - L + 1): assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) @pytest.mark.parametrize("normalise", NORMALISE) def test__naive_squared_distance_profile(normalise): - """Test Euclidean distance profile calculation.""" + """Test Euclidean distance profile calculation with brute force.""" L = 3 X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) @@ -107,18 +115,20 @@ def test__naive_squared_distance_profile(normalise): def test__naive_squared_matrix_profile( k, allow_neighboring_matches, inverse_distance, normalise ): - """Test STOMP method.""" + """Test brute force matrix profile method.""" L = 3 - - X = make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=6, - max_n_timepoints=8, - return_y=False, + X = List( + make_example_3d_numpy_list( + n_cases=3, + n_channels=2, + min_n_timepoints=6, + max_n_timepoints=8, + return_y=False, + ) ) + X_copy = X.copy() T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) - + T_copy = T.copy() T_index = None threshold = np.inf exclusion_size = L @@ -136,6 +146,9 @@ def test__naive_squared_matrix_profile( inverse_distance, normalise=normalise, ) + assert_array_equal(T, T_copy) + for i in range(len(X)): + assert_array_equal(X[i], X_copy[i]) # For each query of size L in T for i in range(T.shape[1] - L + 1): dist_profiles = _naive_squared_distance_profile( From d7da68bf4f7806b78b2532baba5c77f21d80f447 Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 2 Jan 2025 14:50:20 +0100 Subject: [PATCH 08/18] more debug of subsequence tests --- aeon/similarity_search/_base.py | 89 +++++++- .../similarity_search/series_search/_r_lsh.py | 2 +- aeon/similarity_search/series_search/base.py | 209 +++++++++++++++++- .../subsequence_search/_brute_force.py | 8 + .../subsequence_search/_stomp.py | 9 + .../subsequence_search/base.py | 1 + .../subsequence_search/tests/test_commons.py | 5 +- .../subsequence_search/tests/test_stomp.py | 10 +- .../_mock_similarity_searchers.py | 18 +- aeon/utils/numba/general.py | 89 ++++++-- 10 files changed, 396 insertions(+), 44 deletions(-) diff --git a/aeon/similarity_search/_base.py b/aeon/similarity_search/_base.py index d486491fa4..476dc664c2 100644 --- a/aeon/similarity_search/_base.py +++ b/aeon/similarity_search/_base.py @@ -90,7 +90,6 @@ def find_motifs( X: np.ndarray, k: int, threshold: float, - allow_overlap: Optional[bool] = True, ): """ Find the top-k motifs in the training data. @@ -109,9 +108,6 @@ def find_motifs( threshold : int, optional A threshold on the similarity measure to determine which candidates will be part of a motif set. - allow_overlap: bool, optional - Wheter a candidate can be part of multiple motif sets (True), or if motif - sets should be mutually exclusive (False). Returns ------- @@ -194,3 +190,88 @@ def _check_find_neighbors_motif_format(self, X): @abstractmethod def _fit(self, X, y=None): ... + + def _check_X_index_int(self, X_index: int): + """ + Check wheter the X_index parameter is correctly formated and is admissible. + + This check is made for motif search functions. + + Parameters + ---------- + X_index : int + Index of a series in X_. + + Returns + ------- + X_index : int + Index of a series in X_ + + """ + if X_index is not None: + if not isinstance(X_index, int): + raise TypeError("Expected an integer for X_index but got {X_index}") + + if X_index >= self.n_cases_ or X_index < 0: + raise ValueError( + "The value of X_index cannot exced the number " + "of series in the collection given during fit. Expected a value " + f"between [0, {self.n_cases_ - 1}] but got {X_index}" + ) + return X_index + + def _check_X_index_array(self, X_index: np.ndarray): + """ + Check wheter the X_index parameter is correctly formated and is admissible. + + This check is made for neighbour search functions. + + Parameters + ---------- + X_index : np.ndarray, 1D array of shape (2) + Array of integer containing the sample and timestamp identifiers of the + starting point of a subsequence in X_. + + Returns + ------- + X_index : np.ndarray, 1D array of shape (2) + Array of integer containing the sample and timestamp identifiers of the + starting point of a subsequence in X_. + + """ + if X_index is not None: + if ( + isinstance(X_index, list) + and len(X_index) == 2 + and isinstance(X_index[0], int) + and isinstance(X_index[1], int) + ): + X_index = np.asarray(X_index, dtype=int) + elif len(X_index) != 2: + raise TypeError( + "Expected a numpy array or list of integers with 2 elements " + f"for X_index but got {X_index}" + ) + elif ( + not (isinstance(X_index[0], int) or not isinstance(X_index[1], int)) + or X_index.dtype != int + ): + raise TypeError( + "Expected a numpy array or list of integers for X_index but got " + f"{X_index}" + ) + + if X_index[0] >= self.n_cases_ or X_index[0] < 0: + raise ValueError( + "The sample ID (first element) of X_index cannot exced the number " + "of series in the collection given during fit. Expected a value " + f"between [0, {self.n_cases_ - 1}] but got {X_index[0]}" + ) + _max_timestamp = self.X_[X_index[0]].shape[1] - self.length + 1 + if X_index[1] >= _max_timestamp: + raise ValueError( + "The timestamp ID (second element) of X_index cannot exced the " + "number of timestamps minus the length parameter plus one. Expected" + f" a value between [0, {_max_timestamp - 1}] but got {X_index[1]}" + ) + return X_index diff --git a/aeon/similarity_search/series_search/_r_lsh.py b/aeon/similarity_search/series_search/_r_lsh.py index 9921aeeba1..a98dbfc562 100644 --- a/aeon/similarity_search/series_search/_r_lsh.py +++ b/aeon/similarity_search/series_search/_r_lsh.py @@ -3,7 +3,7 @@ import numpy as np from numba import njit, prange -TPB = 16 +# TPB = 16 @njit(cache=True) diff --git a/aeon/similarity_search/series_search/base.py b/aeon/similarity_search/series_search/base.py index bcbc92c042..9f0e4f4ca6 100644 --- a/aeon/similarity_search/series_search/base.py +++ b/aeon/similarity_search/series_search/base.py @@ -2,13 +2,218 @@ __maintainer__ = ["baraline"] +import warnings +from abc import abstractmethod +from typing import Optional, final + +import numpy as np +from numba import get_num_threads, set_num_threads + from aeon.similarity_search._base import BaseSimilaritySearch +from aeon.utils.numba.general import compute_mean_stds_collection_parallel class BaseSeriesSearch(BaseSimilaritySearch): - """.""" + """ + Base class for similarity search on whole time series. - ... + Parameters + ---------- + normalise : bool, optional + Whether the inputs should be z-normalised. The default is False. + n_jobs : int, optional + Number of parallel jobs to use. The default is 1. + """ + + @final + def find_motifs( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, + inverse_distance: Optional[bool] = False, + ): + """ + Find the top-k motifs in the training data. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif + sets. We define a motif set as a set of candidates which all are at a distance + of at most ``threshold`` from each other. The top-k motifs sets are the + motif sets with the most candidates. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, n_timestamps) + A series in which we want to indentify motifs. + k : int, optional + Number of motifs to return + threshold : int, optional + A threshold on the similarity measure to determine which candidates will be + part of a motif set. + X_index : Optional[int], optional + If ``X`` is a series of the database given in fit, specify its index in + ``X_``. If specified, this series won't be able to match with itself. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the anomalies instead of motifs. + + Returns + ------- + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + motifs in X. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the distances of the + motifs macthes to the motif in X. + + """ + self._check_is_fitted() + if X is not None: + self._check_find_neighbors_motif_format(X) + prev_threads = get_num_threads() + X_index = self._check_X_index_int(X_index) + motifs_indexes, distances = self._find_motifs( + X, + k=k, + threshold=threshold, + inverse_distance=inverse_distance, + X_index=X_index, + ) + set_num_threads(prev_threads) + return motifs_indexes, distances + + @final + def find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, + inverse_distance: Optional[bool] = False, + ): + """ + Find the top-k neighbors of X in the database. + + Given ``k`` and ``threshold`` parameters, this methods returns the top-k + neighbors of X, such as each of the ``k`` neighbors as a distance inferior or + equal to ``threshold``. By default, ``threshold`` is set to infinity. It is + possible for this method to return less than ``k`` neighbors, either if there + is less than ``k`` admissible candidate in the database, or if in the top-k + candidates, some do not meet the ``threshold`` condition. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The subsequence for which we want to identify nearest neighbors in the + database. + k : int, optional + Number of neighbors to return. + threshold : int, optional + A threshold on the distance to determine which candidates will be returned. + X_index : Optional[int], optional + If ``X`` is a series of the database given in fit, specify its index in + ``X_``. If specified, this series won't be able to match with itself. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the k most dissimilar neighbors instead of the k most similar. + + + Returns + ------- + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the indexes of the + neighbors. + ndarray, shape=(k,) + A numpy array of at most ``k`` elements containing the distances of the + neighbors to X. + + """ + self._check_is_fitted() + + self._check_find_neighbors_motif_format(X) + if self.length != X.shape[1]: + raise ValueError( + f"Expected X to be of shape {(self.n_channels_, self.length)} but" + f" got {X.shape} in find_neighbors." + ) + + X_index = self._check_X_index_int(X_index) + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) + neighbors, distances = self._find_neighbors( + X, + k=k, + threshold=threshold, + inverse_distance=inverse_distance, + X_index=X_index, + ) + set_num_threads(prev_threads) + if len(neighbors) < k: + warnings.warn( + f"The number of admissible neighbors found is {len(neighbors)}, instead" + f" of {k}", + stacklevel=2, + ) + return neighbors, distances + + def _compute_mean_std_from_collection(self, X: np.ndarray): + """ + Compute the mean and std of each channel for all series in X. + + Parameters + ---------- + X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + Collection of series from which we extract mean and stds. If it is an + unequal length collection, it should be a list of 2d numpy arrays. + + Returns + ------- + Tuple(np.ndarray, np.ndarray) + Both array are of shape (n_cases, n_channels), the first contains the means + and the second the stds for each series in X. + + """ + means, stds = compute_mean_stds_collection_parallel(X) + return means, stds + + def _fit(self, X, y=None): + if self.length >= self.min_timepoints_ or self.length < 1: + raise ValueError( + "The length of the query should be inferior or equal to the length of " + "data (X_) provided during fit, but got {} for X and {} for X_".format( + self.length, self.min_timepoints_ + ) + ) + + if self.normalise: + self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) + self.X_ = X + return self + + @abstractmethod + def _find_motifs( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, + inverse_distance: Optional[bool] = False, + allow_neighboring_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): ... + + @abstractmethod + def _find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + allow_neighboring_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2.0, + ): ... class BaseIndexSearch(BaseSimilaritySearch): diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py index a7227499b6..2225fbd0ad 100644 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -27,6 +27,14 @@ class BruteForceMatrixProfile(BaseMatrixProfile): """Estimator to compute matrix profile and distance profile using brute force.""" + def __init__( + self, + length: int, + normalise: Optional[bool] = False, + n_jobs: Optional[int] = 1, + ): + super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) + def compute_matrix_profile( self, k, diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py index 21fdacdfcd..a1d6ac8730 100644 --- a/aeon/similarity_search/subsequence_search/_stomp.py +++ b/aeon/similarity_search/subsequence_search/_stomp.py @@ -1,6 +1,7 @@ """Implementation of STOMP with squared euclidean distance.""" __maintainer__ = ["baraline"] +from typing import Optional import numpy as np from numba import njit, prange @@ -22,6 +23,14 @@ class StompMatrixProfile(BaseMatrixProfile): """Estimator to compute matrix profile and distance profile using STOMP.""" + def __init__( + self, + length: int, + normalise: Optional[bool] = False, + n_jobs: Optional[int] = 1, + ): + super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) + def compute_matrix_profile( self, X: np.ndarray, diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py index 238b749b5f..4c26a6a06a 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/base.py @@ -34,6 +34,7 @@ class BaseSubsequenceSearch(BaseSimilaritySearch): Number of parallel jobs to use. The default is 1. """ + @abstractmethod def __init__( self, length: int, diff --git a/aeon/similarity_search/subsequence_search/tests/test_commons.py b/aeon/similarity_search/subsequence_search/tests/test_commons.py index 50c5cfad31..e5b4272285 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_commons.py +++ b/aeon/similarity_search/subsequence_search/tests/test_commons.py @@ -24,14 +24,15 @@ def test_fft_sliding_dot_product(): """Test the fft_sliding_dot_product function.""" + L = 4 X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=4) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) values = fft_sliding_dot_product(X, Q) # Compare values[0] only as input is univariate assert_array_almost_equal( values[0], - [np.dot(Q[0], X[0, i : i + 5]) for i in range(X.shape[1] - 5 + 1)], + [np.dot(Q[0], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], ) diff --git a/aeon/similarity_search/subsequence_search/tests/test_stomp.py b/aeon/similarity_search/subsequence_search/tests/test_stomp.py index 12d7738eaf..757c8a3133 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_stomp.py +++ b/aeon/similarity_search/subsequence_search/tests/test_stomp.py @@ -265,13 +265,9 @@ def test__stomp(k, allow_neighboring_matches, inverse_distance): assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) -@pytest.mark.parametrize( - [ - ("k", K_VALUES), - ("allow_neighboring_matches", NN_MATCHES), - ("inverse_distance", INVERSE), - ] -) +@pytest.mark.parametrize("k", K_VALUES) +@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) +@pytest.mark.parametrize("inverse_distance", INVERSE) def test__stomp_normalised(k, allow_neighboring_matches, inverse_distance): """Test STOMP normalised method.""" L = 3 diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index 824a627d7a..5362137ba9 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -17,8 +17,13 @@ class MockMatrixProfile(BaseMatrixProfile): """Mock estimator for BaseMatrixProfile.""" - def __init__(self, length=3): - super().__init__(length=length) + def __init__( + self, + length=3, + normalise=False, + n_jobs=1, + ): + super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) def compute_matrix_profile( self, @@ -45,8 +50,13 @@ def compute_distance_profile(self, X): class MockSubsequenceSearch(BaseSubsequenceSearch): """Mock estimator for BaseSubsequenceSearch.""" - def __init__(self, length=3): - super().__init__(length=length) + def __init__( + self, + length=3, + normalise=False, + n_jobs=1, + ): + super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) def _find_motifs( self, diff --git a/aeon/utils/numba/general.py b/aeon/utils/numba/general.py index b398a8414b..958c584459 100644 --- a/aeon/utils/numba/general.py +++ b/aeon/utils/numba/general.py @@ -276,7 +276,7 @@ def z_normalise_series_2d_with_mean_std( Parameters ---------- - X : array, shape = (n_channels, n_timestamps) + X : array, shape = (n_channels, n_timepoints) Input array to normalise. mean : array, shape = (n_channels) Mean of each channel of X. @@ -285,7 +285,7 @@ def z_normalise_series_2d_with_mean_std( Returns ------- - arr : array, shape = (n_channels, n_timestamps) + arr : array, shape = (n_channels, n_timepoints) The normalised array """ arr = np.zeros(X.shape) @@ -379,10 +379,10 @@ def get_subsequence( Parameters ---------- - X : array, shape (n_channels, n_timestamps) + X : array, shape (n_channels, n_timepoints) Input time series. i_start : int - A starting index between [0, n_timestamps - (length-1)*dilation] + A starting index between [0, n_timepoints - (length-1)*dilation] length : int Length parameter of the subsequence. dilation : int @@ -411,10 +411,10 @@ def get_subsequence_with_mean_std( Parameters ---------- - X : array, shape (n_channels, n_timestamps) + X : array, shape (n_channels, n_timepoints) Input time series. i_start : int - A starting index between [0, n_timestamps - (length-1)*dilation] + A starting index between [0, n_timepoints - (length-1)*dilation] length : int Length parameter of the subsequence. dilation : int @@ -454,15 +454,56 @@ def get_subsequence_with_mean_std( return values, means, stds +@njit(cache=True, fastmath=True, parallel=True) +def compute_mean_stds_collection_parallel(X): + """ + Return the mean and standard deviation for each channel of all series in X. + + Parameters + ---------- + X : array, shape (n_cases, n_channels, n_timepoints) + A time series collection + + Returns + ------- + means : array, shape (n_cases, n_channels) + The mean of each channel of each time series in X. + stds : array, shape (n_cases, n_channels) + The std of each channel of each time series in X. + + """ + n_channels = X[0].shape[0] + n_cases = len(X) + means = np.zeros((n_cases, n_channels)) + stds = np.zeros((n_cases, n_channels)) + for i_x in prange(n_cases): + n_timepoints = X[i_x].shape[1] + _s = np.zeros(n_channels) + _s2 = np.zeros(n_channels) + for i_t in range(n_timepoints): + for i_c in range(n_channels): + _s += X[i_x][i_c, i_t] + _s2 += X[i_x][i_c, i_t] ** 2 + + for i_c in range(n_channels): + means[i_x, i_c] = _s / n_timepoints + _std = _s2 / n_timepoints - means[i_x, i_c] ** 2 + if _s > AEON_NUMBA_STD_THRESHOLD: + stds[i_x, i_c] = _std**0.5 + + return means, stds + + @njit(fastmath=True, cache=True) def sliding_mean_std_one_series( X: np.ndarray, length: int, dilation: int ) -> tuple[np.ndarray, np.ndarray]: - """Return the mean and standard deviation for all subsequence (l,d) in X. + """ + Return the mean and standard deviation for all subsequence (l,d) in X. Parameters ---------- - X : array, shape (n_channels, n_timestamps) + X : array, shape (n_channels, n_timepoints) An input time series length : int Length of the subsequence @@ -471,14 +512,14 @@ def sliding_mean_std_one_series( Returns ------- - mean : array, shape (n_channels, n_timestamps - (length-1) * dilation) + mean : array, shape (n_channels, n_timepoints - (length-1) * dilation) The mean of each subsequence with parameter length and dilation in X. - std : array, shape (n_channels, n_timestamps - (length-1) * dilation) + std : array, shape (n_channels, n_timepoints - (length-1) * dilation) The standard deviation of each subsequence with parameter length and dilation in X. """ - n_channels, n_timestamps = X.shape - n_subs = n_timestamps - (length - 1) * dilation + n_channels, n_timepoints = X.shape + n_subs = n_timepoints - (length - 1) * dilation if n_subs <= 0: raise ValueError( "Invalid input parameter for sliding mean and std computations" @@ -496,7 +537,7 @@ def sliding_mean_std_one_series( _sum2 = np.zeros(n_channels) # Initialize first subsequence if it is valid - if np.all(_idx_sub < n_timestamps): + if np.all(_idx_sub < n_timepoints): for i_length in prange(length): _idx_sub[i_length] = (i_length * dilation) + i_mod_dil for i_channel in prange(n_channels): @@ -513,7 +554,7 @@ def sliding_mean_std_one_series( _idx_sub += dilation # As long as subsequences further subsequences are valid - while np.all(_idx_sub < n_timestamps): + while np.all(_idx_sub < n_timepoints): # Update sums and mean stds arrays for i_channel in prange(n_channels): _v_new = X[i_channel, _idx_sub[-1]] @@ -537,17 +578,17 @@ def normalise_subsequences(X_subs: np.ndarray, X_means: np.ndarray, X_stds: np.n Parameters ---------- - X_subs : array, shape (n_timestamps-(length-1)*dilation, n_channels, length) - The subsequences of an input time series of size n_timestamps given the + X_subs : array, shape (n_timepoints-(length-1)*dilation, n_channels, length) + The subsequences of an input time series of size n_timepoints given the length and dilation parameter. - X_means : array, shape (n_channels, n_timestamps-(length-1)*dilation) + X_means : array, shape (n_channels, n_timepoints-(length-1)*dilation) Mean of the subsequences to normalise. - X_stds : array, shape (n_channels, n_timestamps-(length-1)*dilation) + X_stds : array, shape (n_channels, n_timepoints-(length-1)*dilation) Stds of the subsequences to normalise. Returns ------- - array, shape = (n_timestamps-(length-1)*dilation, n_channels, length) + array, shape = (n_timepoints-(length-1)*dilation, n_channels, length) Z-normalised subsequences. """ n_subsequences, n_channels, length = X_subs.shape @@ -758,8 +799,8 @@ def get_all_subsequences(X: np.ndarray, length: int, dilation: int) -> np.ndarra Parameters ---------- - X : array, shape = (n_channels, n_timestamps) - An input time series as (n_channels, n_timestamps). + X : array, shape = (n_channels, n_timepoints) + An input time series as (n_channels, n_timepoints). length : int Length of the subsequences to generate. dilation : int @@ -767,11 +808,11 @@ def get_all_subsequences(X: np.ndarray, length: int, dilation: int) -> np.ndarra Returns ------- - array, shape = (n_timestamps-(length-1)*dilation, n_channels, length) + array, shape = (n_timepoints-(length-1)*dilation, n_channels, length) The view of the subsequences of the input time series. """ - n_features, n_timestamps = X.shape + n_features, n_timepoints = X.shape s0, s1 = X.strides - out_shape = (n_timestamps - (length - 1) * dilation, n_features, np.int64(length)) + out_shape = (n_timepoints - (length - 1) * dilation, n_features, np.int64(length)) strides = (s1, s0, s1 * dilation) return np.lib.stride_tricks.as_strided(X, shape=out_shape, strides=strides) From da2758c4fbfb1c9405b4aff1fa12fa14b94522ba Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 2 Jan 2025 16:12:53 +0100 Subject: [PATCH 09/18] more debug of subsequence tests --- .../subsequence_search/base.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/base.py index 4c26a6a06a..9df76d233b 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/base.py @@ -357,6 +357,29 @@ def _find_neighbors( exclusion_factor: Optional[float] = 2.0, ): ... + @classmethod + def _get_test_params(cls, parameter_set: str = "default") -> dict: + """Return testing parameter settings for the estimator. + + Parameters + ---------- + parameter_set : str, default="default" + Name of the set of test parameters to return, for use in tests. If no + special parameters are defined for a value, will return `"default"` set. + For classifiers, a "default" set of parameters should be provided for + general testing, and a "results_comparison" set for comparing against + previously recorded results if the general set does not produce suitable + probabilities to compare against. + + Returns + ------- + params : dict or list of dict, default={} + Parameters to create testing instances of the class. + Each dict are parameters to construct an "interesting" test instance, i.e., + `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. + """ + return {"length": 3} + class BaseMatrixProfile(BaseSubsequenceSearch): """Base class for Matrix Profile methods using a length parameter.""" From 2191ac27c259ab09d9e2d21d267af1a1628b3783 Mon Sep 17 00:00:00 2001 From: baraline Date: Fri, 10 Jan 2025 12:03:53 +0100 Subject: [PATCH 10/18] Add functional LSH neighbors --- aeon/similarity_search/_base.py | 1 - .../series_search/__init__.py | 2 +- .../series_search/{base.py => _base.py} | 85 ++++-- .../similarity_search/series_search/_r_lsh.py | 239 ---------------- .../series_search/_rp_lsh.py | 263 ++++++++++++++++++ .../subsequence_search/__init__.py | 8 +- .../subsequence_search/{base.py => _base.py} | 4 + .../subsequence_search/_brute_force.py | 2 +- .../subsequence_search/_stomp.py | 2 +- .../_mock_similarity_searchers.py | 2 +- aeon/utils/base/_register.py | 7 +- 11 files changed, 339 insertions(+), 276 deletions(-) rename aeon/similarity_search/series_search/{base.py => _base.py} (79%) delete mode 100644 aeon/similarity_search/series_search/_r_lsh.py create mode 100644 aeon/similarity_search/series_search/_rp_lsh.py rename aeon/similarity_search/subsequence_search/{base.py => _base.py} (99%) diff --git a/aeon/similarity_search/_base.py b/aeon/similarity_search/_base.py index 476dc664c2..68e35c6cbb 100644 --- a/aeon/similarity_search/_base.py +++ b/aeon/similarity_search/_base.py @@ -26,7 +26,6 @@ class BaseSimilaritySearch(BaseCollectionEstimator): _tags = { "capability:multivariate": True, - "capability:unequal_length": True, "capability:multithreading": True, "fit_is_empty": False, "X_inner_type": ["np-list", "numpy3D"], diff --git a/aeon/similarity_search/series_search/__init__.py b/aeon/similarity_search/series_search/__init__.py index 2f69dab51a..9a618540db 100644 --- a/aeon/similarity_search/series_search/__init__.py +++ b/aeon/similarity_search/series_search/__init__.py @@ -2,4 +2,4 @@ __all__ = ["BaseSeriesSearch", "BaseIndexSearch"] -from aeon.similarity_search.series_search.base import BaseIndexSearch, BaseSeriesSearch +from aeon.similarity_search.series_search._base import BaseIndexSearch, BaseSeriesSearch diff --git a/aeon/similarity_search/series_search/base.py b/aeon/similarity_search/series_search/_base.py similarity index 79% rename from aeon/similarity_search/series_search/base.py rename to aeon/similarity_search/series_search/_base.py index 9f0e4f4ca6..f9c6ed8097 100644 --- a/aeon/similarity_search/series_search/base.py +++ b/aeon/similarity_search/series_search/_base.py @@ -132,11 +132,6 @@ def find_neighbors( self._check_is_fitted() self._check_find_neighbors_motif_format(X) - if self.length != X.shape[1]: - raise ValueError( - f"Expected X to be of shape {(self.n_channels_, self.length)} but" - f" got {X.shape} in find_neighbors." - ) X_index = self._check_X_index_int(X_index) prev_threads = get_num_threads() @@ -178,14 +173,6 @@ def _compute_mean_std_from_collection(self, X: np.ndarray): return means, stds def _fit(self, X, y=None): - if self.length >= self.min_timepoints_ or self.length < 1: - raise ValueError( - "The length of the query should be inferior or equal to the length of " - "data (X_) provided during fit, but got {} for X and {} for X_".format( - self.length, self.min_timepoints_ - ) - ) - if self.normalise: self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) self.X_ = X @@ -199,8 +186,6 @@ def _find_motifs( threshold: Optional[float] = np.inf, X_index: Optional[int] = None, inverse_distance: Optional[bool] = False, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, ): ... @abstractmethod @@ -211,17 +196,69 @@ def _find_neighbors( threshold: Optional[float] = np.inf, inverse_distance: Optional[bool] = False, X_index=None, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, ): ... -class BaseIndexSearch(BaseSimilaritySearch): - """.""" +# TODO : Add an update method to add series to the index +class BaseIndexSearch(BaseSeriesSearch): + """ + Base class for similarity search on whole time series using indexes. + + Parameters + ---------- + normalise : bool, optional + Whether the inputs should be z-normalised. The default is False. + n_jobs : int, optional + Number of parallel jobs to use. The default is 1. + """ + + def _fit(self, X, y=None): + super()._fit(X) + self._build_index() + return self + + @abstractmethod + def _build_index(self): ... + + @abstractmethod + def _query_index( + self, + X, + k=1, + inverse_distance=False, + threshold=np.inf, + ): ... + + @abstractmethod + def _get_bucket_sizes(self): ... + + @abstractmethod + def _get_bucket_content(self, key): ... - ... + def _find_motifs( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + X_index: Optional[int] = None, + inverse_distance: Optional[bool] = False, + ): + bucket_sizes = self._get_bucket_sizes() + idx_motifs = np.argsort(list(bucket_sizes.values()))[::-1][:, k] + # TODO : review distance return on motif for whole series and buckets + return [self._get_bucket_content(idx_motif) for idx_motif in idx_motifs], [ + 0 for _ in idx_motifs + ] - def batch_fit(sourcefiles, batch_size): - """.""" - # fit - # and then update + def _find_neighbors( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + inverse_distance: Optional[bool] = False, + X_index=None, + ): + top_k, top_k_dist = self._query_index( + X, k=k, inverse_distance=inverse_distance, threshold=threshold + ) + return top_k, top_k_dist diff --git a/aeon/similarity_search/series_search/_r_lsh.py b/aeon/similarity_search/series_search/_r_lsh.py deleted file mode 100644 index a98dbfc562..0000000000 --- a/aeon/similarity_search/series_search/_r_lsh.py +++ /dev/null @@ -1,239 +0,0 @@ -"""Random projection LSH index.""" - -import numpy as np -from numba import njit, prange - -# TPB = 16 - - -@njit(cache=True) -def _hamming_dist(X, Y): - d = 0 - for i in prange(X.shape[0]): - d += X[i] ^ Y[i] - return d - - -@njit(cache=True, parallel=True) -def _hamming_dist_matrix(bool_hashes_value_list, bool_hashes): - n_hashes = bool_hashes.shape[0] - res = np.zeros((n_hashes, bool_hashes_value_list.shape[0]), dtype=np.int64) - for i in prange(n_hashes): - for j in prange(bool_hashes_value_list.shape[0]): - res[i, j] = _hamming_dist(bool_hashes_value_list[j], bool_hashes[i]) - return res - - -@njit(cache=True, fastmath=True, parallel=True) -def _series_to_bool(X, hash_funcs, start_points, length): - n_hash_funcs = hash_funcs.shape[0] - res = np.empty(n_hash_funcs, dtype=np.bool_) - for j in prange(n_hash_funcs): - res[j] = ( - np.dot(X[start_points[j] : start_points[j] + length], hash_funcs[j]) >= 0 - ) - return res - - -@njit(cache=True, fastmath=True, parallel=True) -def _collection_to_bool(X, hash_funcs, start_points, length): - n_hash_funcs = hash_funcs.shape[0] - n_samples = X.shape[0] - res = np.empty((n_samples, n_hash_funcs), dtype=np.bool_) - for i in prange(n_samples): - for j in prange(n_hash_funcs): - res[i, j] = ( - np.dot(X[i, start_points[j] : start_points[j] + length], hash_funcs[j]) - >= 0 - ) - return res - - -class LSH: - """ - . - - Parameters - ---------- - n_vectors : TYPE - DESCRIPTION. - custom_table : TYPE, optional - DESCRIPTION. The default is None. - - Returns - ------- - None. - - """ - - def __init__(self, n_hash_funcs=128, window_length=1.0, seed=None): - self.n_hash_funcs = n_hash_funcs - self.window_length = window_length - self.seed = seed - - def fit(self, X): - """ - . - - Parameters - ---------- - X : TYPE - DESCRIPTION. - - Returns - ------- - TYPE - DESCRIPTION. - - """ - self.rng_ = np.random.default_rng(self.seed) - self.X_ = np.array( - [X[i].flatten() for i in range(len(X))] - ) # n_samples, n_channels * n_timepoints - - self.window_length_ = max(1, int(self.X_.shape[1] * self.window_length)) - # Can replace with choice [-1, 1] - self.hash_funcs_ = self.rng_.uniform( - low=-1, high=1.0, size=(self.n_hash_funcs, self.window_length_) - ) - self.start_points_ = self.rng_.choice( - self.X_.shape[1] - self.window_length_ + 1, - size=self.n_hash_funcs, - replace=True, - ) - - bool_hashes = _collection_to_bool( - self.X_, self.hash_funcs_, self.start_points_, self.window_length_ - ) - # could yield this - str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] - self.dict_X_index = {} - self.dict_bool_hashes = {} - for i in range(len(str_hashes)): - if str_hashes[i] in self.dict_X_index: - self.dict_X_index[str_hashes[i]].append(i) - else: - self.dict_X_index[str_hashes[i]] = [i] - self.dict_bool_hashes[str_hashes[i]] = bool_hashes[i] - - self.bool_hashes_value_list = np.asarray(list(self.dict_bool_hashes.values())) - self.bool_hashes_key_list = np.asarray(list(self.dict_bool_hashes.keys())) - - return self - - def update(self, X): - """ - . - - Parameters - ---------- - X : TYPE - DESCRIPTION. - - Returns - ------- - TYPE - DESCRIPTION. - - """ - X_ = np.array( - [X[i].flatten() for i in range(len(X))] - ) # n_samples, n_channels * n_timepoints - bool_hashes = _collection_to_bool( - X_, self.hash_funcs_, self.start_points_, self.window_length_ - ) - - str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] - base_index = self.X_.shape[0] - for i in range(len(str_hashes)): - if str_hashes[i] in self.dict_X_index: - self.dict_X_index[str_hashes[i]].append(i + base_index) - else: - self.dict_X_index[str_hashes[i]] = [i + base_index] - self.dict_bool_hashes[str_hashes[i]] = bool_hashes[i] - self.X_ = np.concatenate((self.X_, X_)) - - self.bool_hashes_value_list = np.asarray(list(self.dict_bool_hashes.values())) - self.bool_hashes_key_list = np.asarray(list(self.dict_bool_hashes.keys())) - return self - - def get_bucket_collection_indexes(self, X): - """ - . - - Parameters - ---------- - X : TYPE - DESCRIPTION. - - Returns - ------- - TYPE - DESCRIPTION. - - """ - bool_hash = _series_to_bool( - X.flatten(), self.hash_funcs_, self.start_points_, self.window_length_ - ) - str_hash = hash(bool_hash.tobytes()) - if str_hash in self.dict_X_index: - return self.dict_X_index[str_hash] - else: - return [] - - def predict(self, X, k=1): - """ - . - - Parameters - ---------- - X : TYPE - DESCRIPTION. - k : TYPE, optional - DESCRIPTION. The default is 1. - - Returns - ------- - top_k : TYPE - DESCRIPTION. - - """ - X_ = np.array([X[i].flatten() for i in range(len(X))]) - bool_hashes = _collection_to_bool( - X_, self.hash_funcs_, self.start_points_, self.window_length_ - ) - top_k = np.zeros((len(X), k), dtype=int) - dists = _hamming_dist_matrix(self.bool_hashes_value_list, bool_hashes) - self.h_dists = dists - # Deal with equality by merging bucket contents ? - for i_x in range(len(X)): - ids = np.argsort(dists[i_x]) - _i = 0 - c = k - while c > 0: - candidates = self.dict_X_index[self.bool_hashes_key_list[ids[_i]]] - # Can do exact search by computing distances here - if len(candidates) > c: - candidates = candidates[:c] - top_k[i_x, k - c : k - c + len(candidates)] = candidates - c -= len(candidates) - _i += 1 - return top_k - - def find_motif(Index, X=None): - """ - . - - Parameters - ---------- - Index : TYPE - DESCRIPTION. - X : TYPE, optional - DESCRIPTION. The default is None. - - Returns - ------- - None. - - """ - pass diff --git a/aeon/similarity_search/series_search/_rp_lsh.py b/aeon/similarity_search/series_search/_rp_lsh.py new file mode 100644 index 0000000000..8d1701793e --- /dev/null +++ b/aeon/similarity_search/series_search/_rp_lsh.py @@ -0,0 +1,263 @@ +"""Random projection LSH index.""" + +import numpy as np +from numba import njit, prange + +from aeon.similarity_search.series_search._base import BaseIndexSearch + +# TPB = 16 + + +@njit(cache=True) +def _hamming_dist(X, Y): + d = 0 + for i in prange(X.shape[0]): + d += X[i] ^ Y[i] + return d + + +@njit(cache=True, parallel=True) +def _hamming_dist_matrix(bool_hashes_value_list, bool_hashes): + n_hash_funcs = bool_hashes.shape[0] + res = np.zeros((n_hash_funcs, bool_hashes_value_list.shape[0]), dtype=np.int64) + for i in prange(n_hash_funcs): + for j in range(bool_hashes_value_list.shape[0]): + res[i, j] = _hamming_dist(bool_hashes_value_list[j], bool_hashes[i]) + return res + + +@njit(cache=True, fastmath=True, parallel=True) +def _series_to_bool(X, hash_funcs, start_points, length): + n_hash_funcs = hash_funcs.shape[0] + res = np.empty(n_hash_funcs, dtype=np.bool_) + for j in prange(n_hash_funcs): + res[j] = _nb_flat_dot( + X[start_points[j] : start_points[j] + length], hash_funcs[j] + ) + return res + + +@njit(cache=True, fastmath=True) +def _nb_flat_dot(X, Y): + n_channels, n_timepoints = X.shape + out = 0 + for i in prange(n_channels): + for j in prange(n_timepoints): + out += X[i, j] * Y[i, j] + return out >= 0 + + +@njit(cache=True, parallel=True) +def _collection_to_bool(X, hash_funcs, start_points, length): + n_hash_funcs = hash_funcs.shape[0] + n_samples = X.shape[0] + res = np.empty((n_samples, n_hash_funcs), dtype=np.bool_) + for j in prange(n_hash_funcs): + for i in range(n_samples): + res[i, j] = _nb_flat_dot( + X[i, :, start_points[j] : start_points[j] + length], hash_funcs[j] + ) + + return res + + +class RP_LSH_Cosine(BaseIndexSearch): + """ + Random Projection Locality Sensitive Hashing index for cosine similarity. + + In this method based on SimHash, we define a hash function as a boolean operation + such as, given a random vector ``V`` of shape ``(n_channels, L)`` and a time series + ``X`` of shape ``(n_channels, n_timeponts)`` (with ``L<=n_timepoints``), we compute + ``X.V > 0`` to obtain the boolean result. + In the case where ``L>> from aeon.datasets import load_classification + >>> from aeon.similarity_search.series_search import RP_LSH_Cosine + >>> index = RP_LSH_Cosine() + >>> X, y = load_classification("ArrowHead") + >>> index.fit(X[:200]) + >>> r = index.find_neighbors(X[201]) + """ + + _tags = { + "capability:unequal_length": False, + } + + def __init__( + self, + n_hash_funcs=128, + hash_func_coverage=0.25, + use_discrete_vectors=True, + random_state=None, + normalise=False, + n_jobs=1, + ): + self.n_hash_funcs = n_hash_funcs + self.hash_func_coverage = hash_func_coverage + self.use_discrete_vectors = use_discrete_vectors + self.random_state = random_state + super().__init__(normalise=normalise, n_jobs=n_jobs) + + def _build_index(self): + """ + Build the index based on the data stored in X_. + + Returns + ------- + self + + """ + rng = np.random.default_rng(self.random_state) + n_timepoints = self.X_.shape[2] + self.window_length_ = max(1, int(n_timepoints * self.hash_func_coverage)) + + if self.use_discrete_vectors: + self.hash_funcs_ = rng.choice( + [-1, 1], size=(self.n_hash_funcs, self.n_channels_, self.window_length_) + ) + else: + self.hash_funcs_ = rng.uniform( + low=-1, + high=1.0, + size=(self.n_hash_funcs, self.n_channels_, self.window_length_), + ) + self.start_points_ = rng.choice( + n_timepoints - self.window_length_ + 1, + size=self.n_hash_funcs, + replace=True, + ) + + bool_hashes = _collection_to_bool( + self.X_, self.hash_funcs_, self.start_points_, self.window_length_ + ) + + str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] + self.dict_X_index_ = {} + self.dict_bool_hashes_ = {} + for i in range(len(str_hashes)): + if str_hashes[i] in self.dict_X_index_: + self.dict_X_index_[str_hashes[i]].append(i) + else: + self.dict_X_index_[str_hashes[i]] = [i] + self.dict_bool_hashes_[str_hashes[i]] = bool_hashes[i] + + self.bool_hashes_value_list_ = np.asarray(list(self.dict_bool_hashes_.values())) + self.bool_hashes_key_list_ = np.asarray(list(self.dict_bool_hashes_.keys())) + + return self + + def _get_bucket_content(self, key): + return self.dict_X_index_[key] + + def _get_bucket_sizes(self): + return {key: len(self.dict_X_index_[key]) for key in self.dict_X_index_} + + def _get_series_bucket(self, X): + """ + Get the matching bucket of a single series X if it exists in the index. + + Parameters + ---------- + X : TYPE + DESCRIPTION. + + Returns + ------- + TYPE + DESCRIPTION. + + """ + bool_hash = _series_to_bool( + X, self.hash_funcs_, self.start_points_, self.window_length_ + ) + str_hash = hash(bool_hash.tobytes()) + if str_hash in self.dict_X_index_: + return str_hash + else: + return None + + def _query_index( + self, + X, + k=1, + threshold=np.inf, + inverse_distance=False, + ): + """ + Find approximate nearest neighbors of a collection in the index. + + Parameters + ---------- + X : np.ndarray, shape = (n_channels, n_tiempoints) + Series for which we want to find neighbors. + k : int, optional + Number of neighbors to return for each series. The default is 1. + threshold : int, optional + A threshold on the distance to determine which candidates will be returned. + inverse_distance : bool, optional + Wheter to inverse the computed distance, meaning that the method will return + the k most dissimilar neighbors instead of the k most similar. + + Returns + ------- + top_k : np.ndarray, shape = (n_cases, k) + Indexes of k series in X_ (the index) that are close to each series in X. + top_k_dist : np.ndarray, shape = (n_cases, k) + Distance of k series in X_ (the index) to each series in X. The distance + is the hamming distance between the result of each hash function. + """ + bool_hashes = _series_to_bool( + X, self.hash_funcs_, self.start_points_, self.window_length_ + ) + top_k = np.zeros(k, dtype=int) + top_k_dist = np.zeros(k, dtype=float) + dists = _hamming_dist_matrix( + self.bool_hashes_value_list_, bool_hashes[np.newaxis, :] + )[0] + if inverse_distance: + dists = 1 / (dists + 1e-8) + # Get top k buckets + ids = np.argpartition(dists, kth=k)[:k] + # and reoder them + ids = ids[np.argsort(dists[ids])] + + _i_bucket = 0 + current_k = 0 + while current_k < k: + if dists[ids[_i_bucket]] <= threshold: + candidates = self.dict_X_index_[ + self.bool_hashes_key_list_[ids[_i_bucket]] + ] + # Can do exact search by computing distances here + if len(candidates) > k - current_k: + candidates = candidates[: k - current_k] + top_k[current_k : current_k + len(candidates)] = candidates + top_k_dist[current_k : current_k + len(candidates)] = dists[ + ids[_i_bucket] + ] + current_k += len(candidates) + else: + break + _i_bucket += 1 + return top_k[:current_k], top_k_dist[:current_k] diff --git a/aeon/similarity_search/subsequence_search/__init__.py b/aeon/similarity_search/subsequence_search/__init__.py index 5d64f901bd..eb062c46b8 100644 --- a/aeon/similarity_search/subsequence_search/__init__.py +++ b/aeon/similarity_search/subsequence_search/__init__.py @@ -7,11 +7,11 @@ "BruteForceMatrixProfile", ] +from aeon.similarity_search.subsequence_search._base import ( + BaseMatrixProfile, + BaseSubsequenceSearch, +) from aeon.similarity_search.subsequence_search._brute_force import ( BruteForceMatrixProfile, ) from aeon.similarity_search.subsequence_search._stomp import StompMatrixProfile -from aeon.similarity_search.subsequence_search.base import ( - BaseMatrixProfile, - BaseSubsequenceSearch, -) diff --git a/aeon/similarity_search/subsequence_search/base.py b/aeon/similarity_search/subsequence_search/_base.py similarity index 99% rename from aeon/similarity_search/subsequence_search/base.py rename to aeon/similarity_search/subsequence_search/_base.py index 9df76d233b..0c55881ad0 100644 --- a/aeon/similarity_search/subsequence_search/base.py +++ b/aeon/similarity_search/subsequence_search/_base.py @@ -44,6 +44,10 @@ def __init__( self.length = length super().__init__(n_jobs=n_jobs, normalise=normalise) + _tags = { + "capability:unequal_length": True, + } + @final def find_motifs( self, diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py index 2225fbd0ad..269cdc369b 100644 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ b/aeon/similarity_search/subsequence_search/_brute_force.py @@ -9,11 +9,11 @@ from numba import njit, prange from numba.typed import List +from aeon.similarity_search.subsequence_search._base import BaseMatrixProfile from aeon.similarity_search.subsequence_search._commons import ( _extract_top_k_from_dist_profile, _inverse_distance_profile_list, ) -from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile from aeon.utils.numba.general import ( get_all_subsequences, z_normalise_series_2d, diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py index a1d6ac8730..66d5270872 100644 --- a/aeon/similarity_search/subsequence_search/_stomp.py +++ b/aeon/similarity_search/subsequence_search/_stomp.py @@ -7,13 +7,13 @@ from numba import njit, prange from numba.typed import List +from aeon.similarity_search.subsequence_search._base import BaseMatrixProfile from aeon.similarity_search.subsequence_search._commons import ( _extract_top_k_from_dist_profile, _inverse_distance_profile_list, fft_sliding_dot_product, get_ith_products, ) -from aeon.similarity_search.subsequence_search.base import BaseMatrixProfile from aeon.utils.numba.general import ( AEON_NUMBA_STD_THRESHOLD, sliding_mean_std_one_series, diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index 5362137ba9..1d3161514a 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -8,7 +8,7 @@ import numpy as np -from aeon.similarity_search.subsequence_search.base import ( +from aeon.similarity_search.subsequence_search._base import ( BaseMatrixProfile, BaseSubsequenceSearch, ) diff --git a/aeon/utils/base/_register.py b/aeon/utils/base/_register.py index 9c576c350a..024ad447ee 100644 --- a/aeon/utils/base/_register.py +++ b/aeon/utils/base/_register.py @@ -24,13 +24,12 @@ from aeon.forecasting.base import BaseForecaster from aeon.regression.base import BaseRegressor from aeon.segmentation.base import BaseSegmenter -from aeon.similarity_search.subsequence_search.base import BaseSubsequenceSearch +from aeon.similarity_search.series_search._base import BaseSeriesSearch +from aeon.similarity_search.subsequence_search._base import BaseSubsequenceSearch from aeon.transformations.base import BaseTransformer from aeon.transformations.collection import BaseCollectionTransformer from aeon.transformations.series import BaseSeriesTransformer -# from aeon.similarity_search.series_search.base import BaseSeriesSearch - # all base classes BASE_CLASS_REGISTER = { # abstract - no estimator directly inherits from these @@ -49,7 +48,7 @@ "series-transformer": BaseSeriesTransformer, "forecaster": BaseForecaster, "subsequence_searcher": BaseSubsequenceSearch, - # "series_searcher": BaseSeriesSearch, + "series_searcher": BaseSeriesSearch, } # base classes which are valid for estimator to directly inherit from From cd33d0a02ea98e9364c7e766f1a5c3520795e388 Mon Sep 17 00:00:00 2001 From: baraline Date: Mon, 13 Jan 2025 10:43:09 +0100 Subject: [PATCH 11/18] add notebook for sim search tasks --- .../subsequence_search/_base.py | 2 + .../similarity_search_tasks.ipynb | 136 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 examples/similarity_search/similarity_search_tasks.ipynb diff --git a/aeon/similarity_search/subsequence_search/_base.py b/aeon/similarity_search/subsequence_search/_base.py index 0c55881ad0..a8d78b029d 100644 --- a/aeon/similarity_search/subsequence_search/_base.py +++ b/aeon/similarity_search/subsequence_search/_base.py @@ -19,6 +19,8 @@ # We can define a BaseVariableLengthSubsequenceSearch later for VALMOD and the likes. +# BaseSubSeries 'replace sub by series' + class BaseSubsequenceSearch(BaseSimilaritySearch): """ diff --git a/examples/similarity_search/similarity_search_tasks.ipynb b/examples/similarity_search/similarity_search_tasks.ipynb new file mode 100644 index 0000000000..a42339c611 --- /dev/null +++ b/examples/similarity_search/similarity_search_tasks.ipynb @@ -0,0 +1,136 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2347de94-27a7-486e-a900-e80db5c7f427", + "metadata": {}, + "source": [ + "# Similarity search tasks\n", + "\n", + "To discuss : the term subsequences appear more often than subseries in similarity search papers, so maybe stick to subsequences ?\n", + "\n", + "## Notations\n", + "- A single time point $x \\in \\mathbb{R}^{d}$ representing a vector of size $d$, with $d$ the number of channels\n", + "- A single time series $X \\in \\mathbb{R}^{d,m}$ of $d$ channels and $m$ timepoints\n", + "- A collection ${\\cal X} \\in \\mathbb{R}^{n,d,m}$ of $n$ time series \n", + "- $l$ a length parameter for subseries extracted using a sliding window on a time series $X$ over its timepoints\n", + "- $W_{i,j} \\in \\mathbb{R}^{d,l}$ a subseries extracted from a collection ${\\cal X}$, with $i$ the sample id and $j$ the starting timepoint, such as $W_{i,j} = X_{i,[j:j+l[}$. Denoted $W_{j}$ if used outside of the context of a collection. ${\\cal W}$ denotes the set of all admissible subseries.\n", + " \n", + "## Series tasks\n", + "Given a single series $X$, we want to be able to do the following tasks :\n", + "\n", + "#### Subseries Neighbor search:\n", + "$K$-nn based and/or range ($r$) based search (radius only for now, extent necessary for [k-Motiflefts](https://www.vldb.org/pvldb/vol16/p725-schafer.pdf) ?). Given a series $X$ and a subseries $W_i$, find the other subseries in $X$ that are the most similar to $W_i$. In terms of parameterization, we want to be able to toggle on/off :\n", + "- ignore neighboring matches. Given $W_j$ a neighboring subseries of $W_i$, the subseries $W_{j-l//\\epsilon}, ..., W_{j+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations\n", + "\n", + "#### Subseries Motif search :\n", + "Extract $k$-motifs or range $r$-motifs.\n", + "\n", + "The $k^{th}$ motif is the $k^{th}$ most similar pair of subseries in $X$. Given $\\forall a,b,i,j$ the pair ${W_i, W_j}$ is the motif if $dist(W_i, W_j) ≤ dist(W_a, W_b), i \\neq j$ and $a \\neq b$\n", + "\n", + "For the $r$-motif,: $S$ is a maximal set of subseries with range $r$ if $\\forall\\ W_i,W_j \\in S,\\ dist(W_i, W_j) \\leq 2r$ and $\\forall\\ W_a \\in {\\cal W}-S,\\ dist(W_a, W_i) > 2r$\n", + "\n", + "\n", + "#### Compute self distance profile\n", + "Given a subseries $W_i$, compute the self distance profile to $X$. Returns a vector of size $m-l+1$ containing the distance to all subseries. \n", + "\n", + "In terms of parameterization, we want to be able to toggle on/off :\n", + "- ignore neighboring matches. Given $W_j$ a neighboring subseries of $W_i$, the subseries $W_{j-l//\\epsilon}, ..., W_{j+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations\n", + "\n", + "\n", + "#### Compute self matrix profile\n", + "Given a series $X$ and a length parameter $l$, compute its self matrix profile. Returns a vector of size $m-l+1$ containing the distances to the best matches of each subseries $W_i$, and another vector of size $m-l+1$ containg the timestamp of the best matches in $X$ for each subseries. Implement it as A/B matrix profile with B=A.\n", + "\n", + "In terms of parameterization, we want to be able to toggle on/off :\n", + "- $k$ : number of best matches to return for each subseries in $X$\n", + "- $r$ : maximal distance of the best matches to be in the returned set for each subseries in $X$\n", + "- ignore neighboring matches. Given $W_j$ a neighboring subseries of $W_i$, the subseries $W_{j-l//\\epsilon}, ..., W_{j+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "7313599d-66e2-4d03-959e-bd0abe05baed", + "metadata": {}, + "source": [ + "\n", + "## Collection tasks\n", + "Given a time series collection $\\cal X$, we want to be able to do the following tasks :\n", + "(we consider all subseries $W_{i,j}$ part its of $\\cal X$ due to notation but doesn't have to be when given as inputs for example in neighbor search).\n", + "\n", + "#### Subseries Neighbor search :\n", + "$K$-nn based and/or range ($r$) based search (radius only for now, extent necessary for [k-Motiflefts](https://www.vldb.org/pvldb/vol16/p725-schafer.pdf) ?). Given a subseries $W_{i,j}$, find the other subseries in $\\cal X$ that are the most similar to $W_{i,j}$. In terms of parameterization, we want to be able to toggle on/off :\n", + "- ignore neighboring matches. Given ${W_a,b}$ a neighboring subseries of $W_{i,j}$, the subseries $W_{a, b-l//\\epsilon}, ..., W_{a,b+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations\n", + "\n", + "#### Series Neighbor search :\n", + "$K$-nn based and/or range ($r$) based search. Given a series $X_i$, find the other series in $\\cal X$ that are the most similar to $X_i$. In terms of parameterization, we want to be able to toggle on/off :\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations\n", + "\n", + "#### Subseries Motif search :\n", + "Extract $k$-motifs or range $r$-motifs.\n", + "\n", + "The $k^{th}$ motif is the $k^{th}$ most similar pair of subseries in $X$. Given $\\forall a,b,a^\\prime,b^\\prime,i,j,i^\\prime,j^\\prime$ the pair $(W_{i,j}, W_{i^\\prime,j^\\prime})$ is the motif if $dist(W_{i,j}, W_{i^\\prime,j^\\prime}) ≤ dist(W_{a,b}, W_{a^\\prime,b^\\prime}), i \\neq i^\\prime, j \\neq j^\\prime, a \\neq a^\\prime, b \\neq b^\\prime$.\n", + "\n", + "For the $r$-motif,: $S$ is a maximal set of subseries with range $r$ if $\\forall\\ (W_{i,j},W_{i^\\prime,j^\\prime}) \\in S,\\ dist(W_{i,j}, W_{i^\\prime,j^\\prime}) \\leq 2r$ and $\\forall\\ W_{a,b} \\in {\\cal W}-S,\\ dist(W_{i,j}, W_{a,b}) > 2r$\n", + "\n", + "\n", + "#### Compute distance profiles :\n", + "Given a subseries $W_{i,j}$, compute the distance profiles to all series in $\\cal X$. Returns a vector of size $n, m-l+1$ containing the distance to all subseries. \n", + "\n", + "In terms of parameterization, we want to be able to toggle on/off :\n", + "- ignore neighboring matches. Given $W_{i,b}$ a neighboring subseries of $W_{i,j}$ the subseries $W_{i,b-l//\\epsilon}, ..., W_{i,b+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations.\n", + "\n", + "\n", + "#### Compute matrix profiles :\n", + "Given a series $X_i \\in {\\cal X}$ and a length parameter $l$, compute its matrix profile over the collection. Returns a vector of size $m-l+1$ containing the distances to the best matches of each subseries $W_{i,j}$, and another vector of size $m-l+1$ containg the timestamp of the best matches in ${\\cal X}$ for each subseries.\n", + "\n", + "In terms of parameterization, we want to be able to toggle on/off :\n", + "- $k$ : number of best matches to return for each subseries in $X$\n", + "- $r$ : maximal distance of the best matches to be in the returned set for each subseries in $X$\n", + "- ignore neighboring matches. Given $W_{a,b}$ a neighbor of subseries $W_{i,j}$ the subseries $W_{a,b-l//\\epsilon}, ..., W_{a,b+l//\\epsilon}$ cannot be in the returned set.\n", + "- inverse distance. Return the worst matches instead of the best ones.\n", + "- normalize. Wheter subseries should be normalized prior to distance computations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "be1430f0-dce0-4de4-b702-11ee5e33f462", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (Spyder)", + "language": "python3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From b841b79796e4f7214fd0bb2dc4c381c42cfe554b Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 16 Jan 2025 09:55:29 +0100 Subject: [PATCH 12/18] Updated series similarity search --- aeon/similarity_search/_base.py | 252 ++----- aeon/similarity_search/collection/__init__.py | 1 + aeon/similarity_search/collection/_base.py | 96 +++ .../collection/motifs/__init__.py | 1 + .../collection/neighbors/__init__.py | 1 + .../neighbors/_rp_cosine_lsh.py} | 0 aeon/similarity_search/series/__init__.py | 7 + aeon/similarity_search/series/_base.py | 115 ++++ aeon/similarity_search/series/_commons.py | 210 ++++++ .../series/motifs/__init__.py | 7 + .../similarity_search/series/motifs/_stomp.py | 457 +++++++++++++ .../series/motifs/tests/__init__.py | 1 + .../series/motifs/tests/test_stomp.py | 149 +++++ .../series/neighbors/__init__.py | 9 + .../series/neighbors/_dummy.py | 159 +++++ .../series/neighbors/_mass.py | 247 +++++++ .../series/neighbors/tests/__init__.py | 1 + .../series/neighbors/tests/test_dummy.py | 40 ++ .../series/neighbors/tests/test_mass.py | 44 ++ .../series/tests/__init__.py | 1 + .../tests/test_base.py | 31 +- .../series/tests/test_commons.py | 174 +++++ .../series_search/__init__.py | 5 - aeon/similarity_search/series_search/_base.py | 264 -------- .../subsequence_search/__init__.py | 17 - .../subsequence_search/_base.py | 509 -------------- .../subsequence_search/_brute_force.py | 319 --------- .../subsequence_search/_commons.py | 170 ----- .../subsequence_search/_stomp.py | 619 ------------------ .../subsequence_search/tests/__init__.py | 1 - .../tests/test_brute_force.py | 172 ----- .../subsequence_search/tests/test_commons.py | 97 --- .../subsequence_search/tests/test_stomp.py | 332 ---------- .../_mock_similarity_searchers.py | 81 +-- aeon/transformations/collection/base.py | 4 +- .../similarity_search_tasks.ipynb | 2 +- 36 files changed, 1793 insertions(+), 2802 deletions(-) create mode 100644 aeon/similarity_search/collection/__init__.py create mode 100644 aeon/similarity_search/collection/_base.py create mode 100644 aeon/similarity_search/collection/motifs/__init__.py create mode 100644 aeon/similarity_search/collection/neighbors/__init__.py rename aeon/similarity_search/{series_search/_rp_lsh.py => collection/neighbors/_rp_cosine_lsh.py} (100%) create mode 100644 aeon/similarity_search/series/__init__.py create mode 100644 aeon/similarity_search/series/_base.py create mode 100644 aeon/similarity_search/series/_commons.py create mode 100644 aeon/similarity_search/series/motifs/__init__.py create mode 100644 aeon/similarity_search/series/motifs/_stomp.py create mode 100644 aeon/similarity_search/series/motifs/tests/__init__.py create mode 100644 aeon/similarity_search/series/motifs/tests/test_stomp.py create mode 100644 aeon/similarity_search/series/neighbors/__init__.py create mode 100644 aeon/similarity_search/series/neighbors/_dummy.py create mode 100644 aeon/similarity_search/series/neighbors/_mass.py create mode 100644 aeon/similarity_search/series/neighbors/tests/__init__.py create mode 100644 aeon/similarity_search/series/neighbors/tests/test_dummy.py create mode 100644 aeon/similarity_search/series/neighbors/tests/test_mass.py create mode 100644 aeon/similarity_search/series/tests/__init__.py rename aeon/similarity_search/{subsequence_search => series}/tests/test_base.py (76%) create mode 100644 aeon/similarity_search/series/tests/test_commons.py delete mode 100644 aeon/similarity_search/series_search/__init__.py delete mode 100644 aeon/similarity_search/series_search/_base.py delete mode 100644 aeon/similarity_search/subsequence_search/__init__.py delete mode 100644 aeon/similarity_search/subsequence_search/_base.py delete mode 100644 aeon/similarity_search/subsequence_search/_brute_force.py delete mode 100644 aeon/similarity_search/subsequence_search/_commons.py delete mode 100644 aeon/similarity_search/subsequence_search/_stomp.py delete mode 100644 aeon/similarity_search/subsequence_search/tests/__init__.py delete mode 100644 aeon/similarity_search/subsequence_search/tests/test_brute_force.py delete mode 100644 aeon/similarity_search/subsequence_search/tests/test_commons.py delete mode 100644 aeon/similarity_search/subsequence_search/tests/test_stomp.py diff --git a/aeon/similarity_search/_base.py b/aeon/similarity_search/_base.py index 68e35c6cbb..fc58838eb4 100644 --- a/aeon/similarity_search/_base.py +++ b/aeon/similarity_search/_base.py @@ -1,176 +1,87 @@ """Base class for similarity search.""" __maintainer__ = ["baraline"] +__all__ = [ + "BaseSimilaritySearch", +] + from abc import abstractmethod -from typing import Optional, Union, final +from typing import Union import numpy as np -from numba import get_num_threads, set_num_threads from numba.typed import List -from aeon.base import BaseCollectionEstimator - +from aeon.base import BaseAeonEstimator -class BaseSimilaritySearch(BaseCollectionEstimator): - """ - Base class for similarity search applications. - Parameters - ---------- - normalise : bool, optional - Whether the inputs should be z-normalised. The default is False. - n_jobs : int, optional - Number of parallel jobs to use. The default is 1. - """ +class BaseSimilaritySearch(BaseAeonEstimator): + """Base class for similarity search applications.""" _tags = { + "requires_y": False, "capability:multivariate": True, - "capability:multithreading": True, "fit_is_empty": False, - "X_inner_type": ["np-list", "numpy3D"], } @abstractmethod - def __init__( - self, - normalise: Optional[bool] = False, - n_jobs: Optional[int] = 1, - ): - self.n_jobs = n_jobs - self.normalise = normalise + def __init__(self): super().__init__() - @final + @abstractmethod def fit( self, X: Union[np.ndarray, List], y=None, ): """ - Fit method: data preprocessing and storage. + Fit estimator to X. + + State change: + Changes state to "fitted". + + Writes to self: + _is_fitted : flag is set to True. Parameters ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Input array to be used as database for the similarity search. If it is an - unequal length collection, it should be a list of 2d numpy arrays. - y : optional - Not used. - - Raises - ------ - TypeError - If the input X array is not 3D raise an error. + X : Series or Collection, any supported type + Data to fit transform to, of python type as follows: + Series: 2D np.ndarray shape (n_channels, n_timepoints) + Collection: 3D np.ndarray shape (n_cases, n_channels, n_timepoints) + or list of 2D np.ndarray, case i has shape (n_channels, n_timepoints_i) + y: ignored, exists for API consistency reasons. Returns ------- - self + self : a fitted instance of the estimator """ - self.reset() - prev_threads = get_num_threads() - self._check_fit_format(X) - X = self._preprocess_collection(X) - # Store minimum number of n_timepoints for unequal length collections - self.min_timepoints_ = min([X[i].shape[-1] for i in range(len(X))]) - self.n_channels_ = X[0].shape[0] - self.n_cases_ = len(X) - if self.metadata_["unequal_length"]: - X = List(X) - set_num_threads(self._n_jobs) - self._fit(X, y) - set_num_threads(prev_threads) - self.is_fitted = True - return self + ... @abstractmethod - def find_motifs( + def predict( self, - X: np.ndarray, - k: int, - threshold: float, + X: Union[np.ndarray, None] = None, ): """ - Find the top-k motifs in the training data. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif - sets. We define a motif set as a set of candidates which all are at a distance - of at most ``threshold`` from each other. The top-k motifs sets are the - motif sets with the most candidates. + Predict method. Parameters ---------- - X : np.ndarray, - A series in which we want to indentify motifs. - k : int, optional - Number of motifs to return - threshold : int, optional - A threshold on the similarity measure to determine which candidates will be - part of a motif set. - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - motifs. - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the distances of the - motifs to . - + X : 2D np.array of shape ``(n_cases, n_timepoints)`` + Optional data to use for predict. """ ... - @abstractmethod - def find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - ): + def _check_predict_series_format(self, X): """ - Find the top-k neighbors of X in the database. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k - neighbors of X, such as each of the ``k`` neighbors as a distance inferior or - equal to ``threshold``. By default, ``threshold`` is set to infinity. It is - possible for this method to return less than ``k`` neighbors, either if there - is less than ``k`` admissible candidate in the database, or if in the top-k - candidates, some do not meet the ``threshold`` condition. + Check wheter a series X in predict is correctly formated. Parameters ---------- - X: np.ndarray - The query for which we want to identify nearest neighbors in the database. - k : int, optional - Number of neighbors to return. - threshold : int, optional - A threshold on the distance to determine which candidates will be returned. - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - candidates in each motif. - + X : np.ndarray, shape = (n_channels, n_timepoints) + A series to be used in predict. """ - ... - - def _check_fit_format(self, X): - if isinstance(X, np.ndarray): # "numpy3D" or numpy2D - if X.ndim != 3: - raise TypeError( - f"A np.ndarray given in fit must be 3D but found {X.ndim}D" - ) - elif isinstance(X, list): # np-list or df-list - if isinstance(X[0], np.ndarray): # if one a numpy they must all be 2D numpy - for a in X: - if not (isinstance(a, np.ndarray) and a.ndim == 2): - raise TypeError( - "A np-list given in fit must contain 2D np.ndarray but" - f" found {a.ndim}D" - ) - - def _check_find_neighbors_motif_format(self, X): if isinstance(X, np.ndarray): if X.ndim != 2: raise TypeError( @@ -186,91 +97,8 @@ def _check_find_neighbors_motif_format(self, X): f"Expected X to have {self.n_channels_} channels but" f" got {X.shape[0]} channels." ) - - @abstractmethod - def _fit(self, X, y=None): ... - - def _check_X_index_int(self, X_index: int): - """ - Check wheter the X_index parameter is correctly formated and is admissible. - - This check is made for motif search functions. - - Parameters - ---------- - X_index : int - Index of a series in X_. - - Returns - ------- - X_index : int - Index of a series in X_ - - """ - if X_index is not None: - if not isinstance(X_index, int): - raise TypeError("Expected an integer for X_index but got {X_index}") - - if X_index >= self.n_cases_ or X_index < 0: - raise ValueError( - "The value of X_index cannot exced the number " - "of series in the collection given during fit. Expected a value " - f"between [0, {self.n_cases_ - 1}] but got {X_index}" - ) - return X_index - - def _check_X_index_array(self, X_index: np.ndarray): - """ - Check wheter the X_index parameter is correctly formated and is admissible. - - This check is made for neighbour search functions. - - Parameters - ---------- - X_index : np.ndarray, 1D array of shape (2) - Array of integer containing the sample and timestamp identifiers of the - starting point of a subsequence in X_. - - Returns - ------- - X_index : np.ndarray, 1D array of shape (2) - Array of integer containing the sample and timestamp identifiers of the - starting point of a subsequence in X_. - - """ - if X_index is not None: - if ( - isinstance(X_index, list) - and len(X_index) == 2 - and isinstance(X_index[0], int) - and isinstance(X_index[1], int) - ): - X_index = np.asarray(X_index, dtype=int) - elif len(X_index) != 2: - raise TypeError( - "Expected a numpy array or list of integers with 2 elements " - f"for X_index but got {X_index}" - ) - elif ( - not (isinstance(X_index[0], int) or not isinstance(X_index[1], int)) - or X_index.dtype != int - ): - raise TypeError( - "Expected a numpy array or list of integers for X_index but got " - f"{X_index}" - ) - - if X_index[0] >= self.n_cases_ or X_index[0] < 0: - raise ValueError( - "The sample ID (first element) of X_index cannot exced the number " - "of series in the collection given during fit. Expected a value " - f"between [0, {self.n_cases_ - 1}] but got {X_index[0]}" - ) - _max_timestamp = self.X_[X_index[0]].shape[1] - self.length + 1 - if X_index[1] >= _max_timestamp: - raise ValueError( - "The timestamp ID (second element) of X_index cannot exced the " - "number of timestamps minus the length parameter plus one. Expected" - f" a value between [0, {_max_timestamp - 1}] but got {X_index[1]}" - ) - return X_index + if hasattr(self, "length") and X.shape[1] != self.length: + raise ValueError( + f"Expected X to have {self.length} timepoints but" + f" got {X.shape[1]} timepoints." + ) diff --git a/aeon/similarity_search/collection/__init__.py b/aeon/similarity_search/collection/__init__.py new file mode 100644 index 0000000000..0aef46ef49 --- /dev/null +++ b/aeon/similarity_search/collection/__init__.py @@ -0,0 +1 @@ +"""Similarity search for time series collection.""" diff --git a/aeon/similarity_search/collection/_base.py b/aeon/similarity_search/collection/_base.py new file mode 100644 index 0000000000..402b7342a2 --- /dev/null +++ b/aeon/similarity_search/collection/_base.py @@ -0,0 +1,96 @@ +"""Base similiarity search for collections.""" + +__maintainer__ = ["baraline"] +__all__ = [ + "BaseCollectionSimilaritySearch", +] + +from abc import abstractmethod +from typing import Union, final + +import numpy as np +from numba import get_num_threads, set_num_threads + +from aeon.base import BaseCollectionEstimator +from aeon.similarity_search._base import BaseSimilaritySearch + + +class BaseCollectionSimilaritySearch(BaseCollectionEstimator, BaseSimilaritySearch): + """Similarity search base class for collections.""" + + # tag values specific to CollectionTransformers + _tags = { + "input_data_type": "Collection", + } + + @abstractmethod + def __init__(self, n_jobs=1): + self.n_jobs = n_jobs + super().__init__() + + @final + def fit( + self, + X: np.ndarray, + y=None, + ): + """ + Fit method: data preprocessing and storage. + + Parameters + ---------- + X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + Input array to be used as database for the similarity search. If it is an + unequal length collection, it should be a list of 2d numpy arrays. + y : optional + Not used. + + Raises + ------ + TypeError + If the input X array is not 3D raise an error. + + Returns + ------- + self + """ + self.reset() + X = self._preprocess_collection(X) + # Store minimum number of n_timepoints for unequal length collections + self.n_channels_ = X[0].shape[1] + self.n_cases_ = len(X) + self.X_ = X + + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) + self._fit(X, y=y) + set_num_threads(prev_threads) + + self.is_fitted = True + return self + + @abstractmethod + def _fit( + self, + X: np.ndarray, + y=None, + ): ... + + def _pre_predict( + self, + X: Union[np.ndarray, None] = None, + ): + """ + Predict method. + + Parameters + ---------- + X : Union[np.ndarray, None], optional + Optional data to use for predict.. The default is None. + + """ + self._check_is_fitted() + if X is not None: + # Could we call somehow _preprocess_series from a BaseCollectionEstimator ? + self._check_predict_format(X) + return X diff --git a/aeon/similarity_search/collection/motifs/__init__.py b/aeon/similarity_search/collection/motifs/__init__.py new file mode 100644 index 0000000000..fc014bcced --- /dev/null +++ b/aeon/similarity_search/collection/motifs/__init__.py @@ -0,0 +1 @@ +"""Motif search for time series collection.""" diff --git a/aeon/similarity_search/collection/neighbors/__init__.py b/aeon/similarity_search/collection/neighbors/__init__.py new file mode 100644 index 0000000000..e9a5d49d49 --- /dev/null +++ b/aeon/similarity_search/collection/neighbors/__init__.py @@ -0,0 +1 @@ +"""Neighbors search for time series collection.""" diff --git a/aeon/similarity_search/series_search/_rp_lsh.py b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py similarity index 100% rename from aeon/similarity_search/series_search/_rp_lsh.py rename to aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py diff --git a/aeon/similarity_search/series/__init__.py b/aeon/similarity_search/series/__init__.py new file mode 100644 index 0000000000..23df7d1b53 --- /dev/null +++ b/aeon/similarity_search/series/__init__.py @@ -0,0 +1,7 @@ +"""Similarity search for series.""" + +__all__ = [ + "BaseSeriesSimilaritySearch", +] + +from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch diff --git a/aeon/similarity_search/series/_base.py b/aeon/similarity_search/series/_base.py new file mode 100644 index 0000000000..b9cca5d5cb --- /dev/null +++ b/aeon/similarity_search/series/_base.py @@ -0,0 +1,115 @@ +"""Base similiarity search for series.""" + +from abc import abstractmethod +from typing import Union, final + +import numpy as np +from numba import get_num_threads, set_num_threads + +from aeon.base import BaseSeriesEstimator +from aeon.similarity_search._base import BaseSimilaritySearch +from aeon.utils.validation import check_n_jobs + + +class BaseSeriesSimilaritySearch(BaseSeriesEstimator, BaseSimilaritySearch): + """Base class for similarity search applications on single series.""" + + _tags = { + "input_data_type": "Series", + } + + @abstractmethod + def __init__(self, axis=1, n_jobs=1): + self.n_jobs = n_jobs + super().__init__(axis=axis) + + @final + def fit( + self, + X: np.ndarray, + y=None, + ): + """ + Fit method: data preprocessing and storage. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, n_timepoints) + Input series to be used for the similarity search operations. + y : optional + Not used. + + Raises + ------ + TypeError + If the input X array is not 2D raise an error. + + Returns + ------- + self + """ + self.reset() + self._n_jobs = check_n_jobs(self.n_jobs) + X = self._preprocess_series(X, self.axis, True) + # Store minimum number of n_timepoints for unequal length collections + self.n_channels_ = X.shape[0] + self.n_timepoints_ = X.shape[1] + self.X_ = X + + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) + self._fit(X, y=y) + set_num_threads(prev_threads) + + self.is_fitted = True + return self + + @abstractmethod + def _fit( + self, + X: np.ndarray, + y=None, + ): ... + + def _pre_predict( + self, + X: Union[np.ndarray, None] = None, + ): + """ + Predict method. + + Parameters + ---------- + X : Union[np.ndarray, None], optional + Optional data to use for predict.. The default is None. + + """ + self._check_is_fitted() + if X is not None: + X = self._preprocess_series(X, self.axis, False) + self._check_predict_format(X) + return X + + def _check_X_index(self, X_index: int): + """ + Check wheter a X_index parameter is correctly formated and is admissible. + + Parameters + ---------- + X_index : int + Index of a timestamp in X_. + + """ + if X_index is not None: + if not isinstance(X_index, int): + raise TypeError("Expected an integer for X_index but got {X_index}") + + max_timepoints = self.n_timepoints_ + if hasattr(self, "length"): + max_timepoints -= self.length + if X_index >= max_timepoints or X_index < 0: + raise ValueError( + "The value of X_index cannot exced the number " + "of timepoint in series given during fit. Expected a value " + f"between [0, {max_timepoints - 1}] but got {X_index}" + ) diff --git a/aeon/similarity_search/series/_commons.py b/aeon/similarity_search/series/_commons.py new file mode 100644 index 0000000000..d14281573f --- /dev/null +++ b/aeon/similarity_search/series/_commons.py @@ -0,0 +1,210 @@ +"""Helper and common function for similarity search series estimators.""" + +__maintainer__ = ["baraline"] + +import numpy as np +from numba import njit +from scipy.signal import convolve + + +def fft_sliding_dot_product(X, q): + """ + Use FFT convolution to calculate the sliding window dot product. + + This function applies the Fast Fourier Transform (FFT) to efficiently compute + the sliding dot product between the input time series `X` and the query `q`. + The dot product is computed for each channel individually. The sliding window + approach ensures that the dot product is calculated for every possible subsequence + of `X` that matches the length of `q` + + Parameters + ---------- + X : array, shape=(n_channels, n_timepoints) + Input time series + q : array, shape=(n_channels, query_length) + Input query + + Returns + ------- + out : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + Sliding dot product between q and X. + """ + n_channels, n_timepoints = X.shape + query_length = q.shape[1] + out = np.zeros((n_channels, n_timepoints - query_length + 1)) + for i in range(n_channels): + out[i, :] = convolve(np.flipud(q[i, :]), X[i, :], mode="valid").real + return out + + +def get_ith_products(X, T, L, ith): + """ + Compute dot products between X and the i-th subsequence of size L in T. + + Parameters + ---------- + X : array, shape = (n_channels, n_timepoints_X) + Input data. + T : array, shape = (n_channels, n_timepoints_T) + Data containing the query. + L : int + Overall query length. + ith : int + Query starting index in T. + + Returns + ------- + np.ndarray, 2D array of shape (n_channels, n_timepoints_X - L + 1) + Sliding dot product between the i-th subsequence of size L in T and X. + + """ + return fft_sliding_dot_product(X, T[:, ith : ith + L]) + + +def _inverse_distance_profile(dist_profile): + return 1 / (dist_profile + 1e-8) + + +@njit(cache=True) +def _extract_top_k_from_dist_profile( + dist_profile, + k, + threshold, + allow_trivial_matches, + exclusion_size, +): + """ + Given a distance profiles, extract the top k lower distances. + + Parameters + ---------- + dist_profile : np.ndarray, shape = (n_timepoints - length + 1) + A distance profile of length ``n_timepoints - length + 1``, with + ``length`` the size of the query used to compute the distance profiles. + k : int + Number of best matches to return + threshold : float + A threshold on the distances of the best matches. To be returned, a candidate + must have a distance bellow this threshold. This can reduce the number of + returned matches to be bellow ``k`` + allow_trivial_matches : bool + Wheter to allow returning matches that are in the same neighborhood. + exclusion_size : int + The size of the exlusion size to apply when ``allow_trivial_matches`` is + False. It is applied on both side of existing matches (+/- their indexes). + + Returns + ------- + top_k_indexes : np.ndarray, shape = (k) + The indexes of the best matches in ``distance_profile``. + top_k_distances : np.ndarray, shape = (k) + The distances of the best matches. + + """ + if k == np.inf: + k = dist_profile.shape[0] + top_k_indexes = np.zeros((k), dtype=np.int64) - 1 + top_k_distances = np.full(k, np.inf, dtype=np.float64) + ub = np.full(k, np.inf) + lb = np.full(k, -1.0) + # Could be optimized by using argpartition + sorted_indexes = np.argsort(dist_profile) + _current_k = 0 + if not allow_trivial_matches: + _current_j = 0 + # Until we extract k value or explore all the array or until dist is > threshold + while _current_k < k and _current_j < len(sorted_indexes): + # if we didn't insert anything or there is a conflict in lb/ub + if _current_k > 0 and np.any( + (sorted_indexes[_current_j] >= lb[:_current_k]) + & (sorted_indexes[_current_j] <= ub[:_current_k]) + ): + pass + else: + _idx = sorted_indexes[_current_j] + if dist_profile[_idx] <= threshold: + top_k_indexes[_current_k] = _idx + top_k_distances[_current_k] = dist_profile[_idx] + ub[_current_k] = min( + top_k_indexes[_current_k] + exclusion_size, + len(dist_profile), + ) + lb[_current_k] = max(top_k_indexes[_current_k] - exclusion_size, 0) + _current_k += 1 + else: + break + _current_j += 1 + else: + _current_k += min(k, len(dist_profile)) + dist_profile = dist_profile[sorted_indexes[:_current_k]] + dist_profile = dist_profile[dist_profile <= threshold] + _current_k = len(dist_profile) + + top_k_indexes[:_current_k] = sorted_indexes[:_current_k] + top_k_distances[:_current_k] = dist_profile[:_current_k] + + return top_k_indexes[:_current_k], top_k_distances[:_current_k] + + +# Could add aggregation function as parameter instead of just max +def _extract_top_k_motifs(MP, IP, k): + criterion = np.zeros(len(MP)) + for i in range(len(MP)): + criterion[i] = max(MP[i]) + idx = np.argsort(criterion) + return [MP[i] for i in idx[:k]], [IP[i] for i in idx[:k]] + + +def _extract_top_r_motifs(MP, IP, k): + criterion = np.zeros(len(MP)) + for i in range(len(MP)): + criterion[i] = len(MP[i]) + idx = np.argsort(criterion)[::-1] + return [MP[i] for i in idx[:k]], [IP[i] for i in idx[:k]] + + +@njit(cache=True, fastmath=True) +def _update_dot_products( + X, + T, + XT_products, + L, + i_query, +): + """ + Update dot products of the i-th query of size L in T from the dot products of i-1. + + Parameters + ---------- + X: np.ndarray, 2D array of shape (n_channels, n_timepoints) + Input time series on which the sliding dot product is computed. + T: np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + L : int + The length of the subsequences considered during the search. This parameter + cannot be larger than n_timepoints and series_length. + i_query : int + Query starting index in T. + + Returns + ------- + XT_products : np.ndarray of shape (n_channels, n_timepoints - L + 1) + Sliding dot product between the i-th subsequence of size L in T and X. + + """ + n_channels = T.shape[0] + Q = T[:, i_query : i_query + L] + n_candidates = X.shape[1] - L + 1 + + for i_ft in range(n_channels): + # first element of all 0 to n-1 candidates * first element of previous query + _a1 = X[i_ft, : n_candidates - 1] * T[i_ft, i_query - 1] + # last element of all 1 to n candidates * last element of current query + _a2 = X[i_ft, L : L - 1 + n_candidates] * T[i_ft, i_query + L - 1] + + XT_products[i_ft, 1:] = XT_products[i_ft, :-1] - _a1 + _a2 + + # Compute first dot product + XT_products[i_ft, 0] = np.sum(Q[i_ft] * X[i_ft, :L]) + return XT_products diff --git a/aeon/similarity_search/series/motifs/__init__.py b/aeon/similarity_search/series/motifs/__init__.py new file mode 100644 index 0000000000..d4853a68fe --- /dev/null +++ b/aeon/similarity_search/series/motifs/__init__.py @@ -0,0 +1,7 @@ +"""Subsequence Neighbor search for series.""" + +__all__ = [ + "StompMotif", +] + +from aeon.similarity_search.series.motifs._stomp import StompMotif diff --git a/aeon/similarity_search/series/motifs/_stomp.py b/aeon/similarity_search/series/motifs/_stomp.py new file mode 100644 index 0000000000..9287d80241 --- /dev/null +++ b/aeon/similarity_search/series/motifs/_stomp.py @@ -0,0 +1,457 @@ +"""Implementation of STOMP with squared euclidean distance.""" + +__maintainer__ = ["baraline"] +__all__ = ["StompMotif"] + +from typing import Optional + +import numpy as np +from numba import njit +from numba.typed import List + +from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch +from aeon.similarity_search.series._commons import ( + _extract_top_k_from_dist_profile, + _extract_top_k_motifs, + _extract_top_r_motifs, + _inverse_distance_profile, + _update_dot_products, + get_ith_products, +) +from aeon.similarity_search.series.neighbors._mass import ( + _normalized_squared_distance_profile, + _squared_distance_profile, +) +from aeon.utils.numba.general import sliding_mean_std_one_series + + +class StompMotif(BaseSeriesSimilaritySearch): + """ + Estimator to extract top k motifs using STOMP, descibed in [1]_. + + This estimators allows to perform multiple type of motif search operations by using + different parameterization. We base oursleves on Figure 3 of [2]_ to establish the + following list, we do not yet support "Learning" and "Valmod" motifs : + + - for "Pair Motifs" : This is the default configuration + + - for "k-Motiflets" : { + "motif_size": k, + } + + - for "k-motifs" (naming is confusing here, it is a range based motif): { + "motif_size":np.inf, + "dist_threshold":r, + "motif_extraction_method":"r_motifs" + } + + Parameters + ---------- + length : int + The length of the motifs to extract. This is the length of the subsequence + that will be used in the computations. + normalize : bool + Wheter the computations between subsequences should use a z-normalied distance. + + Notes + ----- + This estimator only provide exact computation method, faster approximate methods + also exists in the litterature. We use a squared euclidean distance instead of the + euclidean distance, if you want euclidean distance results, you should square root + the obtained results. + + References + ---------- + .. [1] Yan Zhu, Zachary Zimmerman, Nader Shakibay Senobari, Chin-Chia Michael + Yeh, Gareth Funning, Abdullah Mueen, Philip Brisk, and Eamonn Keogh. 2016. + Matrix profile II: Exploiting a novel algorithm and GPUs to break the one hundred + million barrier for time series motifs and joins. In 2016 IEEE 16th international + conference on data mining (ICDM). IEEE, 739–748. + .. [2] Patrick Schäfer and Ulf Leser. 2022. Motiflets: Simple and Accurate Detection + of Motifs in Time Series. Proc. VLDB Endow. 16, 4 (December 2022), 725–737. + https://doi.org/10.14778/3574245.3574257 + """ + + def __init__( + self, + length: int, + normalize: Optional[bool] = False, + ): + self.length = length + self.normalize = normalize + super().__init__() + + def _fit( + self, + X: np.ndarray, + y=None, + ): + if self.normalize: + self.X_means_, X_stds_ = sliding_mean_std_one_series(X, self.length, 1) + return self + + def predict( + self, + X: np.ndarray = None, + k: Optional[int] = 1, + motif_size: Optional[int] = 1, + dist_threshold: Optional[float] = np.inf, + allow_trivial_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2, + inverse_distance: Optional[bool] = False, + motif_extraction_method: Optional[str] = "k_motifs", + ): + """ + Exctract the motifs of X_ relative to a series X using STOMP matrix prfoile. + + To compute self-motifs, X is set to None. + + Parameters + ---------- + X : np.ndarray, shape=(n_channels, n_timepoint) + Series to use to compute the matrix profile against X_. If None, will + compute the self matrix profile of X_. Motifs will then be extracted from + the matrix profile. + k : int + The number of motifs to return. The default is 1, meaning we return only + the motif set with the minimal sum of distances to its query. + motif_size : int + The number of subsequences in a motif. Default is 1, meaning we extract + motif pairs (the query and its best match) + dist_threshold : float + The maximum allowed distance of a candidate subsequence of X to a query + subsequence from X_ for the candidate to be considered as a neighbor. + allow_trivial_matches: bool, optional + Wheter a neighbors of a match to a query can be also considered as matches + (True), or if an exclusion zone is applied around each match to avoid + trivial matches with their direct neighbors (False). + exclusion_factor : float, default=1. + A factor of the query length used to define the exclusion zone when + ``allow_trivial_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - length//exclusion_factor` and end at + :math:`id_timestamp + length//exclusion_factor`. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the farther neighbors will be returned instead of the closest ones. + motif_extraction_method : str + A string indicating the methodology to use to extract the top motifs. + Available methods are "r_motifs" and "k_motifs". "r_motifs" means we rank + motif set by their cardinality, with higher is better. "k_motifs" means + we rank motif set by their maximum distance to their query + + Returns + ------- + np.ndarray, shape = (k, motif_size) + The indexes of the best matches in ``distance_profile``. + np.ndarray, shape = (k, motif_size) + The distances of the best matches. + + """ + X = self._pre_predict(X) + if motif_extraction_method not in ["k_motifs", "r_motifs"]: + raise ValueError( + "Expected motif_extraction_method to be either 'k_motifs' or 'r_motifs'" + f"but got {motif_extraction_method}" + ) + exclusion_size = self.length // exclusion_factor + MP, IP = self.compute_matrix_profile( + X, + motif_size=motif_size, + dist_threshold=dist_threshold, + allow_trivial_matches=allow_trivial_matches, + exclusion_size=exclusion_size, + inverse_distance=inverse_distance, + ) + if motif_extraction_method == "k_motifs": + return _extract_top_k_motifs(MP, IP, k) + elif motif_extraction_method == "r_motifs": + return _extract_top_r_motifs(MP, IP, k) + + def compute_matrix_profile( + self, + X: np.ndarray, + motif_size: Optional[int] = 1, + dist_threshold: Optional[float] = np.inf, + allow_trivial_matches: Optional[bool] = False, + exclusion_size: Optional[float] = 2, + inverse_distance: Optional[bool] = False, + ): + """ + Compute matrix profile. + + The matrix profile is computed on the series given in fit (X_). If X is + not given, computes the self matrix profile of X_. Otherwise, compute the matrix + profile of X_ relative to X. + + Parameters + ---------- + X : np.ndarray, shape = (n_channels, n_timepoints) + A 2D array time series on against which the matrix profile of X_ will be + computed. + motif_size : int + The number of subsequences in a motif. Default is 1, meaning we extract + motif pairs (the query and its best match). + dist_threshold : float + The maximum allowed distance of a candidate subsequence of X to a query + subsequence from X_ for the candidate to be considered as a neighbor. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the worst matches to the query will be returned instead of the best ones. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, + the value None means that this is not used. + + Returns + ------- + MP : TypedList of np.ndarray (n_timepoints - L + 1) + Matrix profile distances for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + IP : TypedList of np.ndarray (n_timepoints - L + 1) + Indexes of the top matches for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + """ + if X is None: + is_self_mp = True + X = self.X_ + if self.normalize: + X_means, X_stds = self.X_means_, self.X_stds_ + else: + is_self_mp = False + if self.normalize: + X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) + + X_dotX = get_ith_products(X, self.X_, self.length, 0) + + if self.normalize: + MP, IP = _stomp_normalized( + self.X_, + X, + X_dotX, + self.X_means_, + self.X_stds_, + X_means, + X_stds, + self.length, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + is_self_mp, + ) + else: + MP, IP = _stomp( + self.X_, + X, + X_dotX, + self.length, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + is_self_mp, + ) + return MP, IP + + +@njit(cache=True, fastmath=True) +def _stomp_normalized( + X_A, + X_B, + AdotB, + X_A_means, + X_A_stds, + X_B_means, + X_B_stds, + L, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + is_self_mp, +): + """ + Compute the Matrix Profile using the STOMP algorithm with normalized distances. + + X_A : np.ndarray, 2D array of shape (n_channels, n_timepoints) + The series from which the queries will be extracted. + X_B : np.ndarray, 2D array of shape (n_channels, series_length) + The time series on which the distance profile of each query will be computed. + AdotB : np.ndarray, 2D array of shape (n_channels, series_length - L + 1) + Precomputed dot products between the first query of size L of X_A and X_B. + X_A_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) + Means of each subsequences of X_A of size L. + X_A_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) + Stds of each subsequences of X of size L. + X_B_means : np.ndarray, 2D array of shape (n_channels, series_length - L + 1) + Means of each subsequences of X_B of size L. + X_B_stds : np.ndarray, 2D array of shape (n_channels, series_length - L + 1) + Stds of each subsequences of X_B of size L. + L : int + Length of the subsequences used for the distance computation. + motif_size : int + The number of subsequences to extract from each distance profile. + dist_threshold : float + The maximum allowed distance of a candidate subsequence of X to a query + subsequence from X_ for the candidate to be considered as a neighbor. + allow_trivial_matches : bool + Wheter the top-k candidates can be neighboring subsequences. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, + the value None means that this is not used. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. + is_self_mp : bool + Wheter X_A == X_B. + + Returns + ------- + MP : TypedList of np.ndarray (n_timepoints - L + 1) + Matrix profile distances for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + IP : TypedList of np.ndarray (n_timepoints - L + 1) + Indexes of the top matches for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + """ + n_queries = X_A.shape[1] - L + 1 + _max_timestamp = X_B.shape[1] - L + MP = List() + IP = List() + + for i_q in range(n_queries): + # size T.shape[1] - L + 1 + dist_profile = _normalized_squared_distance_profile( + AdotB, X_B_means, X_B_stds, X_A_means[:, i_q], X_A_stds[:, i_q], L + ) + + if i_q + 1 < n_queries: + AdotB = _update_dot_products(X_B, X_A, AdotB, L, i_q + 1) + + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + + if is_self_mp: + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profile[lb:ub] = np.inf + + top_indexes, top_dists = _extract_top_k_from_dist_profile( + dist_profile, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + ) + + MP.append(top_dists) + IP.append(top_indexes) + + return MP, IP + + +@njit(cache=True, fastmath=True) +def _stomp( + X_A, + X_B, + AdotB, + L, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + is_self_mp, +): + """ + Compute the Matrix Profile using the STOMP algorithm with non-normalized distances. + + X_A : np.ndarray, 2D array of shape (n_channels, n_timepoints) + The series from which the queries will be extracted. + X_B : np.ndarray, 2D array of shape (n_channels, series_length) + The time series on which the distance profile of each query will be computed. + AdotB : np.ndarray, 2D array of shape (n_channels, series_length - L + 1) + Precomputed dot products between the first query of size L of X_A and X_B. + L : int + Length of the subsequences used for the distance computation. + motif_size : int + The number of subsequences to extract from each distance profile. + dist_threshold : float + The maximum allowed distance of a candidate subsequence of X to a query + subsequence from X_ for the candidate to be considered as a neighbor. + allow_trivial_matches : bool + Wheter the top-k candidates can be neighboring subsequences. + exclusion_size : int + The size of the exclusion zone used to prevent returning as top k candidates + the ones that are close to each other (for example i and i+1). + It is used to define a region between + :math:`id_timestamp - exclusion_size` and + :math:`id_timestamp + exclusion_size` which cannot be returned + as best match if :math:`id_timestamp` was already selected. By default, + the value None means that this is not used. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, the + worst matches to the query will be returned instead of the best ones. + is_self_mp : bool + Wheter X_A == X_B. + + Returns + ------- + MP : TypedList of np.ndarray (n_timepoints - L + 1) + Matrix profile distances for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + IP : TypedList of np.ndarray (n_timepoints - L + 1) + Indexes of the top matches for each query subsequence. n_timepoints is the + number of timepoint of X_. Each element of the list contains array of + variable size. + """ + n_queries = X_A.shape[1] - L + 1 + _max_timestamp = X_B.shape[1] - L + MP = List() + IP = List() + + # For each query of size L in X_A + for i_q in range(n_queries): + Q = X_A[:, i_q : i_q + L] + dist_profile = _squared_distance_profile(AdotB, X_B, Q) + if i_q + 1 < n_queries: + AdotB = _update_dot_products(X_B, X_A, AdotB, L, i_q + 1) + + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + + if is_self_mp: + ub = min(i_q + exclusion_size, _max_timestamp) + lb = max(0, i_q - exclusion_size) + dist_profile[lb:ub] = np.inf + + top_indexes, top_dists = _extract_top_k_from_dist_profile( + dist_profile, + motif_size, + dist_threshold, + allow_trivial_matches, + exclusion_size, + ) + + MP.append(top_dists) + IP.append(top_indexes) + + return MP, IP diff --git a/aeon/similarity_search/series/motifs/tests/__init__.py b/aeon/similarity_search/series/motifs/tests/__init__.py new file mode 100644 index 0000000000..d0d8f2c42c --- /dev/null +++ b/aeon/similarity_search/series/motifs/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for series motif search methods.""" diff --git a/aeon/similarity_search/series/motifs/tests/test_stomp.py b/aeon/similarity_search/series/motifs/tests/test_stomp.py new file mode 100644 index 0000000000..67ff930de1 --- /dev/null +++ b/aeon/similarity_search/series/motifs/tests/test_stomp.py @@ -0,0 +1,149 @@ +""" +Tests for stomp algorithm. + +We do not test equality for returned indexes due to the unstable nature of argsort +and the fact that the "kind=stable" parameter is not yet supported in numba. We instead +test that the returned index match the expected distance value. +""" + +__maintainer__ = ["baraline"] + +import numpy as np +import pytest +from numpy.testing import assert_almost_equal, assert_array_almost_equal + +from aeon.similarity_search.series._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile, + get_ith_products, +) +from aeon.similarity_search.series.motifs._stomp import _stomp, _stomp_normalized +from aeon.similarity_search.series.neighbors._dummy import ( + _naive_squared_distance_profile, +) +from aeon.testing.data_generation import make_example_2d_numpy_series +from aeon.utils.numba.general import ( + get_all_subsequences, + sliding_mean_std_one_series, + z_normalise_series_3d, +) + +MOTIFS_SIZE_VALUES = [1, 3] +THRESHOLD = [np.inf, 0.75] +THRESHOLD_NORM = [np.inf, 4.5] +NN_MATCHES = [True, False] +INVERSE = [True, False] + + +@pytest.mark.parametrize("motif_size", MOTIFS_SIZE_VALUES) +@pytest.mark.parametrize("threshold", THRESHOLD) +@pytest.mark.parametrize("allow_trivial_matches", NN_MATCHES) +@pytest.mark.parametrize("inverse_distance", INVERSE) +def test__stomp(motif_size, threshold, allow_trivial_matches, inverse_distance): + """Test STOMP method.""" + L = 3 + + X_A = make_example_2d_numpy_series( + n_channels=2, + n_timepoints=10, + ) + X_B = make_example_2d_numpy_series(n_channels=2, n_timepoints=10) + AdotB = get_ith_products(X_B, X_A, L, 0) + + exclusion_size = L + # MP : distances to best matches for each query + # IP : Indexes of best matches for each query + MP, IP = _stomp( + X_A, + X_B, + AdotB, + L, + motif_size, + threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + False, + ) + # For each query of size L in T + X_B_subs = get_all_subsequences(X_B, L, 1) + X_A_subs = get_all_subsequences(X_A, L, 1) + for i in range(X_A.shape[1] - L + 1): + dist_profile = _naive_squared_distance_profile(X_B_subs, X_A_subs[i]) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + dist_profile, motif_size, threshold, allow_trivial_matches, exclusion_size + ) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + assert_array_almost_equal(MP[i], top_k_distances) + + # Check that the index in IP correspond to a distance profile point + # with value equal to the corresponding MP point. + for j, index in enumerate(top_k_indexes): + assert_almost_equal(MP[i][j], dist_profile[index]) + + +@pytest.mark.parametrize("motif_size", MOTIFS_SIZE_VALUES) +@pytest.mark.parametrize("threshold", THRESHOLD_NORM) +@pytest.mark.parametrize("allow_trivial_matches", NN_MATCHES) +@pytest.mark.parametrize("inverse_distance", INVERSE) +def test__stomp_normalised( + motif_size, threshold, allow_trivial_matches, inverse_distance +): + """Test STOMP normalised method.""" + L = 3 + + X_A = make_example_2d_numpy_series( + n_channels=2, + n_timepoints=10, + ) + X_B = make_example_2d_numpy_series(n_channels=2, n_timepoints=10) + X_A_means, X_A_stds = sliding_mean_std_one_series(X_A, L, 1) + X_B_means, X_B_stds = sliding_mean_std_one_series(X_B, L, 1) + AdotB = get_ith_products(X_B, X_A, L, 0) + + exclusion_size = L + # MP : distances to best matches for each query + # IP : Indexes of best matches for each query + MP, IP = _stomp_normalized( + X_A, + X_B, + AdotB, + X_A_means, + X_A_stds, + X_B_means, + X_B_stds, + L, + motif_size, + threshold, + allow_trivial_matches, + exclusion_size, + inverse_distance, + False, + ) + # For each query of size L in T + X_B_subs = z_normalise_series_3d(get_all_subsequences(X_B, L, 1)) + X_A_subs = z_normalise_series_3d(get_all_subsequences(X_A, L, 1)) + for i in range(X_A.shape[1] - L + 1): + dist_profile = _naive_squared_distance_profile(X_B_subs, X_A_subs[i]) + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + dist_profile, motif_size, threshold, allow_trivial_matches, exclusion_size + ) + + # Check that the top matches extracted have the same value that the + # top matches in the distance profile + assert_array_almost_equal(MP[i], top_k_distances) + + # Check that the index in IP correspond to a distance profile point + # with value equal to the corresponding MP point. + for j, index in enumerate(top_k_indexes): + assert_almost_equal(MP[i][j], dist_profile[index]) diff --git a/aeon/similarity_search/series/neighbors/__init__.py b/aeon/similarity_search/series/neighbors/__init__.py new file mode 100644 index 0000000000..047bfbe9c4 --- /dev/null +++ b/aeon/similarity_search/series/neighbors/__init__.py @@ -0,0 +1,9 @@ +"""Subsequence Neighbor search for series.""" + +__all__ = [ + "DummySNN", + "MassSNN", +] + +from aeon.similarity_search.series.neighbors._dummy import DummySNN +from aeon.similarity_search.series.neighbors._mass import MassSNN diff --git a/aeon/similarity_search/series/neighbors/_dummy.py b/aeon/similarity_search/series/neighbors/_dummy.py new file mode 100644 index 0000000000..bbea714eda --- /dev/null +++ b/aeon/similarity_search/series/neighbors/_dummy.py @@ -0,0 +1,159 @@ +"""Implementation of NN with brute force.""" + +from typing import Optional + +__maintainer__ = ["baraline"] +__all__ = ["DummySNN"] + +import numpy as np +from numba import njit, prange + +from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch +from aeon.similarity_search.series._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile, +) +from aeon.utils.numba.general import ( + get_all_subsequences, + z_normalise_series_2d, + z_normalise_series_3d, +) + + +class DummySNN(BaseSeriesSimilaritySearch): + """Estimator to compute the on profile and distance profile using brute force.""" + + def __init__( + self, + length: int, + normalize: Optional[bool] = False, + n_jobs: Optional[int] = 1, + ): + self.length = length + self.normalize = normalize + super().__init__(n_jobs=n_jobs) + + def _fit( + self, + X: np.ndarray, + y=None, + ): + self.X_subs = get_all_subsequences(self.X_, self.length, 1) + if self.normalize: + self.X_subs = z_normalise_series_3d(self.X_subs) + return self + + def predict( + self, + X: np.ndarray, + k: Optional[int] = 1, + threshold: Optional[float] = np.inf, + exclusion_factor: Optional[float] = 2, + inverse_distance: Optional[bool] = False, + allow_neighboring_matches: Optional[bool] = False, + X_index: Optional[int] = None, + ): + """ + Compute nearest neighbors to X in subsequences of X_. + + Parameters + ---------- + X : np.ndarray, shape=(n_channels, length) + Subsequence we want to find neighbors for. + k : int + The number of neighbors to return. + threshold : float + The maximum distance of neighbors to X. + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the farther neighbors will be returned instead of the closest ones. + exclusion_factor : float, default=1. + A factor of the query length used to define the exclusion zone when + ``allow_neighboring_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - length//exclusion_factor` and end at + :math:`id_timestamp + length//exclusion_factor`. + X_index : Optional[int], optional + If ``X`` is a subsequence of X_, specify its starting timestamp in ``X_``. + If specified, neighboring subsequences of X won't be able to match as + neighbors. + + Returns + ------- + np.ndarray, shape = (k) + The indexes of the best matches in ``distance_profile``. + np.ndarray, shape = (k) + The distances of the best matches. + + """ + X = self._pre_predict(X) + X_index = self._check_X_index(X_index) + dist_profile = self.compute_distance_profile(X) + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + + if X_index is not None: + exclusion_size = self.length // exclusion_factor + _max_timestamp = self.n_timepoints_ - self.length + ub = min(X_index + exclusion_size, _max_timestamp) + lb = max(0, X_index - exclusion_size) + dist_profile[lb:ub] = np.inf + + return _extract_top_k_from_dist_profile( + dist_profile, + k, + threshold, + allow_neighboring_matches, + exclusion_size, + ) + + def compute_distance_profile(self, X: np.ndarray): + """ + Compute the distance profile of X to all samples in X_. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The query to use to compute the distance profiles. + + Returns + ------- + distance_profile : np.ndarray, 1D array of shape (n_candidates) + The distance profile of X to X_. The ``n_candidates`` value + is equal to ``n_timepoins - length + 1``, with ``n_timepoints`` the + length of X_. + + """ + if self.normalize: + X = z_normalise_series_2d(X) + return _naive_squared_distance_profile(self.X_subs, X) + + +@njit(cache=True, fastmath=True, parallel=True) +def _naive_squared_distance_profile( + X_subs, + Q, +): + """ + Compute a squared euclidean distance profile. + + Parameters + ---------- + X_subs : array, shape=(n_subsequences, n_channels, length) + Subsequences of size length of the input time series to search in. + Q : array, shape=(n_channels, query_length) + Query used during the search. + + Returns + ------- + out : np.ndarray, 1D array of shape (n_samples, n_timepoints_t - query_length + 1) + The distance between the query and all candidates in X. + + """ + n_subs, n_channels, length = X_subs.shape + dist_profile = np.zeros(n_subs) + for i in prange(n_subs): + for j in range(n_channels): + for k in range(length): + dist_profile[i] += (X_subs[i, j, k] - Q[j, k]) ** 2 + return dist_profile diff --git a/aeon/similarity_search/series/neighbors/_mass.py b/aeon/similarity_search/series/neighbors/_mass.py new file mode 100644 index 0000000000..bb56815f4e --- /dev/null +++ b/aeon/similarity_search/series/neighbors/_mass.py @@ -0,0 +1,247 @@ +"""Implementation of NN with MASS.""" + +from typing import Optional + +__maintainer__ = ["baraline"] +__all__ = ["MassSNN"] + +import numpy as np +from numba import njit, prange + +from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch +from aeon.similarity_search.series._commons import ( + _extract_top_k_from_dist_profile, + _inverse_distance_profile, + fft_sliding_dot_product, +) +from aeon.utils.numba.general import ( + AEON_NUMBA_STD_THRESHOLD, + sliding_mean_std_one_series, +) + + +class MassSNN(BaseSeriesSimilaritySearch): + """Estimator to compute the on profile and distance profile using MASS.""" + + def __init__( + self, + length: int, + normalize: Optional[bool] = False, + ): + self.length = length + self.normalize = normalize + super().__init__() + + def _fit( + self, + X: np.ndarray, + y=None, + ): + if self.normalize: + self.X_means_, X_stds_ = sliding_mean_std_one_series(X, self.length, 1) + return self + + def predict( + self, + X: np.ndarray, + k: Optional[int] = 1, + dist_threshold: Optional[float] = np.inf, + allow_trivial_matches: Optional[bool] = False, + exclusion_factor: Optional[float] = 2, + inverse_distance: Optional[bool] = False, + X_index: Optional[int] = None, + ): + """ + Compute nearest neighbors to X in subsequences of X_. + + Parameters + ---------- + X : np.ndarray, shape=(n_channels, length) + Subsequence we want to find neighbors for. + k : int + The number of neighbors to return. + dist_threshold : float + The maximum allowed distance of a candidate subsequence of X_ to X + for the candidate to be considered as a neighbor. + allow_trivial_matches: bool, optional + Wheter a neighbors of a match to a query can be also considered as matches + (True), or if an exclusion zone is applied around each match to avoid + trivial matches with their direct neighbors (False). + inverse_distance : bool + If True, the matching will be made on the inverse of the distance, and thus, + the farther neighbors will be returned instead of the closest ones. + exclusion_factor : float, default=1. + A factor of the query length used to define the exclusion zone when + ``allow_trivial_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - length//exclusion_factor` and end at + :math:`id_timestamp + length//exclusion_factor`. + X_index : Optional[int], optional + If ``X`` is a subsequence of X_, specify its starting timestamp in ``X_``. + If specified, neighboring subsequences of X won't be able to match as + neighbors. + + Returns + ------- + np.ndarray, shape = (k) + The indexes of the best matches in ``distance_profile``. + np.ndarray, shape = (k) + The distances of the best matches. + + """ + X = self._pre_predict(X) + X_index = self._check_X_index(X_index) + dist_profile = self.compute_distance_profile(X) + if inverse_distance: + dist_profile = _inverse_distance_profile(dist_profile) + + if X_index is not None: + exclusion_size = self.length // exclusion_factor + _max_timestamp = self.n_timepoints_ - self.length + ub = min(X_index + exclusion_size, _max_timestamp) + lb = max(0, X_index - exclusion_size) + dist_profile[lb:ub] = np.inf + + return _extract_top_k_from_dist_profile( + dist_profile, + k, + dist_threshold, + allow_trivial_matches, + exclusion_size, + ) + + def compute_distance_profile(self, X: np.ndarray): + """ + Compute the distance profile of X to all samples in X_. + + Parameters + ---------- + X : np.ndarray, 2D array of shape (n_channels, length) + The query to use to compute the distance profiles. + + Returns + ------- + distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) + The distance profile of X to all samples in X_. The ``n_candidates`` value + is equal to ``n_timepoins - length + 1``. If X_ is an unequal length + collection, returns a numba typed list instead of an ndarray. + + """ + QT = fft_sliding_dot_product(self.X_, X) + + if self.normalize: + distance_profile = _normalized_squared_distance_profile( + QT, + self.X_means_, + self.X_stds_, + X.mean(axis=1), + X.std(axis=1), + self.length, + ) + else: + distance_profile = _squared_distance_profile( + QT, + self.X_, # T + X, # Q + ) + + return distance_profile + + +@njit(cache=True, fastmath=True) +def _squared_distance_profile(QT, T, Q): + """ + Compute squared distance profile between query subsequence and a single time series. + + This function calculates the squared distance profile for a single time series by + leveraging the dot product of the query and time series as well as precomputed sums + of squares to efficiently compute the squared distances. + + Parameters + ---------- + QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + The dot product between the query and the time series. + T : np.ndarray, 2D array of shape (n_channels, series_length) + The series used for similarity search. Note that series_length can be equal, + superior or inferior to n_timepoints, it doesn't matter. + Q : np.ndarray + 2D array of shape (n_channels, query_length) representing query subsequence. + + Returns + ------- + distance_profile : np.ndarray + 2D array of shape (n_channels, n_timepoints - query_length + 1) + The squared distance profile between the query and the input time series. + """ + n_channels, profile_length = QT.shape + query_length = Q.shape[1] + _QT = -2 * QT + distance_profile = np.zeros(profile_length) + for k in prange(n_channels): + _sum = 0 + _qsum = 0 + for j in prange(query_length): + _sum += T[k, j] ** 2 + _qsum += Q[k, j] ** 2 + + distance_profile += _qsum + _QT[k] + distance_profile[0] += _sum + for i in prange(1, profile_length): + _sum += T[k, i + (query_length - 1)] ** 2 - T[k, i - 1] ** 2 + distance_profile[i] += _sum + return distance_profile + + +@njit(cache=True, fastmath=True) +def _normalized_squared_distance_profile( + QT, T_means, T_stds, Q_means, Q_stds, query_length +): + """ + Compute the z-normalized squared Euclidean distance profile for one time series. + + Parameters + ---------- + QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) + The dot product between the query and the time series. + T_means : np.ndarray, 1D array of length n_channels + The mean values of the time series for each channel. + T_stds : np.ndarray, 2D array of shape (n_channels, profile_length) + The standard deviations of the time series for each channel and position. + Q_means : np.ndarray, 1D array of shape (n_channels) + Means of the query q + Q_stds : np.ndarray, 1D array of shape (n_channels) + Stds of the query q + query_length : int + The length of the query subsequence used for the distance profile computation. + + + Returns + ------- + np.ndarray + 2D array of shape (n_channels, n_timepoints - query_length + 1) containing the + z-normalized squared distance profile between the query subsequence and the time + series. Entries are computed based on the z-normalized values, with special + handling for constant values. + """ + n_channels, profile_length = QT.shape + distance_profile = np.zeros(profile_length) + Q_is_constant = Q_stds <= AEON_NUMBA_STD_THRESHOLD + for i in prange(profile_length): + Sub_is_constant = T_stds[:, i] <= AEON_NUMBA_STD_THRESHOLD + for k in prange(n_channels): + # Two Constant case + if Q_is_constant[k] and Sub_is_constant[k]: + _val = 0 + # One Constant case + elif Q_is_constant[k] or Sub_is_constant[k]: + _val = query_length + else: + denom = query_length * Q_stds[k] * T_stds[k, i] + + p = (QT[k, i] - query_length * (Q_means[k] * T_means[k, i])) / denom + p = min(p, 1.0) + + _val = abs(2 * query_length * (1.0 - p)) + distance_profile[i] += _val + + return distance_profile diff --git a/aeon/similarity_search/series/neighbors/tests/__init__.py b/aeon/similarity_search/series/neighbors/tests/__init__.py new file mode 100644 index 0000000000..00ef2e73ec --- /dev/null +++ b/aeon/similarity_search/series/neighbors/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for series neighbors search methods.""" diff --git a/aeon/similarity_search/series/neighbors/tests/test_dummy.py b/aeon/similarity_search/series/neighbors/tests/test_dummy.py new file mode 100644 index 0000000000..df8ff72655 --- /dev/null +++ b/aeon/similarity_search/series/neighbors/tests/test_dummy.py @@ -0,0 +1,40 @@ +""" +Tests for stomp algorithm. + +We do not test equality for returned indexes due to the unstable nature of argsort +and the fact that the "kind=stable" parameter is not yet supported in numba. We instead +test that the returned index match the expected distance value. +""" + +__maintainer__ = ["baraline"] + +import numpy as np +import pytest +from numpy.testing import assert_almost_equal + +from aeon.similarity_search.series.neighbors._brute_force import ( + _naive_squared_distance_profile, +) +from aeon.testing.data_generation import make_example_2d_numpy_series +from aeon.utils.numba.general import get_all_subsequences, z_normalise_series_2d + +NORMALIZE = [True, False] + + +@pytest.mark.parametrize("normalize", NORMALIZE) +def test__naive_squared_distance_profile(normalize): + """Test Euclidean distance with brute force.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + dist_profile = _naive_squared_distance_profile( + get_all_subsequences(X, L, 1), Q, normalize=normalize + ) + + if normalize: + Q = z_normalise_series_2d(Q) + for i_t in range(X.shape[1] - L + 1): + S = X[:, i_t : i_t + L] + if normalize: + S = z_normalise_series_2d(X[:, i_t : i_t + L]) + assert_almost_equal(dist_profile[i_t], np.sum((S - Q) ** 2)) diff --git a/aeon/similarity_search/series/neighbors/tests/test_mass.py b/aeon/similarity_search/series/neighbors/tests/test_mass.py new file mode 100644 index 0000000000..b6bf1953ea --- /dev/null +++ b/aeon/similarity_search/series/neighbors/tests/test_mass.py @@ -0,0 +1,44 @@ +"""Tests for MASS algorithm.""" + +__maintainer__ = ["baraline"] + +import numpy as np +from numpy.testing import assert_almost_equal + +from aeon.similarity_search.series._commons import fft_sliding_dot_product +from aeon.similarity_search.series.neighbors._mass import ( + _normalized_squared_distance_profile, + _squared_distance_profile, +) +from aeon.testing.data_generation import make_example_2d_numpy_series +from aeon.utils.numba.general import sliding_mean_std_one_series, z_normalise_series_2d + + +def test__squared_distance_profile(): + """Test squared distance profile.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = fft_sliding_dot_product(X, Q) + dist_profile = _squared_distance_profile(QX, X, Q) + for i_t in range(X.shape[1] - L + 1): + assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) + + +def test__normalized_squared_distance_profile(): + """Test Euclidean distance.""" + L = 3 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + QX = fft_sliding_dot_product(X, Q) + X_mean, X_std = sliding_mean_std_one_series(X, L, 1) + Q_mean = Q.mean(axis=1) + Q_std = Q.std(axis=1) + + dist_profile = _normalized_squared_distance_profile( + QX, X_mean, X_std, Q_mean, Q_std, L + ) + Q = z_normalise_series_2d(Q) + for i_t in range(X.shape[1] - L + 1): + S = z_normalise_series_2d(X[:, i_t : i_t + L]) + assert_almost_equal(dist_profile[i_t], np.sum((S - Q) ** 2)) diff --git a/aeon/similarity_search/series/tests/__init__.py b/aeon/similarity_search/series/tests/__init__.py new file mode 100644 index 0000000000..4762fe16ce --- /dev/null +++ b/aeon/similarity_search/series/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for base class and commons functions.""" diff --git a/aeon/similarity_search/subsequence_search/tests/test_base.py b/aeon/similarity_search/series/tests/test_base.py similarity index 76% rename from aeon/similarity_search/subsequence_search/tests/test_base.py rename to aeon/similarity_search/series/tests/test_base.py index e1a314f38a..d3dc953c6a 100644 --- a/aeon/similarity_search/subsequence_search/tests/test_base.py +++ b/aeon/similarity_search/series/tests/test_base.py @@ -1,10 +1,11 @@ """Test for subsequence search base class.""" +__maintainer__ = ["baraline"] + import pytest from aeon.testing.mock_estimators._mock_similarity_searchers import ( - MockMatrixProfile, - MockSubsequenceSearch, + MockSeriesSimilaritySearch, ) from aeon.testing.testing_data import ( make_example_1d_numpy, @@ -13,11 +14,11 @@ make_example_3d_numpy_list, ) -BASES = [MockMatrixProfile, MockSubsequenceSearch] +BASES = [MockSeriesSimilaritySearch] @pytest.mark.parametrize("base", BASES) -def test_input_shape_fit_neighbord_motifs(base): +def test_input_shape_fit_predict(base): """Test input shapes.""" estimator = base() # dummy data to pass to fit when testing predict/predict_proba @@ -29,31 +30,31 @@ def test_input_shape_fit_neighbord_motifs(base): X_2D_multi = make_example_2d_numpy_series(n_channels=2) X_1D = make_example_1d_numpy() - valid_inputs_fit = [X_3D_uni, X_3D_multi, X_3D_uni_list, X_3D_multi_list] + valid_inputs_fit = [X_2D_uni, X_2D_multi] # Valid inputs for _input in valid_inputs_fit: estimator.fit(_input) - invalid_inputs_fit = [X_2D_uni, X_2D_multi, X_1D] + invalid_inputs_fit = [X_1D, X_3D_multi_list, X_3D_uni_list, X_3D_multi, X_3D_uni] for _input in invalid_inputs_fit: with pytest.raises(TypeError): estimator.fit(_input) - valid_inputs_neighboord_motifs_uni = [X_2D_uni] - invalid_inputs_neighboord_motifs_uni = [ + valid_inputs_predict = [X_2D_uni, X_2D_multi] + invalid_inputs_predict_uni = [ X_1D, X_3D_uni, X_3D_uni_list, ] - invalid_inputs_neighboord_motifs_multi = [ + invalid_inputs_predict_multi = [ X_3D_multi, X_3D_multi_list, ] - L = 5 - estimator_multi = base(length=L).fit(X_3D_multi) - estimator_uni = base(length=L).fit(X_3D_uni) + L = 3 + estimator_multi = base(length=L).fit(X_2D_multi) + estimator_uni = base(length=L).fit(X_2D_uni) - for _input in valid_inputs_neighboord_motifs_uni: + for _input in valid_inputs_predict: estimator_uni.find_neighbors(_input[:, :L]) estimator_uni.find_motifs(_input) with pytest.raises(ValueError): @@ -65,7 +66,7 @@ def test_input_shape_fit_neighbord_motifs(base): with pytest.raises(ValueError): estimator_uni.find_neighbors(_input[:, : L + 2]) - for _input in invalid_inputs_neighboord_motifs_uni: + for _input in invalid_inputs_predict_uni: with pytest.raises(TypeError): estimator_uni.find_neighbors(_input) with pytest.raises(TypeError): @@ -75,7 +76,7 @@ def test_input_shape_fit_neighbord_motifs(base): with pytest.raises(TypeError): estimator_multi.find_motifs(_input) - for _input in invalid_inputs_neighboord_motifs_multi: + for _input in invalid_inputs_predict_multi: with pytest.raises(TypeError): estimator_uni.find_neighbors(_input) with pytest.raises(TypeError): diff --git a/aeon/similarity_search/series/tests/test_commons.py b/aeon/similarity_search/series/tests/test_commons.py new file mode 100644 index 0000000000..774eee8dee --- /dev/null +++ b/aeon/similarity_search/series/tests/test_commons.py @@ -0,0 +1,174 @@ +"""Test _commons.py functions.""" + +__maintainer__ = ["baraline"] +import numpy as np +import pytest +from numba.typed import List +from numpy.testing import assert_, assert_array_almost_equal + +from aeon.similarity_search.series._commons import ( + _extract_top_k_from_dist_profile, + _extract_top_k_motifs, + _extract_top_r_motifs, + _inverse_distance_profile, + _update_dot_products, + fft_sliding_dot_product, + get_ith_products, +) +from aeon.testing.data_generation import ( + make_example_1d_numpy, + make_example_2d_numpy_series, +) + +K_VALUES = [1, 3, np.inf] +THRESHOLDS = [np.inf, 0.7] +NN_MATCHES = [False, True] +EXCLUSION_SIZE = [3, 5] + + +def test_fft_sliding_dot_product(): + """Test the fft_sliding_dot_product function.""" + L = 4 + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) + + values = fft_sliding_dot_product(X, Q) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], + ) + + +def test__update_dot_products(): + """Test the _update_dot_product function.""" + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=20) + T = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + L = 7 + current_product = get_ith_products(X, T, L, 0) + for i_query in range(1, T.shape[1] - L + 1): + new_product = get_ith_products( + X, + T, + L, + i_query, + ) + current_product = _update_dot_products( + X, + T, + current_product, + L, + i_query, + ) + assert_array_almost_equal(new_product, current_product) + + +def test_get_ith_products(): + """Test i-th dot product of a subsequence of size L.""" + X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) + L = 5 + + values = get_ith_products(X, Q, L, 0) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0, 0:L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], + ) + + values = get_ith_products(X, Q, L, 4) + # Compare values[0] only as input is univariate + assert_array_almost_equal( + values[0], + [np.dot(Q[0, 4 : 4 + L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], + ) + + +def test__inverse_distance_profile(): + """Test method to inverse a TypedList of distance profiles.""" + X = make_example_1d_numpy() + X_inv = _inverse_distance_profile(X) + assert_array_almost_equal(1 / (X + 1e-8), X_inv) + + +def test__extract_top_k_motifs(): + """Test motif extraction based on max distance.""" + MP = List( + [ + [1.0, 2.0], + [1.0, 4.0], + [0.5, 0.9], + [0.6, 0.7], + ] + ) + IP = List( + [ + [1, 2], + [1, 4], + [0, 3], + [0, 7], + ] + ) + MP_k, IP_k = _extract_top_k_motifs(MP, IP, 2) + assert_(len(MP_k) == 2) + assert_(MP_k[0] == [0.6, 0.7]) + assert_(IP_k[0] == [0, 7]) + assert_(MP_k[1] == [0.5, 0.9]) + assert_(IP_k[1] == [0, 3]) + + +def test__extract_top_r_motifs(): + """Test motif extraction based on motif set cardinality.""" + MP = List( + [ + [1.0, 1.5, 2.0, 1.5], + [1.0, 4.0], + [0.5, 0.9, 1.0], + [0.6, 0.7], + ] + ) + IP = List( + [ + [1, 2, 3, 4], + [1, 4], + [0, 3, 6], + [0, 7], + ] + ) + MP_k, IP_k = _extract_top_r_motifs(MP, IP, 2) + assert_(len(MP_k) == 2) + assert_(MP_k[0] == [1.0, 1.5, 2.0, 1.5]) + assert_(IP_k[0] == [1, 2, 3, 4]) + assert_(MP_k[1] == [0.5, 0.9, 1.0]) + assert_(IP_k[1] == [0, 3, 6]) + + +@pytest.mark.parametrize("k", K_VALUES) +@pytest.mark.parametrize("threshold", THRESHOLDS) +@pytest.mark.parametrize("allow_nn_matches", NN_MATCHES) +@pytest.mark.parametrize("exclusion_size", EXCLUSION_SIZE) +def test__extract_top_k_from_dist_profile( + k, threshold, allow_nn_matches, exclusion_size +): + """Test method to esxtract the top k candidates from a list of distance profiles.""" + X = make_example_1d_numpy(n_timepoints=30) + X_sort = np.argsort(X) + exclusion_size = 3 + top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( + X, k, threshold, allow_nn_matches, exclusion_size + ) + + if len(top_k_indexes) == 0 or len(top_k_distances) == 0: + raise AssertionError("_extract_top_k_from_dist_profile returned empty list") + for i, index in enumerate(top_k_indexes): + assert_(X[index] == top_k_distances[i]) + + assert_(np.all(top_k_distances <= threshold)) + + if allow_nn_matches: + assert_(np.all(top_k_distances <= X_sort[len(top_k_indexes) - 1])) + + if not allow_nn_matches: + same_X = np.sort(top_k_indexes) + if len(same_X) > 1: + assert_(np.all(np.diff(same_X) >= exclusion_size)) diff --git a/aeon/similarity_search/series_search/__init__.py b/aeon/similarity_search/series_search/__init__.py deleted file mode 100644 index 9a618540db..0000000000 --- a/aeon/similarity_search/series_search/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Series search module.""" - -__all__ = ["BaseSeriesSearch", "BaseIndexSearch"] - -from aeon.similarity_search.series_search._base import BaseIndexSearch, BaseSeriesSearch diff --git a/aeon/similarity_search/series_search/_base.py b/aeon/similarity_search/series_search/_base.py deleted file mode 100644 index f9c6ed8097..0000000000 --- a/aeon/similarity_search/series_search/_base.py +++ /dev/null @@ -1,264 +0,0 @@ -"""Base class for whole series search.""" - -__maintainer__ = ["baraline"] - -import warnings -from abc import abstractmethod -from typing import Optional, final - -import numpy as np -from numba import get_num_threads, set_num_threads - -from aeon.similarity_search._base import BaseSimilaritySearch -from aeon.utils.numba.general import compute_mean_stds_collection_parallel - - -class BaseSeriesSearch(BaseSimilaritySearch): - """ - Base class for similarity search on whole time series. - - Parameters - ---------- - normalise : bool, optional - Whether the inputs should be z-normalised. The default is False. - n_jobs : int, optional - Number of parallel jobs to use. The default is 1. - """ - - @final - def find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - ): - """ - Find the top-k motifs in the training data. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif - sets. We define a motif set as a set of candidates which all are at a distance - of at most ``threshold`` from each other. The top-k motifs sets are the - motif sets with the most candidates. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, n_timestamps) - A series in which we want to indentify motifs. - k : int, optional - Number of motifs to return - threshold : int, optional - A threshold on the similarity measure to determine which candidates will be - part of a motif set. - X_index : Optional[int], optional - If ``X`` is a series of the database given in fit, specify its index in - ``X_``. If specified, this series won't be able to match with itself. - inverse_distance : bool, optional - Wheter to inverse the computed distance, meaning that the method will return - the anomalies instead of motifs. - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - motifs in X. - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the distances of the - motifs macthes to the motif in X. - - """ - self._check_is_fitted() - if X is not None: - self._check_find_neighbors_motif_format(X) - prev_threads = get_num_threads() - X_index = self._check_X_index_int(X_index) - motifs_indexes, distances = self._find_motifs( - X, - k=k, - threshold=threshold, - inverse_distance=inverse_distance, - X_index=X_index, - ) - set_num_threads(prev_threads) - return motifs_indexes, distances - - @final - def find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - ): - """ - Find the top-k neighbors of X in the database. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k - neighbors of X, such as each of the ``k`` neighbors as a distance inferior or - equal to ``threshold``. By default, ``threshold`` is set to infinity. It is - possible for this method to return less than ``k`` neighbors, either if there - is less than ``k`` admissible candidate in the database, or if in the top-k - candidates, some do not meet the ``threshold`` condition. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, length) - The subsequence for which we want to identify nearest neighbors in the - database. - k : int, optional - Number of neighbors to return. - threshold : int, optional - A threshold on the distance to determine which candidates will be returned. - X_index : Optional[int], optional - If ``X`` is a series of the database given in fit, specify its index in - ``X_``. If specified, this series won't be able to match with itself. - inverse_distance : bool, optional - Wheter to inverse the computed distance, meaning that the method will return - the k most dissimilar neighbors instead of the k most similar. - - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - neighbors. - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the distances of the - neighbors to X. - - """ - self._check_is_fitted() - - self._check_find_neighbors_motif_format(X) - - X_index = self._check_X_index_int(X_index) - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) - neighbors, distances = self._find_neighbors( - X, - k=k, - threshold=threshold, - inverse_distance=inverse_distance, - X_index=X_index, - ) - set_num_threads(prev_threads) - if len(neighbors) < k: - warnings.warn( - f"The number of admissible neighbors found is {len(neighbors)}, instead" - f" of {k}", - stacklevel=2, - ) - return neighbors, distances - - def _compute_mean_std_from_collection(self, X: np.ndarray): - """ - Compute the mean and std of each channel for all series in X. - - Parameters - ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Collection of series from which we extract mean and stds. If it is an - unequal length collection, it should be a list of 2d numpy arrays. - - Returns - ------- - Tuple(np.ndarray, np.ndarray) - Both array are of shape (n_cases, n_channels), the first contains the means - and the second the stds for each series in X. - - """ - means, stds = compute_mean_stds_collection_parallel(X) - return means, stds - - def _fit(self, X, y=None): - if self.normalise: - self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) - self.X_ = X - return self - - @abstractmethod - def _find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - ): ... - - @abstractmethod - def _find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - inverse_distance: Optional[bool] = False, - X_index=None, - ): ... - - -# TODO : Add an update method to add series to the index -class BaseIndexSearch(BaseSeriesSearch): - """ - Base class for similarity search on whole time series using indexes. - - Parameters - ---------- - normalise : bool, optional - Whether the inputs should be z-normalised. The default is False. - n_jobs : int, optional - Number of parallel jobs to use. The default is 1. - """ - - def _fit(self, X, y=None): - super()._fit(X) - self._build_index() - return self - - @abstractmethod - def _build_index(self): ... - - @abstractmethod - def _query_index( - self, - X, - k=1, - inverse_distance=False, - threshold=np.inf, - ): ... - - @abstractmethod - def _get_bucket_sizes(self): ... - - @abstractmethod - def _get_bucket_content(self, key): ... - - def _find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - ): - bucket_sizes = self._get_bucket_sizes() - idx_motifs = np.argsort(list(bucket_sizes.values()))[::-1][:, k] - # TODO : review distance return on motif for whole series and buckets - return [self._get_bucket_content(idx_motif) for idx_motif in idx_motifs], [ - 0 for _ in idx_motifs - ] - - def _find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - inverse_distance: Optional[bool] = False, - X_index=None, - ): - top_k, top_k_dist = self._query_index( - X, k=k, inverse_distance=inverse_distance, threshold=threshold - ) - return top_k, top_k_dist diff --git a/aeon/similarity_search/subsequence_search/__init__.py b/aeon/similarity_search/subsequence_search/__init__.py deleted file mode 100644 index eb062c46b8..0000000000 --- a/aeon/similarity_search/subsequence_search/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Subsequence search module.""" - -__all__ = [ - "BaseSubsequenceSearch", - "BaseMatrixProfile", - "StompMatrixProfile", - "BruteForceMatrixProfile", -] - -from aeon.similarity_search.subsequence_search._base import ( - BaseMatrixProfile, - BaseSubsequenceSearch, -) -from aeon.similarity_search.subsequence_search._brute_force import ( - BruteForceMatrixProfile, -) -from aeon.similarity_search.subsequence_search._stomp import StompMatrixProfile diff --git a/aeon/similarity_search/subsequence_search/_base.py b/aeon/similarity_search/subsequence_search/_base.py deleted file mode 100644 index a8d78b029d..0000000000 --- a/aeon/similarity_search/subsequence_search/_base.py +++ /dev/null @@ -1,509 +0,0 @@ -"""Base class for subsequence search.""" - -__maintainer__ = ["baraline"] - -import warnings -from abc import abstractmethod -from typing import Optional, final - -import numpy as np -from numba import get_num_threads, set_num_threads -from numba.typed import List - -from aeon.similarity_search._base import BaseSimilaritySearch -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, -) -from aeon.utils.numba.general import sliding_mean_std_one_series - -# We can define a BaseVariableLengthSubsequenceSearch later for VALMOD and the likes. - -# BaseSubSeries 'replace sub by series' - - -class BaseSubsequenceSearch(BaseSimilaritySearch): - """ - Base class for similarity search on time series subsequences. - - Parameters - ---------- - length : int - The length of the subsequence to be considered. - normalise : bool, optional - Whether the inputs should be z-normalised. The default is False. - n_jobs : int, optional - Number of parallel jobs to use. The default is 1. - """ - - @abstractmethod - def __init__( - self, - length: int, - normalise: Optional[bool] = False, - n_jobs: Optional[int] = 1, - ): - self.length = length - super().__init__(n_jobs=n_jobs, normalise=normalise) - - _tags = { - "capability:unequal_length": True, - } - - @final - def find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): - """ - Find the top-k motifs in the training data. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k motif - sets. We define a motif set as a set of candidates which all are at a distance - of at most ``threshold`` from each other. The top-k motifs sets are the - motif sets with the most candidates. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, n_timestamps) - A series in which we want to indentify motifs. - k : int, optional - Number of motifs to return - threshold : int, optional - A threshold on the similarity measure to determine which candidates will be - part of a motif set. - X_index : Optional[int], optional - If ``X`` is a series of the database given in fit, specify its index in - ``X_``. If specified, each query of this series won't be able to match with - its neighboring subsequences. - inverse_distance : bool, optional - Wheter to inverse the computed distance, meaning that the method will return - the anomalies instead of motifs. - allow_neighboring_matches: bool, optional - Wheter a candidate can be part of multiple motif sets (True), or if motif - sets should be mutually exclusive (False). - exclusion_factor : float, default=2. - A factor of the query length used to define the exclusion zone when - ``allow_neighboring_matches`` is set to False. For a given timestamp, - the exclusion zone starts from - :math:`id_timestamp - query_length//exclusion_factor` and end at - :math:`id_timestamp + query_length//exclusion_factor`. - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - motifs in X. - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the distances of the - motifs macthes to the motif in X. - - """ - self._check_is_fitted() - if X is not None: - self._check_find_neighbors_motif_format(X) - prev_threads = get_num_threads() - X_index = self._check_X_index_int(X_index) - motifs_indexes, distances = self._find_motifs( - X, - k=k, - threshold=threshold, - exclusion_factor=exclusion_factor, - inverse_distance=inverse_distance, - allow_neighboring_matches=allow_neighboring_matches, - X_index=X_index, - ) - set_num_threads(prev_threads) - return motifs_indexes, distances - - @final - def find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - inverse_distance: Optional[bool] = False, - X_index: Optional[np.ndarray] = None, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): - """ - Find the top-k neighbors of X in the database. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k - neighbors of X, such as each of the ``k`` neighbors as a distance inferior or - equal to ``threshold``. By default, ``threshold`` is set to infinity. It is - possible for this method to return less than ``k`` neighbors, either if there - is less than ``k`` admissible candidate in the database, or if in the top-k - candidates, some do not meet the ``threshold`` condition. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, length) - The subsequence for which we want to identify nearest neighbors in the - database. - k : int, optional - Number of neighbors to return. - threshold : int, optional - A threshold on the distance to determine which candidates will be returned. - inverse_distance : bool, optional - Wheter to inverse the computed distance, meaning that the method will return - the k most dissimilar neighbors instead of the k most similar. - X_index : np.ndarray, shape=(2,), optional - If ``X`` is a subsequence of the database given in fit, specify its starting - index as (i_case, i_timestamp). If specified, this subsequence and the - neighboring ones (according to ``exclusion_factor``) won't be considered as - admissible candidates. - allow_neighboring_matches: bool, optional - Wheter the top-k candidates can be neighboring subsequences. - exclusion_factor : float, default=2. - A factor of the query length used to define the exclusion zone when - ``allow_neighboring_matches`` is set to False. For a given timestamp, - the exclusion zone starts from - :math:`id_timestamp - query_length//exclusion_factor` and end at - :math:`id_timestamp + query_length//exclusion_factor`. - - Returns - ------- - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the indexes of the - neighbors. - ndarray, shape=(k,) - A numpy array of at most ``k`` elements containing the distances of the - neighbors to X. - - """ - self._check_is_fitted() - - self._check_find_neighbors_motif_format(X) - if self.length != X.shape[1]: - raise ValueError( - f"Expected X to be of shape {(self.n_channels_, self.length)} but" - f" got {X.shape} in find_neighbors." - ) - - X_index = self._check_X_index_array(X_index) - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) - neighbors, distances = self._find_neighbors( - X, - k=k, - threshold=threshold, - inverse_distance=inverse_distance, - X_index=X_index, - allow_neighboring_matches=allow_neighboring_matches, - exclusion_factor=exclusion_factor, - ) - set_num_threads(prev_threads) - if len(neighbors) < k: - warnings.warn( - f"The number of admissible neighbors found is {len(neighbors)}, instead" - f" of {k}", - stacklevel=2, - ) - return neighbors, distances - - def _check_X_index_int(self, X_index: int): - """ - Check wheter the X_index parameter is correctly formated and is admissible. - - This check is made for motif search functions. - - Parameters - ---------- - X_index : int - Index of a series in X_. - - Returns - ------- - X_index : int - Index of a series in X_ - - """ - if X_index is not None: - if not isinstance(X_index, int): - raise TypeError("Expected an integer for X_index but got {X_index}") - - if X_index >= self.n_cases_ or X_index < 0: - raise ValueError( - "The value of X_index cannot exced the number " - "of series in the collection given during fit. Expected a value " - f"between [0, {self.n_cases_ - 1}] but got {X_index}" - ) - return X_index - - def _check_X_index_array(self, X_index: np.ndarray): - """ - Check wheter the X_index parameter is correctly formated and is admissible. - - This check is made for neighbour search functions. - - Parameters - ---------- - X_index : np.ndarray, 1D array of shape (2) - Array of integer containing the sample and timestamp identifiers of the - starting point of a subsequence in X_. - - Returns - ------- - X_index : np.ndarray, 1D array of shape (2) - Array of integer containing the sample and timestamp identifiers of the - starting point of a subsequence in X_. - - """ - if X_index is not None: - if ( - isinstance(X_index, list) - and len(X_index) == 2 - and isinstance(X_index[0], int) - and isinstance(X_index[1], int) - ): - X_index = np.asarray(X_index, dtype=int) - elif len(X_index) != 2: - raise TypeError( - "Expected a numpy array or list of integers with 2 elements " - f"for X_index but got {X_index}" - ) - elif ( - not (isinstance(X_index[0], int) or not isinstance(X_index[1], int)) - or X_index.dtype != int - ): - raise TypeError( - "Expected a numpy array or list of integers for X_index but got " - f"{X_index}" - ) - - if X_index[0] >= self.n_cases_ or X_index[0] < 0: - raise ValueError( - "The sample ID (first element) of X_index cannot exced the number " - "of series in the collection given during fit. Expected a value " - f"between [0, {self.n_cases_ - 1}] but got {X_index[0]}" - ) - _max_timestamp = self.X_[X_index[0]].shape[1] - self.length + 1 - if X_index[1] >= _max_timestamp: - raise ValueError( - "The timestamp ID (second element) of X_index cannot exced the " - "number of timestamps minus the length parameter plus one. Expected" - f" a value between [0, {_max_timestamp - 1}] but got {X_index[1]}" - ) - return X_index - - def _compute_mean_std_from_collection(self, X: np.ndarray): - """ - Compute the mean and std of each subsequence of size ``length`` in X. - - Parameters - ---------- - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Collection of series from which we extract mean and stds. If it is an - unequal length collection, it should be a list of 2d numpy arrays. - - Returns - ------- - Tuple(np.ndarray, np.ndarray) - Both array are of shape (n_cases, n_timepoints-length+1, n_channels), - the first contains the means and the second the stds for each subsequence - of size ``length`` in X. - - """ - means = [] - stds = [] - - for i_x in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i_x], self.length, 1) - stds.append(_std) - means.append(_mean) - - if self.metadata_["unequal_length"]: - return List(means), List(stds) - else: - return np.asarray(means), np.asarray(stds) - - def _fit(self, X, y=None): - if self.length >= self.min_timepoints_ or self.length < 1: - raise ValueError( - "The length of the query should be inferior or equal to the length of " - "data (X_) provided during fit, but got {} for X and {} for X_".format( - self.length, self.min_timepoints_ - ) - ) - - if self.normalise: - self.X_means_, self.X_stds_ = self._compute_mean_std_from_collection(X) - self.X_ = X - return self - - @abstractmethod - def _find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): ... - - @abstractmethod - def _find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - inverse_distance: Optional[bool] = False, - X_index=None, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): ... - - @classmethod - def _get_test_params(cls, parameter_set: str = "default") -> dict: - """Return testing parameter settings for the estimator. - - Parameters - ---------- - parameter_set : str, default="default" - Name of the set of test parameters to return, for use in tests. If no - special parameters are defined for a value, will return `"default"` set. - For classifiers, a "default" set of parameters should be provided for - general testing, and a "results_comparison" set for comparing against - previously recorded results if the general set does not produce suitable - probabilities to compare against. - - Returns - ------- - params : dict or list of dict, default={} - Parameters to create testing instances of the class. - Each dict are parameters to construct an "interesting" test instance, i.e., - `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. - """ - return {"length": 3} - - -class BaseMatrixProfile(BaseSubsequenceSearch): - """Base class for Matrix Profile methods using a length parameter.""" - - def _find_motifs( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - X_index: Optional[int] = None, - inverse_distance: Optional[bool] = False, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): - exclusion_size = self.length // exclusion_factor - - MP, IP = self.compute_matrix_profile( - k, - threshold, - exclusion_size, - inverse_distance, - allow_neighboring_matches, - X=X, - X_index=X_index, - ) - # TODO check motif extraction logic, sure its not this one - MP_avg = np.array([[np.mean(MP[i]) for i in range(len(MP))]]) - # TODO: appening IP of identified motifs to return to get motifs matches in X_ - return _extract_top_k_from_dist_profile( - MP_avg, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - ) - - def _find_neighbors( - self, - X: np.ndarray, - k: Optional[int] = 1, - threshold: Optional[float] = np.inf, - inverse_distance: Optional[bool] = False, - X_index=None, - allow_neighboring_matches: Optional[bool] = False, - exclusion_factor: Optional[float] = 2.0, - ): - """ - Find the top-k neighbors of X in the database. - - Given ``k`` and ``threshold`` parameters, this methods returns the top-k - neighbors of X, such as each of the ``k`` neighbors as a distance inferior or - equal to ``threshold``. By default, ``threshold`` is set to infinity. It is - possible for this method to return less than ``k`` neighbors, either if there - is less than ``k`` admissible candidate in the database, or if in the top-k - candidates, some do not meet the ``threshold`` condition. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, length) - The subsequence for which we want to identify nearest neighbors in the - database. - k : int, optional - Number of neighbors to return. - threshold : int, optional - A threshold on the distance to determine which candidates will be returned. - inverse_distance : bool, optional - Wheter to inverse the computed distance, meaning that the method will return - the k most dissimilar neighbors instead of the k most similar. - X_index : np.ndarray, shape=(2,), optional - If ``X`` is a subsequence of the database given in fit, specify its starting - index as (i_case, i_timestamp). If specified, this subsequence and the - neighboring ones (according to ``exclusion_factor``) won't be considered as - admissible candidates. - allow_neighboring_matches: bool, optional - Wheter the top-k candidates can be neighboring subsequences. - exclusion_factor : float, default=2. - A factor of the query length used to define the exclusion zone when - ``allow_neighboring_matches`` is set to False. For a given timestamp, the - exclusion zone starts from - :math:`id_timestamp - query_length//exclusion_factor` and end at - :math:`id_timestamp + query_length//exclusion_factor`. - """ - exclusion_size = self.length // exclusion_factor - dist_profiles = self.compute_distance_profile(X) - - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - # Deal with self-matches - if X_index is not None: - _max_timestamp = self.X_[X_index[0]].shape[1] - self.length - ub = min(X_index[1] + exclusion_size, _max_timestamp) - lb = max(0, X_index[1] - exclusion_size) - dist_profiles[X_index[0]][lb:ub] = np.inf - - return _extract_top_k_from_dist_profile( - dist_profiles, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - ) - - @abstractmethod - def compute_matrix_profile( - self, - X: np.ndarray, - k: int, - threshold: float, - exclusion_size: int, - inverse_distance: bool, - allow_neighboring_matches: bool, - X_index: Optional[int] = None, - ): - """Compute matrix profiles between X_ and X or between all series in X_.""" - ... - - @abstractmethod - def compute_distance_profile(self, X: np.ndarray): - """Compute distrance profiles between X_ and X (a series of size length).""" - ... diff --git a/aeon/similarity_search/subsequence_search/_brute_force.py b/aeon/similarity_search/subsequence_search/_brute_force.py deleted file mode 100644 index 269cdc369b..0000000000 --- a/aeon/similarity_search/subsequence_search/_brute_force.py +++ /dev/null @@ -1,319 +0,0 @@ -"""Implementation of matrix profile with brute force.""" - -from typing import Optional - -__maintainer__ = ["baraline"] - - -import numpy as np -from numba import njit, prange -from numba.typed import List - -from aeon.similarity_search.subsequence_search._base import BaseMatrixProfile -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, -) -from aeon.utils.numba.general import ( - get_all_subsequences, - z_normalise_series_2d, - z_normalise_series_3d, -) - -# TODO : check function params and make docstrings -# TODO : make tests - - -class BruteForceMatrixProfile(BaseMatrixProfile): - """Estimator to compute matrix profile and distance profile using brute force.""" - - def __init__( - self, - length: int, - normalise: Optional[bool] = False, - n_jobs: Optional[int] = 1, - ): - super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) - - def compute_matrix_profile( - self, - k, - threshold, - exclusion_size, - inverse_distance, - allow_neighboring_matches, - X: Optional[np.ndarray] = None, - X_index: Optional[int] = None, - ): - """ - Compute matrix profiles. - - The matrix profiles are computed on the collection given in fit. If ``X`` is - not given, computes the matrix profile of each series in the collection. If it - is given, only computes it for ``X``. - - Parameters - ---------- - k : int - The number of best matches to return during predict for each subsequence. - threshold : float - The number of best matches to return during predict for each subsequence. - inverse_distance : bool - If True, the matching will be made on the inverse of the distance, and thus, - the worst matches to the query will be returned instead of the best ones. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - X : Optional[np.ndarray], optional - The time series on which the matrix profile will be compute. - The default is None, meaning that the series in the collection given in fit - will be used instead. - X_index : Optional[int], optional - If ``X`` is a series of the database given in fit, specify its index in - ``X_``. If specified, each query of this series won't be able to match with - its neighboring subsequences. - - Returns - ------- - MP : array of shape (series_length - L + 1,) - Matrix profile distances for each query subsequence. If X is none, this - will be a list of MP for each series in X_. - IP : array of shape (series_length - L + 1,) - Indexes of the top matches for each query subsequence. If X is none, this - will be a list of MP for each series in X_. - """ - # pairwise if none - if X is None: - MP = [] - IP = [] - for i in range(len(self.X_)): - _MP, _IP = self.compute_matrix_profile( - k, - threshold, - exclusion_size, - inverse_distance, - X=self.X_[i], - X_index=i, - ) - MP.append(_MP) - IP.append(_IP) - else: - MP, IP = _naive_squared_matrix_profile( - self.X_, - X, - self.length, - X_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - normalise=self.normalise, - ) - - return MP, IP - - def compute_distance_profile(self, X: np.ndarray): - """ - Compute the distance profile of X to all samples in X_. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, length) - The query to use to compute the distance profiles. - - Returns - ------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) - The distance profile of X to all samples in X_. The ``n_candidates`` value - is equal to ``n_timepoins - length + 1``. If X_ is an unequal length - collection, returns a numba typed list instead of an ndarray. - - """ - distance_profiles = _naive_squared_distance_profile( - self.X_, X, normalise=self.normalise - ) - - if not self.metadata_["unequal_length"]: - distance_profiles = np.asarray(distance_profiles) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _compute_dist_profile(X_subs, q): - """ - Compute the distance profile between subsequences and a query. - - Parameters - ---------- - X_subs : array, shape=(n_samples, n_channels, query_length) - Input subsequences extracted from a time series. - q : array, shape=(n_channels, query_length) - Query used for the distance computation - - Returns - ------- - dist_profile : np.ndarray, 1D array of shape (n_samples) - The distance between the query all subsequences. - - """ - n_candidates, n_channels, q_length = X_subs.shape - dist_profile = np.zeros(n_candidates) - for i in range(n_candidates): - for j in range(n_channels): - for k in range(q_length): - dist_profile[i] += (X_subs[i, j, k] - q[j, k]) ** 2 - return dist_profile - - -@njit(cache=True, fastmath=True, parallel=True) -def _naive_squared_distance_profile( - X, - Q, - normalise=False, -): - """ - Compute a squared euclidean distance profile. - - Parameters - ---------- - X : array, shape=(n_samples, n_channels, n_timepoints) - Input time series dataset to search in. - Q : array, shape=(n_channels, query_length) - Query used during the search. - normalise : bool - Wheter to use a z-normalised distance. - - Returns - ------- - out : np.ndarray, 1D array of shape (n_samples, n_timepoints_t - query_length + 1) - The distance between the query and all candidates in X. - - """ - query_length = Q.shape[1] - dist_profiles = List() - # Init distance profile array with unequal length support - for i in range(len(X)): - dist_profiles.append(np.zeros(X[i].shape[1] - query_length + 1)) - if normalise: - Q = z_normalise_series_2d(Q) - else: - Q = Q.astype(np.float64) - - for _i in prange(len(X)): - # cast uint64 due to parallel prange - i = np.int64(_i) - X_subs = get_all_subsequences(X[i], query_length, 1) - if normalise: - X_subs = z_normalise_series_3d(X_subs) - - dist_profile = _compute_dist_profile(X_subs, Q) - dist_profiles[i] = dist_profile - return dist_profiles - - -@njit(cache=True, fastmath=True, parallel=True) -def _naive_squared_matrix_profile( - X, - T, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - normalise=False, -): - """ - Compute a squared euclidean matrix profile. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - Length of the subsequences used for the distance computation. - T_index : int, - If ``T`` is a series of ``X``, specify its index - in ``X``. If specified, each query of this series won't be able to - match with its neighboring subsequences. - k : int - The number of best matches to return during predict for each subsequence. - threshold : float - The number of best matches to return during predict for each subsequence. - allow_neighboring_matches : bool - Wheter the top-k candidates can be neighboring subsequences. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestomp - exclusion_size` and - :math:`id_timestomp + exclusion_size` which cannot be returned - as best match if :math:`id_timestomp` was already selected. By default, - the value None means that this is not used. - inverse_distance : bool - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - normalise : bool - Wheter to use a z-normalised distance. - - Returns - ------- - out : np.ndarray, 1D array of shape (n_timepoints_t - query_length + 1) - The minimum distance between each query in T and all candidates in X. - """ - n_queries = T.shape[1] - L + 1 - MP = List() - IP = List() - - # Init List to allow parallel, we'll re-use it for all dist profiles - dist_profiles = List() - for i_x in range(len(X)): - dist_profiles.append(np.zeros(X[i_x].shape[1] - L + 1)) - - X_subs = List() - for i in range(len(X)): - i_subs = get_all_subsequences(X[i], L, 1) - if normalise: - i_subs = z_normalise_series_3d(i_subs) - X_subs.append(i_subs) - - for i_q in range(n_queries): - Q = T[:, i_q : i_q + L] - if normalise: - Q = z_normalise_series_2d(Q) - for i_x in prange(len(X)): - dist_profiles[i_x][0 : X[i_x].shape[1] - L + 1] = _compute_dist_profile( - X_subs[i_x], Q - ) - - if T_index is not None: - _max_timestamp = X[T_index].shape[1] - L - ub = min(i_q + exclusion_size, _max_timestamp) - lb = max(0, i_q - exclusion_size) - dist_profiles[T_index][lb:ub] = np.inf - - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - top_indexes, top_dists = _extract_top_k_from_dist_profile( - dist_profiles, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - ) - - MP.append(top_dists) - IP.append(top_indexes) - return MP, IP diff --git a/aeon/similarity_search/subsequence_search/_commons.py b/aeon/similarity_search/subsequence_search/_commons.py deleted file mode 100644 index c13a7381bc..0000000000 --- a/aeon/similarity_search/subsequence_search/_commons.py +++ /dev/null @@ -1,170 +0,0 @@ -"""Helper and common function for similarity search estimators and functions.""" - -__maintainer__ = ["baraline"] - -import numpy as np -from numba import njit, prange -from scipy.signal import convolve - - -def fft_sliding_dot_product(X, q): - """ - Use FFT convolution to calculate the sliding window dot product. - - This function applies the Fast Fourier Transform (FFT) to efficiently compute - the sliding dot product between the input time series `X` and the query `q`. - The dot product is computed for each channel individually. The sliding window - approach ensures that the dot product is calculated for every possible subsequence - of `X` that matches the length of `q` - - Parameters - ---------- - X : array, shape=(n_channels, n_timepoints) - Input time series - q : array, shape=(n_channels, query_length) - Input query - - Returns - ------- - out : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - Sliding dot product between q and X. - """ - n_channels, n_timepoints = X.shape - query_length = q.shape[1] - out = np.zeros((n_channels, n_timepoints - query_length + 1)) - for i in range(n_channels): - out[i, :] = convolve(np.flipud(q[i, :]), X[i, :], mode="valid").real - return out - - -def get_ith_products(X, T, L, ith): - """ - Compute dot products between X and the i-th subsequence of size L in T. - - Parameters - ---------- - X : array, shape = (n_channels, n_timepoints_X) - Input data. - T : array, shape = (n_channels, n_timepoints_T) - Data containing the query. - L : int - Overall query length. - ith : int - Query starting index in T. - - Returns - ------- - np.ndarray, 2D array of shape (n_channels, n_timepoints_X - L + 1) - Sliding dot product between the i-th subsequence of size L in T and X. - - """ - return fft_sliding_dot_product(X, T[:, ith : ith + L]) - - -@njit(cache=True, fastmath=True, parallel=True) -def _inverse_distance_profile_list(dist_profiles): - for i in prange(len(dist_profiles)): - dist_profiles[i] = 1 / (dist_profiles[i] + 1e-8) - return dist_profiles - - -@njit(cache=True) -def _extract_top_k_from_dist_profile( - dist_profiles, - k, - threshold, - allow_neighboring_matches, - exclusion_size, -): - """ - Given an array (or list) of distance profiles, extract the top k lower distances. - - Parameters - ---------- - dist_profiles : np.ndarray, shape = (n_samples, n_timepoints - length + 1) - A collection of distance profiles computed from ``n_samples`` time series of - size ``n_timepoints``, giving distance profiles of length - ``n_timepoints - length + 1``, with ``length`` the size of the query used to - compute the distance profiles. - k : int - Number of best matches to return - threshold : float - A threshold on the distances of the best matches. To be returned, a candidate - must have a distance bellow this threshold. This can reduce the number of - returned matches to be bellow ``k`` - allow_neighboring_matches : bool - Wheter to allow returning matches that are in the same neighborhood. - exclusion_size : int - The size of the exlusion size to apply when ``allow_neighboring_matches`` is - False. It is applied on both side of existing matches (+/- their indexes). - - Returns - ------- - top_k_indexes : np.ndarray, shape = (k, 2) - The indexes of the best matches in ``distance_profiles``. - top_k_distances : np.ndarray, shape = (k) - The distances of the best matches. - - """ - top_k_indexes = np.zeros((2 * k, 2), dtype=np.int64) - 1 - top_k_distances = np.full(2 * k, np.inf) - for i_profile in range(len(dist_profiles)): - # Extract top-k without neighboring matches - if not allow_neighboring_matches: - _sorted_indexes = np.argsort(dist_profiles[i_profile]) - _top_k_indexes = np.zeros(k, dtype=np.int64) - 1 - _current_k = 0 - _current_j = 0 - # Until we extract k value or explore all the array - while _current_k < k and _current_j < len(_sorted_indexes): - _insert = True - # Check for validity with each previously inserted - for i_k in range(_current_k): - ub = min( - _top_k_indexes[i_k] + exclusion_size, - len(dist_profiles[i_profile]), - ) - lb = max(_top_k_indexes[i_k] - exclusion_size, 0) - if ( - _sorted_indexes[_current_j] >= lb - and _sorted_indexes[_current_j] <= ub - ): - _insert = False - break - - if _insert: - _top_k_indexes[_current_k] = _sorted_indexes[_current_j] - _current_k += 1 - _current_j += 1 - - _top_k_indexes = _top_k_indexes[:_current_k] - _top_k_distances = dist_profiles[i_profile][_top_k_indexes] - # Extract top-k with neighboring matches - else: - _top_k_indexes = np.argsort(dist_profiles[i_profile])[:k] - _top_k_distances = dist_profiles[i_profile][_top_k_indexes] - - # Select overall top k by using the buffer array of size 2*k - # Inset top from current sample - top_k_distances[k : k + len(_top_k_distances)] = _top_k_distances - top_k_indexes[k : k + len(_top_k_distances), 1] = _top_k_indexes - top_k_indexes[k : k + len(_top_k_distances), 0] = i_profile - - # Sort overall - idx = np.argsort(top_k_distances) - # Keep top k overall - top_k_distances[:k] = top_k_distances[idx[:k]] - top_k_indexes[:k] = top_k_indexes[idx[:k]] - - top_k_distances[k:] = np.inf - - # get the actual number of extracted values and apply threshold - true_k = 0 - for i in range(k): - # if top_k is inf, it means that no value was extracted - if top_k_distances[i] != np.inf and top_k_distances[i] <= threshold: - true_k += 1 - else: - break - - return top_k_indexes[:true_k], top_k_distances[:true_k] diff --git a/aeon/similarity_search/subsequence_search/_stomp.py b/aeon/similarity_search/subsequence_search/_stomp.py deleted file mode 100644 index 66d5270872..0000000000 --- a/aeon/similarity_search/subsequence_search/_stomp.py +++ /dev/null @@ -1,619 +0,0 @@ -"""Implementation of STOMP with squared euclidean distance.""" - -__maintainer__ = ["baraline"] -from typing import Optional - -import numpy as np -from numba import njit, prange -from numba.typed import List - -from aeon.similarity_search.subsequence_search._base import BaseMatrixProfile -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, - fft_sliding_dot_product, - get_ith_products, -) -from aeon.utils.numba.general import ( - AEON_NUMBA_STD_THRESHOLD, - sliding_mean_std_one_series, -) - - -class StompMatrixProfile(BaseMatrixProfile): - """Estimator to compute matrix profile and distance profile using STOMP.""" - - def __init__( - self, - length: int, - normalise: Optional[bool] = False, - n_jobs: Optional[int] = 1, - ): - super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) - - def compute_matrix_profile( - self, - X: np.ndarray, - k: int, - threshold: float, - exclusion_size: int, - inverse_distance: bool, - allow_neighboring_matches: bool, - X_index=None, - ): - """ - Compute matrix profiles. - - The matrix profiles are computed on the collection given in fit. If ``X`` is - not given, computes the matrix profile of each series in the collection. If it - is given, only computes it for ``X``. - - Parameters - ---------- - X : np.ndarray, shape = (n_channels, n_timepoints) - A 2D array time series on which the matrix profile will be computed. - k : int - The number of best matches to return during predict for each subsequence. - threshold : float - The number of best matches to return during predict for each subsequence. - inverse_distance : bool - If True, the matching will be made on the inverse of the distance, and thus, - the worst matches to the query will be returned instead of the best ones. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - X_index : Optional[int], optional - If ``X`` is a series of the database given in fit, specify its index in - ``X_``. If specified, each query of this series won't be able to match with - its neighboring subsequences. - - Returns - ------- - MP : array of shape (n_timepoints - L + 1,) - Matrix profile distances for each query subsequence. If X is none, this - will be a list of MP for each series in X_. - IP : array of shape (n_timepoints - L + 1,) - Indexes of the top matches for each query subsequence. If X is none, this - will be a list of MP for each series in X_. - """ - XdotT = [ - get_ith_products(self.X[i], X, self.length, 0) for i in range(len(self.X_)) - ] - if isinstance(X, np.ndarray): - XdotT = np.asarray(XdotT) - elif isinstance(X, List): - XdotT = List(XdotT) - - if X_index is None: - X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) - else: - X_means, X_stds = self.X_means_[X_index], self.X_stds_[X_index] - if self.normalise: - MP, IP = _stomp_normalised( - self.X_, - X, - XdotT, - self.X_means_, - self.X_stds_, - X_means, - X_stds, - self.length, - X_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) - else: - MP, IP = _stomp( - self.X_, - X, - XdotT, - self.length, - X_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) - return MP, IP - - def compute_distance_profile(self, X: np.ndarray): - """ - Compute the distance profile of X to all samples in X_. - - Parameters - ---------- - X : np.ndarray, 2D array of shape (n_channels, length) - The query to use to compute the distance profiles. - - Returns - ------- - distance_profiles : np.ndarray, 2D array of shape (n_cases, n_candidates) - The distance profile of X to all samples in X_. The ``n_candidates`` value - is equal to ``n_timepoins - length + 1``. If X_ is an unequal length - collection, returns a numba typed list instead of an ndarray. - - """ - QX = [fft_sliding_dot_product(self.X_[i], X) for i in range(len(self.X_))] - if self.metadata_["unequal_length"]: - QX = List(QX) - else: - QX = np.asarray(QX) - - if self.normalise: - distance_profiles = _normalised_squared_distance_profile( - QX, - self.X_means_, - self.X_stds_, - X.mean(axis=1), - X.std(axis=1), - self.length, - ) - else: - distance_profiles = _squared_distance_profile( - QX, - self.X_, - X, - ) - - if not self.metadata_["unequal_length"]: - distance_profiles = np.asarray(distance_profiles) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _stomp_normalised( - X, - T, - XdotT, - X_means, - X_stds, - T_means, - T_stds, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, -): - """ - Compute the Matrix Profile using the STOMP algorithm with normalised distances. - - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Precomputed dot products between each time series in X and the query series T. - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Means of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Stds of each subsequences of X of size L. Should be a numba TypedList if X is - unequal length. - T_means : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Means of each subsequences of T of size L. - T_stds : np.ndarray, 2D array of shape (n_channels, n_timepoints - L + 1) - Stds of each subsequences of T of size L. - L : int - Length of the subsequences used for the distance computation. - T_index : int, - If ``T`` is a series of the database given in fit, specify its index - in ``X_``. If specified, each query of this series won't be able to - match with its neighboring subsequences. - k : int, - The number of best matches to return during predict for each subsequence. - threshold : float - The number of best matches to return during predict for each subsequence. - allow_neighboring_matches : bool - Wheter the top-k candidates can be neighboring subsequences. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - inverse_distance : bool - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - - Returns - ------- - tuple of np.ndarray - - MP : array of shape (series_length - L + 1,) - Matrix profile distances for each query subsequence. - - IP : array of shape (series_length - L + 1,) - Indexes of the top matches for each query subsequence. - """ - n_queries = T.shape[1] - L + 1 - MP = List() - IP = List() - - for i_q in range(n_queries): - dist_profiles = _normalised_squared_distance_profile( - XdotT, X_means, X_stds, T_means[:, i_q], T_stds[:, i_q], L - ) - if i_q + 1 < n_queries: - for i_x in range(len(X)): - XdotT[i_x] = _update_dot_products_one_series( - X[i_x], T, XdotT[i_x], L, i_q + 1 - ) - - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - # Deal with self-matches - if T_index is not None: - _max_timestamp = X[T_index].shape[1] - L - ub = min(i_q + exclusion_size, _max_timestamp) - lb = max(0, i_q - exclusion_size) - dist_profiles[T_index][lb:ub] = np.inf - - top_indexes, top_dists = _extract_top_k_from_dist_profile( - dist_profiles, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - ) - - MP.append(top_dists) - IP.append(top_indexes) - - return MP, IP - - -@njit(cache=True, fastmath=True) -def _stomp( - X, - T, - XdotT, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, -): - """ - Compute the Matrix Profile using the STOMP algorithm with non-normalised distances. - - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a TypedList - of 2D arrays of shape (n_channels, n_timepoints) - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - XdotT : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - L + 1) - Precomputed dot products between each time series in X and the query series T. - L : int - Length of the subsequences used for the distance computation. - T_index : int, - If ``T`` is a series of the database given in fit, specify its index - in ``X_``. If specified, each query of this series won't be able to - match with its neighboring subsequences. - k : int, - The number of best matches to return during predict for each subsequence. - threshold : float - The number of best matches to return during predict for each subsequence. - allow_neighboring_matches : bool - Wheter the top-k candidates can be neighboring subsequences. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. - inverse_distance : bool - If True, the matching will be made on the inverse of the distance, and thus, the - worst matches to the query will be returned instead of the best ones. - - Returns - ------- - tuple of np.ndarray - - MP : array of shape (series_length - L + 1,) - Matrix profile distances for each query subsequence. - - IP : array of shape (series_length - L + 1,) - Indexes of the top matches for each query subsequence. - """ - n_queries = T.shape[1] - L + 1 - MP = List() - IP = List() - - # For each query of size L in T - for i_q in range(n_queries): - Q = T[:, i_q : i_q + L] - dist_profiles = _squared_distance_profile(XdotT, X, Q) - # For each series in X compute distance profile to the query - if i_q + 1 < n_queries: - for i_x in range(len(X)): - XdotT[i_x] = _update_dot_products_one_series( - X[i_x], T, XdotT[i_x], L, i_q + 1 - ) - - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - # Deal with self-matches - if T_index is not None: - _max_timestamp = X[T_index].shape[1] - L - ub = min(i_q + exclusion_size, _max_timestamp) - lb = max(0, i_q - exclusion_size) - dist_profiles[T_index][lb:ub] = np.inf - - top_indexes, top_dists = _extract_top_k_from_dist_profile( - dist_profiles, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - ) - - MP.append(top_dists) - IP.append(top_indexes) - - return MP, IP - - -@njit(cache=True, fastmath=True) -def _update_dot_products_one_series( - X, - T, - XT_products, - L, - i_query, -): - """ - Update dot products of the i-th query of size L in T from the dot products of i-1. - - Parameters - ---------- - X: np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - Input time series on which the sliding dot product is computed. - T: np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - L : int - The length of the subsequences considered during the search. This parameter - cannot be larger than n_timepoints and series_length. - i_query : int - Query starting index in T. - - Returns - ------- - XT_products : np.ndarray of shape (n_cases, n_channels, n_timepoints - L + 1) - Sliding dot product between the i-th subsequence of size L in T and X. - - """ - n_channels = T.shape[0] - Q = T[:, i_query : i_query + L] - n_candidates = X.shape[1] - L + 1 - - for i_ft in range(n_channels): - # first element of all 0 to n-1 candidates * first element of previous query - _a1 = X[i_ft, : n_candidates - 1] * T[i_ft, i_query - 1] - # last element of all 1 to n candidates * last element of current query - _a2 = X[i_ft, L : L - 1 + n_candidates] * T[i_ft, i_query + L - 1] - - XT_products[i_ft, 1:] = XT_products[i_ft, :-1] - _a1 + _a2 - - # Compute first dot product - XT_products[i_ft, 0] = np.sum(Q[i_ft] * X[i_ft, :L]) - return XT_products - - -@njit(cache=True, fastmath=True, parallel=True) -def _squared_distance_profile(QX, X, Q): - """ - Compute squared distance profiles between query subsequence and time series. - - Parameters - ---------- - QX : List of np.ndarray - List of precomputed dot products between queries and time series, with each - element corresponding to a different time series. - Shape of each array is (n_channels, n_timepoints - query_length + 1). - X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) - The input samples. If X is an unquel length collection, expect a numba TypedList - 2D array of shape (n_channels, n_timepoints) - Q : np.ndarray, 2D array of shape (n_channels, query_length) - The query used for similarity search. - mask : np.ndarray, 3D array of shape (n_cases, n_timepoints - query_length + 1) - Boolean mask of the shape of the distance profile indicating for which part - of it the distance should be computed. - - Returns - ------- - distance_profiles : np.ndarray - 3D array of shape (n_cases, n_timepoints - query_length + 1) - The distance profile between Q and the input time series X. - - """ - distance_profiles = List() - query_length = Q.shape[1] - - # Init distance profile array with unequal length support - for i_instance in range(len(X)): - profile_length = X[i_instance].shape[1] - query_length + 1 - distance_profiles.append(np.full((profile_length), np.inf)) - - for _i_instance in prange(len(QX)): - # prange cast iterator to unit64 with parallel=True - i_instance = np.int_(_i_instance) - - distance_profiles[i_instance] = _squared_dist_profile_one_series( - QX[i_instance], X[i_instance], Q - ) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _squared_dist_profile_one_series(QT, T, Q): - """ - Compute squared distance profile between query subsequence and a single time series. - - This function calculates the squared distance profile for a single time series by - leveraging the dot product of the query and time series as well as precomputed sums - of squares to efficiently compute the squared distances. - - Parameters - ---------- - QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - The dot product between the query and the time series. - T : np.ndarray, 2D array of shape (n_channels, series_length) - The series used for similarity search. Note that series_length can be equal, - superior or inferior to n_timepoints, it doesn't matter. - Q : np.ndarray - 2D array of shape (n_channels, query_length) representing query subsequence. - - Returns - ------- - distance_profile : np.ndarray - 2D array of shape (n_channels, n_timepoints - query_length + 1) - The squared distance profile between the query and the input time series. - """ - n_channels, profile_length = QT.shape - query_length = Q.shape[1] - _QT = -2 * QT - distance_profile = np.zeros(profile_length) - for k in prange(n_channels): - _sum = 0 - _qsum = 0 - for j in prange(query_length): - _sum += T[k, j] ** 2 - _qsum += Q[k, j] ** 2 - - distance_profile += _qsum + _QT[k] - distance_profile[0] += _sum - for i in prange(1, profile_length): - _sum += T[k, i + (query_length - 1)] ** 2 - T[k, i - 1] ** 2 - distance_profile[i] += _sum - return distance_profile - - -@njit(cache=True, fastmath=True, parallel=True) -def _normalised_squared_distance_profile( - QX, X_means, X_stds, Q_means, Q_stds, query_length -): - """ - Compute the normalised squared distance profiles between query subsequence and input time series. - - Parameters - ---------- - QX : List of np.ndarray - List of precomputed dot products between queries and time series, with each element - corresponding to a different time series. - Shape of each array is (n_channels, n_timepoints - query_length + 1). - X_means : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Means of each subsequences of X of size query_length - X_stds : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints - query_length + 1) # noqa: E501 - Stds of each subsequences of X of size query_length - Q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - Q_stds : np.ndarray, 1D array of shape (n_channels) - Stds of the query q - query_length : int - The length of the query subsequence used for the distance profile computation. - - Returns - ------- - List of np.ndarray - List of 2D arrays, each of shape (n_channels, n_timepoints - query_length + 1). - Each array contains the normalised squared distance profile between the query subsequence and the corresponding time series. - Entries in the array are set to infinity where the mask is False. - """ - distance_profiles = List() - Q_is_constant = Q_stds <= AEON_NUMBA_STD_THRESHOLD - # Init distance profile array with unequal length support - for i_instance in range(len(QX)): - profile_length = QX[i_instance].shape[1] - distance_profiles.append(np.zeros(profile_length)) - - for _i_instance in prange(len(QX)): - # iterator is uint64 with prange and parallel so cast to int to avoid warnings - i_instance = np.int64(_i_instance) - distance_profiles[i_instance] = _normalised_squared_dist_profile_one_series( - QX[i_instance], - X_means[i_instance], - X_stds[i_instance], - Q_means, - Q_stds, - query_length, - Q_is_constant, - ) - return distance_profiles - - -@njit(cache=True, fastmath=True) -def _normalised_squared_dist_profile_one_series( - QT, T_means, T_stds, Q_means, Q_stds, query_length, Q_is_constant -): - """ - Compute the z-normalised squared Euclidean distance profile for one time series. - - Parameters - ---------- - QT : np.ndarray, 2D array of shape (n_channels, n_timepoints - query_length + 1) - The dot product between the query and the time series. - T_means : np.ndarray, 1D array of length n_channels - The mean values of the time series for each channel. - T_stds : np.ndarray, 2D array of shape (n_channels, profile_length) - The standard deviations of the time series for each channel and position. - Q_means : np.ndarray, 1D array of shape (n_channels) - Means of the query q - Q_stds : np.ndarray, 1D array of shape (n_channels) - Stds of the query q - query_length : int - The length of the query subsequence used for the distance profile computation. - Q_is_constant : np.ndarray - 1D array of shape (n_channels,) where each element is a Boolean indicating - whether the query standard deviation for that channel is less than or equal - to a specified threshold. - - Returns - ------- - np.ndarray - 2D array of shape (n_channels, n_timepoints - query_length + 1) containing the - z-normalised squared distance profile between the query subsequence and the time - series. Entries are computed based on the z-normalised values, with special - handling for constant values. - """ - n_channels, profile_length = QT.shape - distance_profile = np.zeros(profile_length) - - for i in prange(profile_length): - Sub_is_constant = T_stds[:, i] <= AEON_NUMBA_STD_THRESHOLD - for k in prange(n_channels): - # Two Constant case - if Q_is_constant[k] and Sub_is_constant[k]: - _val = 0 - # One Constant case - elif Q_is_constant[k] or Sub_is_constant[k]: - _val = query_length - else: - denom = query_length * Q_stds[k] * T_stds[k, i] - - p = (QT[k, i] - query_length * (Q_means[k] * T_means[k, i])) / denom - p = min(p, 1.0) - - _val = abs(2 * query_length * (1.0 - p)) - distance_profile[i] += _val - - return distance_profile diff --git a/aeon/similarity_search/subsequence_search/tests/__init__.py b/aeon/similarity_search/subsequence_search/tests/__init__.py deleted file mode 100644 index 0287f2ee04..0000000000 --- a/aeon/similarity_search/subsequence_search/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for subsequence search methods.""" diff --git a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py b/aeon/similarity_search/subsequence_search/tests/test_brute_force.py deleted file mode 100644 index 9ef0eb44e8..0000000000 --- a/aeon/similarity_search/subsequence_search/tests/test_brute_force.py +++ /dev/null @@ -1,172 +0,0 @@ -""" -Tests for stomp algorithm. - -We do not test equality for returned indexes due to the unstable nature of argsort -and the fact that the "kind=stable" parameter is not yet supported in numba. We instead -test that the returned index match the expected distance value. -""" - -__maintainer__ = ["baraline"] - -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import ( - assert_almost_equal, - assert_array_almost_equal, - assert_array_equal, -) - -from aeon.similarity_search.subsequence_search._brute_force import ( - _compute_dist_profile, - _naive_squared_distance_profile, - _naive_squared_matrix_profile, -) -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, -) -from aeon.testing.data_generation import ( - make_example_2d_numpy_series, - make_example_3d_numpy, - make_example_3d_numpy_list, -) -from aeon.utils.numba.general import ( - get_all_subsequences, - sliding_mean_std_one_series, - z_normalise_series_2d, -) - -K_VALUES = [1, 3, 5] -NN_MATCHES = [True, False] -INVERSE = [True, False] -NORMALISE = [True, False] - - -def _get_mean_sdts_inputs(X, Q, L): - X_means = [] - X_stds = [] - - for i_x in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i_x], L, 1) - X_stds.append(_std) - X_means.append(_mean) - - Q_means = Q.mean(axis=1) - Q_stds = Q.std(axis=1) - - return X_means, X_stds, Q_means, Q_stds - - -def test__compute_dist_profile(): - """Test Euclidean distance with brute force.""" - L = 3 - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - dist_profile = _compute_dist_profile(get_all_subsequences(X, L, 1), Q) - for i_t in range(X.shape[1] - L + 1): - assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) - - -@pytest.mark.parametrize("normalise", NORMALISE) -def test__naive_squared_distance_profile(normalise): - """Test Euclidean distance profile calculation with brute force.""" - L = 3 - X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - dist_profiles = _naive_squared_distance_profile(X, Q, normalise=normalise) - - if normalise: - Q = z_normalise_series_2d(Q) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - _x = X[i_x, :, i_t : i_t + L] - if normalise: - _x = z_normalise_series_2d(_x) - assert_almost_equal(dist_profiles[i_x][i_t], np.sum((_x - Q) ** 2)) - - # test unequal length and multivariate - X = List( - make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=10, - max_n_timepoints=20, - return_y=False, - ) - ) - - Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) - dist_profiles = _naive_squared_distance_profile(X, Q, normalise=normalise) - if normalise: - Q = z_normalise_series_2d(Q) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - _x = X[i_x][:, i_t : i_t + L] - if normalise: - _x = z_normalise_series_2d(_x) - assert_almost_equal(dist_profiles[i_x][i_t], np.sum((_x - Q) ** 2)) - - -@pytest.mark.parametrize("k", K_VALUES) -@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) -@pytest.mark.parametrize("inverse_distance", INVERSE) -@pytest.mark.parametrize("normalise", NORMALISE) -def test__naive_squared_matrix_profile( - k, allow_neighboring_matches, inverse_distance, normalise -): - """Test brute force matrix profile method.""" - L = 3 - X = List( - make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=6, - max_n_timepoints=8, - return_y=False, - ) - ) - X_copy = X.copy() - T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) - T_copy = T.copy() - T_index = None - threshold = np.inf - exclusion_size = L - # MP : distances to best matches for each query - # IP : Indexes of best matches for each query - MP, IP = _naive_squared_matrix_profile( - X, - T, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - normalise=normalise, - ) - assert_array_equal(T, T_copy) - for i in range(len(X)): - assert_array_equal(X[i], X_copy[i]) - # For each query of size L in T - for i in range(T.shape[1] - L + 1): - dist_profiles = _naive_squared_distance_profile( - X, T[:, i : i + L], normalise=normalise - ) - # Check that the top matches extracted have the same value that the - # top matches in the distance profile - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size - ) - # Check that the top matches extracted have the same value that the - # top matches in the distance profile - assert_array_almost_equal(MP[i], top_k_distances) - - # Check that the index in IP correspond to a distance profile point - # with value equal to the corresponding MP point. - for j, index in enumerate(top_k_indexes): - assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) diff --git a/aeon/similarity_search/subsequence_search/tests/test_commons.py b/aeon/similarity_search/subsequence_search/tests/test_commons.py deleted file mode 100644 index e5b4272285..0000000000 --- a/aeon/similarity_search/subsequence_search/tests/test_commons.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Test _commons.py functions.""" - -__maintainer__ = ["baraline"] -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import assert_, assert_array_almost_equal - -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, - fft_sliding_dot_product, - get_ith_products, -) -from aeon.testing.data_generation import ( - make_example_2d_numpy_list, - make_example_2d_numpy_series, -) - -K_VALUES = [1, 3, 5] -THRESHOLDS = [np.inf, 0.7] -NN_MATCHES = [False, True] - - -def test_fft_sliding_dot_product(): - """Test the fft_sliding_dot_product function.""" - L = 4 - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - - values = fft_sliding_dot_product(X, Q) - # Compare values[0] only as input is univariate - assert_array_almost_equal( - values[0], - [np.dot(Q[0], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], - ) - - -def test_get_ith_products(): - """Test i-th dot product of a subsequence of size L.""" - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - L = 5 - - values = get_ith_products(X, Q, L, 0) - # Compare values[0] only as input is univariate - assert_array_almost_equal( - values[0], - [np.dot(Q[0, 0:L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], - ) - - values = get_ith_products(X, Q, L, 4) - # Compare values[0] only as input is univariate - assert_array_almost_equal( - values[0], - [np.dot(Q[0, 4 : 4 + L], X[0, i : i + L]) for i in range(X.shape[1] - L + 1)], - ) - - -def test__inverse_distance_profile_list(): - """Test method to inverse a TypedList of distance profiles.""" - X = make_example_2d_numpy_list(n_cases=2, return_y=False) - T = _inverse_distance_profile_list(List(X)) - assert_array_almost_equal(1 / (X[0] + 1e-8), T[0]) - assert_array_almost_equal(1 / (X[1] + 1e-8), T[1]) - - -@pytest.mark.parametrize("k", K_VALUES) -@pytest.mark.parametrize("threshold", THRESHOLDS) -@pytest.mark.parametrize("allow_nn_matches", NN_MATCHES) -def test__extract_top_k_from_dist_profile(k, threshold, allow_nn_matches): - """Test method to esxtract the top k candidates from a list of distance profiles.""" - X = make_example_2d_numpy_list( - n_cases=2, min_n_timepoints=5, max_n_timepoints=7, return_y=False - ) - X_sort = [X[i][np.argsort(X[i])] for i in range(len(X))] - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - X, k, threshold, allow_nn_matches, 3 - ) - for i, index in enumerate(top_k_indexes): - assert_(X[index[0]][index[1]] == top_k_distances[i]) - assert_(np.all(top_k_distances <= threshold)) - if allow_nn_matches: - for i in range(len(X)): - assert_(np.all(top_k_distances <= X_sort[i][k - 1])) - if not allow_nn_matches: - for i_x in range(len(X)): - # test same index X respect exclusion - same_X = [ - top_k_indexes[i][1] - for i in range(len(top_k_indexes)) - if top_k_indexes[i][0] == i_x - ] - same_X = np.sort(same_X) - if len(same_X) > 1: - assert_(np.all(np.diff(same_X) >= 3)) diff --git a/aeon/similarity_search/subsequence_search/tests/test_stomp.py b/aeon/similarity_search/subsequence_search/tests/test_stomp.py deleted file mode 100644 index 757c8a3133..0000000000 --- a/aeon/similarity_search/subsequence_search/tests/test_stomp.py +++ /dev/null @@ -1,332 +0,0 @@ -""" -Tests for stomp algorithm. - -We do not test equality for returned indexes due to the unstable nature of argsort -and the fact that the "kind=stable" parameter is not yet supported in numba. We instead -test that the returned index match the expected distance value. -""" - -__maintainer__ = ["baraline"] - -import numpy as np -import pytest -from numba.typed import List -from numpy.testing import assert_almost_equal, assert_array_almost_equal - -from aeon.similarity_search.subsequence_search._commons import ( - _extract_top_k_from_dist_profile, - _inverse_distance_profile_list, - get_ith_products, -) -from aeon.similarity_search.subsequence_search._stomp import ( - _normalised_squared_dist_profile_one_series, - _normalised_squared_distance_profile, - _squared_dist_profile_one_series, - _squared_distance_profile, - _stomp, - _stomp_normalised, - _update_dot_products_one_series, -) -from aeon.testing.data_generation import ( - make_example_2d_numpy_series, - make_example_3d_numpy, - make_example_3d_numpy_list, -) -from aeon.utils.numba.general import ( - sliding_mean_std_one_series, - z_normalise_series_2d_with_mean_std, -) - -K_VALUES = [1, 3, 5] -NN_MATCHES = [True, False] -INVERSE = [True, False] - - -def _get_mean_sdts_inputs(X, Q, L): - X_means = [] - X_stds = [] - - for i_x in range(len(X)): - _mean, _std = sliding_mean_std_one_series(X[i_x], L, 1) - X_stds.append(_std) - X_means.append(_mean) - - Q_means = Q.mean(axis=1) - Q_stds = Q.std(axis=1) - - return X_means, X_stds, Q_means, Q_stds - - -def test__update_dot_products_one_series(): - """Test the _update_dot_product function.""" - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=20) - T = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - L = 7 - current_product = get_ith_products(X, T, L, 0) - for i_query in range(1, T.shape[1] - L + 1): - new_product = get_ith_products( - X, - T, - L, - i_query, - ) - current_product = _update_dot_products_one_series( - X, - T, - current_product, - L, - i_query, - ) - assert_array_almost_equal(new_product, current_product) - - -def test__squared_dist_profile_one_series(): - """Test Euclidean distance.""" - L = 3 - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - QX = get_ith_products(X, Q, L, 0) - dist_profile = _squared_dist_profile_one_series(QX, X, Q) - for i_t in range(X.shape[1] - L + 1): - assert_almost_equal(dist_profile[i_t], np.sum((X[:, i_t : i_t + L] - Q) ** 2)) - - -def test__normalised_squared_dist_profile_one_series(): - """Test Euclidean distance.""" - L = 3 - X = make_example_2d_numpy_series(n_channels=1, n_timepoints=10) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - QX = get_ith_products(X, Q, L, 0) - X_mean, X_std = sliding_mean_std_one_series(X, L, 1) - Q_mean = Q.mean(axis=1) - Q_std = Q.std(axis=1) - - dist_profile = _normalised_squared_dist_profile_one_series( - QX, X_mean, X_std, Q_mean, Q_std, L, Q.std(axis=1) <= 0 - ) - Q = z_normalise_series_2d_with_mean_std(Q, Q_mean, Q_std) - for i_t in range(X.shape[1] - L + 1): - S = z_normalise_series_2d_with_mean_std( - X[:, i_t : i_t + L], X_mean[:, i_t], X_std[:, i_t] - ) - assert_almost_equal(dist_profile[i_t], np.sum((S - Q) ** 2)) - - -def test__squared_distance_profile(): - """Test Euclidean distance profile calculation.""" - L = 3 - X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - QX = np.asarray([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) - dist_profiles = _squared_distance_profile(QX, X, Q) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X[i_x, :, i_t : i_t + L] - Q) ** 2) - ) - - # test unequal length and multivariate - X = List( - make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=10, - max_n_timepoints=20, - return_y=False, - ) - ) - - Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) - QX = List([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) - dist_profiles = _squared_distance_profile(QX, X, Q) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X[i_x][:, i_t : i_t + L] - Q) ** 2) - ) - - -def test__normalised_squared_distance_profile(): - """Test Euclidean distance profile calculation.""" - L = 3 - X = make_example_3d_numpy(n_cases=3, n_channels=1, n_timepoints=10, return_y=False) - Q = make_example_2d_numpy_series(n_channels=1, n_timepoints=L) - QX = np.asarray([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) - - X_means, X_stds, Q_means, Q_stds = _get_mean_sdts_inputs(X, Q, L) - - X_means = np.asarray(X_means) - X_stds = np.asarray(X_stds) - - dist_profiles = _normalised_squared_distance_profile( - QX, X_means, X_stds, Q_means, Q_stds, L - ) - - Q_norm = z_normalise_series_2d_with_mean_std(Q, Q_means, Q_stds) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - X_sub_norm = z_normalise_series_2d_with_mean_std( - X[i_x, :, i_t : i_t + L], X_means[i_x][:, i_t], X_stds[i_x][:, i_t] - ) - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X_sub_norm - Q_norm) ** 2) - ) - - # test unequal length and multivariate - X = List( - make_example_3d_numpy_list( - n_cases=5, - n_channels=2, - min_n_timepoints=10, - max_n_timepoints=20, - return_y=False, - ) - ) - Q = make_example_2d_numpy_series(n_channels=2, n_timepoints=L) - - QX = List([get_ith_products(X[i_x], Q, L, 0) for i_x in range(len(X))]) - - X_means, X_stds, Q_means, Q_stds = _get_mean_sdts_inputs(X, Q, L) - # Convert to numba typed list - X_means = List(X_means) - X_stds = List(X_stds) - - dist_profiles = _normalised_squared_distance_profile( - QX, X_means, X_stds, Q_means, Q_stds, L - ) - - Q_norm = z_normalise_series_2d_with_mean_std(Q, Q_means, Q_stds) - for i_x in range(len(X)): - for i_t in range(X[i_x].shape[1] - L + 1): - X_sub_norm = z_normalise_series_2d_with_mean_std( - X[i_x][:, i_t : i_t + L], X_means[i_x][:, i_t], X_stds[i_x][:, i_t] - ) - assert_almost_equal( - dist_profiles[i_x][i_t], np.sum((X_sub_norm - Q_norm) ** 2) - ) - - -@pytest.mark.parametrize("k", K_VALUES) -@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) -@pytest.mark.parametrize("inverse_distance", INVERSE) -def test__stomp(k, allow_neighboring_matches, inverse_distance): - """Test STOMP method.""" - L = 3 - - X = make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=6, - max_n_timepoints=8, - return_y=False, - ) - T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) - XdotT = List([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) - - T_index = None - threshold = np.inf - exclusion_size = L - # MP : distances to best matches for each query - # IP : Indexes of best matches for each query - MP, IP = _stomp( - X, - T, - XdotT, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) - # For each query of size L in T - for i in range(T.shape[1] - L + 1): - dist_profiles = _squared_distance_profile( - List([get_ith_products(X[i_x], T, L, i) for i_x in range(len(X))]), - X, - T[:, i : i + L], - ) - # Check that the top matches extracted have the same value that the - # top matches in the distance profile - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size - ) - # Check that the top matches extracted have the same value that the - # top matches in the distance profile - assert_array_almost_equal(MP[i], top_k_distances) - - # Check that the index in IP correspond to a distance profile point - # with value equal to the corresponding MP point. - for j, index in enumerate(top_k_indexes): - assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) - - -@pytest.mark.parametrize("k", K_VALUES) -@pytest.mark.parametrize("allow_neighboring_matches", NN_MATCHES) -@pytest.mark.parametrize("inverse_distance", INVERSE) -def test__stomp_normalised(k, allow_neighboring_matches, inverse_distance): - """Test STOMP normalised method.""" - L = 3 - X = make_example_3d_numpy_list( - n_cases=3, - n_channels=2, - min_n_timepoints=6, - max_n_timepoints=8, - return_y=False, - ) - T = make_example_2d_numpy_series(n_channels=2, n_timepoints=5) - - XdotT = List([get_ith_products(X[i_x], T, L, 0) for i_x in range(len(X))]) - - T_index = None - threshold = np.inf - exclusion_size = L - X_means, X_stds, _, _ = _get_mean_sdts_inputs(X, T, L) - T_means, T_stds = sliding_mean_std_one_series(T, L, 1) - # MP : distances to best matches for each query - # IP : Indexes of best matches for each query - MP, IP = _stomp_normalised( - X, - T, - XdotT, - X_means, - X_stds, - T_means, - T_stds, - L, - T_index, - k, - threshold, - allow_neighboring_matches, - exclusion_size, - inverse_distance, - ) - # For each query of size L in T - for i in range(T.shape[1] - L + 1): - dist_profiles = _normalised_squared_distance_profile( - List([get_ith_products(X[i_x], T, L, i) for i_x in range(len(X))]), - X_means, - X_stds, - T_means[:, i], - T_stds[:, i], - L, - ) - - if inverse_distance: - dist_profiles = _inverse_distance_profile_list(dist_profiles) - - top_k_indexes, top_k_distances = _extract_top_k_from_dist_profile( - dist_profiles, k, threshold, allow_neighboring_matches, exclusion_size - ) - # Check that the top matches extracted have the same value that the - # top matches in the distance profile - assert_array_almost_equal(MP[i], top_k_distances) - - # Check that the index in IP correspond to a distance profile point - # with value equal to the corresponding MP point. - for j, index in enumerate(top_k_indexes): - assert_almost_equal(MP[i][j], dist_profiles[index[0]][index[1]]) diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index 1d3161514a..89061a6dc2 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -1,83 +1,30 @@ """Mock series transformers useful for testing and debugging.""" -__maintainer__ = [] +__maintainer__ = ["baraline"] __all__ = [ - "MockSubsequenceSearch", - "MockMatrixProfile", + "MockSeriesSimilaritySearch", ] -import numpy as np +from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch -from aeon.similarity_search.subsequence_search._base import ( - BaseMatrixProfile, - BaseSubsequenceSearch, -) - -class MockMatrixProfile(BaseMatrixProfile): +class MockSeriesSimilaritySearch(BaseSeriesSimilaritySearch): """Mock estimator for BaseMatrixProfile.""" def __init__( self, length=3, - normalise=False, + normalize=False, n_jobs=1, ): - super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) - - def compute_matrix_profile( - self, - k, - threshold, - exclusion_size, - inverse_distance, - allow_neighboring_matches, - X=None, - X_index=None, - ): - """Compute matrix profiles between X_ and X or between all series in X_.""" - return np.zeros((X.shape[1] - self.length + 1, k)), np.zeros( - (X.shape[1] - self.length + 1, k, 2), dtype=np.int64 - ) + self.length = length + self.normalize = normalize + super().__init__(n_jobs=n_jobs) - def compute_distance_profile(self, X): - """Compute distrance profiles between X_ and X (a series of size length).""" - return [ - np.zeros(self.X_[i].shape[1] - self.length + 1) for i in range(len(self.X_)) - ] + def _fit(self, X, y=None): + return self - -class MockSubsequenceSearch(BaseSubsequenceSearch): - """Mock estimator for BaseSubsequenceSearch.""" - - def __init__( - self, - length=3, - normalise=False, - n_jobs=1, - ): - super().__init__(length=length, n_jobs=n_jobs, normalise=normalise) - - def _find_motifs( - self, - X, - k=1, - threshold=np.inf, - X_index=None, - inverse_distance=False, - allow_neighboring_matches=False, - exclusion_factor=2.0, - ): - return [[0, 0]], self.X_[0][0:1] # TODO: update after logic is implemented - - def _find_neighbors( - self, - X, - k=1, - threshold=np.inf, - inverse_distance=False, - X_index=None, - allow_neighboring_matches=False, - exclusion_factor=2.0, - ): - return [[0, 0]], self.X_[0][0:1] + def predict(self, X): + """Compute matrix profiles between X_ and X or between all series in X_.""" + X = self._pre_predict(X) + return [0], [0.1] diff --git a/aeon/transformations/collection/base.py b/aeon/transformations/collection/base.py index 013001d80e..54442dd6db 100644 --- a/aeon/transformations/collection/base.py +++ b/aeon/transformations/collection/base.py @@ -31,10 +31,10 @@ class name: BaseCollectionTransformer import pandas as pd from aeon.base import BaseCollectionEstimator -from aeon.transformations.base import BaseTransformer +from aeon.similarity_search._base import BaseSimilaritySearch -class BaseCollectionTransformer(BaseCollectionEstimator, BaseTransformer): +class BaseCollectionTransformer(BaseCollectionEstimator, BaseSimilaritySearch): """Transformer base class for collections.""" # tag values specific to CollectionTransformers diff --git a/examples/similarity_search/similarity_search_tasks.ipynb b/examples/similarity_search/similarity_search_tasks.ipynb index a42339c611..86fe5b5274 100644 --- a/examples/similarity_search/similarity_search_tasks.ipynb +++ b/examples/similarity_search/similarity_search_tasks.ipynb @@ -26,7 +26,7 @@ "- normalize. Wheter subseries should be normalized prior to distance computations\n", "\n", "#### Subseries Motif search :\n", - "Extract $k$-motifs or range $r$-motifs.\n", + "Extract $k$-motifs or range motifs or $r$-motifs.\n", "\n", "The $k^{th}$ motif is the $k^{th}$ most similar pair of subseries in $X$. Given $\\forall a,b,i,j$ the pair ${W_i, W_j}$ is the motif if $dist(W_i, W_j) ≤ dist(W_a, W_b), i \\neq j$ and $a \\neq b$\n", "\n", From 57e5e7b5e324426ea69a168709f7d0bac291054e Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 16 Jan 2025 15:56:05 +0100 Subject: [PATCH 13/18] Fix mistake addition in transformers and fix base classes --- aeon/similarity_search/_base.py | 5 +- aeon/similarity_search/collection/_base.py | 12 ++- .../collection/neighbors/__init__.py | 6 ++ .../collection/neighbors/_rp_cosine_lsh.py | 96 +++++++++---------- .../collection/neighbors/tests/__init__.py | 1 + .../collection/tests/__init__.py | 1 + .../collection/tests/test_base.py | 62 ++++++++++++ aeon/similarity_search/series/_base.py | 5 +- .../series/tests/test_base.py | 81 ++++++---------- .../_mock_similarity_searchers.py | 31 +++--- aeon/transformations/collection/base.py | 4 +- 11 files changed, 180 insertions(+), 124 deletions(-) create mode 100644 aeon/similarity_search/collection/neighbors/tests/__init__.py create mode 100644 aeon/similarity_search/collection/tests/__init__.py create mode 100644 aeon/similarity_search/collection/tests/test_base.py diff --git a/aeon/similarity_search/_base.py b/aeon/similarity_search/_base.py index fc58838eb4..5204163315 100644 --- a/aeon/similarity_search/_base.py +++ b/aeon/similarity_search/_base.py @@ -20,7 +20,6 @@ class BaseSimilaritySearch(BaseAeonEstimator): _tags = { "requires_y": False, - "capability:multivariate": True, "fit_is_empty": False, } @@ -85,12 +84,12 @@ def _check_predict_series_format(self, X): if isinstance(X, np.ndarray): if X.ndim != 2: raise TypeError( - "A np.ndarray given in find_neighbors must be 2D" + "A np.ndarray given in predict must be 2D" f"(n_channels, n_timepoints) but found {X.ndim}D." ) else: raise TypeError( - "Expected a 2D np.ndarray in find_neighbors but found" f" {type(X)}." + "Expected a 2D np.ndarray in predict but found" f" {type(X)}." ) if self.n_channels_ != X.shape[0]: raise ValueError( diff --git a/aeon/similarity_search/collection/_base.py b/aeon/similarity_search/collection/_base.py index 402b7342a2..3fde03d420 100644 --- a/aeon/similarity_search/collection/_base.py +++ b/aeon/similarity_search/collection/_base.py @@ -15,12 +15,16 @@ from aeon.similarity_search._base import BaseSimilaritySearch -class BaseCollectionSimilaritySearch(BaseCollectionEstimator, BaseSimilaritySearch): +class BaseCollectionSimilaritySearch(BaseSimilaritySearch, BaseCollectionEstimator): """Similarity search base class for collections.""" # tag values specific to CollectionTransformers _tags = { "input_data_type": "Collection", + "capability:multivariate": True, + "capability:unequal_length": True, + "capability:multithreading": True, + "X_inner_type": ["np-list", "numpy3D"], } @abstractmethod @@ -57,10 +61,8 @@ def fit( self.reset() X = self._preprocess_collection(X) # Store minimum number of n_timepoints for unequal length collections - self.n_channels_ = X[0].shape[1] + self.n_channels_ = X[0].shape[0] self.n_cases_ = len(X) - self.X_ = X - prev_threads = get_num_threads() set_num_threads(self._n_jobs) self._fit(X, y=y) @@ -92,5 +94,5 @@ def _pre_predict( self._check_is_fitted() if X is not None: # Could we call somehow _preprocess_series from a BaseCollectionEstimator ? - self._check_predict_format(X) + self._check_predict_series_format(X) return X diff --git a/aeon/similarity_search/collection/neighbors/__init__.py b/aeon/similarity_search/collection/neighbors/__init__.py index e9a5d49d49..f5cf0d925b 100644 --- a/aeon/similarity_search/collection/neighbors/__init__.py +++ b/aeon/similarity_search/collection/neighbors/__init__.py @@ -1 +1,7 @@ """Neighbors search for time series collection.""" + +__all__ = ["RandomProjectionIndexANN"] + +from aeon.similarity_search.collection.neighbors._rp_cosine_lsh import ( + RandomProjectionIndexANN, +) diff --git a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py index 8d1701793e..6774803984 100644 --- a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py +++ b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py @@ -3,9 +3,8 @@ import numpy as np from numba import njit, prange -from aeon.similarity_search.series_search._base import BaseIndexSearch - -# TPB = 16 +from aeon.similarity_search.collection._base import BaseCollectionSimilaritySearch +from aeon.utils.numba.general import z_normalise_series_2d, z_normalise_series_3d @njit(cache=True) @@ -17,12 +16,11 @@ def _hamming_dist(X, Y): @njit(cache=True, parallel=True) -def _hamming_dist_matrix(bool_hashes_value_list, bool_hashes): - n_hash_funcs = bool_hashes.shape[0] - res = np.zeros((n_hash_funcs, bool_hashes_value_list.shape[0]), dtype=np.int64) - for i in prange(n_hash_funcs): - for j in range(bool_hashes_value_list.shape[0]): - res[i, j] = _hamming_dist(bool_hashes_value_list[j], bool_hashes[i]) +def _hamming_dist_series_to_collection(X_bool, collection_bool): + n_buckets = collection_bool.shape[0] + res = np.zeros(n_buckets, dtype=np.int64) + for i in prange(n_buckets): + res[i] = _hamming_dist(collection_bool[i], X_bool) return res @@ -32,7 +30,7 @@ def _series_to_bool(X, hash_funcs, start_points, length): res = np.empty(n_hash_funcs, dtype=np.bool_) for j in prange(n_hash_funcs): res[j] = _nb_flat_dot( - X[start_points[j] : start_points[j] + length], hash_funcs[j] + X[:, start_points[j] : start_points[j] + length], hash_funcs[j] ) return res @@ -57,13 +55,12 @@ def _collection_to_bool(X, hash_funcs, start_points, length): res[i, j] = _nb_flat_dot( X[i, :, start_points[j] : start_points[j] + length], hash_funcs[j] ) - return res -class RP_LSH_Cosine(BaseIndexSearch): +class RandomProjectionIndexANN(BaseCollectionSimilaritySearch): """ - Random Projection Locality Sensitive Hashing index for cosine similarity. + Random Projection Locality Sensitive Hashing index with cosine similarity. In this method based on SimHash, we define a hash function as a boolean operation such as, given a random vector ``V`` of shape ``(n_channels, L)`` and a time series @@ -74,8 +71,8 @@ class RP_LSH_Cosine(BaseIndexSearch): as ``X[:, s:s+L].V`` Note that this method will not provide exact results, but will perform approximate - searchs. This also ignore any temporal correlation and treat series as - high dimensional points. + searchs. This also ignore any temporal correlation and consider series as + high dimensional points due to the cosine similarity distance. Parameters ---------- @@ -93,15 +90,16 @@ class RP_LSH_Cosine(BaseIndexSearch): Example ------- >>> from aeon.datasets import load_classification - >>> from aeon.similarity_search.series_search import RP_LSH_Cosine - >>> index = RP_LSH_Cosine() + >>> from aeon.similarity_search.collection.neighbors import RandomProjectionIndexANN + >>> index = RandomProjectionIndexANN() >>> X, y = load_classification("ArrowHead") >>> index.fit(X[:200]) - >>> r = index.find_neighbors(X[201]) + >>> r = index.predict(X[201]) """ _tags = { "capability:unequal_length": False, + "capability:multithreading": True, } def __init__( @@ -110,18 +108,26 @@ def __init__( hash_func_coverage=0.25, use_discrete_vectors=True, random_state=None, - normalise=False, + normalize=True, n_jobs=1, ): self.n_hash_funcs = n_hash_funcs self.hash_func_coverage = hash_func_coverage self.use_discrete_vectors = use_discrete_vectors self.random_state = random_state - super().__init__(normalise=normalise, n_jobs=n_jobs) + self.normalize = normalize + super().__init__(n_jobs=n_jobs) - def _build_index(self): + def _fit(self, X, y=None): """ - Build the index based on the data stored in X_. + Build the index based on the X. + + Parameters + ---------- + X : np.ndarray, 3D array of shape (n_cases, n_channels, n_timepoints) + Input array to be used to build the index. + y : optional + Not used. Returns ------- @@ -129,8 +135,10 @@ def _build_index(self): """ rng = np.random.default_rng(self.random_state) - n_timepoints = self.X_.shape[2] - self.window_length_ = max(1, int(n_timepoints * self.hash_func_coverage)) + if self.normalize: + X = z_normalise_series_3d(X) + self.n_timepoints_ = X.shape[2] + self.window_length_ = max(1, int(self.n_timepoints_ * self.hash_func_coverage)) if self.use_discrete_vectors: self.hash_funcs_ = rng.choice( @@ -143,13 +151,12 @@ def _build_index(self): size=(self.n_hash_funcs, self.n_channels_, self.window_length_), ) self.start_points_ = rng.choice( - n_timepoints - self.window_length_ + 1, + self.n_timepoints_ - self.window_length_ + 1, size=self.n_hash_funcs, replace=True, ) - bool_hashes = _collection_to_bool( - self.X_, self.hash_funcs_, self.start_points_, self.window_length_ + X, self.hash_funcs_, self.start_points_, self.window_length_ ) str_hashes = [hash(bool_hashes[i].tobytes()) for i in range(len(bool_hashes))] @@ -174,20 +181,6 @@ def _get_bucket_sizes(self): return {key: len(self.dict_X_index_[key]) for key in self.dict_X_index_} def _get_series_bucket(self, X): - """ - Get the matching bucket of a single series X if it exists in the index. - - Parameters - ---------- - X : TYPE - DESCRIPTION. - - Returns - ------- - TYPE - DESCRIPTION. - - """ bool_hash = _series_to_bool( X, self.hash_funcs_, self.start_points_, self.window_length_ ) @@ -197,7 +190,7 @@ def _get_series_bucket(self, X): else: return None - def _query_index( + def predict( self, X, k=1, @@ -222,19 +215,26 @@ def _query_index( Returns ------- top_k : np.ndarray, shape = (n_cases, k) - Indexes of k series in X_ (the index) that are close to each series in X. + Indexes of k series in the index that are similar to X. top_k_dist : np.ndarray, shape = (n_cases, k) - Distance of k series in X_ (the index) to each series in X. The distance + Distance of k series in the index to X. The distance is the hamming distance between the result of each hash function. """ - bool_hashes = _series_to_bool( + X = self._pre_predict(X) + if X.shape[1] != self.n_timepoints_: + raise ValueError( + f"Expected a series with {self.n_timepoints_} but got {X.shape[1]}." + "Unequal length is not supported by this estimator." + ) + if self.normalize: + X = z_normalise_series_2d(X) + + X_bool = _series_to_bool( X, self.hash_funcs_, self.start_points_, self.window_length_ ) top_k = np.zeros(k, dtype=int) top_k_dist = np.zeros(k, dtype=float) - dists = _hamming_dist_matrix( - self.bool_hashes_value_list_, bool_hashes[np.newaxis, :] - )[0] + dists = _hamming_dist_series_to_collection(X_bool, self.bool_hashes_value_list_) if inverse_distance: dists = 1 / (dists + 1e-8) # Get top k buckets diff --git a/aeon/similarity_search/collection/neighbors/tests/__init__.py b/aeon/similarity_search/collection/neighbors/tests/__init__.py new file mode 100644 index 0000000000..89bc3412fb --- /dev/null +++ b/aeon/similarity_search/collection/neighbors/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for similarity search for time series collection neighbors module.""" diff --git a/aeon/similarity_search/collection/tests/__init__.py b/aeon/similarity_search/collection/tests/__init__.py new file mode 100644 index 0000000000..d136a8571e --- /dev/null +++ b/aeon/similarity_search/collection/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for similarity search for time series collection base class and commons.""" diff --git a/aeon/similarity_search/collection/tests/test_base.py b/aeon/similarity_search/collection/tests/test_base.py new file mode 100644 index 0000000000..9180a071cf --- /dev/null +++ b/aeon/similarity_search/collection/tests/test_base.py @@ -0,0 +1,62 @@ +"""Test for collection similarity search base class.""" + +__maintainer__ = ["baraline"] + +import pytest + +from aeon.testing.mock_estimators._mock_similarity_searchers import ( + MockCollectionSimilaritySearch, +) +from aeon.testing.testing_data import ( + make_example_1d_numpy, + make_example_2d_numpy_series, + make_example_3d_numpy, + make_example_3d_numpy_list, +) + + +def test_input_shape_fit_predict_collection(): + """Test input shapes.""" + estimator = MockCollectionSimilaritySearch() + # dummy data to pass to fit when testing predict/predict_proba + X_3D_uni = make_example_3d_numpy(n_channels=1, return_y=False) + X_3D_multi = make_example_3d_numpy(n_channels=2, return_y=False) + X_3D_uni_list = make_example_3d_numpy_list(n_channels=1, return_y=False) + X_3D_multi_list = make_example_3d_numpy_list(n_channels=2, return_y=False) + X_2D_uni = make_example_2d_numpy_series(n_channels=1) + X_2D_multi = make_example_2d_numpy_series(n_channels=2) + X_1D = make_example_1d_numpy() + + # 2D are converted to 3D + valid_inputs_fit = [ + X_3D_uni, + X_3D_multi, + X_3D_multi_list, + X_3D_uni_list, + X_2D_uni, + X_2D_multi, + ] + # Valid inputs + for _input in valid_inputs_fit: + estimator.fit(_input) + + with pytest.raises(ValueError): + estimator.fit(X_1D) + + estimator_multi = MockCollectionSimilaritySearch().fit(X_3D_multi) + estimator_uni = MockCollectionSimilaritySearch().fit(X_3D_uni) + + estimator_uni.predict(X_2D_uni) + estimator_multi.predict(X_2D_multi) + + with pytest.raises(ValueError): + estimator_uni.predict(X_2D_multi) + with pytest.raises(ValueError): + estimator_multi.predict(X_2D_uni) + + for _input in [X_3D_uni, X_3D_uni_list]: + with pytest.raises(TypeError): + estimator_uni.predict(_input) + for _input in [X_3D_multi, X_3D_multi_list]: + with pytest.raises(TypeError): + estimator_multi.predict(_input) diff --git a/aeon/similarity_search/series/_base.py b/aeon/similarity_search/series/_base.py index b9cca5d5cb..bd07f25ba6 100644 --- a/aeon/similarity_search/series/_base.py +++ b/aeon/similarity_search/series/_base.py @@ -11,11 +11,12 @@ from aeon.utils.validation import check_n_jobs -class BaseSeriesSimilaritySearch(BaseSeriesEstimator, BaseSimilaritySearch): +class BaseSeriesSimilaritySearch(BaseSimilaritySearch, BaseSeriesEstimator): """Base class for similarity search applications on single series.""" _tags = { "input_data_type": "Series", + "capability:multivariate": True, } @abstractmethod @@ -87,7 +88,7 @@ def _pre_predict( self._check_is_fitted() if X is not None: X = self._preprocess_series(X, self.axis, False) - self._check_predict_format(X) + self._check_predict_series_format(X) return X def _check_X_index(self, X_index: int): diff --git a/aeon/similarity_search/series/tests/test_base.py b/aeon/similarity_search/series/tests/test_base.py index d3dc953c6a..1b4d17b991 100644 --- a/aeon/similarity_search/series/tests/test_base.py +++ b/aeon/similarity_search/series/tests/test_base.py @@ -1,4 +1,4 @@ -"""Test for subsequence search base class.""" +"""Test for series similarity search base class.""" __maintainer__ = ["baraline"] @@ -14,13 +14,10 @@ make_example_3d_numpy_list, ) -BASES = [MockSeriesSimilaritySearch] - -@pytest.mark.parametrize("base", BASES) -def test_input_shape_fit_predict(base): +def test_input_shape_fit_predict_series(): """Test input shapes.""" - estimator = base() + estimator = MockSeriesSimilaritySearch() # dummy data to pass to fit when testing predict/predict_proba X_3D_uni = make_example_3d_numpy(n_channels=1, return_y=False) X_3D_multi = make_example_3d_numpy(n_channels=2, return_y=False) @@ -30,58 +27,38 @@ def test_input_shape_fit_predict(base): X_2D_multi = make_example_2d_numpy_series(n_channels=2) X_1D = make_example_1d_numpy() - valid_inputs_fit = [X_2D_uni, X_2D_multi] - # Valid inputs + valid_inputs_fit = [X_1D, X_2D_uni, X_2D_multi] + # 1D is converted to 2D univariate for _input in valid_inputs_fit: estimator.fit(_input) - invalid_inputs_fit = [X_1D, X_3D_multi_list, X_3D_uni_list, X_3D_multi, X_3D_uni] - for _input in invalid_inputs_fit: - with pytest.raises(TypeError): - estimator.fit(_input) - - valid_inputs_predict = [X_2D_uni, X_2D_multi] - invalid_inputs_predict_uni = [ - X_1D, - X_3D_uni, - X_3D_uni_list, - ] - invalid_inputs_predict_multi = [ + invalid_inputs_fit = [ X_3D_multi, + X_3D_uni, X_3D_multi_list, + X_3D_uni_list, ] - L = 3 - estimator_multi = base(length=L).fit(X_2D_multi) - estimator_uni = base(length=L).fit(X_2D_uni) - - for _input in valid_inputs_predict: - estimator_uni.find_neighbors(_input[:, :L]) - estimator_uni.find_motifs(_input) - with pytest.raises(ValueError): - # Wrong number of channels - estimator_multi.find_neighbors(_input) - with pytest.raises(ValueError): - estimator_multi.find_motifs(_input) - # X length not of size L + for _input in invalid_inputs_fit: with pytest.raises(ValueError): - estimator_uni.find_neighbors(_input[:, : L + 2]) + estimator.fit(_input) + + estimator_multi = MockSeriesSimilaritySearch().fit(X_2D_multi) + estimator_uni = MockSeriesSimilaritySearch().fit(X_2D_uni) - for _input in invalid_inputs_predict_uni: - with pytest.raises(TypeError): - estimator_uni.find_neighbors(_input) - with pytest.raises(TypeError): - estimator_uni.find_motifs(_input) - with pytest.raises(TypeError): - estimator_multi.find_neighbors(_input) - with pytest.raises(TypeError): - estimator_multi.find_motifs(_input) + estimator_uni.predict(X_2D_uni) + # 1D is converted to 2D univariate + estimator_uni.predict(X_1D) + estimator_multi.predict(X_2D_multi) - for _input in invalid_inputs_predict_multi: - with pytest.raises(TypeError): - estimator_uni.find_neighbors(_input) - with pytest.raises(TypeError): - estimator_uni.find_motifs(_input) - with pytest.raises(TypeError): - estimator_multi.find_neighbors(_input) - with pytest.raises(TypeError): - estimator_multi.find_motifs(_input) + with pytest.raises(ValueError): + estimator_uni.predict(X_2D_multi) + with pytest.raises(ValueError): + estimator_multi.predict(X_2D_uni) + + for _input in [X_3D_uni, X_3D_uni_list]: + with pytest.raises(ValueError): + estimator_uni.predict(_input) + + for _input in [X_3D_multi, X_3D_multi_list]: + with pytest.raises(ValueError): + estimator_multi.predict(_input) diff --git a/aeon/testing/mock_estimators/_mock_similarity_searchers.py b/aeon/testing/mock_estimators/_mock_similarity_searchers.py index 89061a6dc2..a2919c939d 100644 --- a/aeon/testing/mock_estimators/_mock_similarity_searchers.py +++ b/aeon/testing/mock_estimators/_mock_similarity_searchers.py @@ -1,25 +1,32 @@ """Mock series transformers useful for testing and debugging.""" __maintainer__ = ["baraline"] -__all__ = [ - "MockSeriesSimilaritySearch", -] +__all__ = ["MockSeriesSimilaritySearch", "MockCollectionSimilaritySearch"] +from aeon.similarity_search.collection._base import BaseCollectionSimilaritySearch from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch class MockSeriesSimilaritySearch(BaseSeriesSimilaritySearch): """Mock estimator for BaseMatrixProfile.""" - def __init__( - self, - length=3, - normalize=False, - n_jobs=1, - ): - self.length = length - self.normalize = normalize - super().__init__(n_jobs=n_jobs) + def __init__(self): + super().__init__() + + def _fit(self, X, y=None): + return self + + def predict(self, X): + """Compute matrix profiles between X_ and X or between all series in X_.""" + X = self._pre_predict(X) + return [0], [0.1] + + +class MockCollectionSimilaritySearch(BaseCollectionSimilaritySearch): + """Mock estimator for BaseMatrixProfile.""" + + def __init__(self): + super().__init__() def _fit(self, X, y=None): return self diff --git a/aeon/transformations/collection/base.py b/aeon/transformations/collection/base.py index 54442dd6db..013001d80e 100644 --- a/aeon/transformations/collection/base.py +++ b/aeon/transformations/collection/base.py @@ -31,10 +31,10 @@ class name: BaseCollectionTransformer import pandas as pd from aeon.base import BaseCollectionEstimator -from aeon.similarity_search._base import BaseSimilaritySearch +from aeon.transformations.base import BaseTransformer -class BaseCollectionTransformer(BaseCollectionEstimator, BaseSimilaritySearch): +class BaseCollectionTransformer(BaseCollectionEstimator, BaseTransformer): """Transformer base class for collections.""" # tag values specific to CollectionTransformers From 2078086a8c8a142f2a8d5cf166d8eb2b7898f830 Mon Sep 17 00:00:00 2001 From: baraline Date: Thu, 16 Jan 2025 16:18:38 +0100 Subject: [PATCH 14/18] Fix registry and api reference --- aeon/similarity_search/collection/__init__.py | 4 ++ aeon/testing/testing_config.py | 4 -- aeon/utils/base/_register.py | 11 ++-- docs/api_reference/similarity_search.rst | 63 +++++++++++-------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/aeon/similarity_search/collection/__init__.py b/aeon/similarity_search/collection/__init__.py index 0aef46ef49..ab3a546193 100644 --- a/aeon/similarity_search/collection/__init__.py +++ b/aeon/similarity_search/collection/__init__.py @@ -1 +1,5 @@ """Similarity search for time series collection.""" + +__all__ = ["BaseCollectionSimilaritySearch"] + +from aeon.similarity_search.collection._base import BaseCollectionSimilaritySearch diff --git a/aeon/testing/testing_config.py b/aeon/testing/testing_config.py index 4c46058318..61ff90cdd1 100644 --- a/aeon/testing/testing_config.py +++ b/aeon/testing/testing_config.py @@ -57,10 +57,6 @@ "ClaSPSegmenter": ["check_non_state_changing_method"], "HMMSegmenter": ["check_non_state_changing_method"], "RSTSF": ["check_non_state_changing_method"], - # Keeps length during predict to avoid recomputing means and std of data in fit - # if the next predict calls uses the same query length parameter. - "QuerySearch": ["check_non_state_changing_method"], - "SeriesSearch": ["check_non_state_changing_method"], # Unknown issue not producing the same results "RDSTRegressor": ["check_regressor_against_expected_results"], "RISTRegressor": ["check_regressor_against_expected_results"], diff --git a/aeon/utils/base/_register.py b/aeon/utils/base/_register.py index 024ad447ee..5e81e29b33 100644 --- a/aeon/utils/base/_register.py +++ b/aeon/utils/base/_register.py @@ -24,8 +24,9 @@ from aeon.forecasting.base import BaseForecaster from aeon.regression.base import BaseRegressor from aeon.segmentation.base import BaseSegmenter -from aeon.similarity_search.series_search._base import BaseSeriesSearch -from aeon.similarity_search.subsequence_search._base import BaseSubsequenceSearch +from aeon.similarity_search._base import BaseSimilaritySearch +from aeon.similarity_search.collection import BaseCollectionSimilaritySearch +from aeon.similarity_search.series import BaseSeriesSimilaritySearch from aeon.transformations.base import BaseTransformer from aeon.transformations.collection import BaseCollectionTransformer from aeon.transformations.series import BaseSeriesTransformer @@ -37,6 +38,7 @@ "estimator": BaseAeonEstimator, "series-estimator": BaseSeriesEstimator, "transformer": BaseTransformer, + "similarity-search": BaseSimilaritySearch, # estimator types "anomaly-detector": BaseAnomalyDetector, "collection-transformer": BaseCollectionTransformer, @@ -47,8 +49,8 @@ "segmenter": BaseSegmenter, "series-transformer": BaseSeriesTransformer, "forecaster": BaseForecaster, - "subsequence_searcher": BaseSubsequenceSearch, - "series_searcher": BaseSeriesSearch, + "series-similarity-search": BaseSeriesSimilaritySearch, + "collection-similarity-search": BaseCollectionSimilaritySearch, } # base classes which are valid for estimator to directly inherit from @@ -60,5 +62,6 @@ "collection-estimator", "series-estimator", "transformer", + "similarity-search", } } diff --git a/docs/api_reference/similarity_search.rst b/docs/api_reference/similarity_search.rst index eb13cafd23..7212179953 100644 --- a/docs/api_reference/similarity_search.rst +++ b/docs/api_reference/similarity_search.rst @@ -4,51 +4,47 @@ Similarity search ================= The :mod:`aeon.similarity_search` module contains algorithms and tools for similarity -search tasks. +search tasks. First, we distinguish between `series` estimator and `collection` +estimators, similarly to the `aeon.transformer` module. Secondly, we distinguish between +estimators used `neighbors` (with sufix SNN for subsequence nearest neighbors, or ANN +for approximate nearest neighbors) search and estimators used for `motifs` search. -Similarity search estimators ----------------------------- +Series Similarity search estimators +----------------------------------- -.. currentmodule:: aeon.similarity_search +.. currentmodule:: aeon.similarity_search.series.neighbors .. autosummary:: :toctree: auto_generated/ :template: class.rst - QuerySearch - SeriesSearch + DummySNN + MassSNN -Distance profile functions --------------------------- - -.. currentmodule:: aeon.similarity_search.distance_profiles +.. currentmodule:: aeon.similarity_search.series.motifs .. autosummary:: :toctree: auto_generated/ - :template: function.rst + :template: class.rst + + StompMotif - euclidean_distance_profile - normalised_euclidean_distance_profile - squared_distance_profile - normalised_squared_distance_profile -Matrix profile functions --------------------------- +Collection Similarity search estimators +----------------------------------- -.. currentmodule:: aeon.similarity_search.matrix_profiles +.. currentmodule:: aeon.similarity_search.collection.neighbors .. autosummary:: :toctree: auto_generated/ - :template: function.rst + :template: class.rst + + RandomProjectionIndexANN - stomp_normalised_euclidean_matrix_profile - stomp_euclidean_matrix_profile - stomp_normalised_squared_matrix_profile - stomp_squared_matrix_profile -Base ----- +Base Estimators +--------------- .. currentmodule:: aeon.similarity_search.base @@ -57,3 +53,20 @@ Base :template: class.rst BaseSimilaritySearch + + +.. currentmodule:: aeon.similarity_search.series.base + +.. autosummary:: + :toctree: auto_generated/ + :template: class.rst + + BaseSeriesSimilaritySearch + +.. currentmodule:: aeon.similarity_search.collection.base + +.. autosummary:: + :toctree: auto_generated/ + :template: class.rst + + BaseCollectionSimilaritySearch From 9effbd9a9ed1afc69428d76501a7e143717ff90d Mon Sep 17 00:00:00 2001 From: baraline Date: Fri, 17 Jan 2025 22:40:49 +0100 Subject: [PATCH 15/18] Update documentation and fix some leftover bugs --- aeon/similarity_search/_base.py | 6 +- aeon/similarity_search/collection/_base.py | 7 +- .../collection/neighbors/_rp_cosine_lsh.py | 8 +- aeon/similarity_search/series/__init__.py | 6 +- aeon/similarity_search/series/_base.py | 7 +- aeon/similarity_search/series/_commons.py | 5 +- .../similarity_search/series/motifs/_stomp.py | 38 +- .../series/neighbors/_dummy.py | 14 +- .../series/neighbors/_mass.py | 28 +- docs/getting_started.md | 5 +- examples/similarity_search/code_speed.ipynb | 2 +- .../similarity_search/distance_profiles.ipynb | 2 +- .../similarity_search/similarity_search.ipynb | 425 +++++------------- 13 files changed, 201 insertions(+), 352 deletions(-) diff --git a/aeon/similarity_search/_base.py b/aeon/similarity_search/_base.py index 5204163315..a87487fde1 100644 --- a/aeon/similarity_search/_base.py +++ b/aeon/similarity_search/_base.py @@ -72,7 +72,7 @@ def predict( """ ... - def _check_predict_series_format(self, X): + def _check_predict_series_format(self, X, length=None): """ Check wheter a series X in predict is correctly formated. @@ -96,8 +96,8 @@ def _check_predict_series_format(self, X): f"Expected X to have {self.n_channels_} channels but" f" got {X.shape[0]} channels." ) - if hasattr(self, "length") and X.shape[1] != self.length: + if length is not None and X.shape[1] != length: raise ValueError( - f"Expected X to have {self.length} timepoints but" + f"Expected X to have {length} timepoints but" f" got {X.shape[1]} timepoints." ) diff --git a/aeon/similarity_search/collection/_base.py b/aeon/similarity_search/collection/_base.py index 3fde03d420..618a531081 100644 --- a/aeon/similarity_search/collection/_base.py +++ b/aeon/similarity_search/collection/_base.py @@ -15,7 +15,7 @@ from aeon.similarity_search._base import BaseSimilaritySearch -class BaseCollectionSimilaritySearch(BaseSimilaritySearch, BaseCollectionEstimator): +class BaseCollectionSimilaritySearch(BaseCollectionEstimator, BaseSimilaritySearch): """Similarity search base class for collections.""" # tag values specific to CollectionTransformers @@ -81,6 +81,7 @@ def _fit( def _pre_predict( self, X: Union[np.ndarray, None] = None, + length: int = None, ): """ Predict method. @@ -89,10 +90,12 @@ def _pre_predict( ---------- X : Union[np.ndarray, None], optional Optional data to use for predict.. The default is None. + length: int, optional + If not None, the number of timepoint of X should be equal to length. """ self._check_is_fitted() if X is not None: # Could we call somehow _preprocess_series from a BaseCollectionEstimator ? - self._check_predict_series_format(X) + self._check_predict_series_format(X, length=length) return X diff --git a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py index 6774803984..a6f3097f78 100644 --- a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py +++ b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py @@ -220,12 +220,8 @@ def predict( Distance of k series in the index to X. The distance is the hamming distance between the result of each hash function. """ - X = self._pre_predict(X) - if X.shape[1] != self.n_timepoints_: - raise ValueError( - f"Expected a series with {self.n_timepoints_} but got {X.shape[1]}." - "Unequal length is not supported by this estimator." - ) + X = self._pre_predict(X, length=self.n_timepoints_) + if self.normalize: X = z_normalise_series_2d(X) diff --git a/aeon/similarity_search/series/__init__.py b/aeon/similarity_search/series/__init__.py index 23df7d1b53..d1b5494c13 100644 --- a/aeon/similarity_search/series/__init__.py +++ b/aeon/similarity_search/series/__init__.py @@ -1,7 +1,7 @@ """Similarity search for series.""" -__all__ = [ - "BaseSeriesSimilaritySearch", -] +__all__ = ["BaseSeriesSimilaritySearch", "MassSNN", "StompMotif"] from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch +from aeon.similarity_search.series.motifs._stomp import StompMotif +from aeon.similarity_search.series.neighbors._mass import MassSNN diff --git a/aeon/similarity_search/series/_base.py b/aeon/similarity_search/series/_base.py index bd07f25ba6..2e1b6d40e0 100644 --- a/aeon/similarity_search/series/_base.py +++ b/aeon/similarity_search/series/_base.py @@ -11,7 +11,7 @@ from aeon.utils.validation import check_n_jobs -class BaseSeriesSimilaritySearch(BaseSimilaritySearch, BaseSeriesEstimator): +class BaseSeriesSimilaritySearch(BaseSeriesEstimator, BaseSimilaritySearch): """Base class for similarity search applications on single series.""" _tags = { @@ -75,6 +75,7 @@ def _fit( def _pre_predict( self, X: Union[np.ndarray, None] = None, + length: int = None, ): """ Predict method. @@ -83,12 +84,14 @@ def _pre_predict( ---------- X : Union[np.ndarray, None], optional Optional data to use for predict.. The default is None. + length: int, optional + If not None, the number of timepoint of X should be equal to length. """ self._check_is_fitted() if X is not None: X = self._preprocess_series(X, self.axis, False) - self._check_predict_series_format(X) + self._check_predict_series_format(X, length=length) return X def _check_X_index(self, X_index: int): diff --git a/aeon/similarity_search/series/_commons.py b/aeon/similarity_search/series/_commons.py index d14281573f..4e62e5aacb 100644 --- a/aeon/similarity_search/series/_commons.py +++ b/aeon/similarity_search/series/_commons.py @@ -61,6 +61,7 @@ def get_ith_products(X, T, L, ith): return fft_sliding_dot_product(X, T[:, ith : ith + L]) +@njit(cache=True, fastmath=True) def _inverse_distance_profile(dist_profile): return 1 / (dist_profile + 1e-8) @@ -101,9 +102,7 @@ def _extract_top_k_from_dist_profile( The distances of the best matches. """ - if k == np.inf: - k = dist_profile.shape[0] - top_k_indexes = np.zeros((k), dtype=np.int64) - 1 + top_k_indexes = np.zeros(k, dtype=np.int64) - 1 top_k_distances = np.full(k, np.inf, dtype=np.float64) ub = np.full(k, np.inf) lb = np.full(k, -1.0) diff --git a/aeon/similarity_search/series/motifs/_stomp.py b/aeon/similarity_search/series/motifs/_stomp.py index 9287d80241..fbd459b890 100644 --- a/aeon/similarity_search/series/motifs/_stomp.py +++ b/aeon/similarity_search/series/motifs/_stomp.py @@ -154,13 +154,13 @@ def predict( "Expected motif_extraction_method to be either 'k_motifs' or 'r_motifs'" f"but got {motif_extraction_method}" ) - exclusion_size = self.length // exclusion_factor + MP, IP = self.compute_matrix_profile( X, motif_size=motif_size, dist_threshold=dist_threshold, allow_trivial_matches=allow_trivial_matches, - exclusion_size=exclusion_size, + exclusion_factor=exclusion_factor, inverse_distance=inverse_distance, ) if motif_extraction_method == "k_motifs": @@ -170,11 +170,11 @@ def predict( def compute_matrix_profile( self, - X: np.ndarray, + X: np.ndarray = None, motif_size: Optional[int] = 1, dist_threshold: Optional[float] = np.inf, allow_trivial_matches: Optional[bool] = False, - exclusion_size: Optional[float] = 2, + exclusion_factor: Optional[float] = 2, inverse_distance: Optional[bool] = False, ): """ @@ -198,14 +198,12 @@ def compute_matrix_profile( inverse_distance : bool If True, the matching will be made on the inverse of the distance, and thus, the worst matches to the query will be returned instead of the best ones. - exclusion_size : int - The size of the exclusion zone used to prevent returning as top k candidates - the ones that are close to each other (for example i and i+1). - It is used to define a region between - :math:`id_timestamp - exclusion_size` and - :math:`id_timestamp + exclusion_size` which cannot be returned - as best match if :math:`id_timestamp` was already selected. By default, - the value None means that this is not used. + exclusion_factor : float, default=1. + A factor of the query length used to define the exclusion zone when + ``allow_trivial_matches`` is set to False. For a given timestamp, + the exclusion zone starts from + :math:`id_timestamp - length//exclusion_factor` and end at + :math:`id_timestamp + length//exclusion_factor`. Returns ------- @@ -229,7 +227,7 @@ def compute_matrix_profile( X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) X_dotX = get_ith_products(X, self.X_, self.length, 0) - + exclusion_size = self.length // exclusion_factor if self.normalize: MP, IP = _stomp_normalized( self.X_, @@ -353,14 +351,17 @@ def _stomp_normalized( lb = max(0, i_q - exclusion_size) dist_profile[lb:ub] = np.inf - top_indexes, top_dists = _extract_top_k_from_dist_profile( + _top_indexes, top_dists = _extract_top_k_from_dist_profile( dist_profile, motif_size, dist_threshold, allow_trivial_matches, exclusion_size, ) - + top_indexes = np.zeros((len(_top_indexes), 2), dtype=np.int64) + for i_idx in range(len(_top_indexes)): + top_indexes[i_idx, 0] = i_q + top_indexes[i_idx, 1] = _top_indexes[i_idx] MP.append(top_dists) IP.append(top_indexes) @@ -443,14 +444,17 @@ def _stomp( lb = max(0, i_q - exclusion_size) dist_profile[lb:ub] = np.inf - top_indexes, top_dists = _extract_top_k_from_dist_profile( + _top_indexes, top_dists = _extract_top_k_from_dist_profile( dist_profile, motif_size, dist_threshold, allow_trivial_matches, exclusion_size, ) - + top_indexes = np.zeros((len(_top_indexes), 2), dtype=np.int64) + for i_idx in range(len(_top_indexes)): + top_indexes[i_idx, 0] = i_q + top_indexes[i_idx, 1] = _top_indexes[i_idx] MP.append(top_dists) IP.append(top_indexes) diff --git a/aeon/similarity_search/series/neighbors/_dummy.py b/aeon/similarity_search/series/neighbors/_dummy.py index bbea714eda..7b4d4d89da 100644 --- a/aeon/similarity_search/series/neighbors/_dummy.py +++ b/aeon/similarity_search/series/neighbors/_dummy.py @@ -47,7 +47,7 @@ def predict( self, X: np.ndarray, k: Optional[int] = 1, - threshold: Optional[float] = np.inf, + dist_threshold: Optional[float] = np.inf, exclusion_factor: Optional[float] = 2, inverse_distance: Optional[bool] = False, allow_neighboring_matches: Optional[bool] = False, @@ -62,7 +62,7 @@ def predict( Subsequence we want to find neighbors for. k : int The number of neighbors to return. - threshold : float + dist_threshold : float The maximum distance of neighbors to X. inverse_distance : bool If True, the matching will be made on the inverse of the distance, and thus, @@ -73,7 +73,7 @@ def predict( the exclusion zone starts from :math:`id_timestamp - length//exclusion_factor` and end at :math:`id_timestamp + length//exclusion_factor`. - X_index : Optional[int], optional + X_index : int, optional If ``X`` is a subsequence of X_, specify its starting timestamp in ``X_``. If specified, neighboring subsequences of X won't be able to match as neighbors. @@ -86,12 +86,13 @@ def predict( The distances of the best matches. """ - X = self._pre_predict(X) + X = self._pre_predict(X, length=self.length) X_index = self._check_X_index(X_index) dist_profile = self.compute_distance_profile(X) if inverse_distance: dist_profile = _inverse_distance_profile(dist_profile) + exclusion_size = self.length // exclusion_factor if X_index is not None: exclusion_size = self.length // exclusion_factor _max_timestamp = self.n_timepoints_ - self.length @@ -99,10 +100,13 @@ def predict( lb = max(0, X_index - exclusion_size) dist_profile[lb:ub] = np.inf + if k == np.inf: + k = len(dist_profile) + return _extract_top_k_from_dist_profile( dist_profile, k, - threshold, + dist_threshold, allow_neighboring_matches, exclusion_size, ) diff --git a/aeon/similarity_search/series/neighbors/_mass.py b/aeon/similarity_search/series/neighbors/_mass.py index bb56815f4e..9565407fc8 100644 --- a/aeon/similarity_search/series/neighbors/_mass.py +++ b/aeon/similarity_search/series/neighbors/_mass.py @@ -21,7 +21,22 @@ class MassSNN(BaseSeriesSimilaritySearch): - """Estimator to compute the on profile and distance profile using MASS.""" + """ + Estimator to compute the subsequences nearest neighbors using MASS _[1]. + + Parameters + ---------- + length : int + The length of the subsequences to use for the search. + normalize : bool + Wheter the subsequences should be z-normalized. + + References + ---------- + .. [1] Abdullah Mueen, Yan Zhu, Michael Yeh, Kaveh Kamgar, Krishnamurthy + Viswanathan, Chetan Kumar Gupta and Eamonn Keogh (2015), The Fastest Similarity + Search Algorithm for Time Series Subsequences under Euclidean Distance. + """ def __init__( self, @@ -38,7 +53,7 @@ def _fit( y=None, ): if self.normalize: - self.X_means_, X_stds_ = sliding_mean_std_one_series(X, self.length, 1) + self.X_means_, self.X_stds_ = sliding_mean_std_one_series(X, self.length, 1) return self def predict( @@ -76,7 +91,7 @@ def predict( the exclusion zone starts from :math:`id_timestamp - length//exclusion_factor` and end at :math:`id_timestamp + length//exclusion_factor`. - X_index : Optional[int], optional + X_index : int, optional If ``X`` is a subsequence of X_, specify its starting timestamp in ``X_``. If specified, neighboring subsequences of X won't be able to match as neighbors. @@ -89,19 +104,22 @@ def predict( The distances of the best matches. """ - X = self._pre_predict(X) + X = self._pre_predict(X, length=self.length) X_index = self._check_X_index(X_index) dist_profile = self.compute_distance_profile(X) if inverse_distance: dist_profile = _inverse_distance_profile(dist_profile) + exclusion_size = self.length // exclusion_factor if X_index is not None: - exclusion_size = self.length // exclusion_factor _max_timestamp = self.n_timepoints_ - self.length ub = min(X_index + exclusion_size, _max_timestamp) lb = max(0, X_index - exclusion_size) dist_profile[lb:ub] = np.inf + if k == np.inf: + k = len(dist_profile) + return _extract_top_k_from_dist_profile( dist_profile, k, diff --git a/docs/getting_started.md b/docs/getting_started.md index 36f18583cb..ce519359f2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -21,8 +21,9 @@ classical techniques for the following learning tasks: - [**Clustering**](api_reference/clustering), where a collection of time series without any labels are used to train a model to label cases ([more details](examples/clustering/clustering.ipynb)). -- [**Similarity search**](api_reference/similarity_search), where the goal is to evaluate - the similarity between a query time series and a collection of other longer time series +- [**Similarity search**](api_reference/similarity_search), where the goal is to find + time series motifs or nearest neighbors in an efficient way for either single series + or collections. ([more details](examples/similarity_search/similarity_search.ipynb)). - [**Anomaly detection**](api_reference/anomaly_detection), where the goal is to find values or areas of a single time series that are not representative of the whole series. diff --git a/examples/similarity_search/code_speed.ipynb b/examples/similarity_search/code_speed.ipynb index f31155333d..9b4c08acf3 100644 --- a/examples/similarity_search/code_speed.ipynb +++ b/examples/similarity_search/code_speed.ipynb @@ -554,7 +554,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/examples/similarity_search/distance_profiles.ipynb b/examples/similarity_search/distance_profiles.ipynb index ec56fcc6bf..d5ea595ff5 100644 --- a/examples/similarity_search/distance_profiles.ipynb +++ b/examples/similarity_search/distance_profiles.ipynb @@ -146,7 +146,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.0" } }, "nbformat": 4, diff --git a/examples/similarity_search/similarity_search.ipynb b/examples/similarity_search/similarity_search.ipynb index cdbaa86948..803398d551 100644 --- a/examples/similarity_search/similarity_search.ipynb +++ b/examples/similarity_search/similarity_search.ipynb @@ -7,12 +7,27 @@ "source": [ "# Time Series Similarity Search with aeon\n", "\n", - "The goal of Time Series Similarity Search is to asses the similarities between a time\n", - " series, denoted as a query `q` of length `l`, and a collection of time series,\n", - " denoted as `X`, with lengths greater than or equal to `l`. In this\n", - " context, the notion of similiarity between `q` and the other series in `X` is quantified by similarity functions. Those functions are most of the time defined as distance function, such as the Euclidean distance. Knowing the similarity between `q` and other admissible candidates, we can then perform many other tasks for \"free\", such as anomaly or motif detection.\n", + "\"time\n", "\n", - "\"time" + "The objectives of the similarity search module in aeon is to provide estimators with a `fit`/`predict` interface to solve the following use cases :\n", + "\n", + "- Nearest neighbors search on time series subesequences or whole series\n", + "- Motifs search on time series subsequences\n", + "\n", + "Similarly to the `transformer` module, the `similarity_search` module split estimators between `series` estimators and `collection` estimators, such as :\n", + "\n", + "- `series` estimators take as input a single time series of shape `(n_channels, n_timepoints)` during fit and predict.\n", + "- `collection` estimators take as input a time series collection of shape `(n_cases, n_channels, n_timepoints)` during fit, and a single series of shape `(n_channels, n_timepoints)` during predict.\n", + "\n", + "Note that the above is a general guideline, and that some estimators can also take `None` as input during predict, or series of length different to `n_timepoints`. We'll explore the different estimators in the next sections.\n", + "\n", + "### Other similarity search notebooks\n", + "\n", + "This notebook gives an overview of similarity search module and the available estimators. The following notebooks are also avaiable to go more in depth with specific subject of similarity search in aeon:\n", + "\n", + "- [The theory and math behind the similarity search estimators in aeon](distance_profiles.ipynb)\n", + "- [Analysis of the performance of the estimators provided by similarity search module](code_speed.ipynb)\n", + "\n" ] }, { @@ -22,25 +37,34 @@ "metadata": {}, "outputs": [], "source": [ - "def plot_best_matches(top_k_search, best_matches):\n", + "# Define some plotting functions we'll use later !\n", + "def plot_best_matches(\n", + " X_fit, X_predict, idx_predict, idx_matches, length, normalize=False\n", + "):\n", " \"\"\"Plot the top best matches of a query in a dataset.\"\"\"\n", - " fig, ax = plt.subplots(figsize=(20, 5), ncols=3)\n", - " for i_k, (id_sample, id_timestamp) in enumerate(best_matches):\n", + " fig, ax = plt.subplots(figsize=(20, 5), ncols=len(idx_matches))\n", + " if len(idx_matches) == 1:\n", + " ax = [ax]\n", + " for i_k, id_timestamp in enumerate(idx_matches):\n", " # plot the sample of the best match\n", - " ax[i_k].plot(top_k_search.X_[id_sample, 0], linewidth=2)\n", + " ax[i_k].plot(X_fit[0], linewidth=2)\n", " # plot the location of the best match on it\n", + " match = X_fit[0, id_timestamp : id_timestamp + length]\n", " ax[i_k].plot(\n", - " range(id_timestamp, id_timestamp + q.shape[1]),\n", - " top_k_search.X_[id_sample, 0, id_timestamp : id_timestamp + q.shape[1]],\n", + " range(id_timestamp, id_timestamp + length),\n", + " match,\n", " linewidth=7,\n", " alpha=0.5,\n", " color=\"green\",\n", " label=\"best match location\",\n", " )\n", " # plot the query on the location of the best match\n", + " Q = X_predict[0, idx_predict : idx_predict + length]\n", + " if normalize:\n", + " Q = Q * np.std(match) + np.mean(match)\n", " ax[i_k].plot(\n", - " range(id_timestamp, id_timestamp + q.shape[1]),\n", - " q[0],\n", + " range(id_timestamp, id_timestamp + length),\n", + " Q,\n", " linewidth=5,\n", " alpha=0.5,\n", " color=\"red\",\n", @@ -66,73 +90,32 @@ " plt.show()" ] }, - { - "cell_type": "markdown", - "id": "7e06b213-6038-4901-b98e-2433625115c4", - "metadata": {}, - "source": [ - "## Similarity search Notebooks\n", - "\n", - "This notebook gives an overview of similarity search module and the available estimators. The following notebooks are avaiable to go more in depth with specific subject of similarity search in aeon:\n", - "\n", - "- [Deep dive in the distance profiles](distance_profiles.ipynb)\n", - "- [Analysis of the speedups provided by similarity search module](code_speed.ipynb)" - ] - }, - { - "cell_type": "markdown", - "id": "ca967c08-9a05-411a-a09a-ad8a13c0adb9", - "metadata": {}, - "source": [ - "## Expected inputs and format\n", - "For both `QuerySearch` and `SeriesSearch`, the `fit` method expects a time series dataset of shape `(n_cases, n_channels, n_timepoints)`. This can be 3D numpy array or a list of 2D numpy arrays if `n_timepoints` varies between cases (i.e. unequal length dataset).\n", - "\n", - "The `predict` method expects a 2D numpy array of shape `(n_channels, query_length)` for `QuerySearch`. In `SeriesSearch`, the predict methods also expects a 2D numpy array, but of shape `(n_channels, n_timepoints)` (`n_timepoints` doesn't have to be the same as in fit) and a `query_length` parameter." - ] - }, { "cell_type": "markdown", "id": "d1fd75ae-84c2-40be-95f6-bd7de409317d", "metadata": {}, "source": [ - "## Available estimators\n", + "### A word on base clases\n", "\n", - "All estimators of the similarity search module in aeon inherit from the `BaseSimilaritySearch` class, which requires the following arguments:\n", - "- `distance` : a string indicating which distance function to use as similarity function. By default this is `\"euclidean\"`, which means that the Euclidean distance is used.\n", - "- `normalise` : a boolean indicating whether this similarity function should be z-normalised. This means that the scale of the two series being compared will be ignored, and that, loosely speaking, we will only focus on their shape during the comparison. By default, this parameter is set `False`.\n", + "All estimators of the similarity search module in aeon inherit from the `BaseSimilaritySearch` class, which define the some abstract methods that estimator must implement, such as `fit` and `predict` and some private function used to validate the format of the time series you will provide. Then, the two submodules `series` and `collection` also define a base class (`BaseSeriesSimilaritySearch` and `BaseCollectionSeriesSearch`) that their respective estimator will inherit from. If you ever want to extend the module or create your own estimators, these are the classes you'll want to use to define the base structure of your estimator.\n", "\n", - "Another parameter, which has no effect on the output of the estimators, is a boolean named `store_distance_profile`, set to `False` by default. If set to `True`, the estimators will expose an attribute named `_distance_profile` after the `predict` function is called. This attribute will contain the computed distance profile for query given as input to the `predict` function.\n", + "### Load a dataset\n", + "In the following, we'll use an easy dataset (`GunPoint`) to help build intuition. Don't hesitate to swap it with other datasets to explore ! We load it using the `load_classification` function.\n", "\n", - "To illustrate how to work with similarity search estimators in aeon, we will now present some example use cases." - ] - }, - { - "cell_type": "markdown", - "id": "01fa67c2-0126-4152-98a9-fa0df84c4629", - "metadata": {}, - "source": [ - "### Query search" - ] - }, - { - "cell_type": "markdown", - "id": "8e99b251-d156-4989-b5a0-3a2c79cb75d4", - "metadata": {}, - "source": [ - "We will use the GunPoint dataset for this example, which can be loaded using the `load_classification` function." + "The GunPoint dataset is composed of two classes which are discriminated by the \"bumps\" located before and after the central peak. These bumps correspond to an actor drawing a fake gun from a holster before pointing it (hence the name \"GunPoint\" !). In the second class, the actor simply points his fingers without making the motion of taking the gun out of the holster." ] }, { "cell_type": "code", "execution_count": 2, - "id": "f8a6bb7e-b219-41f1-b508-b849c45672eb", + "id": "20d3b591-f275-4548-a7d2-75b16380b055", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABIkAAAFTCAYAAAC9L1y2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAAsTAAALEwEAmpwYAACncElEQVR4nOzdd3ydZf3/8dc52Xvv0TSjSbpHSlvoYpRRoCAbAUGQCoKKA+GnqIioKLgQFPmKDJWNUgRaCsimg3TQmTTd2Xvv5Ny/P+4mEJq2J2ckJ8n7+XjkcSfnXNd1PicdufK5r+tzWQzDMBARERERERERkXHNOtIBiIiIiIiIiIjIyFOSSERERERERERElCQSEREREREREREliUREREREREREBCWJREREREREREQEJYlERERERERERAQliURERDzeE088wcKFC0c6DIfdfffdXH311S4d0zAMvvrVrxIREcFJJ53k0rH7jPbvu72Cg4PZv3+/W8Y+ePAgFouFnp4et4wvIiIirqUkkYiIjGtpaWkEBAQQHBzc/3HrrbeOdFhyAh9++CFvvvkmJSUlbNy40enxhiOZUVRUxBVXXEFMTAyhoaFkZWXxzW9+k5KSEpeMb7FYCAoKIjg4mKSkJL773e/S29t7wn4tLS2kp6fb/Rp79+51NtRBvfvuuyQnJ7tl7JF4HRERkdFISSIRERn3/vvf/9LS0tL/8dBDD410SHIChw4dIi0tjaCgoCH3HYlVLXv37mXevHkkJiayZcsWmpqa+Oijj8jIyODDDz902et8+umntLS08Pbbb/P000/zf//3fy4bW0RERMY+JYlERESO4eabb+biiy/u//qOO+7g9NNPxzAM6uvrOe+884iJiSEiIoLzzjtvwIqQpUuXctddd3HyyScTHBzM+eefT21tLVdddRWhoaHMnTuXgwcP9re3WCw8+OCDpKenEx0dze23347NZhs0roKCApYtW0ZkZCTZ2dk8//zzx3wPTzzxBOnp6YSEhDBx4kT+9a9/AbBv3z5OO+00oqKiiI6O5qqrrqKhoaG/X1paGvfffz/Tp08nKCiIG264gcrKSs455xxCQkI444wzqK+vBz5bhfPoo4+SmJhIQkICDzzwwDFjWr9+PSeffDLh4eHMmDGDd99994Txft5jjz3G1772NdatW0dwcDA//elPAfi///s/MjMziYyMZMWKFZSVlQ34/j788MNkZWWRlZV11JiLFy8GIDw8nODgYNatW9f/3Pe//30iIiKYOHEiq1ev7n+8sbGRG264gYSEBJKSkrjrrruOuXLn7rvv5pRTTuF3v/td/yqW2NhYbrvtNq644or+9/7F7W2fX7lz3XXXccstt3DuuecSEhLCvHnz2Ldv36Cvl5OTw6JFi9ixY4dd3xt7XqPvezRjxgyCg4N57rnnjnrd3t5evv/97xMdHU16ejqvvfbagOcff/xxcnNzCQkJIT09nb/+9a8AtLa2cs4551BWVta/oq+srIyNGzeyYMECwsPDSUhI4NZbb6Wrqwswtxx+5zvfITY2ltDQUKZNm9b/fjs7O/n+979PamoqcXFx3HTTTbS3tx/zdUREROQIQ0REZBybMGGC8eabbw76XGtrq5GVlWU8/vjjxvvvv29ERUUZxcXFhmEYRk1NjfHiiy8ara2tRlNTk3HJJZcYF1xwQX/fJUuWGBkZGcbevXuNhoYGIzc318jKyjLefPNNo7u727jmmmuM6667rr89YCxdutSora01Dh06ZGRlZRn/93//ZxiGYTz++OPGKaecYhiGYbS0tBjJycnG3//+d6O7u9vYvHmzERUVZezcufOo+FtaWoyQkBCjoKDAMAzDKCsrM3bs2GEYhmEUFRUZa9euNTo6Ooyqqipj0aJFxre//e0B35d58+YZFRUVRklJiRETE2PMmjXL2Lx5s9He3m6ceuqpxt13320YhmEcOHDAAIwrrrjCaGlpMbZt22ZER0f3f19/+tOfGldddZVhGIZRUlJiREZGGq+99prR29trrF271oiMjDSqqqqOG+8Xff57YhiG8fbbbxtRUVHGpk2bjI6ODuPWW281Fi1aNOD7e8YZZxi1tbVGW1vbUeP1vYfu7u4Br+Ht7W08+uijRk9Pj/HnP//ZSEhIMGw2m2EYhnHhhRcaK1euNFpaWozKykpj7ty5xiOPPDJovHFxccbjjz8+6HPHek99cRcVFRmGYRjXXnutERkZaWzYsMHo7u42vvzlLxuXX375oG137txpxMXFGX/729/s+t448hqD+ctf/mJkZ2cbhw8fNmpra42lS5cO+L6++uqrxt69ew2bzWa8++67RkBAgLFp0ybDMAzjnXfeMZKSkgaMl5+fb6xbt87o7u42Dhw4YOTk5Bi///3vDcMwjDVr1hizZ8826uvrDZvNZuzatcsoKyszDMMwbrvtNuP88883amtrjaamJuO8884z7rzzzmO+joiIiJiUJBIRkXFtwoQJRlBQkBEWFtb/8eijj/Y/v379eiMiIsJITU01nn766WOOs2XLFiM8PLz/6yVLlhj33ntv/9ff/e53jbPPPrv/61deecWYMWNG/9eAsXr16v6vH374YeO0004zDGNg8uDZZ581Fi5cOOC1V65c2Z+w+byWlhYjLCzMePHFFwdNjHzef/7zH2PmzJn9X0+YMMH45z//2f/1RRddZNx00039Xz/44IP9SbG+BMvu3bv7n7/99tuN66+/3jCMgUmi++67z7j66qsHvPaZZ55pPPHEE0OK94sJleuvv964/fbb+79ubm42vL29jQMHDhiGYX5/33777WOOd6wkUUZGRv/Xra2tBmCUl5cbFRUVhq+v74A4n376aWPp0qWDju/l5TXgz/dPf/qTERYWZgQFBRlf+9rXBn1PfXF/PoFzww039D/32muvGdnZ2QPahoSEGOHh4UZ6errxox/9yOjt7bXrezOU1zhekujUU081/vKXv/R//cYbbxz1ff28Cy64wPjDH/5gGIZ9yZvf//73xoUXXmgYhpkYzMrKMtatW2f09vb2t7HZbEZgYKCxd+/e/sc+/vhjIy0tze7XERERGa+03UxERMa9l19+mYaGhv6PG2+8sf+5efPmkZ6ejmEYXHbZZf2Pt7W18fWvf50JEyYQGhrK4sWLaWhoGLDdKC4urv/zgICAo75uaWkZEEdKSkr/5xMmTBh0G8yhQ4fYsGED4eHh/R//+te/qKioOKptUFAQzz33HI888ggJCQmce+65FBQUAFBZWckVV1xBUlISoaGhXH311dTU1Azo7674X3jhhQHxf/jhh5SXlx833hMpKytjwoQJ/V8HBwcTFRVFaWnpoPHZKz4+vv/zwMBAwCz0fOjQIbq7u0lISOh/H1//+tepqqoadJyoqCjKy8v7v7711ltpaGjgtttuo7u72+F4vvhnsHnzZurr69m3bx/33nsvVqvVru/NUF7jeMrKyo76e/B5q1evZv78+URGRhIeHs7rr79+1N+7z9uzZw/nnXce8fHxhIaG8sMf/rC//Wmnncatt97KLbfcQmxsLCtXrqSpqYnq6mra2tqYM2dO/5/N2WefTXV1td3vQ0REZLxSkkhEROQ4Hn74YTo7O0lMTOQ3v/lN/+O//e1vKSwsZMOGDTQ1NfH+++8DZp0URxUXF/d/fvjwYRITE49qk5KSwpIlSwYktVpaWvjLX/4y6JhnnXUWb775JuXl5eTk5PQnwH74wx9isVjYvn07TU1N/POf/3Qq9qHEf8011wyIv7W1lTvvvPO48Z5IYmIihw4d6v+6tbWV2tpakpKS+h+zWCzH7H+85waTkpKCn58fNTU1/e+jqamJnTt3Dtr+9NNP59///vdxxwwKCqKtra3/68ESf46w53vjKgkJCUf9PejT2dnJxRdfzPe//30qKytpaGhg+fLl/X/vBvszuPnmm8nJyaGoqIimpiZ++ctfDvh7+q1vfYtNmzaxa9cu9uzZw/333090dDQBAQHs3Lmz/8+msbGxP9k11D9rERGR8URJIhERkWPYs2cPd911F//85z/5xz/+wW9+8xu2bt0KQHNzMwEBAYSHh1NXV8fPfvYzp1/v/vvvp76+nuLiYv74xz9y+eWXH9XmvPPOY8+ePfzjH/+gu7ub7u5uPvnkE3bv3n1U28rKSlatWkVrayt+fn4EBwdjtVr74w8ODiYsLIzS0lLuv/9+p+P/+c9/TltbGzt37uTxxx8fNP6rr76a//73v7zxxhv09vbS0dHBu+++S0lJyXHjPZErr7ySxx9/nK1bt9LZ2ckPf/hD5s2bR1paml39Y2JisFqt7N+/3672CQkJnHnmmXzve9+jqakJm83Gvn37eO+99wZtf/fdd/PBBx/w3e9+t38FT01NzYA/txkzZrBz5062bt1KR0cHd999t12xnIiz35vPi4uLO+736LLLLuPBBx+kpKSE+vp67rvvvv7nurq66OzsJCYmBm9vb1avXs3atWsHjF1bW0tjY2P/Y83NzYSGhhIcHExBQcGAZOgnn3zChg0b6O7uJigoCH9/f6xWK1arlRtvvJHvfOc7/Su7SktLeeONN475OiIiImJSkkhERMa9888/v/+ko+DgYL70pS/R09PD1VdfzR133MGMGTPIysril7/8Jddccw2dnZ3cdttttLe3Ex0dzfz58zn77LOdjuOCCy5gzpw5zJw5k3PPPZcbbrjhqDYhISGsXbuWZ599lsTEROLj47njjjvo7Ow8qq3NZuN3v/sdiYmJREZG8t577/X/kv3Tn/6UzZs3ExYWxrnnnstFF13kdPxLliwhMzOT008/ne9///uceeaZR7VJSUlh1apV/PKXvyQmJoaUlBTuv/9+bDbbceM9kTPOOIOf//znXHzxxSQkJLBv3z6effZZu2MPDAzkRz/6Eaeccgrh4eGsX7/+hH2eeuopurq6mDx5MhEREVxyySUDtpR93qRJk9iwYQMlJSXMmDGDkJAQTjnlFBITE/n5z3/e3+YnP/kJZ5xxBllZWUeddOYoZ783n3f33Xdz7bXXEh4ePuipejfeeCNnnXUWM2bMYPbs2QP+XoWEhPDggw9y2WWXERERwdNPP82KFSv6n8/JyeHKK68kPT2d8PBwysrKeOCBB3j66acJCQnhxhtvHJB4bGpq4sYbbyQiIoIJEyYQFRXF7bffDsCvf/1rMjMzmT9/PqGhoZxxxhkUFhYe83VERETEZDGcXVsuIiIiTrNYLBQVFZGZmTnSoQzZwYMHmThxIt3d3Xh7e490OCIiIiLiIK0kEhERERERERERJYlERERERERERETbzUREREREREREBK0kEhERERERERERlCQSERERERERERGUJBIREREREREREZQkEhERERERERERlCQSERERERERERGUJBIREREREREREZQkEhE3eOKJJ1i4cOFIhyEiIiIyrmgOJiLOUpJIREa9hx56iLy8PPz8/LjuuutGOhwRERGRMa+zs5MbbriBCRMmEBISwsyZM1m9evVIhyUiTvIe6QBERJyVmJjIXXfdxRtvvEF7e/tIhyMiIiIy5vX09JCSksJ7771Hamoqr7/+Opdddhnbt28nLS1tpMMTEQdpJZGIOKy4uJiLLrqImJgYoqKiuPXWWwdt9+1vf5uUlBRCQ0OZM2cOH3zwQf9zGzduJC8vj9DQUOLi4vjud78LQEdHB1dffTVRUVGEh4czd+5cKisrBx3/oosu4sILLyQqKsr1b1JERETEw3jCHCwoKIi7776btLQ0rFYr5513HhMnTmTTpk3uedMiMiyUJBIRh/T29nLeeecxYcIEDh48SGlpKVdcccWgbefOncvWrVupq6vjy1/+MpdeeikdHR2AOXn59re/TVNTE/v27eOyyy4D4Mknn6SxsZHi4mJqa2t55JFHCAgIGLb3JyIiIuKJPHUOVllZyZ49e5gyZYrr3qyIDDsliUTEIRs3bqSsrIz777+foKAg/P39j1kose9ulLe3N9/73vfo7OyksLAQAB8fH/bu3UtNTQ3BwcHMnz+///Ha2lr27t2Ll5cXc+bMITQ0dNjen4iIiIgn8sQ5WHd3N1dddRXXXnstOTk5rn3DIjKslCQSEYcUFxczYcIEvL1PXNrsgQceIDc3l7CwMMLDw2lsbKSmpgaAxx57jD179pCTk8PcuXN59dVXAbjmmms466yzuOKKK0hMTOQHP/gB3d3dbn1PIiIiIp7O0+ZgNpuNa665Bl9fXx566CHXvEkRGTFKEomIQ1JSUjh8+DA9PT3HbffBBx/wm9/8hueff576+noaGhoICwvDMAwAsrKyeOaZZ6iqquKOO+7gkksuobW1FR8fH37605+ya9cuPv74Y1599VWeeuqp4XhrIiIiIh7Lk+ZghmFwww03UFlZyUsvvYSPj4/L36+IDC8liUTEISeddBIJCQnceeedtLa20tHRwUcffXRUu+bmZry9vYmJiaGnp4d77rmHpqam/uf/+c9/Ul1djdVqJTw8HACr1co777zD9u3b6e3tJTQ0FB8fH6zWwf/L6unpoaOjg97eXnp7e+no6DjhxElERERkNPKkOdjNN9/M7t27+e9//6vakSJjhJJEIuIQLy8v/vvf/7J3715SU1NJTk7mueeeO6rdWWedxdlnn82kSZOYMGEC/v7+pKSk9D+/Zs0apkyZQnBwMN/+9rd59tlnCQgIoKKigksuuYTQ0FByc3NZsmQJ11xzzaCx3HvvvQQEBHDffffxz3/+k4CAAO699163vXcRERGRkeIpc7BDhw7x17/+la1btxIfH09wcDDBwcH861//cuv7FxH3shh96w1FRERERERERGTc0koiERERERERERFRkkhERERERERERJQkEhERERERERERlCQSERERERERERGUJBIREREREREREcB7pAM4lujoaNLS0kY6DBEREXGjgwcPUlNTM9JhyOdoDiYiIjK2HW/+5bFJorS0NPLz80c6DBEREXGjvLy8kQ5BvkBzMBERkbHtePMvbTcTERERGYWKi4s59dRTmTx5MlOmTOGPf/zjUW0Mw+Bb3/oWmZmZTJ8+nc2bN49ApCIiIjJaeOxKIhERERE5Nm9vb377298ye/ZsmpubmTNnDsuWLWPy5Mn9bVavXk1RURFFRUVs2LCBm2++mQ0bNoxg1CIiIuLJtJJIREREZBRKSEhg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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABk0AAAHeCAYAAAA2OUyqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD7qUlEQVR4nOzdd3hb5fn/8bfkIe+94xE7e8eZBAgJhCQkgbIp0JZVWmihlFK+QNgUSn6lrLYQRlldlFIIaSBASckEAiRkkeUsJ87wdry3dX5/HEuJsZ04suQhf17XpescS+c855EsJzq6z33fFsMwDERERERERERERERERPo4a3dPQEREREREREREREREpCdQ0ERERERERERERERERAQFTURERERERERERERERAAFTURERERERERERERERAAFTURERERERERERERERAAFTURERERERERERERERAAFTURERERERERERERERAAFTURERERERERERERERAAFTURERERERERERERERAAFTURERER6rTfeeAOLxdLubeXKld09Rbfo378/1113XXdPo9tNnz6d6dOnd+kx6+vrufnmm0lMTMTHx4exY8d69Hhvvvkmzz77bKv79+/fj8Vi4cknn/To8R3Ky8v5f//v/zF58mQiIiLw8/MjPj6e8847jzfffJO6ujqPHt/xfB03q9VKdHQ0c+fOZe3atac83sMPP4zFYnFpLtu3b+fhhx9m//79Lu3vjjm0977oLgsXLuSNN97o7mmIiIiIiIf4dvcERERERKRzXn/9dYYOHdrq/uHDh3fDbMSbvPDCC7z00kv86U9/Yvz48YSEhHj0eG+++SZbt27l9ttv9+hxTmT37t2cd955FBQU8NOf/pT77ruPyMhIcnNz+e9//8sNN9zAjh07ePTRRz0+l1/84hdcffXVNDU1sW3bNh555BHOPvts1q5dS2ZmZofHufHGGznvvPNcmsP27dt55JFHmD59Ov3793dpjM7qCe+L4y1cuJCYmBgFc0VERES8lIImIiIiIr3cyJEjmTBhQndPQ7zQ1q1bCQwM5NZbb3XbmDU1NQQGBrptPHdqbGzkoosuoqSkhK+//pphw4a1ePyKK67gwQcfZOPGjV0yn9TUVE477TQAzjjjDAYOHMiMGTNYuHAhf/7znzs8TnJyMsnJyZ6apoiIiIiIV1F5LhEREREv99Zbb2GxWHjuueda3P/QQw/h4+PDsmXLnPc98sgjTJ48maioKMLCwhg3bhyvvvoqhmG02Ld///6cf/75fPDBB2RmZhIYGMiwYcP44IMPALN02LBhwwgODmbSpEmsX7++xf7XXXcdISEhbNu2jRkzZhAcHExsbCy33nor1dXVJ31O5eXl3HnnnaSnp+Pv70+/fv24/fbbqaqqOum+Gzdu5PzzzycuLg6bzUZSUhLz5s3j0KFDzm2ef/55zjrrLOLi4ggODmbUqFE88cQTNDQ0tBhr+vTpjBw5krVr13L66acTGBhI//79ef311wFYunQp48aNIygoiFGjRvHxxx+32N9Rsmjjxo1ccsklhIWFER4ezg9/+EMKCwtP+lzq6+t57LHHGDp0KDabjdjYWK6//vpW+y5fvpzp06cTHR1NYGAgqampXHrppSd8rS0WC6+88go1NTXOMlGOkkS1tbXMnz+/xet/yy23UFpa2mIMx/tk0aJFZGZmEhAQwCOPPNLm8aZPn87SpUs5cOBAi9JU3/X000+Tnp5OSEgIU6ZM4csvv2y1zfr16/ne975HVFQUAQEBZGZm8vbbb5/k1YT33nuP7du3c99997UKmDikpaVx0UUXOX92lMn7bvmqlStXtiqT53i/rFu3jqlTpxIUFERGRgb/7//9P+x2+0nn5wigHDhwwHnfa6+9xpgxYwgICCAqKoqLL76YHTt2tNivrdJYjt/Nxx9/zLhx4wgMDGTo0KG89tprLZ7b5ZdfDsDZZ5/d6n3QnqVLlzJ27FhsNhvp6entllXryN/Zyd4XHf03qyN/Ax35e+rfvz/btm1j1apVzrl0VwaOiIiIiHiGMk1EREREermmpiYaGxtb3GexWPDx8QHgyiuvZNWqVfz617/mtNNOY8KECSxfvpzHHnuMe++9l5kzZzr3279/PzfddBOpqakAfPnll/ziF7/g8OHDPPjggy2OsXnzZubPn899991HeHg4jzzyCJdccgnz58/n008/5fHHH8disXD33Xdz/vnnk52d3SLDoKGhgblz53LTTTdxzz338MUXX/DYY49x4MAB3n///Xafb3V1NdOmTePQoUPce++9jB49mm3btvHggw/y7bff8r///a/d3glVVVXMnDmT9PR0nn/+eeLj48nLy2PFihVUVFQ4t9u7dy9XX321MyiwefNmfvvb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m2ZMmzatxX0NDQ3Gk08+6ZxrSEiIMXToUOOmm24ydu/ebRiGYaxdu9a4+OKLjbS0NMNmsxnR0dHGtGnTjCVLlrT7Ojk4fk/fVVNTY9x9991GWlqa4efnZyQmJho/+9nPjKNHj3bodWhPSUmJcdlllxkRERGGxWIxHKcrbb2HHADjoYceanHf5s2bjSuuuMKIi4sz/Pz8jISEBOOcc84xXnzxxQ7No6yszHj88ceNiRMnGmFhYYavr68RFxdnzJw503j++eeNqqqqFtvv2rXLmDVrlhEWFmbExsYav/jFL4ylS5d2+P1y7bXXGmlpac6fT/R8v+uVV14xRo8e7fw7uPDCC1v9rTveZ8dr73fT1vvs2WefNdLT0w0fHx8DMF5//fUTzmnJkiXOOaWmphr/7//9vzbn0NG/s/beF4bRsX+zOvo30JG/J8MwjP379xuzZs0yQkNDDaDF705EREREej+LYRhGVwVoREREREQArrvuOt555x0qKyu7eyrd6uGHH+aRRx6hsLCwW3pQiIiIiIiISEvqaSIiIiIiIiIiIiIiIoKCJiIiIiIiIiIiIiIiIgCoPJeIiIiIiIiIiIiIiAjKNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREWDlypVYLBZWrlzZ3VNp4dChQ9x+++1MmzaNiIgILBYLb7zxRndPS0RERERE+piees60aNEirrrqKgYOHEhgYCD9+/fnBz/4Abt37+7uqYmI9FoKmoiISI+1Z88e/vGPf+Dv78/cuXO7ezoiIiIiIiI9yu9+9zuqq6u57777+Pjjj3nsscfYuHEj48aNY9u2bd09PRGRXsm3uycgIiLSnrPOOovCwkIA1q9fzz//+c9unpGIiIiIiEjP8f777xMXF9fivnPOOYf+/fvzzDPP8Morr3TTzEREei9lmoiI9AE7d+7kqquuIj4+HpvNRmpqKtdccw11dXXt7rN+/XquvPJK+vfv70zzvuqqqzhw4ECL7aqrq7nzzjtJT08nICCAqKgoJkyY0CLAsW/fPq688kqSkpKw2WzEx8czY8YMNm3adMJ5W636b0pERERERDyvt54zfTdgApCUlERycjIHDx48tRdBREQAZZqIiHi9zZs3c+aZZxITE8NvfvMbBg0aRG5uLkuWLKG+vh6bzdbmfvv372fIkCFceeWVREVFkZubywsvvMDEiRPZvn07MTExANxxxx387W9/47HHHiMzM5Oqqiq2bt1KcXGxc6y5c+fS1NTEE088QWpqKkVFRXzxxReUlpZ2xUsgIiIiIiLSLm87Z9q3bx8HDhzgoosucuXlEBHp8yyGYRjdPQkREfGcGTNmsGHDBnbt2kVsbGyb26xcuZKzzz6bFStWMH369Da3aWpqora2lvj4eB5//HFuu+02AEaNGsXAgQN577332tyvuLiYmJgYnn32WX75y1+6/DzWr1/PxIkTef3117nuuutcHkdEREREROR43nLOBNDY2MjMmTPZsGEDW7duJSUlpVPjiYj0Rap7IiLixaqrq1m1ahVXXHFFux/+21NZWcndd9/NwIED8fX1xdfXl5CQEKqqqtixY4dzu0mTJvHRRx9xzz33sHLlSmpqalqMExUVxYABA/j973/P008/zcaNG7Hb7W55fiIiIiIiIp3hTedMhmHw4x//mDVr1vDXv/5VARMRERcpaCIi4sWOHj1KU1MTycnJp7zv1VdfzXPPPceNN97If//7X77++mvWrVtHbGxsiw/5f/zjH7n77rtZvHgxZ599NlFRUVx00UXs3r0bAIvFwqeffsrs2bN54oknGDduHLGxsdx2221UVFS47bmKiIiIiIicKm85ZzIMgxtvvJG///3vvPHGG1x44YWn/HxERMSkniYiIl4sKioKHx8fDh06dEr7lZWV8cEHH/DQQw9xzz33OO+vq6ujpKSkxbbBwcE88sgjPPLII+Tn5zuvoLrgggvYuXMnAGlpabz66qsA7Nq1i7fffpuHH36Y+vp6XnzxxU4+SxEREREREdd4wzmTI2Dy+uuv8+qrr/LDH/7wlJ6LiIi0pEwTEREvFhgYyLRp0/j3v/9NUVFRh/ezWCwYhtGq4eErr7xCU1NTu/vFx8dz3XXXcdVVV5GVlUV1dXWrbQYPHsz999/PqFGj2LBhQ8efjIiIiIiIiJv19nMmwzD4yU9+wuuvv85LL73E9ddf3+HnICIibVOmiYiIl3v66ac588wzmTx5Mvfccw8DBw4kPz+fJUuW8NJLLxEaGtpqn7CwMM466yx+//vfExMTQ//+/Vm1ahWvvvoqERERLbadPHky559/PqNHjyYyMpIdO3bwt7/9jSlTphAUFMSWLVu49dZbufzyyxk0aBD+/v4sX76cLVu2tLgiqz3vvPMOAPv27QPMhvAhISEAXHbZZZ18dUREREREpK/rzedMt912G6+++io33HADo0aN4ssvv3Q+ZrPZyMzMdMtrJCLSlyhoIiLi5caMGcPXX3/NQw89xPz586moqCAhIYFzzjkHf3//dvd78803+eUvf8ldd91FY2MjZ5xxBsuWLWPevHkttjvnnHNYsmQJzzzzDNXV1fTr149rrrmG++67D4CEhAQGDBjAwoULOXjwIBaLhYyMDJ566il+8YtfnHT+l19+eYufn3/+eZ5//nnAvKpKRERERESkM3rzOdP7778PwGuvvcZrr73W4rG0tDT279/vwisiItK3WQx94yQiIiIiIiIiIiIiIqKeJiIiIiIiIiIiIiIiIqCgiYiIiIiIiIiIiIiICKCgiYiIiIiIiIiIiIiICKCgiYiIiIiIiIiIiIiICKCgiYiIiIiIiIiIiIiICAC+3T0Bd7Pb7Rw5coTQ0FAsFkt3T0dERERExOMMw6CiooKkpCSsVl0XJSen8yYRERER6UtO5ZzJ64ImR44cISUlpbunISIiIiLS5Q4ePEhycnJ3T0N6AZ03iYiIiEhf1JFzJq8LmoSGhgLmkw8LC+vm2YiIiIiIeF55eTkpKSnOz8IiJ6PzJhERERHpS07lnMnrgiaO1PKwsDB9+BcRERGRPkVllqSjdN4kIiIiIn1RR86ZVPBYREREREREREREREQEBU1ERERERES6zYIFC5g4cSKhoaHExcVx0UUXkZWVddL9Vq1axfjx4wkICCAjI4MXX3yxC2YrIiIiIuL9FDQRERERERHpJqtWreKWW27hyy+/ZNmyZTQ2NjJr1iyqqqra3Sc7O5u5c+cydepUNm7cyL333sttt93Gu+++24UzFxERERHxTl7X00RERERE2tfU1ERDQ0N3T0NOkZ+fHz4+Pt09DfGAjz/+uMXPr7/+OnFxcXzzzTecddZZbe7z4osvkpqayrPPPgvAsGHDWL9+PU8++SSXXnqpp6csIiIi4vV03tQ7ueu8SUETERERkT7AMAzy8vIoLS3t7qmIiyIiIkhISFCzdy9XVlYGQFRUVLvbrF27llmzZrW4b/bs2bz66qs0NDTg5+fXap+6ujrq6uqcP5eXl7tpxiIiIiLeQ+dNvZ87zpsUNBERERHpAxwf/OPi4ggKCtIX772IYRhUV1dTUFAAQGJiYjfPSDzFMAzuuOMOzjzzTEaOHNnudnl5ecTHx7e4Lz4+nsbGRoqKitp8jyxYsIBHHnnE7XMWERER8SY6b+q93HnepKCJiIiIiJdrampyfvCPjo7u7umICwIDAwEoKCggLi5Opbq81K233sqWLVv47LPPTrrtd0/gDcNo836H+fPnc8cddzh/Li8vJyUlpROzFREREfEuOm/q/dx13qSgiYiIiIiXc9TiDQoK6uaZSGc4fn8NDQ0KmnihX/ziFyxZsoTVq1eTnJx8wm0TEhLIy8trcV9BQQG+vr7tnuDbbDZsNpvb5isiIiLibXTe5B3ccd5kdeeERERERKTnUmp576bfn3cyDINbb72VRYsWsXz5ctLT00+6z5QpU1i2bFmL+z755BMmTJjQZj8TEREREek4fe7u3dzx+1PQREREREREpJvccsst/P3vf+fNN98kNDSUvLw88vLyqKmpcW4zf/58rrnmGufPN998MwcOHOCOO+5gx44dvPbaa7z66qvceeed3fEURERERES8ioImIiIiIiIi3eSFF16grKyM6dOnk5iY6Lz961//cm6Tm5tLTk6O8+f09HQ+/PBDVq5cydixY3n00Uf54x//yKWXXtodT0FERERExKuop4mIiIiIyCm67rrrKC0tZfHixd09FenlHA3cT+SNN95odd+0adPYsGGDB2YkIiIiItJ5vfmcSZkmIiIiIiJdrKGhgbvvvptRo0YRHBxMUlIS11xzDUeOHOnuqYmIiIiIiPQIhmHw8MMPk5SURGBgINOnT2fbtm0eP66CJiIi3sDeBHUVUFkAJdmQvx0OrYfs1XBkE1QWQltXsjbWQU1p24+JiIjHVFdXs2HDBh544AE2bNjAokWL2LVrF9/73ve6e2oiIiLSEzTUmOdyhVk6XxORPuuJJ57g6aef5rnnnmPdunUkJCQwc+ZMKioqPHpclecSEempDAOqiqBk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RARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERARQ0ERERERERERERERERAQA31BPwGmWZQHQ2to6xDMRERERERkciXPfxLmwyKnouklERERETid9uWYacUGTtrY2AMrLy4d4JiIiIiIig6utrY3c3NyhnoakAF03iYiIiMjpqDfXTIY1wh5HM02Tw4cPk52djWEYg77/1tZWysvLqaysJCcnZ9D3P1LpuLpDx9UdOq7u0HF1h46rO3Rc3aHjemKWZdHW1saYMWPweFSBV05N100jk46rO3Rc3aHj6g4dV3fouLpDx9UdOq7H15drphGXaeLxeCgrKxvqaZCTk6NfShfouLpDx9UdOq7u0HF1h46rO3Rc3aHjenzKMJG+0HXTyKbj6g4dV3fouLpDx9UdOq7u0HF1h47rsXp7zaTH0ERERERERERERERERFDQREREREREREREREREBFDQxHHBYJCvf/3rBIPBoZ7KiKLj6g4dV3fouLpDx9UdOq7u0HF1h46ryMih/5/doePqDh1Xd+i4ukPH1R06ru7QcXWHjuvAjbhG8CIiIiIiIiIiIiIiIv2hTBMREREREREREREREREUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNBEREREREREREREREQEUNHHcL3/5SyZOnEhaWhoLFixg9erVQz2llHLbbbdx9tlnk52dTVFREe94xzvYsWNHj20sy+Ib3/gGY8aMIT09nTe/+c1s2bJliGacem677TYMw+Dmm29Ovqdj2n+HDh3i2muvJT8/n4yMDObPn8/atWuT39ex7btoNMpXv/pVJk6cSHp6OpMmTeKb3/wmpmkmt9FxPbXnn3+et73tbYwZMwbDMHjooYd6fL83xzAUCvGpT32KgoICMjMzueKKKzh48OAg/hTDz8mOayQS4Ytf/CJz584lMzOTMWPGcP3113P48OEeY+i4HutUv69H+9jHPoZhGNx+++093tdx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+fLl1mc+85nk1zqm/bNmzRrL5/NZ3/nOd6xdu3ZZ99xzj5WRkWHdfffdyW10bPvuhhtusMaOHWs98sgj1r59+6wHHnjAKigosL7whS8kt9FxPbW2tjZr/fr11vr16y3A+slPfmKtX7/eOnDggGVZvTuGN954o1VWVmY99dRT1rp166wLLrjAmjdvnhWNRofqxxpyJzuukUjEuuKKK6yysjJrw4YNPf6OhUKh5Bg6rsc61e/rfxo/frz1v//7vz3e03EVSQ26Zho4XTMNHl03DZyumdyhayZn6JrJHbpmcoeumQaXgiYO+8UvfmGNHz/eCgQC1llnnWWtWrVqqKeUUoDjvv7whz8ktzFN0/r6179ulZSUWMFg0DrvvPOsTZs2Dd2kU9B/nvzrmPbfww8/bM2ZM8cKBoPWjBkzrLvuuqvH93Vs+661tdX6zGc+Y40bN85KS0uzJk2aZN166609TqB0XE/t2WefPe6/pzfccINlWb07hl1dXdZNN91k5eXlWenp6dbll19uVVRUDMFPM3yc7Lju27fvhH/Hnn322eQYOq7HOtXv63863gWAjqtI6tA108Dommnw6LrJGbpmcp6umZyhayZ36JrJHbpmGlyGZVmWMzkrIiIiIiIiIiIiIiIiqUs9TURERERERERERERERFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBFDQREREREREREREREREBID/D+tfiyoHUWfMAAAAAElFTkSuQmCC", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -162,205 +145,97 @@ }, { "cell_type": "markdown", - "id": "5392f7f4-1825-4b15-9248-27eeecb1af3c", + "id": "01fa67c2-0126-4152-98a9-fa0df84c4629", "metadata": {}, "source": [ - "The GunPoint dataset is composed of two classes which are discriminated by the \"bumps\" located before and after the central peak. These bumps correspond to an actor drawing a fake gun from a holster before pointing it (hence the name \"GunPoint\" !). In the second class, the actor simply points his fingers without making the motion of taking the gun out of the holster.\n", + "## 1. Series estimators\n", "\n", - "Suppose that we define our input query for the similarity search task as one of these bumps:" + "First, we'll explore estimators of the `series` module, where you must provide single series of shape `(n_channels, n_timepoints)` during fit." ] }, { - "cell_type": "code", - "execution_count": 3, - "id": "a494a0be-4459-414d-9fc2-1400feefd171", + "cell_type": "markdown", + "id": "78f17f93-28b3-49c0-be5f-1d430a273b0c", "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], "source": [ - "# We will use the fourth sample an testing data\n", - "X_test = X[3]\n", - "mask = np.ones(X.shape[0], dtype=bool)\n", - "mask[3] = False\n", - "# Use this mask to exluce the sample from which we will extract the query\n", - "X_train = X[mask]\n", + "### 1.1 Subsequence nearest neighbors with MASS\n", "\n", - "q = X_test[:, 20:55]\n", - "plt.plot(q[0])\n", - "plt.show()" + "To perform nearest neighbors search on subsequences on a series, we can use the `MassSNN` estimator.\n", + "\n", + "It takes as parameter during initialisation :\n", + "- `length` : an integer giving the length of the subsequences to extract from the series. It is also the expected length of the series given in `predict`\n", + "- `normalize`: a boolean indicating wheter the subsequences should be independently z-normalized (`(X-mean(X))/std(X)`) before the distance computations. This results in a scale-independent matching.\n", + " \n", + "To parameterize the search, additional parameters are available when calling the `predict` method:\n", + "\n", + "- `k` (int) : the number of nearest neighbors to return.\n", + "- `dist_threshold` (float) : the maximum allowed distance for a candidate subsequence to be considered as a neighbor.\n", + "- `allow_trivial_matches` (bool) : wheter a neighbors of a match to a query can be also considered as matches (True), or if an exclusion zone is applied around each match to avoid trivial matches with their direct neighbors (False).\n", + "- `inverse_distance` (bool) : if True, the matching will be made on the inverse of the distance, and thus, the farther neighbors will be returned instead of the closest ones.\n", + "- `exclusion_factor` (float): A factor of the `length` used to define the exclusion zone when `allow_trivial_matches` is set to False. For a given timestamp, the exclusion zone starts from `id_timestamp - length//exclusion_factor` and end at `id_timestamp + length//exclusion_factor`.\n", + "- `X_index` (int): If series given during predict is a subsequence of series given during fit, specify its starting timestamp. If specified, neighboring subsequences of X won't be able to match as neighbors." ] }, { "cell_type": "markdown", - "id": "fcf10a34-930a-4fce-86f8-4dfa207cad11", + "id": "33105406-fc83-4143-9345-af589a06a00a", "metadata": {}, "source": [ - "Then, we can use the `QuerySearch` class to search for the top `k` matches of this query in a collection of series. The training data for `QuerySearch` can be seen as the database in which want to search for the query on." + "First, we'll select a series from the dataset to use during fit. This is the series we want our neighbors to come from." ] }, { "cell_type": "code", - "execution_count": 4, - "id": "80eaab8f-204f-439f-84c8-ad3462f1575e", + "execution_count": 3, + "id": "a494a0be-4459-414d-9fc2-1400feefd171", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "match 0 : [195 26] with distance 0.1973741999473598 to q\n", - "match 1 : [92 23] with distance 0.20753669049486048 to q\n", - "match 2 : [154 22] with distance 0.21538593730366784 to q\n" + "(1, 150)\n" ] } ], "source": [ - "from aeon.similarity_search import QuerySearch\n", + "from aeon.similarity_search.series import MassSNN\n", "\n", - "# Here, the distance function (distance and normalise arguments)\n", - "top_k_search = QuerySearch(k=3, distance=\"euclidean\")\n", - "# Call fit to store X_train as the database to search in\n", - "top_k_search.fit(X_train)\n", - "distances_to_matches, best_matches = top_k_search.predict(q)\n", - "for i in range(len(best_matches)):\n", - " print(f\"match {i} : {best_matches[i]} with distance {distances_to_matches[i]} to q\")" - ] - }, - { - "cell_type": "markdown", - "id": "3dc402cf-80b7-4d0c-b07c-2f8e7822ac97", - "metadata": {}, - "source": [ - "The similarity search estimators return a list of size `k`, which contains a tuple containing the location of the best matches as `(id_sample, id_timestamp)`. We can then plot the results as:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "23efe48e-8257-4ecc-93a2-d72f19024ab5", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABIkAAAE/CAYAAADCGZOXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAAsTAAALEwEAmpwYAACnOUlEQVR4nOzdeZicZZ3v//dTe1XvezqdpDv7vgAJOzGICKLEwCCoyARRcQOcmeNRRmb4MR4XRp0zjoOO5ojixqKgIKsKElkESQIBQvalk+50p/eu6q59eX5/VFd1d/al07V9XteViyRdqbqrSep+nu/9XQzTNE1ERERERERERKSgWTK9ABERERERERERyTwFiUREREREREREREEiERERERERERFRkEhERERERERERFCQSEREREREREREUJBIRERERERERERQkEiyTFNTE88++2ymlzFu7rvvPi688MJML0NEJGdonxARkaPRPiFyahQkkrx311138bGPfWzcXu/GG2/kX/7lX07Lc/f29nLVVVdRVFREY2Mj999//2l5HRGRQpJP+8Q999zD0qVLcTqd3HjjjaflNURECk2+7BPhcJhPfOITNDY2UlJSwpIlS3j66afH/HUkt9kyvQAROX6f//zncTgcdHR0sHHjRt7//vezePFi5s+fn+mliYhIFpg4cSL/8i//wh/+8AeCwWCmlyMiIlkkFosxefJk/vKXvzBlyhSeeuoprr32Wt5++22ampoyvTzJEsokkqyzbt065s2bR0VFBR//+McJhULprz3xxBMsWbKE8vJyzj//fN5666301/793/+dhoYGSkpKmD17Ns899xzPPPMM3/jGN3jooYcoLi5m8eLFh33NpqYmvv3tb7No0SKKior4xCc+QUdHB+973/soKSnhPe95D319fenHf+hDH2LChAmUlZWxfPly3nnnHQDWrFnDr371K771rW9RXFzMlVdeCUBLSwtXX301NTU1VFVVccstt4x6/S9+8YtUVFQwderUI0bz/X4/jzzyCP/n//wfiouLufDCC1m5ciW/+MUvTu4bLSKSo7RPHPnU9+qrr2bVqlVUVVWd+DdWRCRPaJ84/D5RVFTEXXfdRVNTExaLhQ984ANMnTqVDRs2nNw3WvKTKZJFGhsbzfnz55v79u0ze3p6zPPPP9+84447TNM0zddff92sqakxX331VTMWi5n33Xef2djYaIZCIXPr1q3mpEmTzP3795umaZp79uwxd+7caZqmaf5//9//Z15//fXHfN1zzjnHPHDggNna2mrW1NSYZ5xxhvn666+bwWDQvPjii8277ror/fh7773X9Pl8ZigUMr/whS+YixcvTn9t9erV6TWbpmnGYjFz0aJF5j/8wz+Yg4ODZjAYNF988UXTNE3zpz/9qWmz2cw1a9aYsVjM/MEPfmDW19ebiUTikDW+/vrrptvtHvV73/72t80PfOADJ/AdFhHJbdonjrxPjHTHHXeYq1evPu7vq4hIvtA+cXz7hGma5oEDB0yn02lu2bLl+L65UhCUSSRZ55ZbbmHy5MlUVlZyxx138MADDwDJqPqnP/1pzjnnHKxWK6tXr8bpdPLqq69itVoJh8Ns3ryZaDRKU1MT06dPP6HXvfXWW6mrq6OhoYGLLrqIc845hzPOOAOXy8VVV13FG2+8kX7sTTfdRElJCU6nk7vuuos333wTr9d72Od97bXXaGtr49vf/jZFRUW4XK5RzeUaGxv51Kc+lX5P7e3tdHR0HPI8g4ODlJaWjvq9srIyBgYGTuh9iojkOu0Th98nREQkSfvEsfeJaDTK9ddfz+rVq5kzZ84JvU/JbwoSSdaZPHly+ueNjY20tbUBsHfvXv7jP/6D8vLy9I+Wlhba2tqYMWMG3/3ud7nrrruora3lwx/+cPrPHa+6urr0z91u9yG/HhwcBCAej3P77bczffp0SktL0/W73d3dh33elpYWGhsbsdkO3wJswoQJ6Z97PB6A9GuNVFxcjM/nG/V7Pp+PkpKS43h3IiL5Q/vE4fcJERFJ0j5x9H0ikUhwww034HA4uOeee47vzUnBUJBIsk5LS0v65/v27WPixIlA8sP+jjvuoL+/P/0jEAjwkY98BICPfvSjvPTSS+zduxfDMPjyl78MgGEYY7q++++/n8cee4xnn30Wr9dLc3MzAKZpHvb1Jk+ezL59+4jFYqf0urNmzSIWi7Fjx47077355ptqWi0iBUf7hIiIHI32iSMzTTPdL+mRRx7Bbref8nNKflGQSLLO97//fVpbW+nt7eXrX/861113HQCf+tSn+OEPf8jf/vY3TNPE7/fz5JNPMjAwwLZt2/jzn/9MOBzG5XLhdruxWJJ/vevq6mhubiaRSIzJ+gYGBnA6nVRVVREIBPjKV74y6ut1dXXs3r07/euzzz6b+vp6br/9dvx+P6FQiJdffvmEX7eoqIirr76aO++8E7/fz8svv8xjjz3GDTfccMrvSUQkl2ifOLJYLEYoFCIejxOPxwmFQgo+iUjB0T5xZJ/97GfZsmULjz/+OG63+5Teh+QnBYkk63z0ox/lve99L9OmTWP69On8y7/8CwBLly7l//2//8ctt9xCRUUFM2bM4L777gMgHA5z++23U11dzYQJE+js7OSb3/wmkJwcAFBVVcWZZ555yuv7+7//exobG2loaGDevHmce+65o77+iU98gs2bN1NeXs6qVauwWq08/vjj7Ny5kylTpjBp0iQeeuihk3rtH/zgBwSDQWpra/nIRz7C//zP/yiTSEQKjvaJI/va176G2+3m7rvv5pe//CVut5uvfe1rp/yeRERyifaJw9u7dy8/+tGP2LhxIxMmTKC4uJji4mJ+9atfnfJ7kvxhmKmcNhERERERERERKVjKJBIREREREREREQWJREREREREREREQSIREREREREREUFBIhERERERERERQUEiEREREREREREBbJlewJFUV1fT1NSU6WWIiGSl5uZmuru7M72MjNI+ISJyZNontE+IiBzJ0faIrA0SNTU1sX79+kwvQ0QkKy1dujTTS8g47RMiIkemfUL7hIjIkRxtj1C5mYiIiIiIiIiIKEgkIiIiIiIiIiIKEomIiIiIiIiICFnck+hwotEora2thEKhTC9FsojL5WLSpEnY7fZML0VEROS00XWQHI6ug0REZCzlVJCotbWVkpISmpqaMAwj08uRLGCaJj09PbS2tjJ16tRML0dEROS00XWQHEzXQSIiMtZyqtwsFApRVVWlCyNJMwyDqqoqnaqKiEje03WQHEzXQSIiMtZyKkgE6MJIDqG/EyIiUii058nB9HdCRETGUs4FiTKpubmZBQsWnPLzrF27lr/+9a9jsKJD3XfffbS1tR3zMbfccssxn2vFihWsX79+rJbGxo0beeqpp9K//v3vf8/dd989Zs8vIiIip4+ug06NroNERCQXKEiUAZm+OMqUgy+OVq5cye23357BFYmIiMh403VQkq6DREQkG+VU42qAu9beNX6vteLQ14rFYlx//fW8/vrrzJ8/n5///Od4PB42bNjAP/3TPzE4OEh1dTX33Xcf9fX1fO973+OHP/whNpuNefPmcffdd/PDH/4Qq9XKL3/5S/77v/+biy66aPg177qLPXv2sHv3bvbt28d//ud/8uqrr/L000/T0NDA448/jt1u56tf/SqPP/44wWCQ888/nx/96Ec88sgjrF+/nuuvvx63280rr7zCpk2b+MIXvoDf78fpdPLcc88B0NbWxuWXX86uXbu46qqr+Na3vnXU78UDDzzAN77xDUzT5P3vfz///u//DsAzzzzDV77yFeLxONXV1Tz33HO89tprfOELXyAUCuF2u/npT3/K1KlTufPOOwkGg7z00kv88z//M8FgkPXr13PPPffQ3NzMTTfdRHd3NzU1Nfz0pz9lypQp3HjjjZSWlrJ+/XoOHDjAt771La655pqx+598DPGEyVut/ezsHKSlL0g8kcDAoNRto8xtpz8QpXswTDiWIBpPEImZJEyTulIXTVUeGquKmFLlwWmzYLMYlHsc47Z2ERHJrEgsQYcvRIcvxAFfiAPe5I++QJSJ5S4mVbgxTUiYMK2miLn1pZS5jz6hStdBug4az+sgkULR0hvgD+8cYOuBAcrcdiqLHFR4HJS6bVgMA7vVQoXHTpnbjmEY2CwGZW47pW47VotKPiW/5FyQKNO2bdvGvffeywUXXMBNN93ED37wA77whS9w66238thjj1FTU8NDDz3EHXfcwU9+8hPuvvtu9uzZg9PppL+/n/Lycj7zmc9QXFzMF7/4xcO+xq5du3j++efZvHkz5513Ho888gjf+ta3uOqqq3jyySdZtWoVt9xyC3feeScAN9xwA0888QTXXHMN99xzD9/5zndYunQpkUiE6667joceeohly5bh8/lwu91A8jTrjTfewOl0Mnv2bG699VYmT5582PW0tbXx5S9/mQ0bNlBRUcF73/teHn30US644AI+9alP8cILLzB16lR6e3sBmDNnDi+++CI2m41nn32Wr3zlKzzyyCN89atfTV8MQfK0L+XWW29l9erVrF69mp/85CfcdtttPProowC0t7fz0ksvsXXrVlauXDlmF0eRWII93X52dQ0yGI4RjiUIR+OEonFC0QRdA2Ge29pB92BkTF4PYM6EElad0cCFM6qZPaEEu1XJfCIiucobiPKnLR28squHrsEw3mAUTJNI3KRrIHTC+4dhwLtm1XD9OY1cMqcWSxbeeOg6KH+ug0QEovEE//K7TTy0vuWk/rzDamFOfQlzJpRQ7nFQ7rEzvaaYGbXFNFZ6sOlaX3KQgkQnaPLkyVxwwQUAfOxjH+N73/sel19+OZs2beLSSy8FIB6PU19fD8CiRYu4/vrrWbVqFatWrTqu13jf+96H3W5n4cKFxONxLr/8cgAWLlxIc3MzAM8//zzf+ta3CAQC9Pb2Mn/+fK688spRz7Nt2zbq6+tZtmwZAKWlpemvXXLJJZSVlQEwb9489u7de8SLo3Xr1rFixQpqamoAuP7663nhhRewWq0sX748PXK1srISAK/Xy+rVq9mxYweGYRCNRo/5nl955RV++9vfAsmLvS996Uvpr61atQqLxcK8efPo6Og45nMdiS8U5Scv7eE361vpD0QIROOY5rH/XGOVh8WTymkcygiKJ5LP5Q1GKXPbqS524nFYsVmTpwwG0NYfYm+Pn729AVp6A8QTJoFInK0HBrj76a0AuOwW3j2nlmvOmsS7ZtXqFEJEJAe09gX4y/Yuntl0gFd29RBLHHkjsVoMaoqdTChzMaHUxYQyF3WlLsrcdtr6g7R5g9gtFmIJkx2dA2xp97F2Wxdrt3Vx/vQqvvOhxUwsd4/juzs2XQfl7nWQiIzmD8f47K9e54XtXThtFt4zr45zp1URjMTo9Ufp80fwhaKYJkTiCXqHfg3J4JI3EMUXivFWq5e3Wr2HPL/dajC5wkOxK1mBMGdCCTNrS7BZDdx2K2c1VVBb4hrvty1yTAoSnaCDJ0gYhoFpmsyfP59XXnnlkMc/+eSTvPDCCzz++ON8/etf5+233z7mazidTgAsFgt2uz39mhaLhVgsRigU4nOf+xzr169n8uTJ3HXXXSc8+jT1GgBWq5VYLHZCf/5o/vVf/5WLL76Y3/3udzQ3N7NixYpTer6RazWPJ6pzENM0eeC1Fv79ma3JU94hhpEMAM2sLabUbcdlt+KyWXHZLbjsVjwOK+dNr2JefemYTA6JxBKs3dbJ05sOsLGlnz3dfp56+wBPvX2AxioPn14+navOaMDtsJ7ya4mIyIkzTZMef4T9fUHa+oPs7w/S2hfkgDdEfzDC/v4gLb3B9OOtFoMLZlRx6dw6plR5KHM7sFoMrIZBbamT6mLnCR0A9PojPLKhlR/+ZRd/3dXD5d99gZ/ddDZnTKk4HW/3pOg66Niy7TpIRA7vq49v5oXtXVQWOfjpjctYPLn8hJ/DF4ryzn4fu7sHGQjF6BoIs6trkB0dg+zvD7K7259+7Is7ug/58/PqS7nj/XO5YEb1qbwVkTGlINEJ2rdvH6+88grnnXce999/PxdeeCGzZ8+mq6sr/fvRaJTt27czd+5cWlpauPjii7nwwgt58MEHGRwcpKSkBJ/Pd9JrSF0IVVdXMzg4yMMPP5xOPS4pKWFgYACA2bNn097ezrp161i2bBkDAwPpNOsTcfbZZ3PbbbfR3d1NRUUFDzzwALfeeivnnnsun/vc59izZ086zbqyshKv10tDQwMwOpV65NoOdv755/Pggw9yww038Ktf/WpUf4JT0TMY5rYH3+DlnT0AnDO1kn94zywWTirDZbOMawqow2bhvfMn8N75EwBo9wb53Rv7eeC1feztCfCV373NN57awvsX1nPbe2bSkGWnxyIi+aatP8gb+/p5Y18fb7T0s7nNRzAaP+qfKXHZOHdaFZfOq+PSuXVUFI1dr7nKIgefWj6NVWc08KWH3+T5bV186eG3eOoLF2VNebKug3LrOkhEDi+RMPnD5gMA/Pyms1nQUHZSz1PqsnPe9CrOm151yNcCkRitfUECkThdA2E2t/nY2+PHBLoHw6xv7mNzu4/rf/w3PnL2ZM6ZWkVdqYv6smTmqcuug2PJDAWJTtDs2bP5/ve/z0033cS8efP47Gc/i8Ph4OGHH+a2227D6/USi8X4h3/4B2bNmsXHPvYxvF4vpmly2223UV5ezpVXXsk111zDY489dkjDxuNRXl7Opz71KRYsWMCECRPSadQAN954I5/5zGfSDRsfeughbr31VoLBIG63m2efffaE33N9fT133303F198cbph4wc/+EEA1qxZw9VXX00ikaC2tpY//elPfOlLX2L16tV87Wtf4/3vf3/6eS6++GLuvvtulixZwj//8z+Peo3//u//5uMf/zjf/va30w0bx8Idv9vEyzt7qCxy8G8r5/OBRfVjkhU0FurL3HxuxQxuvmgaT206wL0v7eHNln4eWt/Cy7u6eeSz51NXqhRUEZGx1OuP8IPnd/LnrZ2jTnhTSl02Gio8NJS7aSh30VDhpr7MTVWRg6piJzNqi097eXBNiZP/+dhZXPbdF9jROchPX97Dzcunn9bXPF66Dsqt6yARObzN7T76A1Eayt3Mn1h67D9wEjwOG7PqStK/vnRe3aivh2NxfvSX3Xzv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nmBCmZtIPMLGAxuZXjmdSaWTSJgJtnRtIWEmME2THZ3JAFGZ2860pireec9CfDWluG1uLptxGYvrFivwK2NmRm0x/+vSWXzz6a185bdv84d/XE6pS2Vnkt+6A910+jvpDfbSF+yjL9RHX7CPQDRAJB7B5Pg6igyEouzrDdA9ECEYjTMQihLrGuCGjXtJmFBd7GRSRbIdhf/MBVx1EgH+u9bedcJ/5mTdteL0vNbatWspLi4+bUGiBQsWHDVIlCkbN25k/fr16SDRypUrWblyZYZXdeLev7Ceh2a28OKObn74l13c8X71vjwa1XYUkNfbX2dnb3LKzOZ2H5O2tmG3WmgY+uD32D00TFsM06YBUOQo4mOLPsal0y7FaU1GW4tdNmbVJbM8bBYbfzf376hUgEhOUonLzqozGnjmC8v56ceX8dFzptBQ7iaeMGn3hhgIxbBaDELRBLu6/Pxxcwffe24H7/vui/znn7YTjsUz/RZE8sKWri10DnYwb+07dO/rpcMXxjBgVl0xZ0+tZEplcvpYc0+A3V2DJBImJiY7e3fS6mulub85PS2ztS+YHmxQPbee11cuxVdTyln1Z3HL2bewZMISBYhkzH3yomksmVxOuzfEN57ckunliJx2a5vX8ut3fs2zu59lQ/sGdvftpi/URzgePmyAyDRN+vwRtncM8Ned3Ty2cT8/fnE39760hz9t7uCNlj62HvDR3uvn8reb8VgMZtWVMKO2GIthkHA6uOgDn8duzb0AbCwW4/rrr2fu3Llcc801BAIBADZs2MC73vUuzjrrLC677DLa29sB+N73vse8efNYtGgRH/7wh2lubuaHP/wh//mf/8mSJUt48cUXRz3/XXfdxerVq7noootobGzkt7/9LV/60pdYuHAhl19+OdFoMmvrq1/9KsuWLWPBggXcfPPNmKbJww8/zPr167n++utZsmQJwWCQdevWcf7557N48WLOPvtsBgaSvWDb2tq4/PLLmTlz5nFNgX3ggQdYuHAhCxYs4Mtf/nL695955hnOPPNMFi9ezCWXXALAa6+9xnnnnccZZ5zB+eefz7Zt24hEItx555089NBDLFmyhIceeoj77ruPW265BUhmab373e9m0aJFXHLJJezbtw+AG2+8kdtuu43zzz+fadOm8fDDD5/K/74xYRgG//uy2QA8+FoLA6EjZ9KJMokK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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plot_best_matches(top_k_search, best_matches)" + "length = 35\n", + "# We'll take a sample of the class with a \"bump\".\n", + "series_fit = X[2]\n", + "print(series_fit.shape)\n", + "snn = MassSNN(length=length, normalize=False).fit(series_fit)" ] }, { "cell_type": "markdown", - "id": "877b1b32-d978-4c54-a4e7-b475496f710a", + "id": "320ef728-ca92-4fd5-9686-2b9739fcab83", "metadata": {}, "source": [ - "You may also want to search not for the top-k matches, but for all matches below a threshold on the distance from the query to a candidate. To do so, you can use the `threshold` parameter of `QuerySearch` :" + "Then we'll take a subsequence of size `length` in another series of the same class to use in `predict` :" ] }, { "cell_type": "code", - "execution_count": 6, - "id": "23ad7adb-2b01-4425-a2e8-c393f3721a0f", + "execution_count": 4, + "id": "98560db4-4289-4072-8662-2cde2ad5c44a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "match 0 : [195 26] with distance 0.1973741999473598 to q\n", - "match 1 : [92 23] with distance 0.20753669049486048 to q\n", - "match 2 : [154 22] with distance 0.21538593730366784 to q\n", - "match 3 : [176 25] with distance 0.21889484294879047 to q\n", - "match 4 : [23 20] with distance 0.22668346183441293 to q\n", - "match 5 : [167 23] with distance 0.24774491003815066 to q\n" + "match 0 : 27 with distance 0.3020071566139322\n", + "match 1 : 28 with distance 0.48913603040398357\n", + "match 2 : 26 with distance 0.889697094966067\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\antoine\\Documents\\aeon\\aeon\\similarity_search\\query_search.py:270: UserWarning: Only 6 matches are bellow the threshold of 0.25, while k=inf. The number of returned match will be 6.\n", - " return extract_top_k_and_threshold_from_distance_profiles(\n" - ] - } - ], - "source": [ - "# Here, the distance function (distance and normalise arguments)\n", - "top_k_search = QuerySearch(k=np.inf, threshold=0.25, distance=\"euclidean\")\n", - "top_k_search.fit(X_train)\n", - "distances_to_matches, best_matches = top_k_search.predict(q)\n", - "for i in range(len(best_matches)):\n", - " print(f\"match {i} : {best_matches[i]} with distance {distances_to_matches[i]} to q\")" - ] - }, - { - "cell_type": "markdown", - "id": "0efd83a5-b36f-4809-be96-94de734d931c", - "metadata": {}, - "source": [ - "You may also combine the `k` and `threshold` parameter :" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "65db1593-3873-4a47-9e2a-d8dfcf42dd1a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "match 0 : [195 26] with distance 0.1973741999473598 to q\n", - "match 1 : [92 23] with distance 0.20753669049486048 to q\n", - "match 2 : [154 22] with distance 0.21538593730366784 to q\n" - ] - } - ], - "source": [ - "# Here, the distance function (distance and normalise arguments)\n", - "top_k_search = QuerySearch(k=3, threshold=0.25, distance=\"euclidean\")\n", - "top_k_search.fit(X_train)\n", - "distances_to_matches, best_matches = top_k_search.predict(q)\n", - "for i in range(len(best_matches)):\n", - " print(f\"match {i} : {best_matches[i]} with distance {distances_to_matches[i]} to q\")" - ] - }, - { - "cell_type": "markdown", - "id": "ff62a385-d58e-4fb1-95dd-eb0474711531", - "metadata": {}, - "source": [ - "It is also possible to return the **worst** matches (not that the title of the plots are not accurate here) to the query, by using the `inverse_distance` parameter :" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "6d6078ab-9104-462e-9856-1d0fc9594b24", - "metadata": {}, - "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABIkAAAE/CAYAAADCGZOXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAAsTAAALEwEAmpwYAAClSUlEQVR4nOzdd5xddZ0//tc5t9fpLTOTOklIAiGEgdCLomiQUEQQEUGaWFDXn7vi6rLoWlB3v+sqKEQpKggoKIhIESRSQ0hCei+TTE2m3t7OPef3x7nn3Htn7qTM3Ln19Xw8WCd3bvnMbHLen/P+vD/vj6AoigIiIiIiIiIiIiprYr4HQERERERERERE+cckERERERERERERMUlERERERERERERMEhEREREREREREZgkIiIiIiIiIiIiMElERERERERERERgkogKzMyZM/HKK6/kexg588gjj+Ccc87J9zCIiIoG4wQRER0J4wTR5DBJRCXv7rvvxqc//emcfd6NN96Ib3/721Py3kNDQ7jiiivgcDgwY8YM/P73v5+SzyEiKielFCfuvfdetLe3w2Kx4MYbb5ySzyAiKjelEicikQhuvvlmzJgxAy6XC0uWLMELL7yQ9c+h4mbM9wCI6Nh98YtfhNlsxqFDh7BhwwZccsklOPnkk7Fo0aJ8D42IiArAtGnT8O1vfxsvvfQSQqFQvodDREQFRJIktLa24p///CemT5+Ov/3tb7j66quxefNmzJw5M9/DowLBSiIqOO+99x4WLlyIqqoqfPazn0U4HNa/99e//hVLlixBZWUlzjrrLGzatEn/3o9+9CM0NzfD5XJh/vz5ePXVV/Hiiy/iBz/4AZ588kk4nU6cfPLJGT9z5syZ+MlPfoLFixfD4XDg5ptvxqFDh/DRj34ULpcLF110EYaHh/Xnf+ITn0BjYyMqKipw3nnnYevWrQCAlStX4rHHHsOPf/xjOJ1OXHrppQCAzs5OXHnllairq0NNTQ2+9KUvpX3+17/+dVRVVWHWrFnjZvMDgQCefvpp/Nd//RecTifOOeccrFixAr/73e8m9osmIipSjBPjr/peeeWVuPzyy1FTU3P8v1giohLBOJE5TjgcDtx9992YOXMmRFHExz72McyaNQvr1q2b2C+aSpNCVEBmzJihLFq0SDl48KAyODionHXWWcq3vvUtRVEUZf369UpdXZ2yevVqRZIk5ZFHHlFmzJihhMNhZceOHUpLS4vS3d2tKIqi7N+/X9mzZ4+iKIryn//5n8p111131M9dtmyZ0tfXp3R1dSl1dXXKKaecoqxfv14JhULKhRdeqNx999368x988EHF6/Uq4XBY+cpXvqKcfPLJ+vduuOEGfcyKoiiSJCmLFy9WvvrVryp+v18JhULKG2+8oSiKojz88MOK0WhUVq5cqUiSpPziF79QmpqaFFmWx4xx/fr1is1mS3vsJz/5ifKxj33sOH7DRETFjXFi/DiR6lvf+pZyww03HPPvlYioVDBOHFucUBRF6evrUywWi7J9+/Zj++VSWWAlERWcL33pS2htbUV1dTW+9a1v4fHHHwegZtU/97nPYdmyZTAYDLjhhhtgsViwevVqGAwGRCIRbNu2DbFYDDNnzsScOXOO63PvuOMONDQ0oLm5Geeeey6WLVuGU045BVarFVdccQXef/99/bk33XQTXC4XLBYL7r77bmzcuBEejyfj+65ZswY9PT34yU9+AofDAavVmtZcbsaMGbj11lv1n6m3txeHDh0a8z5+vx9utzvtsYqKCvh8vuP6OYmIih3jROY4QUREKsaJo8eJWCyG6667DjfccANOOOGE4/o5qbQxSUQFp7W1Vf96xowZ6OnpAQAcOHAA//M//4PKykr9v87OTvT09KCtrQ0//elPcffdd6O+vh6f/OQn9dcdq4aGBv1rm8025s9+vx8AEI/Hceedd2LOnDlwu936/t2BgYGM79vZ2YkZM2bAaMzcAqyxsVH/2m63A4D+WamcTie8Xm/aY16vFy6X6xh+OiKi0sE4kTlOEBGRinHiyHFClmVcf/31MJvNuPfee4/th6OywSQRFZzOzk7964MHD2LatGkA1Iv9t771LYyMjOj/BYNBXHvttQCAT33qU3jzzTdx4MABCIKAb3zjGwAAQRCyOr7f//73ePbZZ/HKK6/A4/Ggo6MDAKAoSsbPa21txcGDByFJ0qQ+d968eZAkCbt379Yf27hxI5tWE1HZYZwgIqIjYZwYn6Ioer+kp59+GiaTadLvSaWFSSIqOPfddx+6urowNDSE73//+7jmmmsAALfeeivuv/9+vPvuu1AUBYFAAM8//zx8Ph927tyJf/zjH4hEIrBarbDZbBBF9a93Q0MDOjo6IMtyVsbn8/lgsVhQU1ODYDCIf//3f0/7fkNDA/bt26f/+fTTT0dTUxPuvPNOBAIBhMNhvPXWW8f9uQ6HA1deeSXuuusuBAIBvPXWW3j22Wdx/fXXT/pnIiIqJowT45MkCeFwGPF4HPF4HOFwmMknIio7jBPj+/znP4/t27fjueeeg81mm9TPQaWJSSIqOJ/61Kfw4Q9/GLNnz8acOXPw7W9/GwDQ3t6OX/3qV/jSl76EqqoqtLW14ZFHHgEARCIR3HnnnaitrUVjYyMOHz6MH/7whwDUkwMAoKamBkuXLp30+D7zmc9gxowZaG5uxsKFC3HGGWekff/mm2/Gtm3bUFlZicsvvxwGgwHPPfcc9uzZg+nTp6OlpQVPPvnkhD77F7/4BUKhEOrr63Httdfil7/8JSuJiKjsME6M73vf+x5sNhvuuecePProo7DZbPje97436Z+JiKiYME5kduDAATzwwAPYsGEDGhsb4XQ64XQ68dhjj036Z6LSIShaTRsREREREREREZUtVhIRERERERERERGTRERERERERERExCQRERERERERERGBSSIiIiIiIiIiIgKTREREREREREREBMCY7wGMp7a2FjNnzsz3MIiIClJHRwcGBgbyPYy8YpwgIhof4wTjBBHReI4UIwo2STRz5kysXbs238MgIipI7e3t+R5C3jFOEBGNj3GCcYKIaDxHihHcbkZEREREREREREwSERERERERERERk0RERERERERERIQC7klEVG5isRi6uroQDofzPRQqIFarFS0tLTCZTPkeChHlGeMEZcI4QUQaxgkabSIxgkkiogLR1dUFl8uFmTNnQhCEfA+HCoCiKBgcHERXVxdmzZqV7+EQUZ4xTtBojBNElIpxglJNNEZwuxlRgQiHw6ipqeEFnXSCIKCmpoarQUQEgHGCxmKcIKJUjBOUaqIxgpVEVJJkRUYgGoDD7IAoFE8ulBd0Go1/J4imRlyOIxALwGV2FdW/s2IaK+UG/04QTY1QLISQFIIoiDCKRlgMFpgMhb+tk9cESjWRvw9MElFJGAoNodfXC0/Eg4Oeg9g7tBcxOQazwYyFdQuxpHEJau21cJgcvHCOo6OjAx/72MewZcuWSb3PqlWrYDabcdZZZ2VpZEmPPPIIPvzhD2PatGlHfM7atWtx7733HvG9LrjgAvz3f/832tvbszK2DRs2oKenB8uXLwcA/OUvf8G2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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABk0AAAHBCAYAAADEufzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD870lEQVR4nOzdeZxcZZU//s9da+81SXdnX0gChLAIKkERArK6jYLLfBlBHMZBQEcBUVwRZkYRRyMy6I9RQRBHxmERkVEQCcygKEsiYYeQfeskvVR1bXd7fn/cqlv3dnfSWbqqblV93q9Xv151q2+ln2zdp57znHMkIYQAERERERERERERERFRi5PrvQAiIiIiIiIiIiIiIqIwYNKEiIiIiIiIiIiIiIgITJoQEREREREREREREREBYNKEiIiIiIiIiIiIiIgIAJMmREREREREREREREREAJg0ISIiIiIiIiIiIiIiAsCkCREREREREREREREREQAmTYiIiIiIiIiIiIiIiAAwaUJERERERERERERERASASROi0LjmmmsgSRJ27dpV0697880347bbbqvp19wXf/zjH3HNNddgaGjogF5/8skn44gjjjioNfz+97/HsmXLEI/HMWXKFHzsYx9Df3//Qf2aREREYcVYJKjescgDDzyA888/H0uXLoWmaZAk6YB/LSIiokbAWCSonrFIOp3Gv/zLv+Dkk09Gb28vkskkli5diuuvvx6FQuGAfk2iRsKkCVGLC3Nw8PWvf/2Ag4OD9dhjj+Gss85CT08PfvWrX+F73/sefv/73+PUU09FsVisy5qIiIiaEWOR8d1777148skncfjhh+Ooo46qyxqIiIhaAWORsTZu3IgVK1bgTW96E2655Rbcf//9OPfcc3HNNdfg3e9+N4QQNV8TUS2p9V4AEVEYfe5zn8OiRYvw3//931BV91vlvHnz8La3vQ0/+clP8MlPfrLOKyQiIqJm9h//8R+QZfeM22WXXYZnnnmmzisiIiKiVjFv3jysX78eiUTCe+6UU05BIpHA5z73OTzxxBN4+9vfXscVElUXK02IQmbTpk34wAc+gLa2NrS3t+Pv/u7vsHPnzjH33XXXXVi2bBkSiQSSySTOOOMMrFq1KnDPG2+8gY985COYPn06IpEIenp6cOqpp2L16tUAgLlz5+KFF17AY489BkmSIEkS5s6du9f1SZKEyy67DLfeeisWL16MWCyG4447Dk8++SSEELjhhhswb948JJNJnHLKKXj99dcDr3/44Yfxvve9DzNnzkQ0GsUhhxyCf/zHfwyU315zzTX43Oc+B8D9QV1e28qVK717fv7zn2PZsmVIJpNIJpM4+uij8eMf/3jMep966imceOKJiMfjmD9/Pr75zW/CcZy9/h63bNmCp556Ch/96Ee9hAkAnHDCCVi0aBHuvffevb6eiIiokTEWqX8sAsBLmBAREbUaxiL1j0USiUQgYVL2lre8BYD7d0TUzFhpQhQy73//+/GhD30IF198MV544QV85StfwYsvvog///nP0DQNAPCv//qv+PKXv4wLL7wQX/7yl2EYBm644QaceOKJ+Mtf/oLDDz8cAHD22WfDtm1861vfwuzZs7Fr1y788Y9/9Eo77733Xpx77rlob2/HzTffDACIRCITrvGBBx7AqlWr8M1vfhOSJOHzn/883vWud+GCCy7AG2+8gZtuugnDw8O4/PLLcc4552D16tVeH+61a9di2bJluOiii9De3o7169fjO9/5Dt7+9rdjzZo10DQNF110EQYGBvD9738f99xzD/r6+gDA+3199atfxXXXXYcPfOADuOKKK9De3o7nn38eGzZsCKxz+/btOO+883DFFVfga1/7Gu69915cffXVmD59Os4///w9/v6ef/55AMCRRx455nNHHnkknnjiiQn/jIiIiBoVY5H6xyJEREStjLFIeGORP/zhDwCAJUuW7PdriRqKIKJQ+NrXviYAiM9+9rOB5++8804BQPzsZz8TQgixceNGoaqq+NSnPhW4L5PJiN7eXvGhD31ICCHErl27BACxYsWKvX7dJUuWiJNOOmmf1wlA9Pb2ipGREe+5++67TwAQRx99tHAcx3t+xYoVAoB47rnnxv21HMcRpmmKDRs2CADiV7/6lfe5G264QQAQ69atC7zmjTfeEIqiiPPOO2+v6zzppJMEAPHnP/858Pzhhx8uzjjjjL2+tvxn/qc//WnM5z7xiU8IXdf3+noiIqJGxFgkPLHIaJdeeqngWzciImp2jEXCG4sIIcRf//pXEYvFxPvf//79fi1Ro2HNN1HInHfeeYHrD33oQ1BVFY8++igA4He/+x0sy8L5558Py7K8j2g0ipNOOskr1ezq6sKCBQtwww034Dvf+Q5WrVq1T60g9sXy5csDZZqHHXYYAOCss87yTk74n/efdOjv78fFF1+MWbNmQVVVaJqGOXPmAABeeumlCb/2ww8/DNu2cemll054b29vr1c6WnbkkUeOOXmxJ/7fy748T0RE1AwYi+xdLWMRIiKiVsRYZO/qEYusX78e7373uzFr1iz86Ec/2q/XEjUituciCpne3t7Ataqq6O7uxu7duwEAO3bsAAC8+c1vHvf15f7XkiThkUcewbXXXotvfetbuOKKK9DV1YXzzjsP//Iv/4JUKnXAa+zq6gpc67q+1+cLhQIAwHEcnH766di6dSu+8pWvYOnSpUgkEnAcB8cffzzy+fyEX7vcx3TmzJkT3tvd3T3muUgkMuHXKb+u/GfuNzAwMOb3SURE1EwYi+xdLWIRIiKiVsZYZO9qHYts2LABy5cvh6qqeOSRR7gnQi2BSROikNm+fTtmzJjhXVuWhd27d3s/6KZMmQIA+O///m/vJMKezJkzxxsC9uqrr+K//uu/cM0118AwDPzwhz+s0u9gz55//nn89a9/xW233YYLLrjAe370ULS9mTp1KgBg8+bNmDVr1qSvEQCOOOIIAMCaNWtw9tlnBz63Zs0a7/NERETNiLHI3tUiFiEiImpljEX2rpaxyIYNG3DyySdDCIGVK1fuU6KGqBkwaUIUMnfeeSeOPfZY7/q//uu/YFkWTj75ZADAGWecAVVVsXbtWpxzzjn7/OsuWrQIX/7yl3H33Xfj2Wef9Z6v5WnHconq6KFq/9//9/+Nubd8z+i1nX766VAUBT/4wQ+wbNmyqqxzxowZeMtb3oKf/exnuPLKK6EoCgDgySefxCuvvILPfOYzVfm6REREYcBYBIF76hGLEBERtTLGIgjcU69YZOPGjTj55JNh2zZWrlw5YYKKqJkwaUIUMvfccw9UVcVpp52GF154AV/5yldw1FFH4UMf+hAAYO7cubj22mvxpS99CW+88QbOPPNMdHZ2YseOHfjLX/6CRCKBr3/963juuedw2WWX4YMf/CAWLlwIXdfxhz/8Ac899xy+8IUveF9v6dKl+MUvfoG77roL8+fPRzQaxdKlS6vyezv00EOxYMECfOELX4AQAl1dXfj1r3+Nhx9+eMy95TV873vfwwUXXABN07B48WLMnTsXX/ziF3Hdddchn8/jb//2b9He3o4XX3wRu3btwte//vVJWev111+P0047DR/84AdxySWXoL+/H1/4whdwxBFH4MILL5yUr0FERBRGjEUq6wLqF4ts2LABTz31FABg7dq1ANwTtYD7d3DcccdNytchIiIKG8YilXUB9YlF+vv7sXz5cmzbtg0//vGP0d/fj/7+fu/zM2fOZNUJNbf6zqEnorKvfe1rAoB45plnxHve8x6RTCZFKpUSf/u3fyt27Ngx5v777rtPLF++XLS1tYlIJCLmzJkjzj33XPH73/9eCCHEjh07xMc+9jFx6KGHikQiIZLJpDjyyCPFd7/7XWFZlvfrrF+/Xpx++ukilUoJAGLOnDl7XScAcemllwaeW7dunQAgbrjhhsDzjz76qAAgfvnLX3rPvfjii+K0004TqVRKdHZ2ig9+8INi48aNAoD42te+Fnj91VdfLaZPny5kWRYAxKOPPup97vbbbxdvfvObRTQaFclkUhxzzDHi1ltv9T5/0kkniSVLloxZ/wUXXDDh77HsoYceEscff7yIRqOiq6tLnH/++eP+XRARETUDxiLhikVuvfVWAWDcjwsuuGDC1xMRETUaxiLhiUXK697Tx+h1EjUbSQghqp2YISIiIiIiIiIiIiIiCju53gsgIiIiIiIiIiIiIiIKAyZNiIiIiIiIiIiIiIiIwKQJERERERERERERERERACZNiIiIiIiIiIiIiIiIADBpQkREREREREREREREBIBJEyIiIiIiIiIiIiIiIgCAWu8FTDbHcbB161akUilIklTv5RAREYWCEAKZTAbTp0+HLPPMRLUxHiEiIgpiLFJbjEWIiIiC9icWabqkydatWzFr1qx6L4OIiCiUNm3ahJkzZ9Z7GU2P8QgREdH4GIvUBmMRIiKi8e1LLNJ0SZNUKgXA/c23tbXVeTVEREThkE6nMWvWLO/nJFUX4xEiIqIgxiK1xViEiIgoaH9ikaZLmpTLTtva2hgYEBERjcL2DLXBeISIiGh8jEVqg7EIERHR+PYlFmEjUSIiIiIiIiIiIiIiIjBpQkREREREREREREREBIBJEyIiIiIiIiIiIiIiIgBMmhAREREREREREREREQFg0oSIiIiIiIiIiIiIiAgAkyZEREREREREREREREQAmDQhIiIiIiIiIiIiIiICwKQJERERERERERERERERACZNiIiIiIiIiIiIiIiIADBpQkRERERERERERERE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4h/+4R+wdu1a/Od//ic2b96M6dOnAwCuvPJK/Pa3v8Wtt96Kf/3Xf8XGjRtxzjnnYOnSpQCA+fPne792V5d7gnjatGkT9s40TRM/+MEPsGDBAgDAueeeizvuuAM7duxAMpnE4YcfjuXLl+PRRx/1frh9/OMf914/f/583HjjjXjLW96CkZERJJPJcb9+JpPB9773Pdx000244AK3r+mCBQvw9re/PbCeK6+8Eu9617sAAF//+texZMkSvP766zj00EMn/DO98847kc/ncfvtt3t9NG+66Sa85z3vwfXXX4+enh788z//M6644gr80z/9k/e6N7/5zd5j/yC6efPm4brrrsMnP/lJ3HzzzdB1He3t7ZAkCb29vXtcx+9//3s899xzWLduHWbNmgUAuOOOO7BkyRI89dRT3tdzHAe33XYbUqW5Ah/96EfxyCOPjDllQkS0rzJG5VSWPZz3HutKMGkS65xWszVRdSiSBBvuZpQjhHegY38wFmEswliEiCbNOJUm5X2REU3FTFaaNB1FlmCVDpI6AlD2PxRhLALGIvWIRVhpQlRjxtDuymOrUrKnqzKKviHwB7LBTuHib9F1oMUmxx9/fODfwrJly/Daa6/Btm08++yzEEJg0aJFSCaT3sdjjz2GtWvXAgA+/elP45//+Z/xtre9DV/72tfw3HPPHdA64vG4FxgAQE9PD+bOnYtkMhl4rlxmCgCrVq3C+973PsyZMwepVAonn3wyALf0ck9eeuklFItFnHrqqXtdz5FHHuk97uvrA4DA196bl156CUcddVRg8Njb3vY2OI6DV155Bf39/di6dete1/Doo4/itNNOw4wZM5BKpXD++edj9+7dyGaz+7SG8jpmzZrlBQYAcPjhh6OjowMvvfSS99zcuXO9wKD8+93X3ysR0Xj8lSaOL2kS8VWaaLIGpa29puuiySf7Y5EDDEYYi4yPsQhjESI6AONUmpQ7cIxEgu25FElBXIvXdn006QKtyxmLMBYZZx1hjUWYNCGqIcux4KSHveviqPZcRjwCgKcpmoU8CcHB3jiOA0VR8Mwzz2D16tXex0svveSVdF500UV444038NGPfhRr1qzBcccdh+9///v7/bW0UYOAJUka9znHcf9NZ7NZnH766Ugmk/jZz36Gp556Cvfeey8Atzx1T2Kxfauw8n9tyWuD5uzp9oC9Vf1IkjThGjZs2ICzzz4bRxxxBO6++24888wz+Pd//3cA7smTfbWndYx+fm9/zkRE+8sdyFlJmoiMr9JEVbzHETUC+N6YUGNSfD9PDqZF154wFql8XYCxCBHRXpkmUCgAGFVpYjkoKjJMRUHS156Lh0mbg7/K1WEswlhkH9cRhlikJkmTm2++GfPmzUM0GsWxxx6L//3f/93jvStXrvQGxPg/Xn755Voslaiq0sW0NwQeGN2eS/baczFp0hyUSQgOnnzyyTHXCxcuhKIoOOaYY2DbNvr7+3HIIYcEPvzlj7NmzcLFF1+Me+65B1dccQX+4z/+AwCg6+6/N/+Qssny8ssvY9euXfjmN7+JE088EYceeuiYUwDjff2FCxciFovhkUcemfQ1lR1++OFYvXp14PTDE088AVmWsWjRIqRSKcydO3ePa3j66adhWRb+7d/+DccffzwWLVqErVu3Bu7RdX3CP9fDDz8cGzduxKZNm7znXnzxRQwPD+Owww47iN8hjYexCJErb+VhOZVex9JIwXvsb88VUZg0aQay793egR7gYCwy+RiLtCbGItTySq25HOHAdCqbqobtIKu7G6L+ShPuizSHyag0YSwy+RiLTKzqSZO77roLn/nMZ/ClL30Jq1atwoknnoizzjprr2VIQGUATvlj4cKF1V4qUdWli2noubFlqECpPVecSZNmMhnBwaZNm3D55ZfjlVdewX/+53/i+9//vtdPctGiRTjvvPNw/vnn45577sG6devw1FNP4frrr8eDDz4IwO0x+bvf/Q7r1q3Ds88+iz/84Q/eD545c+ZAkiQ88MAD2LlzJ0ZKQexkmD17NnRdx/e//3288cYbuP/++3HdddcF7hnv60ejUXz+85/HVVddhdtvvx1r167Fk08+iR//+MeTtrbzzjsP0WgUF1xwAZ5//nk8+uij+NSnPoWPfvSj3mC1a665Bv/2b/+GG2+8Ea+99hqeffZZ7yTKggULYFmW93u744478MMf/jDwNebOnYuRkRE88sgj2LVrF3K53Jh1vPOd78SRRx6J8847D88++yz+8pe/4Pzzz8dJJ52E4447btJ+v8RYhMjPX2UCAHLGlzTxteeKqBHA12qAGlOgVegBHsZjLMJYhA4eYxEiVFpz+apMAHdfZER3kyWpKJMmzWYyKk0YizAWqYeqJ02+853v4O///u9x0UUX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3ZyOovQiZKdlD3k0daKOrxIREdH0YjFacP+590MIgUAkoMcf3rC3XywiSzLSzekoTC9Eri2XsQgRERGNSkF6AQrSC/rdrwoVroALvrBP34gRUkJ6LKIKVY9F7GY7CuwFyLPnDdmjlbEIEdHkY9KExsVmssFmsk3Y6zMoICIiotGQJAlppjSkmdKQg/GXqmAsQkRERCMlSzKy0rKQlZaVsNdkLEJENPlGXnCaiIiIiIiIiIiIiIhoGmPShIiIiIiIiIiIiIiICEyaEBERERERERERERERAWDShIiIiIiIiIiIiIiICACTJkRERERERERERERERACYNCEiIiIiIiIiIiIiIgLApAkREREREREREREREREAJk2IiIiIiIiIiIiIiIgAMGlCREREREREREREREQEgEkTIiIiIiIiIiIiIiIiAEyaEBERERERERERERERAQCMyR5AogkhAAButzvJIyEiIpo6+j4X+z4naWIxHiEiIorHWGRyMRYhIiKKN5pYZNolTTweDwCgrKwsySMhIiKaejweD5xOZ7KHMe0xHiEiIhoYY5HJwViEiIhoYCOJRSQxzbZ5qKqKxsZGOBwOSJKUkNd0u90oKytDfX09MjIyEvKaU8l0nt90nhvA+aWy6Tw3gPObioQQ8Hg8KC4uhiyzOudES3Q8kor/5kaD80td03luwPSe33SeG8D5TUWMRSYXY5HR4fxS13SeGzC95zed5wZwflPRaGKRaXfSRJZllJaWTshrZ2RkpMw/grGYzvObznMDOL9UNp3nBnB+Uw13dU6eiYpHUu3f3GhxfqlrOs8NmN7zm85zAzi/qYaxyORhLDI2nF/qms5zA6b3/Kbz3ADOb6oZaSzC7R1ERERERERERERERERg0oSIiIiIiIiIiIiIiAgAkyYjYrFY8O1vfxsWiyXZQ5kQ03l+03luAOeXyqbz3ADOjyjRpvu/Oc4vdU3nuQHTe37TeW4A50eUaNP93xznl7qm89yA6T2/6Tw3gPNLddOuETwREREREREREREREdFY8KQJERERERERERERERERmDQhIiIiIiIiIiIiIiICwKQJERERERERERERERERACZNiIiIiIiIiIiIiIiIADBpMiK/+c1vUFlZCavVitWrV+Odd95J9pBG7cEHH8RZZ50Fh8OB/Px8XH/99aiuro57jBAC3/nOd1BcXIy0tDR8+MMfxsGDB5M04rF78MEHIUkS7rvvPv2+VJ9bQ0MDPvGJTyAnJwc2mw0rVqzArl279OupPL9IJIJvfvObqKysRFpaGqqqqvC9730Pqqrqj0ml+b399tu45pprUFxcDEmS8Mwzz8RdH8lcgsEg7r77buTm5sJut+Paa6/F6dOnJ3EWAxtqbuFwGF/72tewdOlS2O12FBcX47bbbkNjY2Pca0zVuQHD/93F+vznPw9JkvCLX/wi7v6pPD9KbYxFUgtjkdSaH2MRxiJTYW4AYxGa2hiLpBbGIqk1P8YijEWmwtwAxiKxmDQZxpNPPon77rsP3/jGN7Bnzx6cf/75uOKKK3Dq1KlkD21UNm/ejC9+8YvYtm0bNm3ahEgkgg0bNsDr9eqP+fGPf4yf/exneOihh7Bjxw4UFhbi0ksvhcfjSeLIR2fHjh34/e9/j2XLlsXdn8pz6+rqwrnnnguTyYSXXnoJhw4dwk9/+lNkZmbqj0nl+f3oRz/C7373Ozz00EM4fPgwfvzjH+MnP/kJfvWrX+mPSaX5eb1eLF++HA899NCA10cyl/vuuw9PP/00nnjiCbz77rvo6enB1VdfDUVRJmsaAxpqbj6fD7t378a3vvUt7N69G0899RRqampw7bXXxj1uqs4NGP7vrs8zzzyD999/H8XFxf2uTeX5UepiLDI13+8Hw1gk9ebHWISxyFSYG8BYhKYuxiJT8/1+MIxFUm9+jEUYi0yFuQGMReIIGtLatWvFnXfeGXffggULxNe//vUkjSgxWltbBQCxefNmIYQQqqqKwsJC8cMf/lB/TCAQEE6nU/zud79L1jBHxePxiLlz54pNmzaJCy64QNx7771CiNSf29e+9jVx3nnnDXo91ed31VVXiU9/+tNx933kIx8Rn/jEJ4QQqT0/AOLpp5/Wb49kLt3d3cJkMoknnnhCf0xDQ4OQZVm8/PLLkzb24Zw5t4Fs375dABB1dXVCiNSZmxCDz+/06dOipKREHDhwQFRUVIif//zn+rVUmh+lFsYiU//9vg9jkdScH2MRxiJTbW5CMBahqYWxyNR/v+/DWCQ158dYhLHIVJubEIxFeNJkCKFQCLt27cKGDRvi7t+wYQO2bt2apFElhsvlAgBkZ2cDAGpra9Hc3Bw3V4vFggsuuCBl5vrFL34RV111FS655JK4+1N9bs899xzWrFmDG2+8Efn5+Vi5ciUefvhh/Xqqz++8887D66+/jpqaGgDABx98gHfffRdXXnklgNSfX6yRzGXXrl0Ih8NxjykuLsaSJUtSbr4ulwuSJOm7f1J9bqqqYuPGjbj//vuxePHiftdTfX40NTEWSa33e8YiqTk/xiKMRVJlboxFKBkYi6TW+z1jkdScH2MRxiKpMreZFIsYkz2Aqay9vR2KoqCgoCDu/oKCAjQ3NydpVOMnhMCXv/xlnHfeeViyZAkA6PMZaK51dXWTPsbReuKJJ7B7927s2LGj37VUn9uJEyfw29/+Fl/+8pfxH//xH9i+fTvuueceWCwW3HbbbSk/v6997WtwuVxYsGABDAYDFEXBAw88gJtvvhlA6v/9xRrJXJqbm2E2m5GVldXvMan0vhMIBPD1r38dt9xyCzIyMgCk/tx+9KMfwWg04p577hnweqrPj6YmxiKp837PWCR158dYhLFIqsyNsQglA2OR1Hm/ZyySuvNjLMJYJFXmNpNiESZNRkCSpLjbQoh+96WSu+66C/v27cO7777b71oqzrW+vh733nsvXn31VVit1kEfl4pzA7Qs7po1a/CDH/wAALBy5UocPHgQv/3tb3Hbbbfpj0vV+T355JN49NFH8fjjj2Px4sXYu3cv7rvvPhQXF+P222/XH5eq8xvIWOaSSvMNh8O46aaboKoqfvOb3wz7+FSY265du/Df//3f2L1796jHmgrzo6lvOr0HAoxF+qTC3ADGIn1SdX4DYSwSLxXmxliEkm06vQcCjEX6pMLcAMYifVJ1fgNhLBIvFeY202IRlucaQm5uLgwGQ79MWGtra7+MaKq4++678dxzz+HNN99EaWmpfn9hYSEApORcd+3ahdbWVqxevRpGoxFGoxGbN2/GL3/5SxiNRn38qTg3ACgqKsKiRYvi7lu4cKHedC+V/+4A4P7778fXv/513HTTTVi6dCk2btyIL33pS3jwwQcBpP78Yo1kLoWFhQiFQujq6hr0MVNZOBzGxz72MdTW1mLTpk36bgogtef2zjvvoLW1FeXl5fr7TF1dHf7t3/4Ns2bNApDa86Opi7FIasyVsUjq/t0BjEUAxiKpMDfGIpQsjEVSY66MRVL37w5gLAIwFkmFuc20WIRJkyGYzWasXr0amzZtirt/06ZNWL9+fZJGNTZCCNx111146qmn8MYbb6CysjLuemVlJQoLC+PmGgqFsHnz5ik/14svvhj79+/H3r179V9r1qzBrbfeir1796Kqqipl5wYA5557Lqqrq+Puq6mpQUVFBYDU/rsDAJ/PB1mOfysyGAxQVRVA6s8v1kjmsnr1aphMprjHNDU14cCBA1N+vn2BwdGjR/Haa68hJycn7noqz23jxo3Yt29f3PtMcXEx7r//frzyyisAUnt+NHUxFkmN93vGIqn7dwcwFmEskhpzYyxCycJYJDXe7xmLpO7fHcBYhLFIasxtxsUiE95qPsU98cQTwmQyiT/+8Y/i0KFD4r777hN2u12cPHky2UMblS984QvC6XSKt956SzQ1Nem/fD6f/pgf/vCHwul0iqeeekrs379f3HzzzaKoqEi43e4kjnxsLrjgAnHvvffqt1N5btu3bxdGo1E88MAD4ujRo+Kxxx4TNptNPProo/pjUnl+t99+uygpKRH//Oc/RW1trXjqqadEbm6u+OpXv6o/JpXm5/F4xJ49e8SePXsEAPGzn/1M7NmzR9TV1QkhRjaXO++8U5SWlorXXntN7N69W1x00UVi+fLlIhKJJGtaQoih5xYOh8W1114rSktLxd69e+PeZ4LBoP4aU3VuQgz/d3emiooK8fOf/zzuvqk8P0pdjEWm5vv9cBiLpM78GIswFpkKcxOCsQhNXYxFpub7/XAYi6TO/BiLMBaZCnMTgrFILCZNRuDXv/61qKioEGazWaxatUps3rw52UMaNQAD/vrzn/+sP0ZVVfHtb39bFBYWCovFIj70oQ+J/fv3J2/Q43BmcJDqc3v++efFkiVLhMViEQsWLBC///3v466n8vzcbre49957RXl5ubBaraKqqkp84xvfiPtASaX5vfnmmwP+X7v99tuFECObi9/vF3fddZfIzs4WaWlp4uqrrxanTp1KwmziDTW32traQd9n3nzzTf01purchBj+7+5MAwUHU3l+lNoYi6QexiKpMz/GIoxFpsLchGAsQlMbY5HUw1gkdebHWISxyFSYmxCMRWJJQggx0lMpRERERERERERERERE0xV7mhAREREREREREREREYFJEyIiIiIiIiIiIiIiIgBMmhAREREREREREREREQFg0oSIiIiIiIiIiIiIiAgAkyZEREREREREREREREQAmDQhIiIiIiIiIiIiIiICwKQJERERERERERERERERACZNiIiIiIiIiIiIiIiIADBpQkREREREREREREREBIBJEyIiIiIiIiIiIiIiIgBMmhAREREREREREREREQFg0oSIiIiIiIiIiIiIiAgA8P8D44YC6P1yUcsAAAAASUVORK5CYII=", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -368,141 +243,87 @@ } ], "source": [ - "# Here, the distance function (distance and normalise arguments)\n", - "top_k_search = QuerySearch(k=3, inverse_distance=True, distance=\"euclidean\")\n", - "top_k_search.fit(X_train)\n", - "distances_to_matches, best_matches = top_k_search.predict(q)\n", - "plot_best_matches(top_k_search, best_matches)" - ] - }, - { - "cell_type": "markdown", - "id": "b5240535-5123-4ac5-a5e0-e0502ef80b3e", - "metadata": {}, - "source": [ - "## Using the speed_up option for similarity search" + "series_predict = X[3]\n", + "starting_timestep_predict = 25\n", + "indexes, distances = snn.predict(\n", + " series_predict[:, starting_timestep_predict : starting_timestep_predict + length],\n", + " k=3,\n", + " allow_trivial_matches=True,\n", + ")\n", + "for i in range(len(indexes)):\n", + " print(f\"match {i} : {indexes[i]} with distance {distances[i]}\")\n", + "plot_best_matches(\n", + " series_fit, series_predict, starting_timestep_predict, indexes, length\n", + ")" ] }, { "cell_type": "markdown", - "id": "b5e13c31-2aa3-4987-8d44-8a296c81a318", + "id": "fcf10a34-930a-4fce-86f8-4dfa207cad11", "metadata": {}, "source": [ - "In the similarity search module, we implement different kind of optimization to decrease the time necessary to extract the best matches to a query. You can find more information about these optimization in the other notebooks of the similarity search module. An utility function is available to list the optimizations currently implemented in aeon :" + "The `predict` method returns two lists, containing the starting timesteps of the matches in `series_fit` and the squared euclidean distance of these matches to the subsequence we gave in `predict`. Now, you can then play with the different parameters of `predict` to customize your search results to your needs!\n", + "\n", + "It is also possible to get the distance profile which is used to extract the best matches :" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "d22e2d74-f44d-4c81-ba1b-72d618bd5862", + "execution_count": 5, + "id": "7d2bd3f7-7eb9-4406-be1c-b6fcd9c76730", "metadata": {}, "outputs": [ { "data": { + "image/png": "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", "text/plain": [ - "{'normalised euclidean': ['fastest', 'Mueen'],\n", - " 'euclidean': ['fastest', 'Mueen'],\n", - " 'normalised squared': ['fastest', 'Mueen'],\n", - " 'squared': ['fastest', 'Mueen']}" + "
" ] }, - "execution_count": 9, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "QuerySearch.get_speedup_function_names()" - ] - }, - { - "cell_type": "markdown", - "id": "bf12616c-6ace-478b-806f-5419c2c19f2b", - "metadata": {}, - "source": [ - "By default, the `fastest` option is used, which use the best optimisation available. You can change this behavior by using the values of t with the corresponding distance function and normalization options in the estimators, for example with a `QuerySearch` using the `normalised euclidean` distance:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "6313f26a-5788-42dc-881a-40746458414c", - "metadata": {}, - "outputs": [], - "source": [ - "top_k_search = QuerySearch(distance=\"euclidean\", normalise=True, speed_up=\"Mueen\")" - ] - }, - { - "cell_type": "markdown", - "id": "6ab51d84-7220-4333-b50e-2db695eaf45d", - "metadata": {}, - "source": [ - "For more information on these optimizations you can refer to the [distance profile notebook](distance_profiles.ipynb) for the theory, and to the [analysis of the speedups provided by similarity search module](code_speed.ipynb) for a comparison of their performance." + "distance_profile = snn.compute_distance_profile(\n", + " series_predict[:, starting_timestep_predict : starting_timestep_predict + length],\n", + ")\n", + "plt.figure(figsize=(5, 3))\n", + "plt.plot(distance_profile)\n", + "plt.show()" ] }, { "cell_type": "markdown", - "id": "4149c40f", + "id": "b5240535-5123-4ac5-a5e0-e0502ef80b3e", "metadata": {}, "source": [ - "# Series search\n", - "For series search, we are not interest in exploring the relationship of the input dataset `X` (given in `fit`) and a single query, but to all queries of size `query_length` that exists in another time series `T`. For example, with using again our simple GunPoint dataset:" + "### 1.2 Motif search with STOMP" ] }, { "cell_type": "code", - "execution_count": 11, - "id": "d510c4cc", + "execution_count": 6, + "id": "ff23faf5-2941-441a-8c4c-0cf66eaca121", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABJ4AAAJcCAYAAAC4425vAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAAsTAAALEwEAmpwYAADT3klEQVR4nOzdd3hUZcLG4WdKeu+9EELvEKoKiAURxa4oKNiwrvWzrLrq2svquq6uig0UBduuYAE7iiAlVAGBAOkFUgikl5nz/RGIBAhFSc4k+d3XlWvamXOemQyT4Zn3vMdiGIYhAAAAAAAA4Dizmh0AAAAAAAAA7RPFEwAAAAAAAFoExRMAAAAAAABaBMUTAAAAAAAAWgTFEwAAAAAAAFoExRMAAAAAAABaBMUTAAAdWFZWlnx9feVwOMyO0uJmzJihE088sUXWvXDhQsXGxv7h+/v6+mr79u2SpKlTp+qBBx5odlmLxaKtW7ce9bqPdXlX4kqvz//973+Ki4uTr6+vVq9erV69emnhwoWSpIcffliTJ082NyAAAC6K4gkAgA4sPj5e5eXlstlsx22dq1evlr+/f5OyY+XKlQoMDFRGRsZx287xlJGRIYvFovr6elO2X15erqSkpD+9ntGjR+uNN944DolaXmJior799tvDLtMSr88/6v/+7//00ksvqby8XAMGDNCGDRs0evRos2MBAODyKJ4AAOigWqpkGTBggG6++WZde+21MgxDdXV1uuqqq/TII48oMTGxRbaJ9qc1S8Cj2VZmZqZ69erVCmkAAGhfKJ4AAGiDnn76acXExMjPz0/dunXTd999J0lyOp166qmn1LlzZ4WEhOjiiy9WSUmJpN9H9bz55puKj4/XmDFjDhrps3v3bl199dWKiopSTEyMHnjggcbdnLZu3apRo0YpICBAoaGhuuSSS5rN99BDDyk/P1/Tp0/XE088IV9fX918882HXPZQo432H7lzuO1u2rRJp512moKDg9WtWzd9+OGHjbcVFxdrwoQJ8vf315AhQ7Rt27Zm844cOVKSFBgYKF9fX/3yyy9yOp167LHHlJCQoPDwcF1xxRXavXt3878USU888YRCQ0OVmJio995775CPRzp4t7/D7Q737LPPKioqStHR0Xrrrbea3fb999+vRYsW6eabbz7o+f7222/VpUsXBQYG6qabbpJhGI23vfXW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Ibd1rL/v5sTFxenyyy9v8pxWVFTo3nvvPab1AADQXlA8AQDQxmzevFnff/+9ampq5OnpKS8vL1mtDX/Sr7/+et1///2N/4EuLCzU3Llzj2q9UVFROv3003XnnXdqz549cjqd2rZtW+PuUR999JFycnIkNYzusVgsjdvdX0VFhaZNm6Z//vOfCg0N1ZlnnqnTTjtNt99++yG3GxYWppiYGM2aNUsOh0NvvfVWk4nAm9vuWWedpS1btujdd99VXV2d6urqtGLFCv3222+y2Ww6//zz9fDDD6uyslIbN27UzJkzm33sYWFhslqt2r59e+N1l156qf75z38qPT1d5eXluu+++3TJJZfIbrc3u56HHnpItbW1WrRokT7//HNddNFFkqT+/fvrv//9ryorK7V161a9+eabza5jfxdffLFmzJihjRs3qrKyUn//+98Pu3xERESTx3Ak119/vZ588snGcnH37t366KOPjvr+h1NWViZfX18FBAQoNzdXzz777J/KKjVM3m6xWPTWW2/prrvu0hVXXNFk17kDzZo1q/G5e/DBB3XhhRfKZrMdctk/8vs+lMmTJ+uzzz7TV199JYfDoerqai1cuLDxNQwAQEdD8QQAQBtTU1Oje++9V6GhoYqMjNTOnTv15JNPSpJuvfVWTZgwQaeffrr8/Pw0bNgwLVu27KjX/c4776i2tlY9e/ZUUFCQLrzwwsZdhFasWKGhQ4fK19dXEyZM0L/+9S8lJSUdtI777rtP3bt316RJkxqve+GFFzR//nx98803h9zu66+/rmeffVYhISHasGFDkxE3zW3Xz89PX3/9tebMmaPo6GhFRkbqnnvuUU1NjSTppZdeUnl5uSIjIzV16lRdeeWVzT5ub29v3X///TrhhBMUGBiopUuX6qqrrtLll1+ukSNHqlOnTvL09NS///3vZtcRGRmpoKAgRUdHa9KkSXr11Vcb57a6/fbb5e7uroiICE2ZMqXJc3M448aN02233aYxY8YoOTlZY8aMOezyt956qz7++GMFBQXplltuOeL6zzvvPN1zzz2aOHGi/P391bt3b82fP/+osh3JQw89pFWrVikgIEDjx4/X+eef3+T2v/71r3rssccUGBiof/zjH0dc38qVK/X888/rnXfekc1m0z333COLxaKnnnqq2ftcfvnlmjp1qiIjI1VdXa0XX3yx2WWP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7PoHHG8UTwAAAACAdsvb3a7BicFmxwA6LOpWAAAAAAAAtAiKJwAAAAAAALQIiicAAAAAAAC0CIonAAAAAAAAtAiKJwAAAAAAALQIiicAAAAAAAC0CIonAAAAAAAAtAiKJwAAAAAAALQIiicAAAAAAAC0CIthGIbZIVpaaGioEhMTzY5xXBQWFiosLMzsGHBRvD5wOLw+cDi8PnA4vD5wOLw+cCS8RnA4vD7atoyMDBUVFR12mQ5RPLUnKSkpSk1NNTsGXBSvDxwOrw8cDq8PHA6vDxwOrw8cCa8RHA6vj/aPXe0AAAAAAADQIiieAAAAAAAA0CIontqYadOmmR0BLozXBw6H1wcOh9cHDofXBw6H1weOhNcIDofXR/vHHE8AAAAAAABoEYx4AgAAAAAAQIugeAIAAAAAAECLoHhqIxYsWKBu3bopOTlZTz31lNlxYLLs7GydfPLJ6tmzp3r16qV//etfkqSSkhKddtpp6tKli0477TTt2rXL5KQwk8Ph0IABA3TWWWdJktLT0zV06FAlJyfrkksuUW1trckJYabS0lJdeOGF6t69u3r06KFffvmF9xA0+uc//6levXqpd+/euvTSS1VdXc17SAd21VVXKTw8XL179268rrn3C8MwdMsttyg5OVl9+/bVqlWrzIqNVnKo18ddd92l7t27q2/fvjrvvPNUWlraeNuTTz6p5ORkdevWTV999ZUJidHaDvUa2ee5556TxWJRUVGRJN5D2iuKpzbA4XDopptu0vz587Vx40bNnj1bGzduNDsWTGS32/Xcc89p48aNWrp0qV5++WVt3LhRTz31lE455RSlpaXplFNOoaTs4P71r3+pR48ejZfvuece3X777dq6dauCgoL05ptvmpgOZrv11lt1xhlnaNOmTVq7dq169OjBewgkSbm5uXrxxReVmpqq9evXy+FwaM6cObyHdGBTp07VggULmlzX3PvF/PnzlZaWprS0NE2fPl033HCDGZHRig71+jjttNO0fv16rVu3Tl27dtWTTz4pSdq4caPmzJmjDRs2aMGCBbrxxhvlcDjMiI1WdKjXiNTwZfrXX3+t+Pj4xut4D2mfKJ7agOXLlys5OVlJSUlyd3fXxIkTNXfuXLNjwURRUVEaOHCgJMnPz089evRQbm6u5s6dqylTpkiSpkyZok8//dTElDBTTk6OvvjiC11z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ayVJI0eOlCT169dPvr6++uCDDxrX//TTTysyMlJXXnll43WStG3bNgUHB2vVqlWSpLy8PIWFhWnhwoWHzJuYmKgnn3xSPXv2VFBQkK688kpVV1c3eSz7b6u553XLli2Nu/sFBgZqzJgxkg4/Yuvzzz9X//79FRgYqBEjRmjdunXNPq9LlizR4MGDFRAQoMGDB2vJkiWSGnbfmzlzpp555hn5+vrq22+/Pei+kZGReu6553TttdcqKytLt9xyi1577TX5+vo2uz0AAOCaKJ4AAIBLePzxx7V06VKtWbNGa9eu1fLly/XYY4813l5QUKCioiLl5uZq5syZmjZt2nHbXa2goEDV1dXKzc3VI488omuvvVazZs3SypUrtWjRIj366KNKT0+XJNlsNv3zn/9UUVGRfvnlF3333Xf6z3/+I0n66aefJElr165VeXm5Lrnkksb1l5SUKDMzU9OnT2+y7c6dO+vpp5/W5MmTVVlZqSuvvFJTpkw57C6C7733nr766itt27ZNW7ZsOeh52n9bzT2vXbt21YYNGyRJpaWlRxwZtnr1al111VV67bXXVFxcrOuuu04TJkxoLAf3V1JSovHjx+uWW25RcXGx7rjjDo0fP17FxcWaMWOGJk2apLvvvlvl5eXNjnabOnWqOnfurIEDB+qMM87QGWeccdh8AADANVE8AQAAl/Dee+/pwQcfVHh4uMLCwvTQQw8dtGvVo48+Kg8PD40aNUrjx4/Xhx9+eFy27ebmpvvvv19ubm6aOHGiioqKdOutt8rPz0+9evVSz549tXbtWknSoEGDNGzYMNntdiUmJuq6667Tjz/+eNj1W61W/f3vf5eHh4e8vLwOuv3aa69VcnKyhg4dqvz8fD3++OOHXd/NN9+suLg4BQcH6/7779fs2bOb3dbRPK9HY/r06bruuus0dOhQ2Ww2TZkyRR4eHlq6dOlBy37xxRfq0qWLLr/8ctntdl166aXq3r27Pvvss2Pa5kknnaTi4mJNnjz5mPMCAADXQPEEAABcQl5enhISEhovJyQkKC8vr/FyUFCQfHx8mr39zwgJCZHNZpOkxmIoIiKi8XYvL6/Guam2bNmis846S5GRkfL399d9992noqKiw64/LCxMnp6eh13m2muv1fr16/WXv/xFHh4eh102Li6u8fyBz8OB2zrS83q0MjMz9dxzzykwMLDxJzs7+5DrOnCb+7abm5t71NtLS0vTP/7xD91444268847VVdXd8yZAQCA+SieAACAS4iOjlZmZmbj5aysrCZzNO3atUsVFRXN3t5abrjhBnXv3l1paWnas2ePnnjiCRmGcdj7NDeJ9j7l5eW67bbbdPXVV+vhhx9WSUnJYZfPzs5uPH/g83Dgto70vB6tuLg43X///SotLW38qays1KWXXnrQsgduc992Y2JijmpbhmHommuu0W233aZ///vf8vHx0dNPP33MmQEAgPkongAAgEu49NJL9dhjj6mwsFBFRUV65JFHDtrF6qGHHlJtba0WLVqkzz//XBdddNEh1+VwOFRdXa36+no5nU5VV1cftxEzZWVl8vf3l6+vrzZt2qRXXnmlye0RERHavn37Ma3z1ltvVUpKit544w2NHz9e119//WGXf/nll5WTk6OSkhI9/vjjjXNJHcrRPK9H49prr9Wrr76qZcuWyTAMVVRU6IsvvlBZWdlBy5555pnasmWL3n//fdXX1+uDDz7Qxo0bddZZZx3Vtl555RUVFRXpvvvuk9Vq1ZtvvqlnnnlGmzZtOubcAADAXBRPAADAJTzwwANKSUlR37591adPHw0cOFAPPPBA4+2RkZEKCgpSdHS0Jk2apFdffVXdu3c/5LreffddeXl56YYbbtCiRYvk5eWla6+99rjk/Mc//qH3339ffn5+uvbaaw8qfR5++GFNmTJFgYGBRzUH1dy5c7VgwYLGAuv555/XqlWrDnvUvssuu0ynn366kpKS1Llz5ybP04GO9LwerZSUFL3++uu6+eabFRQUpOTkZM2YMeOQy4aEhOjzzz/Xc889p5CQED3zzDP6/PPPFRoaesTtZGVl6b777tObb74pd3d3SVLPnj1155136tprrz3i6DIAAOBaLAZ/vQEAgItbuHChJk+erJycHLOjmC4xMVFvvPFGs0eDAwAAcCWMeAIAAAAAAECLoHgCAAAAAABAi2BXOwAAAAAAALQIRjwBAAAAAACgRdjNDtAaQkNDlZiYaHYMAAAAAACAdiMjI0NFRUWHXaZDFE+JiYlKTU01OwYAAAAAAEC7kZKScsRlWnRXuwULFqhbt25KTk7WU089ddDtzz//vHr27Km+ffvqlFNOUWZmpiRpzZo1Gj58uHr16qW+ffvqgw8+aLzP1KlT1alTJ/Xv31/9+/fXmjVrWvIhAAAAAAAA4A9qsRFPDodDN910k7755hvFxsZq8ODBmjBhgnr27Nm4zIABA5Samipvb2+98soruvvuu/XBBx/I29tb77zzjrp06aK8vDwNGjRIY8eOVWBgoCTp2Wef1YUXXthS0QEAAAAAAHActNiIp+XLlys5OVlJSUlyd3fXxIkTNXfu3CbLnHzyyfL29pYkDRs2TDk5OZKkrl27qkuXLpKk6OhohYeHq7CwsKWiAgAAAAAAoAW0WPGUm5uruLi4xsuxsbHKzc1tdvk333xT48aNO+j65cuXq7a2Vp07d2687v7771ffvn11++23q6am5pDrmz59ulJSUpSSkkJpBQAAAAAAYIIWnePpaM2aNUupqam66667mlyfn5+vyy+/XG+//bas1oaoTz75pDZt2qQVK1aopKRETz/99CHXOW3aNKWmpio1NVVhYWEt/hgAAAAAAADQVIsVTzExMcrOzm68nJOTo5iYmIOW+/bbb/X4449r3rx58vDwaLx+z549Gj9+vB5//HENGzas8fqoqChZLBZ5eHjoyiuv1PLly1vqIQAAAAAAAOBPaLHiafDgwUpLS1N6erpqa2s1Z84cTZgwockyq1ev1nXXXad58+YpPDy88fra2lqdd955uuKKKw6aRDw/P1+SZBiGPv30U/Xu3bulHgIAAAAAAAD+hBY7qp3dbtdLL72ksWPHyuFw6KqrrlKvXr304IMPKiUlRRMmTNBdd92l8vJyXXTRRZKk+Ph4zZs3Tx9++KF++uknFRcXa8aMGZKkGTNmqH///po0aZIKCwtlGIb69++vV199taUeAgAAAAAAAP4Ei2EYhtkhWlpKSopSU1PNjgEAAAAALqO6zqFPVuVowfoCDUsK0SWD4xTq63HkOwLAXkfTt7TYiCcAAAAAgOvZXVmnd5dmaMaSDBWV1yo2yEuL0or0r2/TdGafSF0+PEED44NksVjMjgqgHaB4AgAAAIAW5nQaqql3qrrOoao6h7zcbArycW/VDHmlVXrr53TNXp6lilqHRncL0/WjOmtop2BtK6zQrKWZ+mRljj5dk6eeUf66fHiCzukfLW93/tsI4I9jVzsAAAAAOE62F5br9g/WaE91vapqHaqud6iq1qGaemeT5WxWi8b2itCVJ3RSSkLLji7aXFCm137apnlr8mRImtAvWtNGJqlHlP9By1bU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7dKly0Ptf+DAATz99NON8tj3Ul1djX79+iE4OBgbN26847b//T24u7ujoKBAa1m0KScnByNHjmzw/mq1Gh06dMChQ4fqtg0YMACbN2/WRjwiIiJqBHKxAxAREVHzc/z4cezcuRMJCQkwMDBAQUEBlEolgNrC0/jx42FsbNzg46nVaqxevRoBAQFwcnICAPz444+NlvfYsWONdqzGcOrUKQBAYmLiXbf97++hKaqpqYFcXv/bTCcnJ2zZsqXBx5XJZPj222/x/PPP4+TJk9iyZQukUimee+65x4lLREREWsQRT0RERNTocnNzYWtrCwMDAwCAra0tnJycsGTJEuTk5KB3797o3bs3AGDmzJlQKBTw9/fHu+++W3cMd3d3zJ8/H6GhodiwYQPi4+Mxbtw4BAcHo7KyEr169UJ8fDwAwNTUFAsWLED79u0RHh6OvLw8AMCVK1cQHh6OwMBAvP322zA1Nb1n3tvbDxw4gF69emHkyJHw9fXFuHHjIAgCAGDPnj3w9fVFaGgotm3bVnff8vJyTJ06FR07dkRISAiio6MBAHPmzMEHH3wAAPj999/Ro0cPaDSaOx63qKgIw4YNQ1BQEMLDw3HmzBlcv34d48ePR1xcHIKDg3HlypW6/bds2XLX7wEAvv76a4SGhiIwMBAXL158YK5/EgQBs2fPho+PD/r164ennnqqrhD0z5FU8fHx6NWr1wOPu3r1akRERKBPnz7o27cvJk6ciO3bt9c91rhx4+7KkJaWhoCAgLr7jxgxAoMGDYKXlxdef/31e/5dderUCZ07d8Z7772Ht956C0uXLr3nfkRERNRECERERESNrLS0VGjfvr3g5eUlzJw5Uzhw4EDdba1btxby8/PrrhcWFgqCIAg1NTVCz549hdOnT9ft98knn9Tt17NnTyEuLu6e1wEIO3bsEARBEF577TXhww8/FARBEIYMGSKsX79eEARB+O677wQTE5N75r29/a+//hLMzc2FzMxMQa1WC+Hh4cLhw4eFyspKwcXFRbh8+bKg0WiE5557ThgyZIggCILw5ptvCj/99JMgCIJw48YNwcvLSygrKxPKy8sFPz8/Yf/+/YK3t7eQkpJy1+POnj1beO+99wRBEIR9+/YJ7du3r8tx+/j/639/D61btxaWLFkiCIIgfPPNN8K0adMemOuftm7dKvTr10+oqakRsrOzBQsLC2Hz5s11x7399xQXFyf07NnzgcddtWqV4OzsXPf3eeDAAWHo0KGCIAhCcXGx4O7uLqhUqjsePzU1VfD39xcEQRBWrVoltGnTRiguLhYqKysFNzc3ISMj456/g8LCQsHY2Fh466237nk7ERERNR0c8URERESNztTUFCdPnsTy5cthZ2eH0aNHY/Xq1ffcd9OmTQgNDUVISAjOnz9/R9+m0aNHN+jx9PX163oudejQAWlpaQBqp/zdnoY1duzYBh2rY8eOcHFxgVQqRXBwMNLS0nDx4kW0adMGXl5ekEgkGD9+fN3+e/fuxaJFixAcHIxevXqhqqoKGRkZMDY2xg8//ID+/ftj9uzZaNu27V2PdeTIEUyYMAEA0KdPHxQWFqKkpKRBOf9pxIgRdz33++X6p0OHDmHMmDGQyWRwcnJCnz596n2sBx23f//+sLa2BgD07NkTycnJyM/Px4YNG/Dss8/WO/2ub9++sLCwgKGhIfz8/JCenn7P/Q4dOgQLCwucO3eu3rxEREQkLvZ4IiIiIq2QyWTo1asXevXqhcDAQKxZswaTJ0++Y5/U1FR89tlniIuLg5WVFSZPnoyqqqq6201MTBr0WHp6epBIJHWPW1NT88i5b08PbOixBEHA1q1b4ePjc9dtZ8+ehY2NzR3NwLXhduZ/5n1QroaQy+V1UwP/+Xdyv+PGxMTc9fc1ceJE/Pzzz4iKisKqVasa/Dz+97n8U3l5OV5//XXs378fU6ZMwa5du/DUU0891HMjIiKiJ4cjnoiIiKjRXbp0CcnJyXXXExMT0bp1awCAmZkZSktLAQAlJSUwMTGBhYUF8vLysHv37vse85/3a6jw8HBs3boVABAVFfWwT6OOr68v0tLS6votbdiwoe62gQMH4uuvv67rBXW7MXh6ejo+//xznDp1Crt3765b1e+funfvjnXr1gGo7S9la2sLc3PzB2Zp6O/hfrn+qUePHti4cSPUajVyc3Px119/1d3m7u6OkydPAkDd77Chx71t8uTJWLx4MQDAz8+v3swN8cEHH2DUqFHw9fXFt99+i7lz595RGCMiIqKmhYUnIiIianRlZWWYNGkS/Pz8EBQUhKSkJLz33nsAgBkzZmDQoEHo3bs32rdvj5CQEPj6+mLs2LHo2rXrfY85efJkvPjii3c01a7P4sWL8cUXXyAoKAgpKSmwsLB4pOdjaGiI5cuXY8iQIQgNDYW9vX3dbe+88w5UKhWCgoLg7++Pd955B4IgYNq0afjss8/g5OSEFStWYPr06XcVSN577z2cPHkSQUFBeOONN7BmzZp6szT093CvXP9r+PDh8PLygp+fHyZOnIjOnTvX3fbuu+9izpw5UCgUkMlkD3Xc2xwcHNCuXTtMmTKl3ufVEOfPn8cvv/yCBQsWAABCQkIwcOBAfPLJJ41yfCIiImp8EuH211VEREREzUxFRQWMjIwgkUgQFRWFDRs23HN1N6o1efJkPP300xg5cmSjHK+iogKBgYFISEh45KIfERER6Tb2eCIiIqJm6+TJk5g9ezYEQYClpSVWrlwpdqQW488//8S0adMwd+5cFp2IiIhaMI54IiIiIiIiIiIirWCPJyIiIiIiIiIi0goWnoiIiIiIiIiISCtYeCIiIiIiIiIiIq1g4YmIiIiIiIiIiLSChSciIiIiIiIiItKK/wcXVvsFS0BwogAAAABJRU5ErkJggg==", "text/plain": [ - "
" + "([array([0.02910451])], [array([[7, 0]], dtype=int64)])" ] }, + "execution_count": 6, "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Index of the 20-th query best matches : [[195 26]]\n" - ] + "output_type": "execute_result" } ], "source": [ - "from aeon.similarity_search import SeriesSearch\n", - "\n", - "query_length = 35\n", - "estimator = SeriesSearch(distance=\"euclidean\").fit(X_train) # X_test is a 3D array\n", - "mp, ip = estimator.predict(X_test, query_length) # X_test is a 2D array\n", - "plot_matrix_profile(X_test, mp, 0)\n", - "print(f\"Index of the 20-th query best matches : {ip[20]}\")" - ] - }, - { - "cell_type": "markdown", - "id": "0dca5122", - "metadata": {}, - "source": [ - "Notice that we find the same best match for the 20-ith query, which was the query that we used for `QuerySearch` !\n", - "\n", - "`SeriesSearch` returns two lists, `mp` and `ip`, which respectively contain the distances to the best matches of all queries of size `query_length` in `X_test` (the `i-th` query being `X_test[:, i : i + query_length]`) and the indexes of these best matches in `X_train` in the `(ix_case, ix_timepoint)` format, such as `X_train[ix_case, :, ix_timepoint : ix_timepoint + query_length]` will be the matching subsquence.\n", + "from aeon.similarity_search.series import StompMotif\n", "\n", - "Most of the options (`k`, `threshold`, `inverse_distance`, etc.) from `QuerySearch` are also available for `SeriesSearch`." + "motif = StompMotif(length=length).fit(series_fit)\n", + "motif.predict(series_predict)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ff23faf5-2941-441a-8c4c-0cf66eaca121", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -521,7 +342,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.12.0" } }, "nbformat": 4, From f51d66a6efb78c7bc1b261af6fdc1f1b5e13128e Mon Sep 17 00:00:00 2001 From: baraline Date: Sun, 19 Jan 2025 13:34:51 +0100 Subject: [PATCH 16/18] Update documentation and add default test params --- aeon/similarity_search/series/_commons.py | 26 ++- .../similarity_search/series/motifs/_stomp.py | 49 +++++- .../series/neighbors/_dummy.py | 26 +++ .../series/neighbors/_mass.py | 26 +++ .../similarity_search/similarity_search.ipynb | 157 +++++++++++++++++- 5 files changed, 261 insertions(+), 23 deletions(-) diff --git a/aeon/similarity_search/series/_commons.py b/aeon/similarity_search/series/_commons.py index 4e62e5aacb..8b309bb6b2 100644 --- a/aeon/similarity_search/series/_commons.py +++ b/aeon/similarity_search/series/_commons.py @@ -146,20 +146,32 @@ def _extract_top_k_from_dist_profile( # Could add aggregation function as parameter instead of just max -def _extract_top_k_motifs(MP, IP, k): +def _extract_top_k_motifs(MP, IP, k, allow_trivial_matches, exclusion_size): criterion = np.zeros(len(MP)) for i in range(len(MP)): - criterion[i] = max(MP[i]) - idx = np.argsort(criterion) - return [MP[i] for i in idx[:k]], [IP[i] for i in idx[:k]] + if len(MP[i]) > 0: + criterion[i] = max(MP[i]) + else: + criterion[i] = np.inf + idx, _ = _extract_top_k_from_dist_profile( + criterion, k, np.inf, allow_trivial_matches, exclusion_size + ) + return [MP[i] for i in idx], [IP[i] for i in idx] -def _extract_top_r_motifs(MP, IP, k): + +def _extract_top_r_motifs(MP, IP, k, allow_trivial_matches, exclusion_size): criterion = np.zeros(len(MP)) for i in range(len(MP)): criterion[i] = len(MP[i]) - idx = np.argsort(criterion)[::-1] - return [MP[i] for i in idx[:k]], [IP[i] for i in idx[:k]] + idx, _ = _extract_top_k_from_dist_profile( + _inverse_distance_profile(criterion), + k, + np.inf, + allow_trivial_matches, + exclusion_size, + ) + return [MP[i] for i in idx], [IP[i] for i in idx] @njit(cache=True, fastmath=True) diff --git a/aeon/similarity_search/series/motifs/_stomp.py b/aeon/similarity_search/series/motifs/_stomp.py index fbd459b890..c912cdfacd 100644 --- a/aeon/similarity_search/series/motifs/_stomp.py +++ b/aeon/similarity_search/series/motifs/_stomp.py @@ -87,7 +87,7 @@ def _fit( y=None, ): if self.normalize: - self.X_means_, X_stds_ = sliding_mean_std_one_series(X, self.length, 1) + self.X_means_, self.X_stds_ = sliding_mean_std_one_series(X, self.length, 1) return self def predict( @@ -164,9 +164,13 @@ def predict( inverse_distance=inverse_distance, ) if motif_extraction_method == "k_motifs": - return _extract_top_k_motifs(MP, IP, k) + return _extract_top_k_motifs( + MP, IP, k, allow_trivial_matches, self.length // exclusion_factor + ) elif motif_extraction_method == "r_motifs": - return _extract_top_r_motifs(MP, IP, k) + return _extract_top_r_motifs( + MP, IP, k, allow_trivial_matches, self.length // exclusion_factor + ) def compute_matrix_profile( self, @@ -225,9 +229,12 @@ def compute_matrix_profile( is_self_mp = False if self.normalize: X_means, X_stds = sliding_mean_std_one_series(X, self.length, 1) - X_dotX = get_ith_products(X, self.X_, self.length, 0) exclusion_size = self.length // exclusion_factor + + if motif_size == np.inf: + motif_size = X.shape[1] - self.length + 1 + if self.normalize: MP, IP = _stomp_normalized( self.X_, @@ -260,6 +267,32 @@ def compute_matrix_profile( ) return MP, IP + @classmethod + def _get_test_params(cls, parameter_set: str = "default"): + """Return testing parameter settings for the estimator. + + Parameters + ---------- + parameter_set : str, default="default" + Name of the set of test parameters to return, for use in tests. If no + special parameters are defined for a value, will return `"default"` set. + There are currently no reserved values for transformers. + + Returns + ------- + params : dict or list of dict, default = {} + Parameters to create testing instances of the class + Each dict are parameters to construct an "interesting" test instance, i.e., + `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. + """ + if parameter_set == "default": + params = {"length": 3} + else: + raise NotImplementedError( + f"The parameter set {parameter_set} is not yet implemented" + ) + return params + @njit(cache=True, fastmath=True) def _stomp_normalized( @@ -330,7 +363,7 @@ def _stomp_normalized( variable size. """ n_queries = X_A.shape[1] - L + 1 - _max_timestamp = X_B.shape[1] - L + _max_timestamp = X_B.shape[1] - L + 1 MP = List() IP = List() @@ -347,7 +380,7 @@ def _stomp_normalized( dist_profile = _inverse_distance_profile(dist_profile) if is_self_mp: - ub = min(i_q + exclusion_size, _max_timestamp) + ub = min(i_q + exclusion_size, _max_timestamp + 1) lb = max(0, i_q - exclusion_size) dist_profile[lb:ub] = np.inf @@ -425,7 +458,7 @@ def _stomp( variable size. """ n_queries = X_A.shape[1] - L + 1 - _max_timestamp = X_B.shape[1] - L + _max_timestamp = X_B.shape[1] - L + 1 MP = List() IP = List() @@ -440,7 +473,7 @@ def _stomp( dist_profile = _inverse_distance_profile(dist_profile) if is_self_mp: - ub = min(i_q + exclusion_size, _max_timestamp) + ub = min(i_q + exclusion_size, _max_timestamp + 1) lb = max(0, i_q - exclusion_size) dist_profile[lb:ub] = np.inf diff --git a/aeon/similarity_search/series/neighbors/_dummy.py b/aeon/similarity_search/series/neighbors/_dummy.py index 7b4d4d89da..a3120f98dd 100644 --- a/aeon/similarity_search/series/neighbors/_dummy.py +++ b/aeon/similarity_search/series/neighbors/_dummy.py @@ -132,6 +132,32 @@ def compute_distance_profile(self, X: np.ndarray): X = z_normalise_series_2d(X) return _naive_squared_distance_profile(self.X_subs, X) + @classmethod + def _get_test_params(cls, parameter_set: str = "default"): + """Return testing parameter settings for the estimator. + + Parameters + ---------- + parameter_set : str, default="default" + Name of the set of test parameters to return, for use in tests. If no + special parameters are defined for a value, will return `"default"` set. + There are currently no reserved values for transformers. + + Returns + ------- + params : dict or list of dict, default = {} + Parameters to create testing instances of the class + Each dict are parameters to construct an "interesting" test instance, i.e., + `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. + """ + if parameter_set == "default": + params = {"length": 3} + else: + raise NotImplementedError( + f"The parameter set {parameter_set} is not yet implemented" + ) + return params + @njit(cache=True, fastmath=True, parallel=True) def _naive_squared_distance_profile( diff --git a/aeon/similarity_search/series/neighbors/_mass.py b/aeon/similarity_search/series/neighbors/_mass.py index 9565407fc8..befc8b33fd 100644 --- a/aeon/similarity_search/series/neighbors/_mass.py +++ b/aeon/similarity_search/series/neighbors/_mass.py @@ -165,6 +165,32 @@ def compute_distance_profile(self, X: np.ndarray): return distance_profile + @classmethod + def _get_test_params(cls, parameter_set: str = "default"): + """Return testing parameter settings for the estimator. + + Parameters + ---------- + parameter_set : str, default="default" + Name of the set of test parameters to return, for use in tests. If no + special parameters are defined for a value, will return `"default"` set. + There are currently no reserved values for transformers. + + Returns + ------- + params : dict or list of dict, default = {} + Parameters to create testing instances of the class + Each dict are parameters to construct an "interesting" test instance, i.e., + `MyClass(**params)` or `MyClass(**params[i])` creates a valid test instance. + """ + if parameter_set == "default": + params = {"length": 3} + else: + raise NotImplementedError( + f"The parameter set {parameter_set} is not yet implemented" + ) + return params + @njit(cache=True, fastmath=True) def _squared_distance_profile(QT, T, Q): diff --git a/examples/similarity_search/similarity_search.ipynb b/examples/similarity_search/similarity_search.ipynb index 803398d551..53e5a9bcc5 100644 --- a/examples/similarity_search/similarity_search.ipynb +++ b/examples/similarity_search/similarity_search.ipynb @@ -275,9 +275,9 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -288,7 +288,7 @@ "distance_profile = snn.compute_distance_profile(\n", " series_predict[:, starting_timestep_predict : starting_timestep_predict + length],\n", ")\n", - "plt.figure(figsize=(5, 3))\n", + "plt.figure(figsize=(7, 2))\n", "plt.plot(distance_profile)\n", "plt.show()" ] @@ -301,19 +301,104 @@ "### 1.2 Motif search with STOMP" ] }, + { + "attachments": { + "f492cb89-5bf3-4641-8be2-a77805f20b88.png": { + "image/png": "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JiYmzL+VTpw40b17d/pZz4iIiO7duwcFBVEUJRAIjIyMVq5c2YF/FmoCFpcgAAEIQAACEIAABCCgVQIoc7bDdJw6derbb79lOrazs3v33XeVF3diLnXmA6bMqaebry+++EJrP95LlzmJupfyeyw4OLhfv37MgrQBAQFdunTJzMykKGr58uXr16+nGysUilWrVn399dfK9+JYVwSEQmF0dHRZWdmlS5eY35W3e/IBAQH1ypz79u0bNGgQU/j08vLq168fRVEkSfbu3dva2prJee7cub///jtFUYmJiT179kxNTaUvxcfH9+zZ8+HDh0xLHLAlEB4e3r9///z8fLYCam2c2NjYl5U5663WS5Lk5MmTJ06cyJzncDizZ8+mKConJ+df//rXjRs36GGSJDlw4EAPDw+tHTUS0xWBjIyMDz/88MSJExRFJScn9+nTx9/fn04+Ly/vtddeu3XrFkVR+/bte+ONN2pqauhLzs7O33zzTXnda+DAgRwOhz5PkuSoUaP27t2rK8NHnlorIBaLJ0yYQP/VTFEUXeYkCKJeNSgoKOjtt98WCAT0QNzd3d999116gdDly5dPmDCBaT9nzpy5c+fWW9lea4ePxLRZwMLCYsqUKXSGU6ZMYb4BymSypUuXjhs3jqIouVz+7rvvMgvSxsfHd+/e/fbt2xRFHTlyZNiwYcw7c/fu3R9//DH+Fa/NM47cIAABCEAAAhCAAAQ6iQDKnO0w0Rs3bly6dCnT8d27d998801mPUbmfCc/QJlTfW8Ac3Pznj179ujRo2fPnkuXLk1LS6P7srOzGzlyZFVVFf1lXFzc+++/T6/HOGTIEAcHByYlKyurbt26VVZWMmdwoP0CJEkSBGFvb//tt98yv6DRkrQbljkXL148atQoZgvDjIyM119/vaamprS09NVXX1V+mPjPP/8cOXIkRVFXrlwZOHAgU3vLyckZMGDA2bNntWSMHSMNoVBoaWmZl5fXSdZcfVmZs3fv3t26dfv0008dHBzo74RCoXDIkCFr165lJvr69etffPEFRVGBgYFvvvlmSEgIc2nSpEk7duxgvsQBBFoncO/evW7duj158oSiqOjo6DfffFN5E4QuXbocOXKEIIgNGzYMHTqU6eLhw4cffPBBfn5+Wlpa3759z507x1xav3798uXLmS9xAIHWCWRlZX344YfMNz0LC4ue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AbVavWPHDm9vb8wD3zEaDGuJBJAAEkACSAAJIAEkgASQABJAAkgACSABJIAEkAASaFsCKHO2Le+OeTSdTtfU1IRxU9um9RYvXlxSUoLA24Y2HqU9E1CpVBs3bly4cCGGq23PzYR1QwJIAAkgASSABJAAEkACSAAJIAEkgASQABJAAkgACTwrAihzPivyHem4TCbz+++/P3XqVEeqNK2uAQEBQUFBtA/a6Wptba1KpVq5cuWlS5faaRWxWkigrQhcuHDBycmJx+OpVKq2OiYeBwkgASSABJAAEkACSAAJIAEkgASQABJAAkgACSABJIAEOhIBlDk7Ums9q7ryeLyNGzdeu3btWVXgKY87efJkOzu7pyyktXevr68fNGjQxYsXW/tAWD4SaP8EdDpdUlKSmZmZQCBo/7XFGiIBJIAEkAASQAJIAAkgASSABJAAEkACSAAJIAEkgASQwDMhgDLnM8HewQ7K5/OzsrKampo6WL07SHWlUmlkZKRWq42NjRWJRB2k1lhNJNBaBBoaGlauXFlTU6NUKlvrGFguEkACSAAJIAEkgASQABJAAkgACSABJIAEkAASQAJIAAl0fAIoc3b8Nmx9C86cOdOnT5+O61ZlZmbm6OjY+pye8AiFhYVDhw6trKx8wv1xNyTQuQhUVVV98sknZWVlncsstAYJIAEkgASQABJAAkgACSABJIAEkAASQAJIAAkgASSABFqYAMqcLQy0UxbH4/ESExM7rml+fn779u1rh/W/evWqs7OzWq1mMpntsHpYJSTQxgS0Wm1AQEBeXp5CodDpdG18dDwcEkACSAAJIAEkgASQABJAAkgACSABJIAEkAASQAJIAAl0LAIoc3as9no2tU1LS4uNjX02x+6kR9VoNHK5vKamxsnJCeWcTtrIaNZjE1CpVLa2tikpKY+9J+6ABJAAEkACSAAJIAEkgASQABJAAkgACSABJIAEkAASQAJdjwDKnF2vzR/fYl9f30WLFj3+fu1lj0mTJtnY2LSX2ujrERQU9NVXX7WrKmFlkMCzJZCUlHT27FmVSqXRaJ5tTfDoSAAJIAEkgASQABJAAkgACSABJIAEkAASQAJIAAkgASTQIQigzNkhmukZV1Iul0ul0mdciac4PIvFYrPZT1FAS+5669at7OxsDodz/fr1liwXy0ICHZzAggULvL29O7gRWH0kgASQ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7tzZ2to6yNxIPrEJtLS01NfXV1VVlZeXFxcX5+fn5+TkZGRkpKSkJCYmxt+4LSEhISUlJT09PTs7Oz8/v6ioqKysrLKysra2trm5eVShSySSCXXTo7IgAAIgAAI3DwHInDdPX6IlIAACIAACIAACIAACIAACIAACIAACIAACgyVw6dKlxwa/3XbbbTY2No888sjgsyLHxCbwm9/85uGHH54/f/69995ra2t7xx13zJkzZ9asWdOnT58yZQrnxm02NjbTp0+/5ZZb5syZc/vtt9va2t5zzz3z589/6KGHfvOb34wqdHd398Hed0gPAiAAAiAAAiNCADLniGBEISAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAhOSgLe39++xgQAIDIPArl27JuTNj0qDAAiAAAhMfAKQOSd+H6IFIAACIAACIAACIAACIAACIAACIAACIAACQyVgNBpV2EAABIZBQK/XD/X+Qz4QAAEQAAEQGBYByJzDwofMIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACY08AMufYM8cZQQAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEhkUAMuew8CEzCIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIDA2BOAzDn2zHFGEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEACBYRGAzDksfMgMAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAw9gQgc449c5wRBEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEBgWAQgcw4LHzKDAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiMPQHInGPPHGcEARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAYFgHInMPCh8wgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAJjTwAy59gzxxlBAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAASGRQAy57DwITMIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgMDYE4DMOfbMcUYQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAIFhEYDMOSx8yAwCIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIDD2BCBzjj1znBEEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQGBYBCBzDgsfMoMACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIw9AcicY88cZwQBEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEBgWAcicw8KHzCAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAmNPADLn2DPHGUEABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABEAABIZFADLnsPAhMwiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAwNgTgMw59sxxRhAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAgWERgMw5LHzIDAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgMPYEIHOOPXOcEQRAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAYFgEIHMOCx8ygwAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIjD0ByJxjzxxnBAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQGBYByJzDwofMIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACIAACY08AMufYM8cZQQAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEQAAEhkVgXMicFoslNDR0w4YNe/bsGVZrWJnNZvPevXs3bNhw/vx51uHh7ppMpvPnz2/YsOHw4cPDLetG5zeZTK6urhs2bAgMDLzRdcH5bzABPp8fHx9/5syZn376KSsr6wbXpt/Tc7nczZs3f/vtt5WVlf0mHPSXWVlZGzdu3Llzp0KhGHRmZACBG01Ao9EUFBT4+PicPn06ODhYLpcPoUYymSwpKeno0aPu7u6bNm1ydHTcu3dvQEBAS0uLxWIZQoHIAgK/SKCoqOibb75xdXXl8/m/mHggCSwWi6+v74YNG44ePTqQ9EgzGgTMZnNFRUVgYODp06cvX77c0dExGmdBmeOcgMFg8PDw2LBhw5kzZ0a2qkaj0cnJacOGDXFxcSNbMkoDgYlFQCaTZWRkXLp06cyZMzExMROr8qgtIaDX68m0zLlz50aKicFgcHR03LBhQ1pa2kiViXJAYJgETCZTeXl5QEDA6dOnvb29eTzeMAtE9uETEIlEYWFhQdYtJCREJpP1LtNoNHZ0dNTW1tbU1NTX16tUqvr6epIlKCgoODjYaDT2zoUjo0FAp9N1sTaRSGQ2m/s5kVqtbm5ubmhoqKysbG5u7j9xP+XgKxCYKATGhcwpFAofe+wxDofz6aefjiC49evXc6xbQUHBSBVbVlZ233332djYuLu7kzK9vLzmzZtnO6Tt/fffH6mKDa2c9957j8PhzJ49u76+fmgldHd3y2Sy+fPn9wPgvvvue+KJJ959991z5861tbUZDIYhn6ufjD/88APpiJ9++qmfZEP7KjMz89577yVtfOSRRwYrBJrN5jVr1lBEq1evHlo1hpzr73//Ozl7bGxs70ISExOnT59ObhYOh2Nvb987zTg5YjabV65cyeFwbG1tW1tb2bX673//S9qoVCrZxwe+n5CQcOutt3I4nJMnTw48F02pVCr/8Ic/kDpERUXR47+409HR8cADD/TTQb9YAjvB/v37SVFNTU3s4zfTvr29va2t7d13361SqQbVrl//+tcEjq2t7SeffDKovN3d3S0tLb/61a9ICfPmzevzbhpsmQNPz+PxyJO2zx9Kg8FAnufkRp43b15xcfHACydP8j179tx22230UcDemTp16gcffCAUCiF2DooqEv8iAZPJ9PLLL3M4nBdeeEEikfxi+gEm8PT0JBfwcO7TmJgYcr97enoO8LyDTfbQQw/Rh9KuXbsGmz0kJOSee+4hJTz11FO1tbWDLWE46UnlFy1aJBQKe5RjNBq3bNliY2NDesHGxuby5cs90uDjZCDg6+s7xboFBwcPub0BAQFkEF5WVsYuZPny5RwO54knnhjOConW1tbnnnvO1tZ25cqV7MKx34PAgw8+aGtra2dnN4IP6h6nGL2PpPLkUXngwIHBnujKlSt33303yf773/++ubl5sCUMJz2p/LJly6RSae9y+Hz+888/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" + } + }, + "cell_type": "markdown", + "id": "6aecb58e-9de9-4264-959e-4180ab3fa27a", + "metadata": {}, + "source": [ + "When doing motif search, it's important to define the type of motif you want to extract from a series. We'll use the figure and definitions given by [1] :\n", + "\n", + "![image.png](attachment:f492cb89-5bf3-4641-8be2-a77805f20b88.png)\n", + "\n", + "For now, the `StompMotif` estimators supports only \"Pair motifs\", \"k-Motiflets\", and \"k-motifs\". Note that the naming \"k-motifs\" is a bit confusing, it extract motifs based on a range parameter and not by number of closests neihbors. To choose the type of motifs you want to extract, you will have to use the parameters of the `predict` method :\n", + "\n", + "- for **\"Pair Motifs\"** : This is the default configuration\n", + "\n", + "- for **\"k-Motiflets\"** : ```{\"motif_size\": k}```\n", + "\n", + "- for **\"k-motifs\"** : ```{\"motif_size\": np.inf, \"dist_threshold\": r, \"motif_extraction_method\": \"r_motifs\"}```\n", + "\n", + "These configuration will extract the best motif only, if you want to extract more than one motifs, you can use the `k` parameter to extract the `top-k` motifs. \n", + "\n", + "**The term `k` of `top-k` motifs, while also used in `k-Motiflets`, is not the same. We use `motif_size` as the `k` in `k-Motiflets`. This is to avoid \"extraction the `top-k` `k-motiflets`\", which can lead to confusions. Rather, we extract the `top-k` `motif_size-motiflets`**.\n", + "\n", + "The `top-k` using `motif_extraction_method=\"r_motifs\"` will be the motif with the highest cardinality (i.e. the more matches in range `r`), while for `motif_extraction_method=\"k_motifs\"`,which is the default value, the best motifs will be those who minimize the maximum pairwise distance." + ] + }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "id": "ff23faf5-2941-441a-8c4c-0cf66eaca121", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "([array([0.02910451])], [array([[7, 0]], dtype=int64)])" + "([array([2.16605047]),\n", + " array([3.23155459]),\n", + " array([8.15076681]),\n", + " array([8.15076681]),\n", + " array([26.42906254])],\n", + " [array([[13, 30]], dtype=int64),\n", + " array([[31, 13]], dtype=int64),\n", + " array([[108, 77]], dtype=int64),\n", + " array([[ 77, 108]], dtype=int64),\n", + " array([[59, 76]], dtype=int64)])" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from aeon.similarity_search.series import StompMotif\n", + "\n", + "motif = StompMotif(length=length, normalize=True).fit(series_fit)\n", + "motif.predict(\n", + " k=5,\n", + " motif_size=1,\n", + " motif_extraction_method=\"k_motifs\",\n", + " allow_trivial_matches=False,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d16036a3-f5b9-41d2-ae23-a1bcf0737c93", + "metadata": {}, + "source": [ + "\n", + "Note that we also support giving another series in `predict`, which will use this series to search for the motifs matching subsequences in the series given during `fit`. For those familiar with the matrix profile notations, this is the case of using `MP(A,B)`, while not using a series in `predict` is doing a self matrix profile `MP(A,A)`." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "59117ea7-2cbf-49d6-829a-792805b4aaf7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([array([0.01197907]),\n", + " array([0.0622802]),\n", + " array([0.14565364]),\n", + " array([0.70546699]),\n", + " array([1.19303001])],\n", + " [array([[83, 78]], dtype=int64),\n", + " array([[50, 49]], dtype=int64),\n", + " array([[32, 30]], dtype=int64),\n", + " array([[9, 4]], dtype=int64),\n", + " array([[101, 95]], dtype=int64)])" ] }, - "execution_count": 6, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -321,9 +406,65 @@ "source": [ "from aeon.similarity_search.series import StompMotif\n", "\n", - "motif = StompMotif(length=length).fit(series_fit)\n", - "motif.predict(series_predict)" + "motif.predict(\n", + " series_predict,\n", + " k=5,\n", + " motif_size=1,\n", + " motif_extraction_method=\"k_motifs\",\n", + " allow_trivial_matches=False,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9190fdf4-db3d-4d51-b2c8-41b88a9f6f74", + "metadata": {}, + "source": [ + "You can also return the matrix profile with the same parameterization as `predict` (minus `motif_extraction_method` parameter) using :" ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4c36738a-e6a0-4452-aee2-ccbad99d6d8b", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "MP, IP = motif.compute_matrix_profile()\n", + "\n", + "plt.figure(figsize=(7, 2))\n", + "plt.plot([MP[i][0] for i in range(len(MP))])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1610adf3-5cb1-466e-9cad-fb248148fd5a", + "metadata": {}, + "source": [ + "## References\n", + "[1] Patrick Schäfer and Ulf Leser. 2022. Motiflets: Simple and Accurate Detection\n", + " of Motifs in Time Series. Proc. VLDB Endow. 16, 4 (December 2022), 725–737." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "989ba9f2-6dd8-4db7-9dfc-783aac5e6fcb", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From 763bdcf2794670ceee7ce375868d66c859ad830e Mon Sep 17 00:00:00 2001 From: baraline Date: Sun, 19 Jan 2025 20:41:47 +0100 Subject: [PATCH 17/18] Fix identifiers and test data shape for all_estimators tests --- aeon/similarity_search/collection/__init__.py | 5 +- aeon/similarity_search/collection/_base.py | 14 +---- .../collection/neighbors/_rp_cosine_lsh.py | 6 ++- aeon/similarity_search/series/_base.py | 9 +--- .../similarity_search/series/motifs/_stomp.py | 1 + .../series/neighbors/_dummy.py | 17 ++++-- .../series/tests/test_commons.py | 4 +- aeon/testing/testing_data.py | 52 +++++-------------- aeon/utils/base/_identifier.py | 2 + aeon/utils/tags/_tags.py | 2 +- .../similarity_search/similarity_search.ipynb | 12 ++--- 11 files changed, 46 insertions(+), 78 deletions(-) diff --git a/aeon/similarity_search/collection/__init__.py b/aeon/similarity_search/collection/__init__.py index ab3a546193..3a08ed22d6 100644 --- a/aeon/similarity_search/collection/__init__.py +++ b/aeon/similarity_search/collection/__init__.py @@ -1,5 +1,8 @@ """Similarity search for time series collection.""" -__all__ = ["BaseCollectionSimilaritySearch"] +__all__ = ["BaseCollectionSimilaritySearch", "RandomProjectionIndexANN"] from aeon.similarity_search.collection._base import BaseCollectionSimilaritySearch +from aeon.similarity_search.collection.neighbors._rp_cosine_lsh import ( + RandomProjectionIndexANN, +) diff --git a/aeon/similarity_search/collection/_base.py b/aeon/similarity_search/collection/_base.py index 618a531081..cbbf8de1e9 100644 --- a/aeon/similarity_search/collection/_base.py +++ b/aeon/similarity_search/collection/_base.py @@ -9,7 +9,6 @@ from typing import Union, final import numpy as np -from numba import get_num_threads, set_num_threads from aeon.base import BaseCollectionEstimator from aeon.similarity_search._base import BaseSimilaritySearch @@ -22,16 +21,9 @@ class BaseCollectionSimilaritySearch(BaseCollectionEstimator, BaseSimilaritySear _tags = { "input_data_type": "Collection", "capability:multivariate": True, - "capability:unequal_length": True, - "capability:multithreading": True, - "X_inner_type": ["np-list", "numpy3D"], + "X_inner_type": ["numpy3D"], } - @abstractmethod - def __init__(self, n_jobs=1): - self.n_jobs = n_jobs - super().__init__() - @final def fit( self, @@ -63,11 +55,7 @@ def fit( # Store minimum number of n_timepoints for unequal length collections self.n_channels_ = X[0].shape[0] self.n_cases_ = len(X) - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) self._fit(X, y=y) - set_num_threads(prev_threads) - self.is_fitted = True return self diff --git a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py index a6f3097f78..1fad3f08f7 100644 --- a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py +++ b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py @@ -1,7 +1,7 @@ """Random projection LSH index.""" import numpy as np -from numba import njit, prange +from numba import get_num_threads, njit, prange, set_num_threads from aeon.similarity_search.collection._base import BaseCollectionSimilaritySearch from aeon.utils.numba.general import z_normalise_series_2d, z_normalise_series_3d @@ -134,6 +134,8 @@ def _fit(self, X, y=None): self """ + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) rng = np.random.default_rng(self.random_state) if self.normalize: X = z_normalise_series_3d(X) @@ -171,7 +173,7 @@ def _fit(self, X, y=None): self.bool_hashes_value_list_ = np.asarray(list(self.dict_bool_hashes_.values())) self.bool_hashes_key_list_ = np.asarray(list(self.dict_bool_hashes_.keys())) - + set_num_threads(prev_threads) return self def _get_bucket_content(self, key): diff --git a/aeon/similarity_search/series/_base.py b/aeon/similarity_search/series/_base.py index 2e1b6d40e0..6ee1f27270 100644 --- a/aeon/similarity_search/series/_base.py +++ b/aeon/similarity_search/series/_base.py @@ -4,7 +4,6 @@ from typing import Union, final import numpy as np -from numba import get_num_threads, set_num_threads from aeon.base import BaseSeriesEstimator from aeon.similarity_search._base import BaseSimilaritySearch @@ -20,8 +19,7 @@ class BaseSeriesSimilaritySearch(BaseSeriesEstimator, BaseSimilaritySearch): } @abstractmethod - def __init__(self, axis=1, n_jobs=1): - self.n_jobs = n_jobs + def __init__(self, axis=1): super().__init__(axis=axis) @final @@ -56,12 +54,7 @@ def fit( self.n_channels_ = X.shape[0] self.n_timepoints_ = X.shape[1] self.X_ = X - - prev_threads = get_num_threads() - set_num_threads(self._n_jobs) self._fit(X, y=y) - set_num_threads(prev_threads) - self.is_fitted = True return self diff --git a/aeon/similarity_search/series/motifs/_stomp.py b/aeon/similarity_search/series/motifs/_stomp.py index c912cdfacd..43bc76f049 100644 --- a/aeon/similarity_search/series/motifs/_stomp.py +++ b/aeon/similarity_search/series/motifs/_stomp.py @@ -233,6 +233,7 @@ def compute_matrix_profile( exclusion_size = self.length // exclusion_factor if motif_size == np.inf: + # convert infs here as numba seem to not be able to do == np.inf ? motif_size = X.shape[1] - self.length + 1 if self.normalize: diff --git a/aeon/similarity_search/series/neighbors/_dummy.py b/aeon/similarity_search/series/neighbors/_dummy.py index a3120f98dd..12bb7a1035 100644 --- a/aeon/similarity_search/series/neighbors/_dummy.py +++ b/aeon/similarity_search/series/neighbors/_dummy.py @@ -6,7 +6,7 @@ __all__ = ["DummySNN"] import numpy as np -from numba import njit, prange +from numba import get_num_threads, njit, prange, set_num_threads from aeon.similarity_search.series._base import BaseSeriesSimilaritySearch from aeon.similarity_search.series._commons import ( @@ -23,6 +23,8 @@ class DummySNN(BaseSeriesSimilaritySearch): """Estimator to compute the on profile and distance profile using brute force.""" + _tags = {"capability:multithreading": True} + def __init__( self, length: int, @@ -31,16 +33,21 @@ def __init__( ): self.length = length self.normalize = normalize - super().__init__(n_jobs=n_jobs) + self.n_jobs = n_jobs + super().__init__() def _fit( self, X: np.ndarray, y=None, ): + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) + self.X_subs = get_all_subsequences(self.X_, self.length, 1) if self.normalize: self.X_subs = z_normalise_series_3d(self.X_subs) + set_num_threads(prev_threads) return self def predict( @@ -128,9 +135,13 @@ def compute_distance_profile(self, X: np.ndarray): length of X_. """ + prev_threads = get_num_threads() + set_num_threads(self._n_jobs) if self.normalize: X = z_normalise_series_2d(X) - return _naive_squared_distance_profile(self.X_subs, X) + distance_profile = _naive_squared_distance_profile(self.X_subs, X) + set_num_threads(prev_threads) + return distance_profile @classmethod def _get_test_params(cls, parameter_set: str = "default"): diff --git a/aeon/similarity_search/series/tests/test_commons.py b/aeon/similarity_search/series/tests/test_commons.py index 774eee8dee..36e8b6babc 100644 --- a/aeon/similarity_search/series/tests/test_commons.py +++ b/aeon/similarity_search/series/tests/test_commons.py @@ -20,8 +20,8 @@ make_example_2d_numpy_series, ) -K_VALUES = [1, 3, np.inf] -THRESHOLDS = [np.inf, 0.7] +K_VALUES = [1, 3, 5] +THRESHOLDS = [np.inf, 1.5] NN_MATCHES = [False, True] EXCLUSION_SIZE = [3, 5] diff --git a/aeon/testing/testing_data.py b/aeon/testing/testing_data.py index eb134cddda..e6730c9958 100644 --- a/aeon/testing/testing_data.py +++ b/aeon/testing/testing_data.py @@ -10,7 +10,8 @@ from aeon.forecasting import BaseForecaster from aeon.regression import BaseRegressor from aeon.segmentation import BaseSegmenter -from aeon.similarity_search import BaseSimilaritySearch +from aeon.similarity_search.collection import BaseCollectionSimilaritySearch +from aeon.similarity_search.series import BaseSeriesSimilaritySearch from aeon.testing.data_generation import ( make_example_1d_numpy, make_example_2d_dataframe_collection, @@ -219,7 +220,7 @@ }, } -EQUAL_LENGTH_UNIVARIATE_SIMILARITY_SEARCH = { +EQUAL_LENGTH_UNIVARIATE_COLLETION_SIMILARITY_SEARCH = { "numpy3D": { "train": ( make_example_3d_numpy( @@ -401,7 +402,7 @@ }, } -EQUAL_LENGTH_MULTIVARIATE_SIMILARITY_SEARCH = { +EQUAL_LENGTH_MULTIVARIATE_COLLETION_SIMILARITY_SEARCH = { "numpy3D": { "train": ( make_example_3d_numpy( @@ -553,7 +554,7 @@ }, } -UNEQUAL_LENGTH_UNIVARIATE_SIMILARITY_SEARCH = { +UNEQUAL_LENGTH_UNIVARIATE_COLLETION_SIMILARITY_SEARCH = { "np-list": { "train": ( make_example_3d_numpy_list( @@ -685,30 +686,6 @@ }, } -UNEQUAL_LENGTH_MULTIVARIATE_SIMILARITY_SEARCH = { - "np-list": { - "train": ( - make_example_3d_numpy_list( - n_cases=10, - n_channels=2, - min_n_timepoints=10, - max_n_timepoints=20, - random_state=data_rng.randint(np.iinfo(np.int32).max), - return_y=False, - ), - None, - ), - "test": ( - make_example_2d_numpy_series( - n_timepoints=10, - n_channels=2, - random_state=data_rng.randint(np.iinfo(np.int32).max), - ), - None, - ), - }, -} - X_classification_missing_train, y_classification_missing_train = make_example_3d_numpy( n_cases=10, n_channels=1, @@ -828,7 +805,7 @@ FULL_TEST_DATA_DICT.update( { f"EqualLengthUnivariate-SimilaritySearch-{k}": v - for k, v in EQUAL_LENGTH_UNIVARIATE_SIMILARITY_SEARCH.items() + for k, v in EQUAL_LENGTH_UNIVARIATE_COLLETION_SIMILARITY_SEARCH.items() } ) FULL_TEST_DATA_DICT.update( @@ -846,7 +823,7 @@ FULL_TEST_DATA_DICT.update( { f"EqualLengthMultivariate-SimilaritySearch-{k}": v - for k, v in EQUAL_LENGTH_MULTIVARIATE_SIMILARITY_SEARCH.items() + for k, v in EQUAL_LENGTH_MULTIVARIATE_COLLETION_SIMILARITY_SEARCH.items() } ) FULL_TEST_DATA_DICT.update( @@ -863,8 +840,8 @@ ) FULL_TEST_DATA_DICT.update( { - f"UnequalLengthUnivariate-SimilaritySearch-{k}": v - for k, v in UNEQUAL_LENGTH_UNIVARIATE_SIMILARITY_SEARCH.items() + f"UnequalLengthUnivariate-CollectionSimilaritySearch-{k}": v + for k, v in UNEQUAL_LENGTH_UNIVARIATE_COLLETION_SIMILARITY_SEARCH.items() } ) FULL_TEST_DATA_DICT.update( @@ -879,12 +856,6 @@ for k, v in UNEQUAL_LENGTH_MULTIVARIATE_REGRESSION.items() } ) -FULL_TEST_DATA_DICT.update( - { - f"UnequalLengthMultivariate-SimilaritySearch-{k}": v - for k, v in UNEQUAL_LENGTH_MULTIVARIATE_SIMILARITY_SEARCH.items() - } -) FULL_TEST_DATA_DICT.update( { f"MissingValues-Classification-{k}": v @@ -1017,14 +988,15 @@ def _get_task_for_estimator(estimator): # collection data with continuous target labels elif isinstance(estimator, BaseRegressor): data_label = "Regression" - elif isinstance(estimator, BaseSimilaritySearch): - data_label = "SimilaritySearch" + elif isinstance(estimator, BaseCollectionSimilaritySearch): + data_label = "CollectionSimilaritySearch" # series data with no secondary input elif ( isinstance(estimator, BaseAnomalyDetector) or isinstance(estimator, BaseSegmenter) or isinstance(estimator, BaseSeriesTransformer) or isinstance(estimator, BaseForecaster) + or isinstance(estimator, BaseSeriesSimilaritySearch) ): data_label = "None" else: diff --git a/aeon/utils/base/_identifier.py b/aeon/utils/base/_identifier.py index cf2722cfcb..03e8d8beaf 100644 --- a/aeon/utils/base/_identifier.py +++ b/aeon/utils/base/_identifier.py @@ -55,6 +55,8 @@ def get_identifier(estimator): identifiers.remove("collection-estimator") if len(identifiers) > 1 and "transformer" in identifiers: identifiers.remove("transformer") + if len(identifiers) > 1 and "similarity-search" in identifiers: + identifiers.remove("similarity-search") if len(identifiers) > 1: TypeError( diff --git a/aeon/utils/tags/_tags.py b/aeon/utils/tags/_tags.py index e1bacdd5ad..d85ba87caa 100644 --- a/aeon/utils/tags/_tags.py +++ b/aeon/utils/tags/_tags.py @@ -138,7 +138,7 @@ class : identifier for the base class of objects this tag applies to "point belongs to.", }, "requires_y": { - "class": ["transformer", "anomaly-detector", "segmenter"], + "class": ["transformer", "anomaly-detector", "segmenter", "similarity-search"], "type": "bool", "description": "Does this estimator require y to be passed in its methods?", }, diff --git a/examples/similarity_search/similarity_search.ipynb b/examples/similarity_search/similarity_search.ipynb index 53e5a9bcc5..91024292ef 100644 --- a/examples/similarity_search/similarity_search.ipynb +++ b/examples/similarity_search/similarity_search.ipynb @@ -332,7 +332,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "id": "ff23faf5-2941-441a-8c4c-0cf66eaca121", "metadata": {}, "outputs": [ @@ -351,7 +351,7 @@ " array([[59, 76]], dtype=int64)])" ] }, - "execution_count": 11, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -363,8 +363,6 @@ "motif.predict(\n", " k=5,\n", " motif_size=1,\n", - " motif_extraction_method=\"k_motifs\",\n", - " allow_trivial_matches=False,\n", ")" ] }, @@ -379,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "id": "59117ea7-2cbf-49d6-829a-792805b4aaf7", "metadata": {}, "outputs": [ @@ -398,7 +396,7 @@ " array([[101, 95]], dtype=int64)])" ] }, - "execution_count": 12, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -410,8 +408,6 @@ " series_predict,\n", " k=5,\n", " motif_size=1,\n", - " motif_extraction_method=\"k_motifs\",\n", - " allow_trivial_matches=False,\n", ")" ] }, From 85c71741af20e7587971b4c7b8a4a06939474a24 Mon Sep 17 00:00:00 2001 From: baraline Date: Mon, 20 Jan 2025 08:50:40 +0100 Subject: [PATCH 18/18] Fix missing params --- .../collection/neighbors/_rp_cosine_lsh.py | 3 ++- .../collection/tests/test_base.py | 16 ++++------------ .../series/tests/test_commons.py | 4 ++-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py index 1fad3f08f7..61142d6f83 100644 --- a/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py +++ b/aeon/similarity_search/collection/neighbors/_rp_cosine_lsh.py @@ -116,7 +116,8 @@ def __init__( self.use_discrete_vectors = use_discrete_vectors self.random_state = random_state self.normalize = normalize - super().__init__(n_jobs=n_jobs) + self.n_jobs = n_jobs + super().__init__() def _fit(self, X, y=None): """ diff --git a/aeon/similarity_search/collection/tests/test_base.py b/aeon/similarity_search/collection/tests/test_base.py index 9180a071cf..c1efaa30f0 100644 --- a/aeon/similarity_search/collection/tests/test_base.py +++ b/aeon/similarity_search/collection/tests/test_base.py @@ -11,7 +11,6 @@ make_example_1d_numpy, make_example_2d_numpy_series, make_example_3d_numpy, - make_example_3d_numpy_list, ) @@ -21,8 +20,6 @@ def test_input_shape_fit_predict_collection(): # dummy data to pass to fit when testing predict/predict_proba X_3D_uni = make_example_3d_numpy(n_channels=1, return_y=False) X_3D_multi = make_example_3d_numpy(n_channels=2, return_y=False) - X_3D_uni_list = make_example_3d_numpy_list(n_channels=1, return_y=False) - X_3D_multi_list = make_example_3d_numpy_list(n_channels=2, return_y=False) X_2D_uni = make_example_2d_numpy_series(n_channels=1) X_2D_multi = make_example_2d_numpy_series(n_channels=2) X_1D = make_example_1d_numpy() @@ -31,8 +28,6 @@ def test_input_shape_fit_predict_collection(): valid_inputs_fit = [ X_3D_uni, X_3D_multi, - X_3D_multi_list, - X_3D_uni_list, X_2D_uni, X_2D_multi, ] @@ -53,10 +48,7 @@ def test_input_shape_fit_predict_collection(): estimator_uni.predict(X_2D_multi) with pytest.raises(ValueError): estimator_multi.predict(X_2D_uni) - - for _input in [X_3D_uni, X_3D_uni_list]: - with pytest.raises(TypeError): - estimator_uni.predict(_input) - for _input in [X_3D_multi, X_3D_multi_list]: - with pytest.raises(TypeError): - estimator_multi.predict(_input) + with pytest.raises(TypeError): + estimator_uni.predict(X_3D_uni) + with pytest.raises(TypeError): + estimator_multi.predict(X_3D_multi) diff --git a/aeon/similarity_search/series/tests/test_commons.py b/aeon/similarity_search/series/tests/test_commons.py index 36e8b6babc..6f2c816193 100644 --- a/aeon/similarity_search/series/tests/test_commons.py +++ b/aeon/similarity_search/series/tests/test_commons.py @@ -109,7 +109,7 @@ def test__extract_top_k_motifs(): [0, 7], ] ) - MP_k, IP_k = _extract_top_k_motifs(MP, IP, 2) + MP_k, IP_k = _extract_top_k_motifs(MP, IP, 2, True, 0) assert_(len(MP_k) == 2) assert_(MP_k[0] == [0.6, 0.7]) assert_(IP_k[0] == [0, 7]) @@ -135,7 +135,7 @@ def test__extract_top_r_motifs(): [0, 7], ] ) - MP_k, IP_k = _extract_top_r_motifs(MP, IP, 2) + MP_k, IP_k = _extract_top_r_motifs(MP, IP, 2, True, 0) assert_(len(MP_k) == 2) assert_(MP_k[0] == [1.0, 1.5, 2.0, 1.5]) assert_(IP_k[0] == [1, 2, 3, 4])