binder

使用 sktime 进行早期时间序列分类#

早期时间序列分类(eTSC)是指在尽可能少的测量数据下,以尽可能高的准确性对时间序列进行分类的问题。任何 eTSC 方法最关键的问题是决定何时看到足够的时间序列数据来做出决策:等待更多数据点通常会使分类问题更容易,但会延迟做出分类的时间;相反,较早的分类必须处理较少的输入数据,这通常会导致较低的准确性。

本 notebook 提供了一个快速指南,帮助您开始在 sktime 中运行 eTSC 算法。

参考文献:#

[1] Schäfer, P., & Leser, U. (2020). TEASER: early and accurate time series classification. Data mining and knowledge discovery, 34(5), 1336-1362

数据集和问题类型#

UCR/UEA 时间序列分类存档 包含了大量示例 TSC 问题,这些问题在文献中已被数千次用于评估 TSC 算法。阅读数据加载文档和 notebook,了解 sktime 数据格式以及如何加载 sktime 数据。

[ ]:
# Imports used in this notebook
import numpy as np

from sktime.classification.early_classification._teaser import TEASER
from sktime.classification.interval_based import TimeSeriesForestClassifier
from sktime.datasets import load_arrow_head
[ ]:
# Load default train/test splits from sktime/datasets/data
arrow_train_X, arrow_train_y = load_arrow_head(split="train", return_type="numpy3d")
arrow_test_X, arrow_test_y = load_arrow_head(split="test", return_type="numpy3d")

arrow_test_X.shape

构建 TEASER 分类器#

TEASER [1] 是一个两层模型,使用一个基础分类器进行预测,并使用一个决策评估器来决定这些预测是否安全。作为第一层,TEASER 需要一个 TSC 算法,例如 WEASEL,它产生类别概率作为输出。作为第二层,需要一个异常检测器,例如单类 SVM。

[ ]:
teaser = TEASER(
    random_state=0,
    classification_points=[25, 50, 75, 100, 125, 150, 175, 200, 251],
    estimator=TimeSeriesForestClassifier(n_estimators=10, random_state=0),
)
teaser.fit(arrow_train_X, arrow_train_y)

确定测试数据上的准确性和早期性#

通常使用准确性来确定预测的正确性,而早期性用于确定平均需要多少序列数据来获得上述准确性。例如,对于下面的值,仅使用完整测试数据的 43%,我们就能够获得 69% 的准确性。

[ ]:
hm, acc, earl = teaser.score(arrow_test_X, arrow_test_y)
print("Earliness on Test Data %2.2f" % earl)
print("Accuracy on Test Data %2.2f" % acc)
print("Harmonic Mean on Test Data %2.2f" % hm)

确定训练数据上的准确性和早期性#

[ ]:
print("Earliness on Train Data %2.2f" % teaser._train_earliness)
print("Accuracy on Train Data %2.2f" % teaser._train_accuracy)

与完整测试数据上分类的比较#

使用完整的测试数据,我们使用相同的分类器将获得 68% 的准确性。

[ ]:
accuracy = (
    TimeSeriesForestClassifier(n_estimators=10, random_state=0)
    .fit(arrow_train_X, arrow_train_y)
    .score(arrow_test_X, arrow_test_y)
)
print("Accuracy on the full Test Data %2.2f" % accuracy)

使用不完整时间序列进行分类#

eTSC 的主要吸引力在于能够使用不完整的时间序列进行分类。sktime eTSC 算法接受比完整序列长度少的时间点作为输入,并输出两项内容:做出的预测以及算法是否认为该预测是安全的。有关决策的信息,例如做出决策时的时间戳,可以从 state_info 属性中获取。

仅使用 50 个数据点(共 251 个)的首次测试#

[ ]:
X = arrow_test_X[:, :, :50]
probas, _ = teaser.predict_proba(X)
idx = (probas >= 0).all(axis=1)
print("First 10 Finished prediction\n", np.argwhere(idx).flatten()[:10])
print("First 10 Probabilities of finished predictions\n", probas[idx][:10])
[ ]:
_, acc, _ = teaser.score(X, arrow_test_y)
print("Accuracy with 50 points on Test Data %2.2f" % acc)

我们也可以在流式场景中进行预测,其中更多数据会不时可用#

其基本原理是将先前预测的状态信息保存在 TEASER 对象中,并在新数据可用时使用它。

[ ]:
test_points = [25, 50, 75, 100, 125, 150, 175, 200, 251]
final_states = np.zeros((arrow_test_X.shape[0], 4), dtype=int)
final_decisions = np.zeros(arrow_test_X.shape[0], dtype=int)
open_idx = np.arange(0, arrow_test_X.shape[0])
teaser.reset_state_info()

for i in test_points:
    probas, decisions = teaser.update_predict_proba(arrow_test_X[:, :, :i])
    final_states[open_idx] = teaser.get_state_info()

    arrow_test_X, open_idx, final_idx = teaser.split_indices_and_filter(
        arrow_test_X, open_idx, decisions
    )
    final_decisions[final_idx] = i

    (
        hm,
        acc,
        earliness,
    ) = teaser._compute_harmonic_mean(final_states, arrow_test_y)

    print("Earliness on length %2i is %2.2f" % (i, earliness))
    print("Accuracy on length %2i is %2.2f" % (i, acc))
    print("Harmonic Mean on length %2i is %2.2f" % (i, hm))

    print("...........")

print("Time Stamp of final decisions", final_decisions)

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