周期的な現象全体を捉えて変化検知をするには、どれくらい窓幅などを広げると良いだろうか。
適当に窓幅Mを変えて試しても傾向が良く分からないので網羅的に調べてみた。ある窓幅を使って調べたときの変化度の最大値を見る。
定常状態にある周期現象の入力データの全体で変化度の最大値が小さいということは、周期現象を定常状態として認識できたということを意味するはずである。
実験結果は以下の図のとおり。周期60に対して、窓幅は2倍の 120でやっと定常状態として捉えられている。しかし、窓幅が少し増えると、またぞろ定常状態と認識できなくなってしまう。さらに窓幅を広げる実験もあるだろうが、窓幅を広げ履歴行列、テスト行列の列数も比例して大きくしている今回の条件では、計算コストの増加を考慮してやめておく。
<pre>
import numpy as np
import matplotlib.pyplot as plt
import math
def normV(v):
return v / np.linalg.norm(v,2)
pat_len = 600
pat = np.empty(pat_len)
for i in range (10):
for p in range (60):
pat[60*i+p] = (math.exp(-p/4) +0.02)* math.sin(math.pi * p / 5)
plt.plot(pat[pat_len-200:pat_len-100])
plt.plot(pat[:])
a_max = np.zeros(160)
for M in range(60,61):
n = M // 2
k = M // 2
L = k // 2
r = 3
m = 2
a = np.zeros(pat_len)
for i in range (pat_len-L-k-M):
X = np.empty((M,0))
for j in range(n):
X = np.hstack((X, np.array([normV(pat[i+j:i+j+M])]).T) )
U,Sx,Vx = np.linalg.svd(X, full_matrices=True)
Z = np.empty((M,0))
for j in range(k):
Z = np.hstack((Z, np.array([normV(pat[i+L+j:i+L+j+M])]).T) )
Q,Sz,Vz = np.linalg.svd(Z, full_matrices=True)
UQ = np.dot(U.T[0:r,:], Q.T[0:m,:].T)
a[i+L+k+M-2]=1-np.linalg.norm(UQ,2)
a_max[M] = 0.0
for i in range (100,pat_len):
if (a[i] > a_max[M]) :
a_max[M] = a[i]
print ("M = ", M)
plt.plot(a[pat_len-200:pat_len-100])
plt.plot(a_max[0:160])
</pre>