ICML、ICLR、KDD等のトップカンファレンスで登場する論文を概観し、これらの中で、センサーやアクチュエータの駆動データなど、時系列データセットで、近年利用されているデータセットを解説します。
本記事の内容
- 時系列異常検知ベンチマークの全体像
- 各データセットの特徴と規模
- Pythonでのデータ読み込みと可視化の例
データセット一覧
本記事で扱うデータセットをまとめます。
| データセット | ドメイン | 次元数 | 訓練サンプル | 異常率 | 公開年 |
|---|---|---|---|---|---|
| telemanom | 人工衛星テレメトリ | 25チャネル | 各数千点 | ~1-3% | 2018 |
| WADI | 水処理プラント | 127 | 1,048,571 | ~6% | 2017 |
| SWaT | 水処理テストベッド | 51 | 495,000 | ~12% | 2016 |
| SMD | サーバーマシン | 38 | 各708,405 | ~4% | 2019 |
| PSM | サーバーメトリクス | 25 | 132,481 | ~28% | 2021 |
telemanom(NASA人工衛星テレメトリ)
telemanom(Telemetry Anomaly Detection)は、NASA JPLのHundman et al.が2018年に発表したデータセットです。火星探査ローバーCuriosityや国際宇宙ステーション(ISS)などの人工衛星のテレメトリ(センサーデータ)から構成されています。
データの特徴
- チャネル数: 25(E, P, M等のプレフィックスで命名)
- 各チャネル: 1次元の時系列
- 訓練データ: 正常なデータのみ
- テストデータ: 正常データ + 異常データ(ラベル付き)
- データ形式: NumPy
.npyファイル
データの読み込みと可視化
import numpy as np
import matplotlib.pyplot as plt
# telemanomデータの想定されるディレクトリ構造:
# telemanom/
# data/
# train/
# E-1.npy, E-2.npy, ...
# test/
# E-1.npy, E-2.npy, ...
# labeled_anomalies.csv
# データ読み込みの例(ファイルパスは環境に合わせて変更)
# train_data = np.load("telemanom/data/train/E-1.npy")
# test_data = np.load("telemanom/data/test/E-1.npy")
# ダミーデータでの可視化例
np.random.seed(42)
n_train = 3000
n_test = 1000
# 正常データ(訓練)
train_data = np.sin(np.linspace(0, 20 * np.pi, n_train)) + np.random.normal(0, 0.1, n_train)
# テストデータ(異常あり)
test_data = np.sin(np.linspace(20 * np.pi, 27 * np.pi, n_test)) + np.random.normal(0, 0.1, n_test)
test_data[500:530] += 3 # 異常区間
fig, axes = plt.subplots(2, 1, figsize=(14, 6))
axes[0].plot(train_data, 'b-', linewidth=0.5)
axes[0].set_title("telemanom: Train Data (normal)")
axes[0].set_xlabel("Time step")
axes[0].set_ylabel("Value")
axes[0].grid(True, alpha=0.3)
axes[1].plot(test_data, 'b-', linewidth=0.5)
axes[1].axvspan(500, 530, alpha=0.3, color='red', label='Anomaly region')
axes[1].set_title("telemanom: Test Data (with anomaly)")
axes[1].set_xlabel("Time step")
axes[1].set_ylabel("Value")
axes[1].legend()
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
WADI(Water Distribution Testbed)
WADIは、シンガポール工科デザイン大学(SUTD)のiTrustラボが構築した水処理・配水プラントのテストベッドから収集されたデータセットです。
データの特徴
- センサー数: 127(流量計、圧力計、バルブ状態等)
- 攻撃の種類: 15種類のサイバーフィジカル攻撃
- 正常データ: 14日間の連続運転データ
- 攻撃データ: 2日間(攻撃を含む)
- サンプリング間隔: 1秒
WADIは多変量時系列異常検知の標準的なベンチマークとして広く利用されています。
SWaT(Secure Water Treatment Testbed)
SWaTは、WADIと同じくSUTDのiTrustラボが提供するデータセットで、水処理プラントのテストベッドから収集されています。
データの特徴
- センサー数: 51(水位、流量、圧力、化学物質濃度等)
- 攻撃の種類: 36種類のサイバーフィジカル攻撃
- 正常データ: 7日間
- 攻撃データ: 4日間
- サンプリング間隔: 1秒
- 異常率: 約12%
データの規模比較
import numpy as np
import matplotlib.pyplot as plt
# 各データセットの規模を比較
datasets = ['telemanom', 'SWaT', 'WADI', 'SMD', 'PSM']
dimensions = [25, 51, 127, 38, 25]
train_samples = [3000, 495000, 1048571, 708405, 132481]
anomaly_rates = [2, 12, 6, 4, 28]
fig, axes = plt.subplots(1, 3, figsize=(16, 4))
# 次元数の比較
axes[0].barh(datasets, dimensions, color='steelblue', alpha=0.8)
axes[0].set_title("Number of Dimensions")
axes[0].set_xlabel("Dimensions")
axes[0].grid(True, alpha=0.3, axis='x')
# 訓練データ数の比較
axes[1].barh(datasets, [s/1000 for s in train_samples], color='coral', alpha=0.8)
axes[1].set_title("Training Samples (x1000)")
axes[1].set_xlabel("Samples (K)")
axes[1].grid(True, alpha=0.3, axis='x')
# 異常率の比較
axes[2].barh(datasets, anomaly_rates, color='mediumseagreen', alpha=0.8)
axes[2].set_title("Anomaly Rate (%)")
axes[2].set_xlabel("Rate (%)")
axes[2].grid(True, alpha=0.3, axis='x')
plt.tight_layout()
plt.show()
SMD(Server Machine Dataset)
SMDは、OmniAnomaly(Su et al., 2019, KDD)の論文で公開されたサーバーマシンのデータセットです。
データの特徴
- サーバー数: 28台
- 各サーバーの次元数: 38(CPU使用率、メモリ、ネットワーク等)
- データ長: 各サーバー約708,405点
- 異常ラベル: テストデータに付与
- 特徴: 各サーバーが異なるパターンを持つ
SMDは、サーバーごとに個別のモデルを訓練して評価することが多く、モデルの汎化性能を評価するのに適しています。
PSM(Pooled Server Metrics)
PSMは、eBay社が公開したサーバーメトリクスデータセットです(Abdulaal et al., 2021, KDD)。
データの特徴
- 次元数: 25
- 訓練データ: 132,481点
- テストデータ: 87,841点
- 異常率: 約28%(比較的高い)
- 特徴: 欠損値を含む
データセット選択のガイドライン
手法を評価する際のデータセット選択の指針をまとめます。
import matplotlib.pyplot as plt
import numpy as np
# レーダーチャートでデータセットの特性を比較
categories = ['Dimensions', 'Data Size', 'Anomaly Rate', 'Complexity', 'Popularity']
n_cats = len(categories)
# 各データセットのスコア(1-5の5段階評価)
scores = {
'telemanom': [2, 1, 1, 2, 4],
'SWaT': [3, 3, 3, 4, 5],
'WADI': [5, 5, 2, 5, 4],
'SMD': [3, 5, 2, 3, 5],
'PSM': [2, 2, 5, 3, 3],
}
angles = np.linspace(0, 2 * np.pi, n_cats, endpoint=False).tolist()
angles += angles[:1]
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
colors = ['steelblue', 'coral', 'mediumseagreen', 'orange', 'mediumpurple']
for (name, vals), color in zip(scores.items(), colors):
vals_closed = vals + vals[:1]
ax.plot(angles, vals_closed, 'o-', linewidth=2, color=color, label=name)
ax.fill(angles, vals_closed, alpha=0.1, color=color)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(categories, fontsize=11)
ax.set_ylim(0, 5)
ax.set_title("Dataset Characteristics Comparison", fontsize=14, pad=20)
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
plt.tight_layout()
plt.show()
まとめ
本記事では、時系列異常検知で利用される代表的なデータセットを解説しました。
- telemanom: NASA人工衛星のテレメトリデータ。1次元チャネルの集合
- SWaT / WADI: 水処理プラントのサイバーフィジカル攻撃データ。高次元で実プラント環境
- SMD: サーバーマシンのメトリクス。複数サーバーで汎化性能を評価可能
- PSM: eBay公開のサーバーメトリクス。異常率が高く欠損値を含む
- データセット選択は、次元数・データ規模・異常率・ドメインの適合性を考慮して行う