原文鏈接:動態時間規整(DTW)算法介紹
導讀:通常我們比較兩個序列的相似性,可以通過直接點對點計算距離的方式實現。但是當兩個序列長度不相等時,原有的方法就變得不適用,比如兩個人對同一個詞語發音不同,導致閱讀同一詞語的時長不同,因此就要對序列進行延伸或壓縮才能比較兩段語音是否閱讀的是同一個詞語。本期介紹的DTW就是解決這類問題的常用算法。
基本概念
動態時間規整(Dynamic Time Warping,DTW)是按照距離最近原則,構建兩個長度不同的序列元素的對應關系,評估兩個序列的相似性。在構建兩個序列元素對應關系時,需要對序列進行延伸或壓縮。以下圖為例,兩條黑色實線代表兩個語音序列,虛線代表兩個序列元素的對應關系,可以看出存在某一元素與多個元素存在對應關系,如果換成一個個離散的點表示的話,就是對該點進行了拉伸處理。
DTW算法最早用于語音識別問題,如:語言學習跟讀軟件中,檢測發音是否標準,后來也在傳感器動作識別、生物信息比對等方面有所應用。
計算過程
DTW的計算過程主要分為構建累積距離矩陣和尋找最短路徑兩部分,類似于動態規劃的過程。現在假設x序列為{3,4,5},y序列為{1,4,2,6},相似度計算采用歐式距離,即d=abs(a-b),我們以此為例介紹DTW算法的計算過程。
step 1 : 構建累積距離矩陣
首先我們形成一個3*4的網格,其中行對應X序列,列對應Y序列,每個網格內元素代表對應點的累積距離。
從左下角開始計算,左下角取值直接套用距離計算公式:3-1=2。然后網格第一列從下往上開始,除了要計算對應點的距離外,還需加上下方相鄰網格的距離,進而實現距離的累積。同理,網格第一行從左至右,除了計算對應點距離之外,還需加上左方相鄰網格的距離。
其余的網格,除要計算對應點的距離外,還需找到左下方三個點的最小值進行相加。
以此類推,得到最終的累積距離矩陣。
step 2 : 尋找最短路徑
從右上角開始,尋找左下方三個點中距離最小的點,以此類推,通過回溯的方式找到最短路徑,得到最短距離。注意,從右上角開始至少找到最短路徑的便捷方法,路徑的起點依舊為左下角的點。
在尋找最短路徑的時候,有三個限制條件:
邊界條件:起點和終點分別為左下角和右上角。比如:語速不同,讀一個詞語的開始和結束應該相同。
連續性:只能和相鄰的點匹配,不能跨過某個點進行匹配。
單調性:路徑上的點隨著時間單調進行,不能往左回退。
因此每個點的下一步路徑,只有可能存在于右上方的三個點當中。
Python實現
選假設x為參照序列,比較y、z哪一個序列與x最為相似。
import numpy as np
x =np.array([2,0,1,1,2,4,2,1,2,0]).reshape(-1,1)
y?=?np.array([1,1,2,4,2,1,2,0]).reshape(-1,1)
z?=?np.array([3,2,2,4,2,1]).reshape(-1,1)
from dtw import dtw
euclidean_norm?=lambdax,?y:?np.abs(x?-?y)
d1,?cost_matrix1,?acc_cost_matrix1,?path1?=?dtw(x,?y,?dist=euclidean_norm)?
d2,?cost_matrix2,?acc_cost_matrix2,?path2?=?dtw(x,?z,?dist=euclidean_norm)?
print("d1=",d1,"d2=",d2)
import matplotlib.pyplot as plt
plt.imshow(acc_cost_matrix1.T, origin='lower', cmap='gray',interpolation='nearest')plt.plot(path1[0],?path1[1],'w')plt.show()
根據計算結果,y與x的距離比z與x的距離更近,因此y相對與x更為相似。具體距離及軌跡線圖如下:
參考內容:
1.http://t.zoukankan.com/wangleBlogs-p-10444892.html
2.https://blog.csdn.net/gdp12315_gu/article/details/55667483
3.https://blog.csdn.net/weixin_39910711/article/details/108178110
4.Eamonn J. Keogh, Derivative Dynamic Time Warping
5.DTW(動態時間規整)算法原理與應用
往期推薦: