binder

MiniRocket#

MiniRocket 使用一组小型固定的卷积核转换输入时间序列。MiniRocket 使用 PPV 池化为每个生成的特征图计算一个单一特征(即,正值的比例)。转换后的特征用于训练线性分类器。

Dempster A, Schmidt DF, Webb GI (2020) MiniRocket: A Very Fast (Almost) Deterministic Transform for Time Series Classification arXiv:2012.08791

1 单变量时间序列#

1.1 导入#

导入示例数据、MiniRocket、RidgeClassifierCV (scikit-learn) 和 NumPy。

注意:MiniRocket 和 MiniRocketMultivariate 在导入时由 Numba 编译。编译后的函数会被缓存,因此这应该只发生一次(即,首次导入 MiniRocket 或 MiniRocketMultivariate 时)。

[ ]:
# !pip install --upgrade numba
[ ]:
import numpy as np
from sklearn.linear_model import RidgeClassifierCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

from sktime.datasets import (
    load_arrow_head,  # univariate dataset
    load_basic_motions,  # multivariate dataset
    load_japanese_vowels,  # multivariate dataset with unequal length
)
from sktime.transformations.panel.rocket import (
    MiniRocket,
    MiniRocketMultivariate,
    MiniRocketMultivariateVariable,
)

1.2 加载训练数据#

有关数据集的更多详细信息,请参阅单变量时间序列分类 notebook

注意:输入时间序列的长度必须至少为 9。请使用例如 PaddingTransformer (sktime.transformers.panel.padder) 填充较短的时间序列。

[ ]:
X_train, y_train = load_arrow_head(split="train", return_X_y=True)
# visualize the first univariate time series
X_train.iloc[0, 0].plot()

1.3 初始化 MiniRocket 并转换训练数据#

[ ]:
minirocket = MiniRocket()  # by default, MiniRocket uses ~10_000 kernels
minirocket.fit(X_train)
X_train_transform = minirocket.transform(X_train)
# test shape of transformed training data -> (n_instances, 9_996)
X_train_transform.shape

1.4 拟合分类器#

对于较小的数据集(少于约 10,000 个训练样本),我们建议使用 RidgeClassifierCV (scikit-learn);对于较大的数据集,建议使用随机梯度下降训练的逻辑回归。

注意:对于较大的数据集,这意味着将 MiniRocket 与随机梯度下降集成,以便按小批量执行转换,而不是简单地用 RidgeClassifierCV 替换例如 LogisticRegression

注意:虽然 MiniRocket 的输入时间序列未缩放,但 MiniRocket 的输出特征可能需要为后续模型进行调整。例如,对于 RidgeClassifierCV,我们使用 sklearn StandardScaler 对特征进行缩放。

[ ]:
scaler = StandardScaler(with_mean=False)
classifier = RidgeClassifierCV(alphas=np.logspace(-3, 3, 10))

X_train_scaled_transform = scaler.fit_transform(X_train_transform)
classifier.fit(X_train_scaled_transform, y_train)

1.5 加载并转换测试数据#

[ ]:
X_test, y_test = load_arrow_head(split="test", return_X_y=True)
X_test_transform = minirocket.transform(X_test)

1.6 分类测试数据#

[ ]:
X_test_scaled_transform = scaler.transform(X_test_transform)
classifier.score(X_test_scaled_transform, y_test)

2 多变量时间序列#

我们可以使用 MiniRocket 的多变量版本处理多变量时间序列输入。

2.1 导入#

导入 MiniRocketMultivariate。

注意:MiniRocketMultivariate 在导入时通过 Numba 编译。

[ ]:

2.2 加载训练数据#

注意:输入时间序列的长度必须至少为 9。请使用例如 PaddingTransformer (sktime.transformers.panel.padder) 填充较短的时间序列。

[ ]:
X_train, y_train = load_basic_motions(split="train", return_X_y=True)

2.3 初始化 MiniRocket 并转换训练数据#

[ ]:
minirocket_multi = MiniRocketMultivariate()
minirocket_multi.fit(X_train)
X_train_transform = minirocket_multi.transform(X_train)

2.4 拟合分类器#

[ ]:
scaler = StandardScaler(with_mean=False)
X_train_scaled_transform = scaler.fit_transform(X_train_transform)

classifier = RidgeClassifierCV(alphas=np.logspace(-3, 3, 10))
classifier.fit(X_train_scaled_transform, y_train)

2.5 加载并转换测试数据#

[ ]:
X_test, y_test = load_basic_motions(split="test", return_X_y=True)
X_test_transform = minirocket_multi.transform(X_test)

2.6 分类测试数据#

[ ]:
X_test_scaled_transform = scaler.transform(X_test_transform)
classifier.score(X_test_scaled_transform, y_test)

3 Pipeline 示例#

我们可以将 MiniRocket 与 RidgeClassifierCV(或其他分类器)一起用于 pipeline。然后,我们可以像使用一个独立的分类器一样使用该 pipeline,只需调用一次 fit,而无需单独转换数据等操作。

3.1 导入#

[ ]:
# (above)

3.2 初始化 Pipeline#

[ ]:
minirocket_pipeline = make_pipeline(
    MiniRocket(),
    StandardScaler(with_mean=False),
    RidgeClassifierCV(alphas=np.logspace(-3, 3, 10)),
)

3.3 加载并拟合训练数据#

注意:输入时间序列的长度必须至少为 9。请使用例如 PaddingTransformer (sktime.transformers.panel.padder) 填充较短的时间序列。

[ ]:
X_train, y_train = load_arrow_head(split="train")

# it is necessary to pass y_train to the pipeline
# y_train is not used for the transform, but it is used by the classifier
minirocket_pipeline.fit(X_train, y_train)

3.4 加载并分类测试数据#

[ ]:
X_test, y_test = load_arrow_head(split="test")

minirocket_pipeline.score(X_test, y_test)

4 使用 MiniRocketMultivariateVariable 处理不等长时序数据的 Pipeline 示例#

对于进一步的 pipeline 示例,我们使用 MiniRocket 的扩展版本 MiniRocketMultivariateVariable 处理可变/不等长时序数据。根据 miniRocket 原始论文的代码实现,我们将其与 RidgeClassifierCV 组合在一个 sklearn pipeline 中。然后,我们可以像使用一个独立的分类器一样使用该 pipeline,只需调用一次 fit,而无需单独转换数据等操作。

4.1 加载 japanese_vowels 作为不等长数据集#

Japanese vowels 是一个 UCI Archive 数据集。记录了 9 位日本男性说话者发元音“a”和“e”的声音。原始记录经过预处理,形成一个 12 维(多变量)分类问题。序列长度在 7 到 29 之间。

[ ]:
X_train_jv, y_train_jv = load_japanese_vowels(split="train", return_X_y=True)
# lets visualize the first three voice recordings with dimension 0-11

print("number of samples training: ", X_train_jv.shape[0])
print("series length of recoding 0, dimension 5: ", X_train_jv.iloc[0, 5].shape)
print("series length of recoding 1, dimension 5: ", X_train_jv.iloc[1, 0].shape)

X_train_jv.head(3)
[ ]:
# additional visualizations
number_example = 153
for i in range(12):
    X_train_jv.loc[number_example, f"dim_{i}"].plot()
print("Speaker ID: ", y_train_jv[number_example])

4.2 创建并训练 Pipeline#

如前所述,我们创建一个 sklearn pipeline。MiniRocketMultivariateVariable 要求序列最小长度为 9,缺失值将被填充至长度 9,填充值为“-10.0”。之后会添加一个缩放器和一个 RidgeClassifierCV。

[ ]:
minirocket_mv_var_pipeline = make_pipeline(
    MiniRocketMultivariateVariable(
        pad_value_short_series=-10.0, random_state=42, max_dilations_per_kernel=16
    ),
    StandardScaler(with_mean=False),
    RidgeClassifierCV(alphas=np.logspace(-3, 3, 10)),
)
print(minirocket_mv_var_pipeline)

minirocket_mv_var_pipeline.fit(X_train_jv, y_train_jv)

4.3 在 japanese vowels 数据集上评估 Pipeline#

使用 MiniRocketMultivariateVariable,我们能够处理比训练时稍长的输入序列。训练时最大序列长度:27,测试时最大序列长度 29。

[ ]:
X_test_jv, y_test_jv = load_japanese_vowels(split="test", return_X_y=True)

minirocket_mv_var_pipeline.score(X_test_jv, y_test_jv)

使用 nbsphinx 生成。Jupyter notebook 可以在此处找到。