04.14.3
DTW vs DDTW
data1 と、振幅 10・オフセット 0 の data2 を用意し、dtaidistance の dtw.warping_paths による DTW と、自作モジュールの DDTW 関数を同じ 2 本に当てて、ワーピングパスの図と累積コストの熱マップを見比べます。動的時間伸縮(DTW) で累積コスト行列とワーピングパスの読み方を先に見ておくと、このページの 2 枚の図(plot_warpingpaths と熱マップ)がすぐ読めます。
直感 #
同じ山道を歩いた 2 人の高度計の記録を比べるとします。1 人は海抜 20 m の町から、もう 1 人は海抜 0 m の海岸から出発しているので、値そのものを比べると全区間で 20 m の差が出続けます。DTW はこの 20 m を「違い」として距離に積み上げます。しかし「登り坂と下り坂のタイミングが同じか」を知りたいなら、比べるべきは高度ではなく傾きです。DDTW は各時点の傾き(1 つ前と 1 つ後の差分の平均)を先に計算し、その傾きの列どうしに DTW をかけるので、出発地点の高さ 20 m は距離に影響しません。
1. ライブラリ #
| |
何が起きているか(ステップで見る) #
コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。
見るポイント:DTW は時間を伸び縮みさせて形を合わせる。タイミングがずれた似た波形を「近い」と判定できる。
実験に使用する二つの波形をプロット #
振幅 12・オフセット +20 の sin 波と、振幅 10・オフセット 0 でノイズを乗せた sin 波を 30 点ずつ作ります。形はほぼ同じで高さが 20 違う、DDTW の効果が最も分かりやすい組み合わせです。
| |

DTW #
dtaidistance で累積コスト行列と最良経路を求め、2 本の系列と一緒に 1 枚の図にします。
| |
(<Figure size 720x720 with 4 Axes>,
[<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>])
![[, , , ])の図](https://k-dm.work/images/timeseries/shape/002_DTWvsDDTW_files/002_DTWvsDDTW_6_1.png)
DDTW #
同じ 2 本に自作の DDTW を当て、累積コスト行列を熱マップで描きます。
| |
findfont: Font family ['IPAexGothic'] not found. Falling back to DejaVu Sans.
findfont: Font family ['IPAexGothic'] not found. Falling back to DejaVu Sans.
![findfont: Font family [‘IPAexGothic’] not found. Falling bac…の図](https://k-dm.work/images/timeseries/shape/002_DTWvsDDTW_files/002_DTWvsDDTW_8_1.png)
使いどころと落とし穴 #
形のタイミングだけを比べたい(心電図の波形、歩行のセンサー、売上の季節パターン)なら DDTW、値の水準そのものに意味がある(温度の異常検知、在庫量の比較)なら DTW を選びます。DDTW は差分を取るので、data2 に乗せた一様ノイズのような細かい揺れが傾きでは増幅されます。ノイズが多いデータでは移動平均や Savitzky–Golay フィルタで平滑化してから DDTW にかけます。同じ効果を手軽に得たいなら、DTW の前に各系列を z 正規化(平均 0・分散 1)する方法もあり、オフセットと振幅の差はこれでも消えますが、途中でベースラインが動く系列には DDTW の方が強いです。
- 動的時間伸縮 (DTW) — 時間軸のずれを許容して距離を最小化
- Soft-DTW — 滑らかな勾配を持つ微分可能なDTW
- tsfreshで特徴量を抽出 — 時系列から自動的に大量の特徴量を生成