Repository: sktime/sktime

Issue:
[DOC] classification tutorial: material on unequal length series
Just like there is a section on handling multivariate time series, there should be a subsection on handling unequal length time series:

* how to search for estimators that can do this
* how to adapt estimators that cannot, e.g., via padding or truncation

This seems to be a frequently asked tutorial feature.

Discussion:
review-notebook-app[bot]: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/sktime/sktime/pull/3809"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>

Patch:
diff --git a/CODEOWNERS b/CODEOWNERS
index 38bec41a4..1b379dd33 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -37,6 +37,7 @@ sktime/transformations/panel/dictionary_based/_sax.py @patrickzib @MatthewMiddle
 sktime/transformations/panel/dictionary_based/_sfa.py @patrickzib @MatthewMiddlehurst
 sktime/transformations/panel/dictionary_based/_sfa_fast.py @patrickzib @MatthewMiddlehurst
 sktime/transformations/panel/catch22.py @MatthewMiddlehurst
+sktime/transformations/panel/catch22wrapper.py @MatthewMiddlehurst
 sktime/transformations/panel/random_intervals.py @MatthewMiddlehurst
 sktime/transformations/panel/shapelet_transform.py @jasonlines @ABostrom @MatthewMiddlehurst @TonyBagnall
 sktime/transformations/panel/supervised_intervals.py @MatthewMiddlehurst
diff --git a/docs/source/api_reference/regression.rst b/docs/source/api_reference/regression.rst
index de1d8e51e..d785b88ac 100644
--- a/docs/source/api_reference/regression.rst
+++ b/docs/source/api_reference/regression.rst
@@ -5,9 +5,9 @@ Time series regression
 
 The :mod:`sktime.regression` module contains algorithms and composition tools for time series regression.
 
-.. automodule:: sktime.regression
-    :no-members:
-    :no-inherited-members:
+All current sktime Regressors can be listed using the ``sktime.registry import
+all_estimators`` function.
+
 
 Composition
 -----------
@@ -20,6 +20,18 @@ Composition
 
     ComposableTimeSeriesForestRegressor
 
+Deep learning
+-------------
+
+.. currentmodule:: sktime.regression.deep_learning
+
+.. autosummary::
+    :toctree: auto_generated/
+    :template: class.rst
+
+    CNNRegressor
+    TapNetRegressor
+
 Interval-based
 --------------
 
@@ -30,3 +42,33 @@ Interval-based
     :template: class.rst
 
     TimeSeriesForestRegressor
+
+Kernel-based
+------------
+
+.. currentmodule:: sktime.regression.kernel_based
+
+.. autosummary::
+    :toctree: auto_generated/
+    :template: class.rst
+
+    RocketRegressor
+
+Base
+----
+
+.. currentmodule:: sktime.regression.base
+
+.. autosummary::
+    :toctree: auto_generated/
+    :template: class.rst
+
+    BaseRegressor
+
+.. currentmodule:: sktime.regression.deep_learning.base
+
+.. autosummary::
+    :toctree: auto_generated/
+    :template: class.rst
+
+    BaseDeepRegressor
diff --git a/examples/02_classification.ipynb b/examples/02_classification.ipynb
index ff815c36f..15a8eb492 100644
--- a/examples/02_classification.ipynb
+++ b/examples/02_classification.ipynb
@@ -46,7 +46,7 @@
    },
    "outputs": [],
    "source": [
-    "# Imports used in this notebook\n",
+    "# Plotting and data loading imports used in this notebook\n",
     "import matplotlib.pyplot as plt\n",
     "\n",
     "from sktime.datasets import (\n",
@@ -165,7 +165,7 @@
     "collapsed": false
    },
    "source": [
-    "Some data sets have unequal length series. Two data sets with this characteristic are shipped with sktime: PLAID (univariate) and JapaneseVowels (multivariate). We cannot store unequal length series in numpy arrays. Instead, we use nested pandas data frames, where each cell is a pandas Series. This is the default return type for all single problem loaders."
+    "Some data sets have unequal length series. Two data sets with this characteristic are shipped with sktime: PLAID (univariate) and JapaneseVowels (multivariate). We cannot store unequal length series in `numpy` arrays. Instead, we use a nested `pandas` `DataFrame`, where each cell is a `pandas` `Series`. This is the default return type for all single problem loaders."
    ]
   },
   {
@@ -197,6 +197,8 @@
    "outputs": [],
    "source": [
     "plaid_X, plaid_y = load_plaid()\n",
+    "plaid_train_X, plaid_train_y = load_plaid(split=\"train\")\n",
+    "plaid_test_X, plaid_test_y = load_plaid(split=\"test\")\n",
     "print(type(plaid_X))\n",
     "\n",
     "plt.title(\" Four instances of PLAID dataset\")\n",
@@ -251,6 +253,7 @@
     "arrow_test_X_2d, arrow_test_y_2d = load_arrow_head(split=\"test\", return_type=\"numpy2d\")\n",
     "classifier.fit(arrow_train_X_2d, arrow_train_y_2d)\n",
     "y_pred = classifier.predict(arrow_test_X_2d)\n",
+    "\n",
     "accuracy_score(arrow_test_y_2d, y_pred)"
    ]
   },
@@ -276,6 +279,7 @@
     "rocket = RocketClassifier(num_kernels=2000)\n",
     "rocket.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = rocket.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ]
   },
@@ -301,6 +305,7 @@
     "hc2 = HIVECOTEV2(time_limit_in_minutes=0.2)\n",
     "hc2.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = hc2.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ]
   },
@@ -338,6 +343,7 @@
     "\n",
     "pipe.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = pipe.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ]
   },
@@ -345,7 +351,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Other transformations such as the TSFreshFeatureExtractor for the tsfresh feature set, SummaryTransformer for basic summary statistics, and the RandomShapeletTransform for the shapelet transform can also be used in pipelines following the same creation and fit/predict structure.\n",
+    "Other transformations such as the `TSFreshFeatureExtractor` for the [tsfresh](https://www.sciencedirect.com/science/article/pii/S0925231218304843) feature set, `SummaryTransformer` for basic summary statistics, and the `RandomShapeletTransform` for the [shapelet transform](https://link.springer.com/chapter/10.1007/978-3-662-55608-5_2) can also be used in pipelines following the same creation and fit/predict structure.\n",
     "\n",
     "In the following example, we pipeline an `sktime` transformer with an `sktime` time series classifier using the `*` dunder operator, which is a shorthand for `make_pipeline`. Estimators on the right are pipelined after estimators on the left of the operator:"
    ]
@@ -365,6 +371,7 @@
     "\n",
     "pipe_sktime.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = pipe_sktime.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ]
   },
@@ -449,6 +456,7 @@
     "\n",
     "parameter_tuning_method.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = parameter_tuning_method.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ]
   },
@@ -476,17 +484,13 @@
     "\n",
     "calibrated_drcif.fit(arrow_train_X, arrow_train_y)\n",
     "y_pred = calibrated_drcif.predict(arrow_test_X)\n",
+    "\n",
     "accuracy_score(arrow_test_y, y_pred)"
    ],
    "metadata": {
     "collapsed": false
    }
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": []
-  },
   {
    "cell_type": "markdown",
    "metadata": {
@@ -494,6 +498,7 @@
    },
    "source": [
     "## Multivariate Classification\n",
+    "\n",
     "Many classifiers, including ROCKET and HC2, are configured to work with multivariate input. For example:"
    ]
   },
@@ -510,6 +515,7 @@
     "rocket = RocketClassifier(num_kernels=2000)\n",
     "rocket.fit(motions_train_X, motions_train_y)\n",
     "y_pred = rocket.predict(motions_test_X)\n",
+    "\n",
     "accuracy_score(motions_test_y, y_pred)"
    ]
   },
@@ -520,9 +526,10 @@
    "source": [
     "from sktime.classification.hybrid import HIVECOTEV2\n",
     "\n",
-    "HIVECOTEV2(time_limit_in_minutes=0.25)\n",
+    "HIVECOTEV2(time_limit_in_minutes=0.2)\n",
     "hc2.fit(motions_train_X, motions_train_y)\n",
     "y_pred = hc2.predict(motions_test_X)\n",
+    "\n",
     "accuracy_score(motions_test_y, y_pred)"
    ],
    "metadata": {
@@ -556,7 +563,9 @@
     "\n",
     "clf = ColumnConcatenator() * DrCIF(n_estimators=10, n_intervals=5)\n",
     "clf.fit(motions_train_X, motions_train_y)\n",
-    "clf.score(motions_test_X, motions_test_y)"
+    "y_pred = clf.predict(motions_test_X)\n",
+    "\n",
+    "accuracy_score(motions_test_y, y_pred)"
    ]
   },
   {
@@ -580,17 +589,76 @@
     "from sktime.classification.interval_based import DrCIF\n",
     "from sktime.classification.kernel_based import RocketClassifier\n",
     "\n",
-    "clf = ColumnEnsembleClassifier(\n",
+    "col = ColumnEnsembleClassifier(\n",
     "    estimators=[\n",
     "        (\"DrCIF0\", DrCIF(n_estimators=10, n_intervals=5), [0]),\n",
     "        (\"ROCKET3\", RocketClassifier(num_kernels=1000), [3]),\n",
     "    ]\n",
     ")\n",
     "\n",
-    "clf.fit(motions_train_X, motions_train_y)\n",
-    "clf.score(motions_test_X, motions_test_y)"
+    "col.fit(motions_train_X, motions_train_y)\n",
+    "y_pred = col.predict(motions_test_X)\n",
+    "\n",
+    "accuracy_score(motions_test_y, y_pred)"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "## Classification with Unequal Length Series\n",
+    "\n",
+    "A common trait in time series data is absence of a uniform series length, as seen in the PLAID and JapaneseVowels datasets introduced previously. None of the `numpy` data formats support ragged arrays, as such one of the `pandas` `DataFrame` formats must be used for unequal length data.\n",
+    "\n",
+    "At the time of writing the number of classifiers which natively support unequal length series is limited. The following outputs the current classifiers which support unequal length data."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "from sktime.registry import all_estimators\n",
+    "\n",
+    "# search for all classifiers which can handle unequal length data. This may give some\n",
+    "# UserWarnings if soft dependencies are not installed.\n",
+    "all_estimators(\n",
+    "    filter_tags={\"capability:unequal_length\": True}, estimator_types=\"classifier\"\n",
+    ")"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Certain `sktime` transformers such as the `PaddingTransformer` and `TruncationTransformer` can be used in a pipeline to process unequal length data for use in a wider range of classification algorithms. Transformers which equalise the length of seres can be found using the `\"capability:unequal_length:removes\"` tag.\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "from sktime.classification.feature_based import RandomIntervalClassifier\n",
+    "from sktime.transformations.panel.padder import PaddingTransformer\n",
+    "\n",
+    "padded_clf = PaddingTransformer() * RandomIntervalClassifier(n_intervals=5)\n",
+    "padded_clf.fit(plaid_train_X, plaid_test_y)\n",
+    "y_pred = padded_clf.predict(plaid_test_X)\n",
+    "\n",
+    "accuracy_score(plaid_test_y, y_pred)"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
   {
    "cell_type": "markdown",
    "metadata": {
@@ -604,7 +672,7 @@
     "One nearest neighbour (1-NN) classification with Dynamic Time Warping (DTW) is one of the oldest TSC approaches, and is commonly used as a performance benchmark.\n",
     "\n",
     "#### RocketClassifier\n",
-    "The RocketClassifier is based on a pipeline combination of the ROCKET transformation (transformations.panel.rocket) and the sklearn RidgeClassifierCV classifier. The RocketClassifier is configurable to use variants MiniRocket and MultiRocket. ROCKET is based on generating random convolutions. A large number are generated then the classifier performs a feature selection.\n",
+    "The RocketClassifier is based on a pipeline combination of the ROCKET transformation (transformations.panel.rocket) and the sklearn RidgeClassifierCV classifier. The RocketClassifier is configurable to use variants MiniRocket and MultiRocket. ROCKET is based on generating random convolutional kernels. A large number are generated, then a linear classifier is built on the output.\n",
     "\n",
     "[1] Dempster, Angus, François Petitjean, and Geoffrey I. Webb. \"Rocket: exceptionally fast and accurate time series classification using random convolutional kernels.\" Data Mining and Knowledge Discovery (2020)\n",
     "[arXiv version](https://arxiv.org/abs/1910.13051)\n",
diff --git a/pyproject.toml b/pyproject.toml
index 2c8d2cb43..23fae5d18 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -45,7 +45,7 @@ classifiers = [
 requires-python = ">=3.7,<3.11"
 dependencies = [
     "deprecated>=1.2.13",
-    "numba>=0.53",
+    "numba>=0.55",
     "numpy>=1.21.0,<1.23",
     "pandas>=1.1.0,<1.6.0",
     "scikit-learn>=0.24.0,<1.2.0",
diff --git a/sktime/classification/sklearn/_continuous_interval_tree.py b/sktime/classification/sklearn/_continuous_interval_tree.py
index 6b04bedf3..4d7b6f3ea 100644
--- a/sktime/classification/sklearn/_continuous_interval_tree.py
+++ b/sktime/classification/sklearn/_continuous_interval_tree.py
@@ -669,7 +669,7 @@ def _drcif_feature(X, interval, dim, att, c22, case_id=None):
     if att > 21:
         return _summary_stat(X[:, dim, interval[0] : interval[1]], att)
     else:
-        return c22.transform_single_feature(
+        return c22._transform_single_feature(
             X[:, dim, interval[0] : interval[1]], att, case_id=case_id
         )
 
diff --git a/sktime/regression/deep_learning/cnn.py b/sktime/regression/deep_learning/cnn.py
index 3d09f7ebd..b4ae0e315 100644
--- a/sktime/regression/deep_learning/cnn.py
+++ b/sktime/regression/deep_learning/cnn.py
@@ -14,7 +14,7 @@ _check_dl_dependencies(severity="warning")
 
 
 class CNNRegressor(BaseDeepRegressor):
-    """Time Convolutional Neural Network (CNN), as described in [1].
+    """Time Series Convolutional Neural Network (CNN), as described in [1].
 
     Parameters
     ----------
diff --git a/sktime/regression/deep_learning/tapnet.py b/sktime/regression/deep_learning/tapnet.py
index bb562cc24..ce70f3cab 100644
--- a/sktime/regression/deep_learning/tapnet.py
+++ b/sktime/regression/deep_learning/tapnet.py
@@ -16,7 +16,12 @@ from sktime.utils.validation._dependencies import _check_dl_dependencies
 
 
 class TapNetRegressor(BaseDeepRegressor):
-    """Implementation of TapNetRegressor, as described in [1].
+    """Time series attentional prototype network (TapNet), as described in [1].
+
+     TapNet was initially proposed for multivariate time series
+     classification. The is an adaptation for time series regression. TapNet comprises
+     these components: random dimension permutation, multivariate time series
+     encoding, and attentional prototype learning.
 
     Parameters
     ----------
diff --git a/sktime/transformations/panel/catch22.py b/sktime/transformations/panel/catch22.py
index 48e25e6c9..c4d73acf2 100644
--- a/sktime/transformations/panel/catch22.py
+++ b/sktime/transformations/panel/catch22.py
@@ -59,10 +59,10 @@ class Catch22(BaseTransformer):
         The number of jobs to run in parallel for transform. Requires multiple input
         cases.
 
-        .. deprecated:: 0.13.4
-            the default = 4 was deprecated in version 0.13.3 and will be changed to
-            default = 2 in 0.15. Please use alphabet_size=2 due to its lower memory
-            footprint, better runtime at equal accuracy.
+        .. deprecated:: 0.14.0
+            ``n_jobs`` default was changed to 1 from -1 in version 0.14.0. In version
+            0.16.0 a value of -1 will use all CPU cores instead of the current 1
+            CPU core.
 
     See Also
     --------
@@ -302,6 +302,9 @@ class Catch22(BaseTransformer):
         -------
         Numpy array containing a catch22 feature for each input series.
         """
+        self._transform_single_feature(X, feature, case_id)
+
+    def _transform_single_feature(self, X, feature, case_id=None):
         if isinstance(feature, (int, np.integer)) or isinstance(
             feature, (float, float)
         ):
diff --git a/sktime/transformations/panel/shapelet_transform.py b/sktime/transformations/panel/shapelet_transform.py
index 7ef287662..31aee1f40 100644
--- a/sktime/transformations/panel/shapelet_transform.py
+++ b/sktime/transformations/panel/shapelet_transform.py
@@ -17,7 +17,8 @@ from operator import itemgetter
 import numpy as np
 import pandas as pd
 from joblib import Parallel, delayed
-from numba import NumbaPendingDeprecationWarning, njit
+from numba import njit
+from numba.typed.typedlist import List
 from sklearn import preprocessing
 from sklearn.utils import check_random_state
 from sklearn.utils.multiclass import class_distribution
@@ -999,6 +1000,11 @@ class RandomShapeletTransform(BaseTransformer):
     n_jobs : int, default=1
         The number of jobs to run in parallel for both `fit` and `transform`.
         ``-1`` means using all processors.
+    parallel_backend : str, ParallelBackendBase instance or None, default=None
+        Specify the parallelisation backend implementation in joblib, if None a 'prefer'
+        value of "threads" is used by default.
+        Valid options are "loky", "multiprocessing", "threading" or a custom backend.
+        See the joblib Parallel documentation for more details.
     batch_size : int or None, default=100
         Number of shapelet candidates processed before being merged into the set of best
         shapelets.
@@ -1084,6 +1090,7 @@ class RandomShapeletTransform(BaseTransformer):
         time_limit_in_minutes=0.0,
         contract_max_n_shapelet_samples=np.inf,
         n_jobs=1,
+        parallel_backend=None,
         batch_size=100,
         random_state=None,
     ):
@@ -1097,6 +1104,7 @@ class RandomShapeletTransform(BaseTransformer):
         self.contract_max_n_shapelet_samples = contract_max_n_shapelet_samples
 
         self.n_jobs = n_jobs
+        self.parallel_backend = parallel_backend
         self.batch_size = batch_size
         self.random_state = random_state
 
@@ -1134,9 +1142,6 @@ class RandomShapeletTransform(BaseTransformer):
         self : RandomShapeletTransform
             This estimator.
         """
-        # this is a few versions away currently, and heaps dont support the replacement
-        warnings.simplefilter("ignore", category=NumbaPendingDeprecationWarning)
-
         self._n_jobs = check_n_jobs(self.n_jobs)
 
         self.classes_, self._class_counts = np.unique(y, return_counts=True)
@@ -1160,8 +1165,13 @@ class RandomShapeletTransform(BaseTransformer):
         start_time = time.time()
         fit_time = 0
 
-        max_shapelets_per_class = self._max_shapelets / self.n_classes
-        shapelets = [[(-1.0, -1, -1, -1, -1, -1)] for _ in range(self.n_classes)]
+        max_shapelets_per_class = int(self._max_shapelets / self.n_classes)
+        if max_shapelets_per_class < 1:
+            max_shapelets_per_class = 1
+
+        shapelets = List(
+            [List([(-1.0, -1, -1, -1, -1, -1)]) for _ in range(self.n_classes)]
+        )
         n_shapelets_extracted = 0
 
         if time_limit > 0:
@@ -1169,7 +1179,9 @@ class RandomShapeletTransform(BaseTransformer):
                 fit_time < time_limit
                 and n_shapelets_extracted < self.contract_max_n_shapelet_samples
             ):
-                candidate_shapelets = Parallel(n_jobs=self._n_jobs)(
+                candidate_shapelets = Parallel(
+                    n_jobs=self._n_jobs, backend=self.parallel_backend, prefer="threads"
+                )(
                     delayed(self._extract_random_shapelet)(
                         X,
                         y,
@@ -1181,19 +1193,17 @@ class RandomShapeletTransform(BaseTransformer):
                 )
 
                 for i, heap in enumerate(shapelets):
-                    RandomShapeletTransform._merge_shapelets(
+                    self._merge_shapelets(
                         heap,
-                        candidate_shapelets,
+                        List(candidate_shapelets),
                         max_shapelets_per_class,
                         i,
                     )
 
                 if self.remove_self_similar:
                     for i, heap in enumerate(shapelets):
-                        to_keep = (
-                            RandomShapeletTransform._remove_self_similar_shapelets(heap)
-                        )
-                        shapelets[i] = [n for (n, b) in zip(heap, to_keep) if b]
+                        to_keep = self._remove_self_similar_shapelets(heap)
+                        shapelets[i] = List([n for (n, b) in zip(heap, to_keep) if b])
 
                 n_shapelets_extracted += self._batch_size
                 fit_time = time.time() - start_time
@@ -1206,7 +1216,9 @@ class RandomShapeletTransform(BaseTransformer):
                     else self._n_shapelet_samples - n_shapelets_extracted
                 )
 
-                candidate_shapelets = Parallel(n_jobs=self._n_jobs)(
+                candidate_shapelets = Parallel(
+                    n_jobs=self._n_jobs, backend=self.parallel_backend, prefer="threads"
+                )(
                     delayed(self._extract_random_shapelet)(
                         X,
                         y,
@@ -1218,19 +1230,17 @@ class RandomShapeletTransform(BaseTransformer):
                 )
 
                 for i, heap in enumerate(shapelets):
-                    RandomShapeletTransform._merge_shapelets(
+                    self._merge_shapelets(
                         heap,
-                        candidate_shapelets,
+                        List(candidate_shapelets),
                         max_shapelets_per_class,
                         i,
                     )
 
                 if self.remove_self_similar:
                     for i, heap in enumerate(shapelets):
-                        to_keep = (
-                            RandomShapeletTransform._remove_self_similar_shapelets(heap)
-                        )
-                        shapelets[i] = [n for (n, b) in zip(heap, to_keep) if b]
+                        to_keep = self._remove_self_similar_shapelets(heap)
+                        shapelets[i] = List([n for (n, b) in zip(heap, to_keep) if b])
 
                 n_shapelets_extracted += n_shapelets_to_extract
 
@@ -1250,14 +1260,16 @@ class RandomShapeletTransform(BaseTransformer):
         ]
         self.shapelets.sort(reverse=True, key=lambda s: (s[0], s[1], s[2], s[3], s[4]))
 
-        to_keep = RandomShapeletTransform._remove_identical_shapelets(self.shapelets)
+        to_keep = self._remove_identical_shapelets(List(self.shapelets))
         self.shapelets = [n for (n, b) in zip(self.shapelets, to_keep) if b]
 
         self._sorted_indicies = []
         for s in self.shapelets:
             sabs = np.abs(s[6])
             self._sorted_indicies.append(
-                sorted(range(s[1]), reverse=True, key=lambda i: sabs[i])  # noqa B023
+                np.array(
+                    sorted(range(s[1]), reverse=True, key=lambda j, sabs=sabs: sabs[j])
+                )
             )
         return self
 
@@ -1274,13 +1286,12 @@ class RandomShapeletTransform(BaseTransformer):
         output : pandas DataFrame
             The transformed dataframe in tabular format.
         """
-        # this is a few versions away currently, and heaps dont support the replacement
-        warnings.simplefilter("ignore", category=NumbaPendingDeprecationWarning)
-
         output = np.zeros((len(X), len(self.shapelets)))
 
         for i, series in enumerate(X):
-            dists = Parallel(n_jobs=self._n_jobs)(
+            dists = Parallel(
+                n_jobs=self._n_jobs, backend=self.parallel_backend, prefer="threads"
+            )(
                 delayed(_online_shapelet_distance)(
                     series[shapelet[3]],
                     shapelet[6],
@@ -1327,7 +1338,9 @@ class RandomShapeletTransform(BaseTransformer):
         inst_idx = i % self.n_instances
         cls_idx = int(y[inst_idx])
         worst_quality = (
-            shapelets[cls_idx][0][0] if shapelets == max_shapelets_per_class else -1
+            shapelets[cls_idx][0][0]
+            if len(shapelets[cls_idx]) == max_shapelets_per_class
+            else -1
         )
 
         length = (
@@ -1339,9 +1352,11 @@ class RandomShapeletTransform(BaseTransformer):
 
         shapelet = z_normalise_series(X[inst_idx, dim, position : position + length])
         sabs = np.abs(shapelet)
-        sorted_indicies = sorted(range(length), reverse=True, key=lambda i: sabs[i])
+        sorted_indicies = np.array(
+            sorted(range(length), reverse=True, key=lambda j: sabs[j])
+        )
 
-        quality = RandomShapeletTransform._find_shapelet_quality(
+        quality = self._find_shapelet_quality(
             X,
             y,
             shapelet,
@@ -1565,8 +1580,9 @@ def _calc_early_binary_ig(
         left_prop = (split + 1 + c1_to_add) / total_all
         ent_left = _binary_entropy(c1_count + c1_to_add, c2_count)
 
-        right_prop = 1 - left_prop  # because right side must
-        # optimistically contain everything else
+        # because right side must optimistically contain everything else
+        right_prop = 1 - left_prop
+
         ent_right = _binary_entropy(
             c1_traversed - c1_count,
             c2_traversed - c2_count + c2_to_add,
@@ -1579,8 +1595,9 @@ def _calc_early_binary_ig(
         left_prop = (split + 1 + c2_to_add) / total_all
         ent_left = _binary_entropy(c1_count, c2_count + c2_to_add)
 
-        right_prop = 1 - left_prop  # because right side must
-        # optimistically contain everything else
+        # because right side must optimistically contain everything else
+        right_prop = 1 - left_prop
+
         ent_right = _binary_entropy(
             c1_traversed - c1_count + c1_to_add,
             c2_traversed - c2_count,
diff --git a/sktime/transformations/panel/supervised_intervals.py b/sktime/transformations/panel/supervised_intervals.py
index ceaa87d53..a3a087e78 100644
--- a/sktime/transformations/panel/supervised_intervals.py
+++ b/sktime/transformations/panel/supervised_intervals.py
@@ -68,9 +68,11 @@ class SupervisedIntervals(BaseTransformer):
         ``-1`` means using all processors.
     random_state : int or None, default=None
         Seed for random number generation.
-    parallel_backend : str, default=None
-        Specify the parallelisation backend implementation in joblib, where
-        "threads" is used by default.
+    parallel_backend : str, ParallelBackendBase instance or None, default=None
+        Specify the parallelisation backend implementation in joblib, if None a 'prefer'
+        value of "threads" is used by default.
+        Valid options are "loky", "multiprocessing", "threading" or a custom backend.
+        See the joblib Parallel documentation for more details.
 
     Attributes
     ----------


Test patch:
diff --git a/sktime/classification/tests/_expected_outputs.py b/sktime/classification/tests/_expected_outputs.py
index 92ab672fc..f40a26e42 100644
--- a/sktime/classification/tests/_expected_outputs.py
+++ b/sktime/classification/tests/_expected_outputs.py
@@ -478,12 +478,12 @@ basic_motions_proba["ShapeletTransformClassifier"] = np.array(
         [0.0, 0.0, 0.2, 0.8],
         [0.2, 0.8, 0.0, 0.0],
         [0.0, 0.2, 0.6, 0.2],
-        [0.2, 0.6, 0.2, 0.0],
+        [0.0, 0.8, 0.2, 0.0],
         [0.0, 0.0, 0.2, 0.8],
         [0.0, 0.0, 0.2, 0.8],
         [0.2, 0.6, 0.0, 0.2],
         [0.0, 0.2, 0.8, 0.0],
-        [0.4, 0.4, 0.0, 0.2],
+        [0.2, 0.6, 0.0, 0.2],
         [0.2, 0.6, 0.0, 0.2],
     ]
 )
diff --git a/sktime/transformations/panel/tests/test_shapelet_transform.py b/sktime/transformations/panel/tests/test_shapelet_transform.py
index 178e643cf..5ded6bb0e 100644
--- a/sktime/transformations/panel/tests/test_shapelet_transform.py
+++ b/sktime/transformations/panel/tests/test_shapelet_transform.py
@@ -21,7 +21,9 @@ def test_st_on_unit_test():
 
     # assert transformed data is the same
     data = st.transform(X_train.iloc[indices])
-    testing.assert_array_almost_equal(data, shapelet_transform_unit_test_data)
+    testing.assert_array_almost_equal(
+        data, shapelet_transform_unit_test_data, decimal=4
+    )
 
 
 def test_st_on_basic_motions():
@@ -38,89 +40,26 @@ def test_st_on_basic_motions():
 
     # assert transformed data is the same
     data = st.transform(X_train.iloc[indices])
-    testing.assert_array_almost_equal(data, shapelet_transform_basic_motions_data)
+    testing.assert_array_almost_equal(
+        data, shapelet_transform_basic_motions_data, decimal=4
+    )
 
 
 shapelet_transform_unit_test_data = np.array(
     [
-        [
-            0.0844948936238554,
-            0.15355295821521212,
-            0.181181653406588,
-        ],
-        [
-            0.1005739706371287,
-            0.13728264572793214,
-            0.14232864157873387,
-        ],
-        [
-            0.15574477738923456,
-            0.24572051577166446,
-            0.28114769465706674,
-        ],
-        [
-            0.14368755013218146,
-            0.11173267717634065,
-            0.0832337710268795,
-        ],
-        [
-            0.05901578181579171,
-            0.11702300016584308,
-            0.14612594209368096,
-        ],
+        [0.0845, 0.1536, 0.1812],
+        [0.1006, 0.1373, 0.1423],
+        [0.1557, 0.2457, 0.2811],
+        [0.1437, 0.1117, 0.0832],
+        [0.059, 0.117, 0.1461],
     ]
 )
 shapelet_transform_basic_motions_data = np.array(
     [
-        [
-            1.0891026731161,
-            0.9869567751155376,
-            1.500478686384502,
-            1.9604066805556999,
-            1.9300459325831565,
-            1.6290470525017764,
-            1.2492444105003735,
-            1.0060446077996184,
-        ],
-        [
-            1.1700758360488173,
-            1.0555356143008514,
-            0.6147335984845409,
-            0.9762741759423724,
-            0.5589265732729417,
-            1.032742062232156,
-            1.083409283764176,
-            1.111697276658204,
-        ],
-        [
-            1.6798705292742746,
-            1.9684063044201972,
-            2.453685502926318,
-            1.9677105642494732,
-            2.029428399113479,
-            1.3483536658952058,
-            1.9877554408696116,
-            0.5488432707540976,
-        ],
-        [
-            1.1079276425471314,
-            1.0065997349055864,
-            1.0618258792202282,
-            0.32297427738972406,
-            1.1450380706584913,
-            1.0387357068111138,
-            0.676941814847556,
-            1.0156811721014811,
-        ],
-        [
-            0.33414369747055067,
-            0.2870956468054047,
-            1.734401894586686,
-            1.9064659364611127,
-            1.7299782521480092,
-            1.6297951854173116,
-            1.5659881867675363,
-            1.1203189560668823,
-        ],
+        [0.987, 0.9232, 1.5005, 1.9604, 1.93, 1.629, 1.2492, 1.006],
+        [1.0555, 1.0586, 0.6147, 0.9763, 0.5589, 1.0327, 1.0834, 1.1117],
+        [1.9684, 1.7907, 2.4537, 1.9677, 2.0294, 1.3484, 1.9878, 0.5488],
+        [1.0066, 1.1597, 1.0618, 0.323, 1.145, 1.0387, 0.6769, 1.0157],
+        [0.2871, 0.0919, 1.7344, 1.9065, 1.73, 1.6298, 1.566, 1.1203],
     ]
 )