心電図の波形が正常か不整脈か、センサ信号がどの動作パターンか、機械の振動がどの故障モードか——時系列を「どのクラスに属するか」当てたい場面は山ほどあります。ここで少し発想を飛ばしてみましょう。文章の分類(スパム判定やニュースのジャンル分けなど)は、すでに情報検索の分野で洗練された道具立てがあります。単語を数えて、tf-idfで重み付けして、コサイン類似度で近いカテゴリに振り分ける——あの枠組みです。
「時系列にも同じことができないか?」という問いに、鮮やかに答えたのが SAX-VSM(Senin & Malinchik, ICDM 2013)です。アイデアは単純明快です。
時系列を SAX で「単語」に変換してしまえば、あとはテキスト分類とまったく同じ。tf-idf でクラスごとの代表ベクトルを作り、コサイン類似度が最も高いクラスに分類する。
SAX-VSMが今も愛される理由は、精度もさることながら 解釈性 にあります。「なぜこの時系列をこのクラスと判定したのか」を、元の波形のどの部分が効いたかというヒートマップで示せるのです。ブラックボックスになりがちな時系列分類で、これは大きな武器です。応用は心電図・脳波の分類、モーション認識、機械の状態監視、異常パターンの識別など多岐にわたります。
本記事の内容
- SAX-VSMの全体像(時系列 → 単語 → tf-idf → コサイン分類)
- SAX(記号集約近似)による時系列の記号化
- Bag-of-Words と tf-idf によるクラス代表ベクトル
- コサイン類似度による分類
- 「どの部分列が効いたか」の解釈性
- CBFデータでのスクラッチ実装と実測
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
- コサイン類似度とは
- MULISSE:多変量時系列の部分列類似検索(SAX/PAAを索引に使う関連手法)
- 時系列データの異常検知
SAX-VSM の全体像
まず全体の流れをつかみましょう。SAX-VSMは、テキスト分類のパイプラインを時系列にそのまま移植したものです。

左から順に、(1) 生の時系列を、(2) SAXで記号列(単語)に変換し、(3) 単語の袋(Bag-of-Words)を作り、(4) tf-idfでクラスを代表するベクトルに重み付けし、(5) 新しい時系列とのコサイン類似度を測って、(6) 最も似たクラスへ分類する、という流れです。
ここでの対応関係が肝心です。テキスト分類では「文書 = 記事、単語 = 語」でしたが、SAX-VSMでは 「文書 = クラス、単語 = SAXパターン(部分列の形)」 と読み替えます。各クラスの訓練データすべてから集めた SAX 単語をひとつの大きな袋にまとめ、そのクラスを代表する1本の tf-idf ベクトルを作るのです。
この読み替えのうまさを味わってください。文章では「政治」記事に『選挙』『議会』という語が頻出し、「スポーツ」記事に『得点』『試合』が頻出します。tf-idfはそうした特徴語を自動的に見つけ、ジャンルの指紋にします。SAX-VSMは、これとまったく同じ仕組みで、「不整脈クラスの心電図に頻出する波形パターン」を特徴語として自動抽出します。つまり、時系列の局所的な形を『語彙』として扱えば、テキスト検索の数十年の蓄積がそっくり使える——これがSAX-VSMの核心的な着想です。
では、その出発点である「時系列を単語に変える」SAXから見ていきましょう。
SAX — 時系列を記号列に変える
SAX(Symbolic Aggregate approXimation、記号集約近似) は、実数値の時系列を短い記号列(例:bbcdbbbb)に圧縮する表現です。Lin と Keogh らが2003年に提案して以来、時系列を離散シンボルに落とす標準的な手法として、類似検索・異常検知・モチーフ発見など幅広く使われてきました。SAX-VSMもその応用の一つです。手順は3ステップです。
- 正規化(z-正規化):平均0・分散1にそろえる。これで振幅やオフセットの違いを吸収し、「形」だけを比べられるようにする
- PAA(Piecewise Aggregate Approximation、区分集約近似):時系列を等間隔の区間に分け、各区間を平均値で置き換える。長い系列を短い数列に粗く要約する
- 記号化:各区間の平均値が、あらかじめ決めたブレークポイントのどの帯に入るかで、
a, b, c, ...という記号を割り当てる

図は、ある波形を正規化し(灰色)、8区間のPAA(青の階段)で要約し、緑の破線のブレークポイントで記号化した様子です。各区間の平均がどの帯に入るかで記号が決まり、この波形は bbcdbbbb という単語になりました。上り坂の区間で c, d と記号が上がっていくのが見て取れます。滑らかな要約により、細かなノイズに惑わされず「大まかな形」を単語として取り出せるわけです。
SAXがただの手抜き圧縮ではないのは、理論的な裏付けがあるからです。PAAは長さ $L$ の系列を $n$ 個の平均に落とす次元圧縮ですが、区間平均どうしのユークリッド距離は、元の系列のユークリッド距離を下から抑える(下界になる)ことが証明できます。さらにSAXの記号間に定義される距離(MINDIST)も、PAA距離を下から抑えます。つまり「記号列で見て遠いものは、元の波形でも必ず遠い」——この下界性があるおかげで、記号化しても本質的な距離構造が壊れず、類似検索での枝刈り(MULISSE などの索引)にも使えるのです。SAX-VSMは距離ではなく単語頻度を使いますが、その土台には「記号化が形の情報を保つ」というSAXの健全性があります。
ブレークポイントはガウス分位点で決める
記号を「どの値で区切るか」は、恣意的に決めるのではなく、各記号がほぼ等確率で現れるように決めます。正規化後の値は近似的に標準正規分布に従うので、ブレークポイントを標準正規分布の分位点に取れば、各帯が等確率になります。記号の種類の数をアルファベットサイズ $a$ と呼びます。

$a=3, 4, 5$ の場合の区切り方です。標準正規分布の面積を等分するようにブレークポイントを置くので、どの記号もおよそ $1/a$ の確率で出現します。$a$ を大きくすると記号が細かくなり表現力は上がりますが、ノイズも拾いやすくなります。等確率にするのは、特定の記号ばかりに偏って情報量が減るのを防ぐためです。
SAXで時系列1本を1つの単語に変えられました。しかし時系列全体を1単語にすると粗すぎます。そこで、スライド窓を使って「単語の袋」を作ります。
Bag-of-Words — スライド窓で単語を集める
時系列の上を長さ $w$ の窓を1点ずつずらしながら動かし、各窓を1つのSAX単語に変換します。こうして得られた単語をすべて袋に入れたものが Bag-of-Words です。文書中の単語を数えるのと同じ要領で、時系列を「どんな部分列(局所的な形)を、どれだけ含むか」で表現します。

上は長さ $w$ の窓をずらして各位置をSAX単語にする様子、下がその単語頻度(上位10)です。ここで一つ工夫があります。窓を1点ずらしただけでは、多くの場合SAX単語は変わりません。同じ単語が連続して大量に数えられると、平坦な区間の単語ばかりが過大にカウントされてしまいます。そこで numerosity reduction(数の削減):連続して同じ単語が出たら1回だけ数える、という処理を入れます。これにより「その形が何度も繰り返し現れたか」ではなく「その形が現れたか」を素直に捉えられ、ノイズに強くなります。
窓の長さ $w$ は、SAX-VSMで最も重要なパラメータです。これは「どのくらいの時間スケールの形を1単語とみなすか」を決めます。短い窓は細かな局所パターン(鋭いピークなど)を、長い窓は大きなうねり(トレンドや周期)を捉えます。判別に効く形がどのスケールにあるかは問題によって違うので、$w$ は交差検証で選ぶのが基本です。スライド窓を使うことのもう一つの重要な利点は、位置ずれに強いことです。同じ形が時系列のどこに現れても、窓がその上を通れば同じ単語として拾われるので、「イベントの発生タイミングがずれていても同じクラスと判定できる」——これはDTWが時間伸縮で吸収するのと同じ頑健性を、単語の袋という形で自然に実現しています。
各時系列がSAX単語の袋になりました。次に、クラスを代表するベクトルを tf-idf で作ります。
tf-idf — クラスを代表するベクトルを作る
あるクラス(たとえば「Bell」)の訓練データすべてから集めたSAX単語を1つの大きな袋にまとめ、単語の頻度を数えます。これを全単語について並べれば、そのクラスを表すベクトルになります。ただし、頻度をそのまま使うと問題があります。どのクラスにも共通して大量に出る「ありふれた単語」(平坦部の単語など)が大きな値を持ち、クラスを区別する役に立ちません。
そこでテキスト検索でおなじみの tf-idf 重み付けを使います。単語 $t$ のクラス $c$ における重みは、次のように定義します。
$$ w_{t,c} = \underbrace{\left(1 + \log f_{t,c}\right)}_{\text{tf: そのクラスでの出現}} \times \underbrace{\log\frac{N}{\mathrm{df}_t}}_{\text{idf: 希少性}} $$
$f_{t,c}$ はクラス $c$ での単語 $t$ の頻度、$N$ はクラス数、$\mathrm{df}_t$ は単語 $t$ が出現するクラスの数です。tf は「そのクラスでよく出る単語ほど重い」、idf は「少数のクラスにしか出ない希少な単語ほど重い」ことを表します。両者を掛けることで、「そのクラスに特有で、他のクラスにはあまり出ない単語」が高く重み付けされます。
具体的な数字で感覚をつかみましょう。3クラス($N=3$)で、ある単語がクラスBellに20回出て、かつBellとFunnelの2クラスに出現する($\mathrm{df}=2$)とします。このときBellでの重みは $(1+\log 20)\times\log(3/2) \approx 4.0 \times 0.41 \approx 1.6$ です。一方、3クラス全部に出るありふれた単語は $\log(3/3)=\log 1 = 0$ となり、idfがゼロなので重みも0——どのクラスの指紋にも使われません。逆に、あるクラスにしか出ない単語は $\log(3/1)\approx1.1$ と大きなidfを得て、そのクラスの強い目印になります。tf-idfは「ありふれた形を捨て、そのクラスならではの形を際立たせる」フィルタとして働くわけです。
ここで、SAX-VSMの計算量の利点も押さえておきましょう。tf-idfベクトルはクラスごとに1本しか作りません。10クラスなら10本のベクトルだけを保持し、分類時はクエリとこの10本の類似度を測るだけです。訓練データを全部保持して都度比較する1-NN(最近傍法)と違い、モデルがコンパクトで、テスト時が高速です。訓練データが何万本あっても、分類器はクラス数本のベクトルに凝縮されます。

CBFデータ(後述)の3クラスについて、tf-idf重みの大きい単語を並べたヒートマップです。行がクラス、列がSAX単語で、明るいほど重みが大きいことを表します。ある単語はCylinderだけで明るく、別の単語はFunnelだけで明るい、というように、各クラスに特有の単語がくっきり分かれています。これがクラスを見分ける手がかりになります。

クラスごとに重みの大きい単語を上位8個ずつ取り出したものです。各クラスが「自分を特徴づける単語」の集合を持っていることがわかります。Cylinder(台地状)、Bell(右上がり)、Funnel(右下がり)それぞれの形を反映した単語が上位に来ています。この tf-idf ベクトルが、各クラスの「指紋」になるわけです。
クラス代表ベクトルができたので、いよいよ分類です。
コサイン類似度で分類する
新しい(未知の)時系列が来たら、同じ手順でSAX単語の袋を作り、tf重みのベクトルにします。あとは、各クラスの tf-idf ベクトルとの コサイン類似度 を測るだけです。
$$ \mathrm{sim}(\bm{q}, \bm{c}) = \frac{\bm{q}\cdot\bm{c}}{\|\bm{q}\|\,\|\bm{c}\|} $$
$\bm{q}$ はクエリ時系列の単語ベクトル、$\bm{c}$ はクラスの tf-idf ベクトルです。コサイン類似度はベクトルの「向き」の近さを測る尺度で、単語の出現パターンがどれだけ似ているかを表します。最も類似度の高いクラスへ分類します。
$$ \hat{c} = \arg\max_{c}\ \mathrm{sim}(\bm{q}, \bm{c}) $$

3つのクエリ(真のクラスがそれぞれCylinder/Bell/Funnel)について、各クラスベクトルとのコサイン類似度を棒グラフにしたものです。いずれも正しいクラス(緑)の類似度が突出して高く、正しく分類できています。類似度の絶対値は語彙が疎なので小さめですが、大事なのはどのクラスが最大かであり、そこは明確に分かれています。
ここまでで分類の仕組みは完成です。しかしSAX-VSMの真価は、この先の「なぜそう判定したか」を語れる点にあります。
解釈性 — どの部分列が効いたのか
SAX-VSMが単なる分類器と一線を画すのが、解釈性です。分類に使ったのは「どのSAX単語がどれだけ効いたか」という情報なので、それを元の波形の上に描き戻せます。具体的には、時系列の各位置について、その位置を覆う窓のSAX単語が持つ(予測クラスの)tf-idf重みを集計し、色の濃さで表します。

CBFの3クラスについて、波形をクラス支持度で色付けしたものです。濃い(暗い)部分ほど、そのクラスと判定する決め手になった区間です。Bellでは右上がりの立ち上がり部分が濃く、Funnelでは急な立ち下がり部分が濃く、Cylinderでは台地の縁が濃くなっています。モデルが波形のどこを見て判断したかが一目でわかります。医療や産業診断のように「なぜそう判断したか」の説明責任が求められる分野で、この可視化は決定的な価値を持ちます。
この解釈性が「タダで」手に入るのが、SAX-VSMの設計の巧みさです。深層学習の分類器では、判断根拠を得るのにGrad-CAMやアテンション可視化といった追加の仕掛けが必要ですが、SAX-VSMでは分類そのものが「単語ごとの重みの足し合わせ」なので、その重みを位置に戻すだけで根拠が出ます。分類の仕組みと説明の仕組みが同じ——後付けの近似ではなく、モデルが実際に使った量そのものを見せられるので、説明が信頼できます。原論文のタイトルに “Interpretable” と冠されているのは伊達ではありません。心電図で「この立ち上がりが不整脈の根拠」と医師に示せる、機械の振動で「この区間の異常な形が故障の証拠」と技術者に示せる——このように、分類結果を人間の判断につなげられるのが、精度以上に効いてくる場面は多いのです。
実務では、パラメータ(窓長・PAA区間数・アルファベットサイズ)の選び方も気になります。
パラメータの効き方
SAX-VSMの主なパラメータは、スライド窓の長さ $w$、PAA区間数 $n$(単語の長さ)、アルファベットサイズ $a$(記号の種類数)の3つです。これらは表現の「粗さ・細かさ」を決めます。

アルファベットサイズとPAA区間数を変えて分類精度を測ったものです。粗すぎる(PAAやアルファベットが小さい)と形の違いを表現しきれず、細かすぎるとノイズを拾って単語がばらつき、いずれも精度が落ちる傾向が見えます。中庸のあたりに良いゾーンがあります。実務では交差検証でこれらを選ぶのが定石です。SAXはもともとノイズに強い表現ですが、パラメータ次第でその強みが活きも死にもします。
直感的には、アルファベットサイズ $a$ は「振幅方向の解像度」、PAA区間数 $n$ は「時間方向の解像度」を決めます。両方を上げれば単語は精密になりますが、語彙が爆発的に増えて各単語の出現がまばらになり、統計が不安定になります(テキストで言えば、めったに使われない専門語ばかりの文書のようなもの)。逆に両方を下げれば頑健になりますが、異なる形が同じ単語に潰れて判別力を失います。この「解像度とロバスト性のトレードオフ」を、データに合わせて調整するのがSAX-VSMを使いこなす勘所です。原論文ではこの3パラメータをDIRECT法という最適化で自動選択しています。
最後に、全体を通した分類性能を確認します。
CBFデータでの実測
定番のベンチマーク CBF(Cylinder-Bell-Funnel) で試します。台地状(Cylinder)、右上がり(Bell)、右下がり(Funnel)の3クラスからなる合成時系列で、ノイズと位置・幅のばらつきが加わります。SAX表現の教科書的なテストケースです。特徴的な形(台地・上り坂・下り坂)が系列のどこに、どの幅で現れるかがランダムなので、「位置ずれに強く、局所的な形を捉える」というSAX-VSMの性質を試すのにうってつけです。

訓練90本・テスト90本で、窓長40・PAA8区間・アルファベット4のSAX-VSMを学習した結果、テスト精度は 1.00(全問正解)でした。混同行列でも対角成分だけに値が集まっています。CBFはSAX-VSMが得意とする素直なデータですが、記号化という一見乱暴な圧縮を経ても、形の違いがしっかり保たれて完璧に分類できることがわかります。
他手法との位置づけ
時系列分類の定番手法と比べると、SAX-VSMの立ち位置がはっきりします。1-NN + DTW(動的時間伸縮) は長年の強豪ですが、全訓練データを保持して都度DTW距離を計算するため、データが増えると遅く、しかも「なぜその予測か」を説明しにくい欠点があります。シェイプレット法 は判別に効く部分形状を明示的に学び解釈性が高いものの、候補探索の計算コストが大きい。SAX-VSMはこの中間で、クラスごとに1本のベクトルという軽量なモデルを持ち、tf-idf重みを通じた解釈性を備え、実装も単純です。精度の絶対王者ではありませんが、「速い・軽い・説明できる」のバランスが良く、まず試すベースラインとして、また解釈性が必須の場面で、今も現役です。より難しい実データでは精度は下がりますが、多くのUCRベンチマークで距離ベース手法に匹敵する結果が報告されています。
まとめ
本記事では、SAX-VSMを仕組みから解説しました。
- 発想 — 時系列をSAXで「単語」に変えれば、テキスト分類の道具(Bag-of-Words・tf-idf・コサイン類似度)がそのまま使える
- SAX — 正規化 → PAA(区間平均)→ ガウス分位点のブレークポイントで記号化。ノイズに強い記号列表現
- tf-idf — クラスを文書とみなし、「そのクラスに特有で希少な単語」を高く重み付けしてクラス代表ベクトルを作る
- 分類 — クエリの単語ベクトルと各クラスベクトルのコサイン類似度が最大のクラスへ
- 解釈性 — どのSAX単語(部分列)が効いたかを元波形にヒートマップで描き戻せる。これがSAX-VSM最大の武器
- 実測 — CBFで精度1.00。パラメータは粗すぎ・細かすぎを避けて交差検証で選ぶ
SAX-VSMは、「異なる分野の成熟した道具を、うまい変換で持ち込む」というアイデアの美しい実例です。時系列を記号列に落とすというSAXの発想は、SAX-VSM以外にも、部分列の類似検索(iSAX索引)や異常検知など幅広く応用されています。
次のステップとして、以下の記事も参考にしてください。