动态时间规整算法——DTW
???沒(méi)有做過(guò)機(jī)器學(xué)習(xí)的小伙伴們對(duì)這個(gè)算法應(yīng)該不是特別的了解,因?yàn)闄C(jī)器學(xué)習(xí)經(jīng)常會(huì)用到這個(gè)算法。再將這個(gè)算法之前,我們先看一下初中的知識(shí)點(diǎn)。
歐幾里得距離
????在講解動(dòng)態(tài)時(shí)間規(guī)整算法(Dynamic Time Warping, DTW)之前,我們先來(lái)了解一下,在日常生活中,用來(lái)計(jì)算兩點(diǎn)的距離,我們是怎么進(jìn)行的。回想一下初中的數(shù)學(xué)知識(shí)點(diǎn)——幾何距離,如下圖所示的二維空間中計(jì)算A點(diǎn)到B點(diǎn)的距離。
其中A點(diǎn)和B點(diǎn)的坐標(biāo)分別為:A(1,2) 和 B(2,1),如果要算A點(diǎn)到B點(diǎn)的距離,那么計(jì)算方式為:
????如果是在三維的空間,如下圖所示:
其中A點(diǎn)和B點(diǎn)的坐標(biāo)分別為:A(0,1,2)?和 B(1,3,1),如果要算A點(diǎn)到B點(diǎn)的距離,那么計(jì)算方式為:
? ? 以此類推,對(duì)于n維的空間,距離公式應(yīng)該表達(dá)為:
????從初中用到現(xiàn)在,那么你知道這個(gè)和計(jì)算距離的方法是誰(shuí)發(fā)明的嗎?(應(yīng)該不是我嘿嘿嘿~~)。發(fā)明這個(gè)方法的大神就是歐幾里得,計(jì)算的距離公式也叫做歐幾里得距離,簡(jiǎn)稱歐氏距離。
? ?
????你會(huì)好奇,無(wú)端端講了歐幾里得距離做什么,我們先不急,繼續(xù)往下看。
動(dòng)態(tài)時(shí)間規(guī)整
? ? 上面我們講到了歐幾里得距離,舉的兩個(gè)例子也是針對(duì)空間上的位置計(jì)算,那么如果現(xiàn)在是兩個(gè)時(shí)序信號(hào)呢,也就是加上了時(shí)間維度,這種計(jì)算是否還能夠成立,接下來(lái)我們來(lái)看一下一個(gè)小例子,如下圖所示,假設(shè)用戶A和用戶B兩個(gè)人在讀 “我愛(ài)中國(guó)”。用戶A說(shuō)的比較干脆,用戶B說(shuō)的有點(diǎn)拖音(即用戶A說(shuō):“我愛(ài)中國(guó)”,用戶B說(shuō)“我~愛(ài)中國(guó)”,差別就是用戶B在說(shuō)我的時(shí)候拖了一下音)。我們假設(shè)用戶A的發(fā)音是【1,2,1,3】,用戶B的發(fā)音是【1,1,2,1,3】,兩個(gè)用戶的發(fā)音區(qū)別就是用戶B在說(shuō)第一個(gè)字的時(shí)候拖了音,如下圖所示:
????因?yàn)橛脩鬉和用戶B講的是同一句話,并且意思也是一樣的,那么按照機(jī)器學(xué)習(xí)理論來(lái)說(shuō),它們的相似性應(yīng)該很相似,也就是距離很近,OK,那如果我們認(rèn)為是n維數(shù)據(jù),然后使用n維的歐氏距離來(lái)計(jì)算一下這兩者的距離,表達(dá)式為:
????通過(guò)上面表達(dá)式計(jì)算得知,用戶A和用戶B的距離為:
這也太遠(yuǎn)了吧。不是說(shuō)相似嗎。
????細(xì)心的你已經(jīng)發(fā)現(xiàn)了一個(gè)問(wèn)題,歐幾里得距離的計(jì)算方式是運(yùn)用在空間上的比較多。對(duì)于時(shí)間序列,歐幾里得距離計(jì)算方法好像顯得不那么友好了。所以為了解決這個(gè)問(wèn)題,日本的一位學(xué)者 Itakura 在60年代提出了動(dòng)態(tài)時(shí)間規(guī)整算法(Dynamic Time Warping,DTW),用于衡量?jī)蓚€(gè)長(zhǎng)度不同的時(shí)間序列的相似度。把未知量伸長(zhǎng)或縮短(壓擴(kuò)),直到與參考模板的長(zhǎng)度一致,在這一過(guò)程中,未知序列會(huì)產(chǎn)生扭曲或彎折,以便其特征量與標(biāo)準(zhǔn)模式對(duì)應(yīng)。具體做法如下圖所示:
????圖中的紅線就是將用戶B的語(yǔ)音序列和用戶A的語(yǔ)音序列對(duì)應(yīng)起來(lái),實(shí)現(xiàn)時(shí)間規(guī)整的思想,這樣計(jì)算的距離才會(huì)是最短的。
????那么DTW算法的步驟如下:
計(jì)算兩個(gè)序列各個(gè)點(diǎn)之間的距離矩陣;
尋找一條從矩陣左上角到右下角的路徑,使得路徑上的元素和最小:
我們稱路徑上的元素之和為路徑的長(zhǎng)度,那么怎么去尋找長(zhǎng)度最小的路徑呢?
矩陣從左上角到右下角的路徑長(zhǎng)度有以下性質(zhì):
(1)?當(dāng)前的路徑長(zhǎng)度 = 前一步的路徑長(zhǎng)度 + 當(dāng)前元素的大小
(2)?路徑上的某個(gè)元素(i,j),它的前一個(gè)元素只可能為以下三者之一:
? ? ? a.? 左邊的相鄰元素(i, j-1)
? ? ? b. 上面的相鄰元素(i-1, j)
? ? ? c.? 左上方的相鄰元素(i-1, j-1)
表達(dá)式表示為:
????????3. 尋找到最后的右下角就是路徑的最小路徑。
接下來(lái),我們來(lái)對(duì)用戶A和用戶B進(jìn)行動(dòng)態(tài)時(shí)間規(guī)整步驟的解析:
首先,將序列A和序列B的矩陣列舉出來(lái),然后元素兩兩相減:
????通過(guò)相減后得到上面的一個(gè)矩陣,接下來(lái)就定義一個(gè)結(jié)果矩陣來(lái)存放路徑的長(zhǎng)度,如下圖所示,初始化結(jié)果矩陣,然后計(jì)算最上面一行和最左邊一列的路徑和,因?yàn)楦鶕?jù)上面公式得到,第一行的每一個(gè)節(jié)點(diǎn)i只能從它的左邊i-1過(guò)來(lái),而每一列的每一個(gè)節(jié)點(diǎn)j只能從它的上一個(gè)節(jié)點(diǎn)j-1過(guò)來(lái)。然后再計(jì)算其他的路徑,根據(jù)公式,在其他的節(jié)點(diǎn)中(i,j)的路徑前一個(gè)點(diǎn)有三個(gè)(i,j-1)、(i-1,j-1)、(i-1,j),分別計(jì)算取最小值作為當(dāng)前的數(shù)值。依次計(jì)算遍歷。
最后得到的結(jié)果矩陣為:
????最右下角的元素?cái)?shù)值就是用戶A和用戶B兩個(gè)序列的距離,結(jié)果為0,說(shuō)明用戶A和用戶B所說(shuō)的話是一樣的。
DTW的代碼如下:
#include<iostream> #include<string.h> #include<stdlib.h> using namespace std; #define NUM1 6 //序列中樣本點(diǎn)的個(gè)數(shù)簡(jiǎn)單起見(jiàn),假設(shè)2個(gè)序列的樣本點(diǎn)一樣多 #define NUM2 5 #define max 999 #define Min(a,b) (a<b?a:b)int main() {int i,j,k;//int a[NUM1],b[NUM2];int b[4]={1,2,1,3};int a[6]={1,1,2,1,3};int distance[NUM1+1][NUM2+1];int output[NUM1+1][NUM2+1];memset(distance,0,sizeof(distance));memset(output,0,sizeof(output));for(i=0;i<=NUM1;i++){for(j=0;j<=NUM2;j++){distance[i][j]=max;output[i][j]=max;}}distance[0][0]=0;output[0][0]=0;//for(i=0;i<NUM1;i++) cin>>a[i];//for(i=0;i<NUM2;i++) cin>>b[i];for(i=1;i<=NUM1;i++)for(j=1;j<=NUM2;j++)distance[i][j]=abs(b[j-1]-a[i-1]); //計(jì)算點(diǎn)與點(diǎn)之間的歐式距離for(i=1;i<NUM1;i++){for(j=1;j<NUM2;j++)cout<<distance[i][j]<<'\t';cout<<endl;} //輸出整個(gè)歐式距離的矩陣cout<<endl;for(i=1;i<NUM1;i++)for(j=1;j<NUM2;j++) output[i][j]=Min ( Min(output[i-1][j-1],output[i][j-1]) ,output[i-1][j] )+distance[i][j];//DP過(guò)程,計(jì)算DTW距離for(i=1;i<NUM1;i++){for(j=1;j<NUM2;j++)cout<<output[i][j]<<'\t';cout<<endl;} //輸出最后的DTW距離矩陣,其中output[NUM][NUM]為最終的DTW距離和system("pause");return 0; }結(jié)果輸出為:
總結(jié)
以上是生活随笔為你收集整理的动态时间规整算法——DTW的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【黑帽大牛】浅谈SEO快排系统对网站排名
- 下一篇: boll指标(布林带)计算公式