DTW算法——Matlab实现
概述
DTW (Dynamic time warping)算法是可以度量?jī)蓚€(gè)獨(dú)立時(shí)間序列的相似度的一種方法。曾被廣泛應(yīng)用在單詞音頻的匹配上。該方法主要用來(lái)解決在兩段序列的時(shí)長(zhǎng)不同的情況下,進(jìn)行相似度的判斷。
上圖中,左側(cè)時(shí)長(zhǎng)相等,可以逐一進(jìn)行歐式距離的計(jì)算,右側(cè)則是時(shí)長(zhǎng)不等,經(jīng)過(guò)DTW之后得到的結(jié)果,可以看出來(lái)兩個(gè)序列并不是一一對(duì)應(yīng)的。
再比如上面左圖,要得到藍(lán)色序列與紅色序列的相似度,因?yàn)榭梢钥闯鰜?lái)兩個(gè)序列有經(jīng)過(guò)平移的跡象,直接用一一匹配的方法顯然是不合理的。要得到左圖的對(duì)應(yīng)效果,就需要用DTW方法。
算法原理與步驟
① 計(jì)算兩個(gè)特征點(diǎn)之間的歐氏距離。構(gòu)成一個(gè) n*m 矩陣,距離矩陣。
②計(jì)算累計(jì)距離 得到DP矩陣。
計(jì)算后的的值,放到DP矩陣中,為了更加直觀的理解,把這兩個(gè)序列繪圖如下:
其實(shí)在計(jì)算過(guò)程中,計(jì)算的順序其實(shí)是有方向的。網(wǎng)上有很多的博客說(shuō)的也非常清楚,博主在這里不再贅述。為了更好的理解計(jì)算過(guò)程,列舉一個(gè)非常非常非常非常簡(jiǎn)單的例子來(lái)幫助理解,如下圖: A B為帶有兩個(gè)特征值的序列,右邊是其對(duì)應(yīng)的DP矩陣的求解步驟。
③ 當(dāng)計(jì)算完整個(gè)DP矩陣 后,右上角的值(不一定是右上角,就是最終的得到的那個(gè)矩陣角上的值)即為兩個(gè)序列的累計(jì)距離。
④從右上角往左下角回溯,找到累計(jì)距離最短的路徑,根據(jù)路徑可以得到各個(gè)點(diǎn)之間的對(duì)應(yīng)關(guān)系。
算法的實(shí)現(xiàn)
博主是利用matlab實(shí)現(xiàn)的這個(gè)算法,只是因?yàn)槔胢atlab可以很方便的查看矩陣和畫(huà)圖,檢查算法的正確性,但是沒(méi)有調(diào)用matlab中成形的函數(shù),所以利用這個(gè)思路,用C/C++也是可以實(shí)現(xiàn)的,便于移植。
首先要寫(xiě)好兩個(gè)函數(shù)。
一個(gè)是Get Min();用來(lái)得到三個(gè)值中的最小值,在計(jì)算 DP矩陣 時(shí)用得到。
另一個(gè)是GetMinIndex();這是用來(lái)在得到 DTW 結(jié)果之后,方便顯示特征點(diǎn)匹配的結(jié)果,返回兩個(gè)序列對(duì)應(yīng)特征點(diǎn)的索引。
function [index_i,index_j] = GetMinIndex(a,b,c,i,j) %a 是相鄰左上角,b 是相鄰正上方,c說(shuō)相鄰正左方 %i 是當(dāng)前的x坐標(biāo) j 是當(dāng)前 y坐標(biāo) if(a <= b && a <= c)index_i = i-1;index_j = j-1; elseif(b <= a && b <= c)index_i = i-1;index_j = j; elseif(c <= b && c <= a)index_i = i;index_j = j-1; end end接下來(lái)就是主函數(shù)了
%生成兩個(gè)有明顯平移性質(zhì)的時(shí)間序列 x = zeros(1,50); for i = 1:50x(i) = sin(i*2*pi/50)+2; end y = zeros(1,50); for i = 1:50y(i) = sin(i*2*pi/50 + pi/6)+2; end x_len = length(x); y_len = length(y); plot(1:x_len,x);hold on plot(1:y_len,y);hold on %計(jì)算兩序列每個(gè)特征點(diǎn)的距離矩陣 distance = zeros(x_len,y_len); for i = 1:x_lenfor j=1:y_lendistance(i,j) = (x(i)-y(j)).^2;end end %計(jì)算兩個(gè)序列 DP = zeros(x_len,y_len); DP(1,1) = distance(1,1); for i=2:x_lenDP(i,1) = distance(i,1)+DP(i-1,1); end for j=2:y_lenDP(1,j) = distance(1,j)+DP(1,j-1); end for i=2:x_lenfor j=2:y_lenDP(i,j) = distance(i,j) + GetMin(DP(i-1,j),DP(i,j-1),DP(i-1,j-1));end end %回溯,找到各個(gè)特征點(diǎn)之間的匹配關(guān)系 i = x_len; j = y_len; while(~((i == 1)&&(j==1)))plot([i,j],[x(i),y(j)],'b');hold on %畫(huà)出匹配之后的特征點(diǎn)之間的匹配關(guān)系if(i==1)index_i = 1index_j = j-1elseif(j==1)index_i = i-1index_j = 1else[index_i,index_j] = GetMinIndex(DP(i-1,j-1),DP(i-1,j),DP(i,j-1),i,j)endi = index_i;j = index_j; end最終效果如下圖,可以看出來(lái)是考慮了平移之后的匹配。
總結(jié)
以上是生活随笔為你收集整理的DTW算法——Matlab实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 前端学习(2941):vue的生命周期
- 下一篇: 递归与分治策略之利用中位数线性时间选择