前回の実験で検知できなかった理由はなぜだろうか。
簡単に言うと、特異ベクトルの数に対して特異ベクトルの次元が足りなかったから。計算過程を目視確認しやすいように部分時系列の長さを3としていた。つまり3次元。ここで、二本のベクトルの張る空間は原点を通る平面となる。3次元空間で2つの平面を考えると、どうしても交わることになる。行列2ノルムで考えたとき、2つの平面に3次元空間は狭すぎたということだ。
部分時系列の長さを4に増やして実験した結果は下図のとおり。最初の 11 が顔を出したところまでは変化度 0 だが、11が途中にある間は 0.0078 や 0.00014 といった値を取っていて、変化検知に成功している。
import numpy as np def normV(v): return v / np.linalg.norm(v,2) pat = [1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0] M = 4 k=4 c = np.empty((M,0)) for j in range(k): c = np.hstack((c, np.array([normV(pat[j:j+M])]).T) ) u1,s1,v1 = np.linalg.svd(c, full_matrices=True) for i in range (12): c = np.empty((M,0)) for j in range(k): c = np.hstack((c, np.array([normV(pat[i+j:i+j+M])]).T) ) q,s,v = np.linalg.svd(c, full_matrices=True) uq = np.dot(u1.T[[0,1],:], q.T[[0,1],:].T) print (pat[i:i+M+k-1]) print ("a = ", 1-np.linalg.norm(uq,2))
[1] 井出 剛、杉山 将, 異常検知と変化検知, 講談社, 2017 ISBN978-4-06-152908-3