{ "cells": [ { "cell_type": "markdown", "source": [ "# Preprocessing time series with aeon\n", "\n", "It is common to need to preprocess time series data before applying machine learning\n", "algorithms. So algorithms can handle these characteristics, or `aeon` transformers can be used to preprocess collections of time\n", "series into standard format. This notebook demonstrates three common use cases\n", "\n", "1. [Rescaling time series](#Rescaling-time-series)\n", "2. [Resizing time series](#Resizing-time-series)\n", "3. [Dealing with missing values](#missing-values)\n" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "## Rescaling time series\n", "\n", "Different levels of scale and variance can mask discriminative patterns in time\n", "series. This is particularly true for methods that are based on distances. It common\n", "to rescale time series to have zero mean and unit variance. For example, the data in\n", "the `UnitTest` dataset is a subset of the [Chinatown dataset]\n", "(https://timeseriesclassification.com/description.php?Dataset=Chinatown. These are\n", "counts of pedestrians in Chinatown, Melbourne. The time series are of different means" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "source": [ "import numpy as np\n", "\n", "from aeon.datasets import load_unit_test\n", "\n", "X, y = load_unit_test(split=\"Train\")\n", "np.mean(X, axis=-1)[0:5]" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:48:57.655001Z", "start_time": "2024-11-17T13:48:57.631756Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[561.875 ],\n", " [604.95833333],\n", " [629.16666667],\n", " [801.45833333],\n", " [540.75 ]])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 3 }, { "cell_type": "code", "source": [ "np.std(X, axis=-1)[0:5]" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:48:59.467239Z", "start_time": "2024-11-17T13:48:59.458263Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[428.95224215],\n", " [483.35481095],\n", " [514.90052977],\n", " [629.00847763],\n", " [389.10059218]])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 4 }, { "cell_type": "markdown", "source": [ "We can rescale the time series in three ways:\n", "1. Normalise: subtract the mean and divide by the standard deviation to make all\n", "series have zero mean and unit variance." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "source": [ "from aeon.transformations.collection import Normalizer\n", "\n", "normalizer = Normalizer()\n", "X2 = normalizer.fit_transform(X)\n", "np.round(np.mean(X2, axis=-1)[0:5], 6)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:49:01.643630Z", "start_time": "2024-11-17T13:49:01.627083Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.],\n", " [-0.],\n", " [ 0.],\n", " [-0.],\n", " [-0.]])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 5 }, { "cell_type": "code", "source": [ "np.round(np.std(X2, axis=-1)[0:5], 6)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:49:02.670358Z", "start_time": "2024-11-17T13:49:02.648594Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[1.],\n", " [1.],\n", " [1.],\n", " [1.],\n", " [1.]])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 6 }, { "cell_type": "markdown", "source": [ "2. Re-center: Recentering involves subtracting the mean of each series" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "source": [ "from aeon.transformations.collection import Centerer\n", "\n", "c = Centerer()\n", "X3 = c.fit_transform(X)\n", "np.round(np.mean(X3, axis=-1)[0:5], 6)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:49:04.345033Z", "start_time": "2024-11-17T13:49:04.332065Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.],\n", " [-0.],\n", " [ 0.],\n", " [-0.],\n", " [ 0.]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 7 }, { "cell_type": "markdown", "source": [ "3. Min-Max: Scale the data to be between 0 and 1" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "source": [ "from aeon.transformations.collection import MinMaxScaler\n", "\n", "minmax = MinMaxScaler()\n", "X4 = minmax.fit_transform(X)\n", "np.round(np.min(X4, axis=-1)[0:5], 6)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:49:06.135780Z", "start_time": "2024-11-17T13:49:06.116831Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[0.],\n", " [0.],\n", " [0.],\n", " [0.],\n", " [0.]])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 8 }, { "cell_type": "code", "source": [ "np.round(np.max(X4, axis=-1)[0:5], 6)" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-11-17T13:49:07.094710Z", "start_time": "2024-11-17T13:49:07.072733Z" } }, "outputs": [ { "data": { "text/plain": [ "array([[1.],\n", " [1.],\n", " [1.],\n", " [1.],\n", " [1.]])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 9 }, { "cell_type": "markdown", "source": [ "There is no best way to do this, although for counts such as this it is more common\n", "to MinMax scale, so that the data still has some interpretation as proportions." ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Resizing time series\n", "\n", "Suppose we have a collections of time series with different lengths, i.e. different\n", "number of time points. Currently, most of aeon's collection estimators\n", "(classification, clustering or regression) require equal-length time\n", "series. Those that can handle unequal length series are tagged with\n", "\"capability:unequal\"." ] }, { "cell_type": "code", "metadata": { "execution": { "iopub.execute_input": "2020-12-19T14:31:58.456171Z", "iopub.status.busy": "2020-12-19T14:31:58.455565Z", "iopub.status.idle": "2020-12-19T14:31:59.189497Z", "shell.execute_reply": "2020-12-19T14:31:59.190005Z" }, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:37:35.086084Z", "start_time": "2025-05-28T13:36:09.244708Z" } }, "source": [ "from aeon.classification.convolution_based import RocketClassifier\n", "from aeon.datasets import (\n", " load_basic_motions,\n", " load_japanese_vowels,\n", " load_pickup_gesture_wiimoteZ,\n", ")\n", "from aeon.utils.validation import has_missing, is_equal_length, is_univariate" ], "outputs": [], "execution_count": 2 }, { "cell_type": "markdown", "source": [ "If you want to use an estimator that cannot internally handle missing values, one\n", "option is to convert unequal length series into equal length. This can be\n", " done through padding, truncation or resizing through fitting a function and\n", " resampling." ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Unequal or equal length collections time series\n", "\n", "If a collection contains all equal length series, it will store the data in a 3D\n", "numpy of shape `(n_cases, n_channels, n_timepoints)`. If it is unequal length, it is\n", "stored in a list of 2D numpy arrays:" ] }, { "cell_type": "code", "metadata": { "execution": { "iopub.execute_input": "2020-12-19T14:31:59.194445Z", "iopub.status.busy": "2020-12-19T14:31:59.193903Z", "iopub.status.idle": "2020-12-19T14:32:01.019896Z", "shell.execute_reply": "2020-12-19T14:32:01.020463Z" }, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:37:44.511744Z", "start_time": "2025-05-28T13:37:44.488521Z" } }, "source": [ "# Equal length multivariate data\n", "bm_X, bm_y = load_basic_motions()\n", "X = bm_X\n", "print(f\"{type(X)}, {X.shape}\")\n", "print(\n", " f\"univariate = {is_univariate(X)}, has missing ={has_missing(X)}, equal \"\n", " f\"length = {is_equal_length(X)}\"\n", ")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ", (80, 6, 100)\n", "univariate = False, has missing =False, equal length = True\n" ] } ], "execution_count": 6 }, { "cell_type": "code", "source": [ "# Unequal length univariate data\n", "wii_X, wii_y = load_pickup_gesture_wiimoteZ()\n", "X = wii_X\n", "print(type(wii_X), \"\\n\", wii_X[0].shape, \"\\n\", wii_X[10].shape)\n", "print(\n", " f\"univariate = {is_univariate(X)}, has missing ={has_missing(X)}, equal \"\n", " f\"length = {is_equal_length(X)}\"\n", ")" ], "metadata": { "collapsed": false, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:37:45.578203Z", "start_time": "2025-05-28T13:37:45.513828Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " \n", " (1, 324) \n", " (1, 97)\n", "univariate = True, has missing =False, equal length = False\n" ] } ], "execution_count": 7 }, { "metadata": { "ExecuteTime": { "end_time": "2025-05-28T13:37:49.679258Z", "start_time": "2025-05-28T13:37:49.639207Z" } }, "cell_type": "code", "source": [ "vowels_X, vowels_y = load_japanese_vowels(split=\"train\")\n", "X = vowels_X\n", "print(\n", " f\"univariate = {is_univariate(X)}, has missing ={has_missing(X)}, equal \"\n", " f\"length = {is_equal_length(X)}\"\n", ")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "univariate = False, has missing =False, equal length = False\n" ] } ], "execution_count": 8 }, { "cell_type": "markdown", "metadata": {}, "source": "\n" }, { "cell_type": "code", "source": [ "series_lengths = [array.shape[1] for array in wii_X]\n", "\n", "# Find the minimum and maximum of the second dimensions\n", "min_length = min(series_lengths)\n", "max_length = max(series_lengths)\n", "print(\" Min length = \", min_length, \" max length = \", max_length)" ], "metadata": { "collapsed": false, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:38:05.700223Z", "start_time": "2025-05-28T13:38:05.689668Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Min length = 29 max length = 361\n" ] } ], "execution_count": 9 }, { "metadata": {}, "cell_type": "markdown", "source": [ "There are two basic strategies for unequal length problems\n", "1. Use an estimator that can internally handle missing values\n", "2. Transform the data to be equal length by, for example, truncating or padding series\n", "\n", "Estimators with the tag `\"capability:unequal_length\": True` have the capability to\n", "handle unequal length series. For classification, regression and\n", "clusterign, the\n", "current list is" ] }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:49:23.280238Z", "start_time": "2024-11-17T13:49:23.143830Z" } }, "cell_type": "code", "source": [ "from aeon.utils.discovery import all_estimators\n", "\n", "all_estimators(\n", " type_filter=[\"classifier\", \"regressor\", \"clusterer\"],\n", " tag_filter={\"capability:unequal_length\": True},\n", ")" ], "outputs": [ { "data": { "text/plain": [ "[('Catch22Classifier',\n", " aeon.classification.feature_based._catch22.Catch22Classifier),\n", " ('Catch22Clusterer', aeon.clustering.feature_based._catch22.Catch22Clusterer),\n", " ('Catch22Regressor', aeon.regression.feature_based._catch22.Catch22Regressor),\n", " ('DummyClassifier', aeon.classification.dummy.DummyClassifier),\n", " ('DummyRegressor', aeon.regression._dummy.DummyRegressor),\n", " ('ElasticEnsemble',\n", " aeon.classification.distance_based._elastic_ensemble.ElasticEnsemble),\n", " ('KNeighborsTimeSeriesClassifier',\n", " aeon.classification.distance_based._time_series_neighbors.KNeighborsTimeSeriesClassifier),\n", " ('KNeighborsTimeSeriesRegressor',\n", " aeon.regression.distance_based._time_series_neighbors.KNeighborsTimeSeriesRegressor),\n", " ('RDSTClassifier', aeon.classification.shapelet_based._rdst.RDSTClassifier),\n", " ('RDSTRegressor', aeon.regression.shapelet_based._rdst.RDSTRegressor)]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 15 }, { "metadata": {}, "cell_type": "markdown", "source": "You can pass these estimators unequal length series and they will work as expected.\n" }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:49:25.499271Z", "start_time": "2024-11-17T13:49:25.466359Z" } }, "cell_type": "code", "source": [ "from aeon.classification.distance_based import KNeighborsTimeSeriesClassifier\n", "\n", "knn = KNeighborsTimeSeriesClassifier()\n", "model = knn.fit(wii_X, wii_y)" ], "outputs": [], "execution_count": 16 }, { "metadata": {}, "cell_type": "markdown", "source": [ "If time series are unequal length, collection estimators will raise an error if they\n", "do not have the capability to handle this characteristic. If you want to use them, \n", "you will need to preprocess the data to be equal length. " ] }, { "metadata": { "ExecuteTime": { "end_time": "2025-05-28T13:38:30.585470Z", "start_time": "2025-05-28T13:38:30.565833Z" } }, "cell_type": "code", "source": [ "rc = RocketClassifier()\n", "try:\n", " rc.fit(wii_X, wii_y)\n", "except ValueError as e:\n", " print(f\"ValueError: {e}\")" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ValueError: Data seen by instance of RocketClassifier has unequal length series, but RocketClassifier cannot handle these characteristics. \n" ] } ], "execution_count": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Padding, truncating or resizing.\n", "\n", "We can pad, truncate or resize. By default, pad adds zeros to make all series the\n", "length of the longest, truncate removes all values beyond the length of the shortest\n", "and resize stretches or shrinks the series." ] }, { "cell_type": "code", "metadata": { "execution": { "iopub.execute_input": "2020-12-19T14:32:01.245270Z", "iopub.status.busy": "2020-12-19T14:32:01.244733Z", "iopub.status.idle": "2020-12-19T14:32:02.911970Z", "shell.execute_reply": "2020-12-19T14:32:02.912833Z" }, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:39:43.878568Z", "start_time": "2025-05-28T13:39:43.857132Z" } }, "source": [ "from aeon.transformations.collection.unequal_length import Padder, Resizer, Truncator\n", "\n", "pad = Padder()\n", "truncate = Truncator()\n", "resize = Resizer(resized_length=600)\n", "X2 = pad.fit_transform(wii_X)\n", "X3 = truncate.fit_transform(wii_X)\n", "X4 = resize.fit_transform(wii_X)\n", "print(X2.shape, \"\\n\", X3.shape, \"\\n\", X4.shape)" ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(100, 1, 361) \n", " (100, 1, 29) \n", " (100, 1, 600)\n" ] } ], "execution_count": 12 }, { "metadata": { "ExecuteTime": { "end_time": "2025-05-28T13:39:45.811784Z", "start_time": "2025-05-28T13:39:44.586889Z" } }, "cell_type": "code", "source": [ "import matplotlib.pyplot as plt\n", "\n", "plt.title(\"Before and after padding: first case (shifted up for unpadded)\")\n", "plt.plot(wii_X[0][0] + 10)\n", "plt.plot(X2[0][0])" ], "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "" ], "image/png": "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" }, "metadata": {}, "output_type": "display_data" } ], "execution_count": 13 }, { "cell_type": "markdown", "source": [ "You can put these transformers in a pipeline to apply to both train/test split\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "source": [ "from sklearn.metrics import accuracy_score\n", "\n", "# Unequal length univariate data\n", "from aeon.pipeline import make_pipeline\n", "\n", "train_X, train_y = load_pickup_gesture_wiimoteZ(split=\"Train\")\n", "test_X, test_y = load_pickup_gesture_wiimoteZ(split=\"Test\")\n", "steps = [truncate, rc]\n", "pipe = make_pipeline(steps)\n", "pipe.fit(train_X, train_y)\n", "preds = pipe.predict(test_X)\n", "accuracy_score(train_y, preds)" ], "metadata": { "collapsed": false, "pycharm": { "is_executing": true }, "ExecuteTime": { "end_time": "2025-05-28T13:39:55.584822Z", "start_time": "2025-05-28T13:39:47.310020Z" } }, "outputs": [ { "data": { "text/plain": [ "0.32" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 14 }, { "metadata": {}, "cell_type": "markdown", "source": [ "## Missing Values\n", "\n", "Missing values are indicated by `NaN` in numpy array. You can test whether any `aeon`\n", " data structure contains missing values using the utility function" ] }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:50:06.076875Z", "start_time": "2024-11-17T13:50:06.065907Z" } }, "cell_type": "code", "source": [ "X = np.random.random(size=(10, 2, 200))\n", "has_missing(X)" ], "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 21 }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:50:06.186109Z", "start_time": "2024-11-17T13:50:06.180126Z" } }, "cell_type": "code", "source": [ "X[5][0][55] = np.nan\n", "has_missing(X)" ], "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 22 }, { "metadata": {}, "cell_type": "markdown", "source": [ "There are a range of strategies for handling missing values. These include:\n", "\n", "1. Use an estimator that internally handles missing values. It is fairly easy for\n", "some algorithms (such as decision trees) to internally deal with missing values,\n", "usually be using it as a distinct series value after discretisation. We do not yet \n", "have many estimators with this capability. Estimators that are able to internally \n", "handle missing values are tagged with `\"capability:missing_values\": True`." ] }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:50:06.436013Z", "start_time": "2024-11-17T13:50:06.296331Z" } }, "cell_type": "code", "source": [ "from aeon.utils.discovery import all_estimators\n", "\n", "all_estimators(\n", " tag_filter={\"capability:missing_values\": True},\n", ")" ], "outputs": [ { "data": { "text/plain": [ "[('BORF', aeon.transformations.collection.dictionary_based._borf.BORF),\n", " ('CollectionId',\n", " aeon.transformations.collection.compose._identity.CollectionId),\n", " ('DummyClassifier', aeon.classification.dummy.DummyClassifier),\n", " ('DummyRegressor', aeon.regression._dummy.DummyRegressor),\n", " ('RandomSegmenter', aeon.segmentation._random.RandomSegmenter),\n", " ('STRAY', aeon.anomaly_detection._stray.STRAY),\n", " ('SimpleImputer', aeon.transformations.collection._impute.SimpleImputer)]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 23 }, { "metadata": {}, "cell_type": "markdown", "source": [ "2. Removing series with missing: this is often desirable if the train set size is\n", "large, the number of series with missing is small and the proportion of missing\n", "values for these series is high.\n", "\n", "We do not yet have a transformer for this, but it is easy to implement yourself.\n", "\n", "3. Interpolating missing values from series: estimating the missing values from the \n", "other values in a time series is commonly done. This is\n", " often desirable if the train set size is small and the proportion of missing values\n", " is low. You can do this with the transformer ``SimpleImputer``. This interpolates \n", " each series and each channel independently. So for example a mean interpolation \n", " of series with two channels `[[NaN,1.0,2.0,3.0],[-1.0,-2.0,-3.0,-4.0]]` would be \n", " `[[2.0,1.0,2.0,3.0],[-1.0,-2.0,-3.0,-4.0]]`. " ] }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:52:23.133162Z", "start_time": "2024-11-17T13:52:23.118202Z" } }, "cell_type": "code", "source": [ "from aeon.transformations.collection import SimpleImputer\n", "\n", "imput = SimpleImputer(strategy=\"mean\")\n", "X2 = imput.fit_transform(X)\n", "has_missing(X2)" ], "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 26 }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:52:23.825897Z", "start_time": "2024-11-17T13:52:23.811936Z" } }, "cell_type": "code", "source": [ "imp2 = SimpleImputer(strategy=\"median\")\n", "X3 = imp2.fit_transform(X)\n", "has_missing(X3)" ], "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 27 }, { "metadata": { "ExecuteTime": { "end_time": "2024-11-17T13:52:24.602058Z", "start_time": "2024-11-17T13:52:24.582111Z" } }, "cell_type": "code", "source": [ "imp3 = SimpleImputer(strategy=\"constant\", fill_value=0)\n", "X4 = imp3.fit_transform(X)\n", "has_missing(X4)" ], "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 28 }, { "metadata": {}, "cell_type": "code", "outputs": [], "execution_count": null, "source": "" } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "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.7.8" } }, "nbformat": 4, "nbformat_minor": 4 } Generated using nbsphinx. The Jupyter notebook can be found here.