<jupyter_start><jupyter_text>Multivariate time series classification with sktime[Github weblink](https://github.com/alan-turing-institute/sktime/blob/master/examples/multivariate_time_series_classification.ipynb)In this notebook, we will use `sktime` for multivariate time series classification. You can find an example notebook for the simpler univariate time series classification setting [here](https://github.com/alan-turing-institute/sktime/blob/master/examples/univariate_time_series_classification.ipynb).  Preliminaries<jupyter_code>from sktime.transformers.compose import ColumnConcatenator 
from sktime.classifiers.compose import TimeSeriesForestClassifier
from sktime.classifiers.dictionary_based.boss import BOSSEnsemble
from sktime.classifiers.compose import ColumnEnsembleClassifier
from sktime.classifiers.shapelet_based import ShapeletTransformClassifier
from sktime.datasets import load_basic_motions
from sktime.pipeline import Pipeline

import numpy as np
import pandas as pd<jupyter_output><empty_output><jupyter_text>Load multivariate time series/panel data<jupyter_code>X_train, y_train = load_basic_motions(split='TRAIN', return_X_y=True)
X_test, y_test = load_basic_motions(split='TEST', return_X_y=True)
# multivariate input data
X_train.head()
# multi-class target variable 
np.unique(y_train)<jupyter_output><empty_output><jupyter_text>Multivariate classification`sktime` offers three main ways of solving multivariate time series classification problems: 1. _Concatenation_ of time series columns into a single long time series column via `ColumnConcatenator` and apply a classifier to the concatenated data, 2. _Column-wise ensembling_ via `ColumnEnsembleClassifier` in which one classifier is fitted for each time series column and their predictions aggregated,3. _Bespoke estimator-specific methods_ for handling multivariate time series data, e.g. finding shapelets in multidimensional spaces (still work in progress).  Time series concatenationWe can concatenate multivariate time series/panel data into long univiariate time series/panel and then apply a classifier to the univariate data.<jupyter_code>steps = [
    ('concatenate', ColumnConcatenator()), 
    ('classify', TimeSeriesForestClassifier(n_estimators=100))]
clf = Pipeline(steps)
clf.fit(X_train, y_train)
clf.score(X_test, y_test)<jupyter_output><empty_output><jupyter_text>Column ensemblingWe can also fit one classifier for each time series column and then aggregated their predictions. The interface is similar to the familiar `ColumnTransformer` from sklearn.<jupyter_code>clf = ColumnEnsembleClassifier(estimators=[
    ("TSF0", TimeSeriesForestClassifier(n_estimators=100), [0]),
    ("BOSSEnsemble3", BOSSEnsemble(ensemble_size=3), [3]),
])
clf.fit(X_train, y_train)
clf.score(X_test, y_test)<jupyter_output><empty_output><jupyter_text>Bespoke methods: shapelets in multidimensional spaceAnother approach is to use bespoke or classifier specific methods for multivariate time series data. Here, we try to find shapelets in multidimensional space.<jupyter_code>clf = ShapeletTransformClassifier(time_contract_in_mins=0.5)
clf.fit(X_train, y_train)
clf.score(X_test, y_test)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07296538821328344, 'fraction_numerical': 0.004989086373557842, 'mean_word_length': 7.861878453038674, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '125764', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1013, 'n_tokens_neox': 934, 'n_words': 265, 'path': 'examples/multivariate_time_series_classification.ipynb', 'repo_name': 'Mo-Saif/sktime', 'size': '3207'}