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)