Dynamic Time Warping(DTW)动态时间规整

1. 问题背景

在时间序列中,需要比较相似性的两段时间序列的长度可能并不相等,在语音识别领域表现为不同人的语速不同。而且同一个单词内的不同音素的发音速度也不同,比如有的人会把“A”这个音拖得很长,或者把“i”发的很短。

另外,不同时间序列可能仅仅存在时间轴上的位移,亦即在还原位移的情况下,两个时间序列是一致的。在这些复杂情况下,使用传统的欧几里得距离无法有效地求的两个时间序列之间的距离(或者相似性)。


欧几里得计算距离.jpg
dtw解决时间序列相似性.jpg

在上图A中,实线和虚线分别是同一个词“pen”的两个语音波形(在y轴上拉开了,以便观察)。可以看到他们整体上的波形形状很相似,但在时间轴上却是不对齐的。例如在第20个时间点的时候,实线波形的a点会对应于虚线波形的b’点,这样传统的通过比较距离来计算相似性很明显不靠谱。因为很明显,实线的a点对应虚线的b点才是正确的。而在图B中,DTW就可以通过找到这两个波形对齐的点,这样计算它们的距离才是正确的。

2. DTW详解

DTW是一类典型的优化问题,通常采用动态规划算法求解。

假设我们有两个时间序列QC,他们的长度分别为nm
Q=q_{1},q_{2},\cdots ,q_{n}

C=c_{1},c_{2},\cdots ,c_{m}

首先,我们依然采用两个序列中每一对“点”之间的距离来计算形似度,即使两个序列中的点的个数可能不一样。

不过,因为可以warping规整时间轴,所以,我们并不是在两个序列中依次取一对点来计算距离,而是每个点有可能对应于另一个序列中的多个点。

我们需要将连个序列对齐。最简单的对齐方式就是线性缩放了。把短的序列线性放大到和长序列一样的长度再比较,或者把长的线性缩短到和短序列一样的长度再比较。但是这样的计算没有考虑到语音中各个段在不同情况下的持续时间会产生或长或短的变化,因此识别效果不可能最佳。因此更多的是采用动态规划的方法。

为了对其两个这两个序列,我们需要构造一个n×m的矩阵网格,矩阵元素(i,j)表示q_{i}c_{j}两点之间的距离d(q_{i},c_{j}),每一个矩阵元素(i,j)表示q_{i}c_{j}对齐。DP算法可以归纳为寻找一条通过此网格中若干格点的路径。

An example warping path.jpg

我们把这条路径定义为规整路径(warping path),并用W来表示:
W=w_{1},w_{2},\cdots ,w_{k},\space\space\space\space\space max\{m,n\} \leqslant k<m+n-1
当然这条规整路径需要满足一定要求:

  1. 边界条件:

    w_{1}=(1,1)w_{k}=(m,n), 两个人分别说了同一个单词,但是由于语速、语气、语调等等各不相同,会导致采样得到的数据无法对齐。但是两段语音采样的第一个采样值和最后一个采样值肯定是两两对应的。因此所选的路径必定是从左下角出发,在右上角结束。

  2. 连续性:

    如果w_{k-1}=(a',b'),那么对于路径的下一个点w_{k}=(a,b)需要满足(a-a')\leqslant 1(b-b')\leqslant 1。也就是不可能跨过某个点去匹配,只能和自己相邻的点对齐。这样可以保证QC中的每个坐标都在W中出现。

  3. 单调性:

    如果w_{k-1}=(a',b'),那么对于路径的下一个点w_{k}=(a, b)需要满足0<=(a-a’)0<= (b-b’)。这限制W上面的点必须是随着时间单调进行的,以保证图B中的虚线不会相交。

由连续性和单调性可知,每次格点(i, j)前进方向只有三种:(i+1, j)(i, j+1)(i+1, j+1)。我们的目的是使得下面的规整代价最小的路径:
DTW(Q,C)=min(\frac{\sum_{k=1}^{K}W_{k}}{K})
分母中的K主要是用来对不同的长度的规整路径做补偿。因为不同的路径其长短不同,较长的路径有较多的“点对”,会有较多的距离累加上去,所以总距离除以K得到单位路径的距离(还不太理解。。。)

这里我们定义一个累加距离(cumulative distances)。从(0, 0)点开始匹配这两个序列QC,每到一个点,之前所有的点计算的距离都会累加。到达终点(n, m)后,这个累积距离就是我们上面说的最后的总的距离,也就是序列QC的相似度。

示例:

给定一个样本序列X和对比序列Y:

X:3,5,6,7,7,1

Y:3,6,6,7,8,1,1

试计算X和Y之间的最小路径。

DTW首先会根据序列点之间的距离(欧氏距离),获得一个序列距离矩阵 M,其中行对应X序列,列对应Y序列,矩阵元素为对应行列中X序列和Y序列点到点的欧氏距离:

X/Y 3 6 6 7 8 1 1
3 0 3 3 4 5 2 2
5 2 1 1 2 3 4 4
6 3 0 0 1 2 5 5
7 4 1 1 0 1 6 6
7 4 1 1 0 1 6 6
1 2 5 5 6 7 0 0

然后根据距离矩阵生成损失矩阵(Cost Matrix)或者叫累积距离矩阵M_{c},其计算方法如下:

  1. 第一行第一列元素为 M 的第一行第一列元素,在这里就是0;

  2. 其他位置的元素(M_{c}(i,j))的值则需要逐步计算,具体值的计算方法为 M_{c}(i,j)=Min(M_{c}(i−1,j−1),M_{c}(i−1,j),M_{c}(i,j−1))+M(i,j),得到的M_{c}如下:

X/Y 3 6 6 7 8 1 1
3 0 3 6 10 15 17 19
5 2 1 2 4 7 11 15
6 5 1 1 2 4 9 14
7 9 2 2 1 2 8 14
7 13 3 3 1 2 8 14
1 15 8 8 7 8 2 2

最后,两个序列的距离,由损失矩阵最后一行最后一列给出,在这里也就是2。

import sys
import numpy as np


def cal_dtw(s1, s2):
    d = lambda x, y: abs(x - y)

    ts_a, ts_b = np.array(s1), np.array(s2)
    m, n = len(ts_a), len(ts_b)

    cost = sys.maxsize * np.ones((m, n))

    # 初始化第一个元素
    cost[0, 0] = d(ts_a[0], ts_b[0])

    # 计算损失矩阵第一列
    for i in range(1, m):
        cost[i, 0] = cost[i - 1, 0] + d(ts_a[i], ts_b[0])

    # 计算损失矩阵第一行
    for j in range(1, n):
        cost[0, j] = cost[0, j - 1] + d(ts_a[0], ts_b[j])

    # 计算损失矩阵剩余元素
    for i in range(1, m):
        for j in range(1, n):
            choices = cost[i - 1, j - 1], cost[i - 1, j], cost[i, j - 1]
            cost[i, j] = min(choices) + d(ts_a[i], ts_b[j])

    return cost[-1, -1]


if __name__ == '__main__':
    ts_a = [1, 5, 8, 10, 56, 21, 32, 8]
    ts_b = [1, 5, 8, 10, 23, 56, 21, 32, 8]
    ts_c = [1, 3, 6, 9, 16, 29, 31, 32, 33]

    # 调用cal_dtw_distance计算dtw相似度
    dtw_ab = cal_dtw(ts_a, ts_b)
    dtw_ac = cal_dtw(ts_a, ts_c)

    print(dtw_ab)
    print(dtw_ac)

3. 参考资料

  1. DTW(Dynamic Time Warping)动态时间规整
  2. 算法笔记-DTW动态时间规整
  3. 维基百科-Dynamic Time Warping
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容