はじめに
相互相関は、信号のズレや類似度を見るための基本的な手法としてよく使われています。
ラグをずらしながら2つの信号を比較することで、「どれくらい似ているか」や「どれくらいずれているか」を評価できます。
一方で、実際のデータでは次のような問題があります:
- スパイクノイズ(外れ値)が混ざる
- 欠損値がある
- 波形そのものは崩れていても、周期構造は残っている
こういう場合、単純な相互相関だと評価が不安定になることがあります。
周期構造で比較するという考え方
今回、周期性解析の枠組みを使って「信号同士を比較する」実装を追加しました(cross-periodicity)。
やっていること自体はシンプルで、
- ラグをずらす
- 対応する位置の値を比較する
- 全体の一致度を評価する
という流れです。
ただし、評価の仕方が少し違います。
- 差ではなく
minベースで一致度を計算 - 有効なデータ数で補正(valid_count)
これにより、
外れ値に引っ張られにくい評価
になっています。
相互相関との違い
相互相関が「波形の一致」を見るのに対して、
この手法は「周期構造の一致」を見るアプローチです。
多少波形が崩れていても、
- 周期的なパターンが残っているか
- どのラグでその構造が一致するか
を見ることができます。
どういうときに使えそうか
今回の実装を考えたきっかけとしては、
「完全一致ではないけど、周期的には似ている」ようなケースです。
例えば:
- ノイズが多い信号同士の比較
- 異なるセンサで観測された周期データの一致評価
- ピッチ検出アルゴリズムの結果比較
- 欠損や外れ値を含む時系列データの比較
といった場面です。
いわゆる「綺麗な波形」を前提にしない比較になります。
実装について
Pythonでシンプルに書くと、イメージはこんな感じです:
import numpy as np
from bedcmm.pattern import cross_periodicity
x = np.array([1, 2, 3, 2, 1], dtype=np.float64)
y = np.array([0, 1, 2, 3, 2], dtype=np.float64)
periods = np.arange(0, 5)
result = cross_periodicity(x, y, periods)
ラグごとに一致度が出るので、ピークを見ることで対応する周期やズレを評価できます。
補足(実装の位置づけ)
この相互周期性解析は、公開している特許アルゴリズムのコア部分とは独立した実装として追加しています。
そのため、周期性解析の応用的なツールとして気軽に使えるようにしています。
リポジトリ
実装はこちらに置いています:
おわりに
まだシンプルな実装ですが、
- NaN対応
- 評価方法の拡張
あたりは今後詰めていく予定です。
もし使い道や改善案があれば、ぜひ教えてもらえると助かります。
※この記事はほぼLLMに書いてもらいました。