Keogh, Eamonn J., and Michael J. Pazzani. “Derivative Dynamic Time Warping.” Proceedings of the 2001 SIAM International Conference on Data Mining. (PDF)
Dynamic Time Warping(DTW)は 2 本の時系列を整列させ、対応付けた点同士の距離を最小化します。ただし値の差をそのまま距離にすると、縦方向のオフセットが大きいケースで「形は近いのに距離が離れてしまう」ことがあります。Derivative Dynamic Time Warping(DDTW)は距離の定義を「傾きの差」に置き換えることで、形状の近さに注目します。
importmatplotlib.pyplotaspltnp.random.seed(0)t=np.linspace(0,4*np.pi,120)series_a=np.sin(t)series_b=np.sin(t)+0.6series_c=np.sin(1.2*t+0.3)plt.figure(figsize=(10,3))plt.plot(t,series_a,label="Series A",color="black")plt.plot(t,series_b,label="Series B (offset)",color="tab:green")plt.plot(t,series_c,label="Series C (shape change)",color="tab:orange")plt.legend()plt.title("比較する 3 つの時系列")plt.tight_layout()plt.show()
defddtw_cost_matrix(x:np.ndarray,y:np.ndarray)->tuple[np.ndarray,list[tuple[int,int]]]:dx,dy=derivative_series(x),derivative_series(y)n,m=len(dx),len(dy)cost=np.full((n+1,m+1),np.inf)cost[0,0]=0.0foriinrange(1,n+1):forjinrange(1,m+1):dist=abs(dx[i-1]-dy[j-1])cost[i,j]=dist+min(cost[i-1,j],cost[i,j-1],cost[i-1,j-1])i,j=n,mpath:list[tuple[int,int]]=[]whilei>0andj>0:path.append((i-1,j-1))step=np.argmin((cost[i-1,j],cost[i,j-1],cost[i-1,j-1]))ifstep==0:i-=1elifstep==1:j-=1else:i-=1j-=1path.reverse()returncost[1:,1:],pathcost_ac,path_ac=ddtw_cost_matrix(series_a,series_c)plt.figure(figsize=(5,4))plt.imshow(cost_ac,origin="lower",cmap="viridis")path_arr=np.array(path_ac)plt.plot(path_arr[:,1],path_arr[:,0],color="white",linewidth=1.5)plt.title("DDTW cumulative cost (Series A vs Series C)")plt.xlabel("Series index j")plt.ylabel("Series index i")plt.colorbar(shrink=0.8,label="Cumulative cost")plt.tight_layout()plt.show()
Series A と Series C の形状が異なるため、パスが水平・垂直方向に大きく移動しながら対応づけていることが分かります。これは形状の違いを埋め合わせようとする DDTW の挙動を示しています。