动态时间规整算法: 从DTW到FastDTW

article/2025/9/12 11:15:56

目录

  • 动态时间规整算法: 从DTW到FastDTW
    • 总结:
    • 简介[^1]
    • DTW[^1]
    • FastDTW:使用多级粗化的方法[^1]
    • 结果

动态时间规整算法: 从DTW到FastDTW

总结:

FastDTW作者对DTW的改进点很巧妙!先通过举例说明在一些情况下目前现有的方法对DTW改进的缺陷,然后阐述自己的算法如何避免这些缺陷,最后还在三个数据集上证明在较长时间序列数据中取得线性复杂度。 说明在做算法时,在无法找到更低复杂度的方法的时候,可以考虑在牺牲一些可接受的准确度的情况下实现更低的复杂度算法!!!同时,必须通过实验证明准确度降低的程度,文中就使用正常复杂度算法和近似复杂度算法进行对比,从而计算出降低的准确率!!最后,可以吸取现有的一些改进的基础上,再进一步改进,就比在原始的DWT算法上改进的效果更好!!!!

简介1

Dynamic time warping:动态时间扭曲 (DTW) 是一种在两个时间序列之间找到最佳对齐的技术,其中一个时间序列可以通过拉伸或收缩其时间轴来非线性地“扭曲”。 这种比对可用于找到对应的区域或确定两个时间序列之间的相似性。 DTW 经常用于语音识别,以确定两个波形是否代表相同的口语短语。 在语音波形中,每个语音的持续时间和声音之间的间隔是允许变化的,但整体语音波形必须相似。 DTW 还用于许多其他学科 ,包括数据挖掘、手势识别、机器人技术、制造和医学。 一个时间序列“扭曲”到一个示例如图 所示:

在这里插入图片描述

FastDTW:动态时间规整 (DTW) 具有平方时间和空间复杂度,这限制了它在大时间序列中的使用。 后面有很多优化,本文主要解释 FastDTW,它是 DTW 的近似,具有线性时间和空间复杂度。 FastDTW 使用多级方法,从较粗的分辨率递归地投影计算并细化投影。 从理论上和经验上证明了 FastDTW 的线性时间和空间复杂度。FastDTW 与其他两种现有的近似 DTW 算法进行比较来分析 FastDTW 的准确性:约束(例如 Sakoe-Chiba Bands)和抽象。 与现有方法相比,准确性有了很大提高。使用的方法太过巧妙,如下所示:

1) 粗化——将时间序列缩小为更小的时间序列,以更少的数据点尽可能准确地表示相同的曲线。

2) 投影——在较低分辨率下找到最小距离扭曲路径,并将其用作更高分辨率最小距离扭曲路径的初始猜测。

3) 细化——通过局部调整扭曲路径来优化从较低分辨率投影的扭曲路径。

DTW1

动态时间扭曲 (DTW) 是一种在两个时间序列之间找到最佳对齐的技术,其中一个时间序列可以通过拉伸或收缩其时间轴来非线性地“扭曲”。最初的实现是使用动态规划,使用数学表达如下:

D ( i , j ) = D i s t ( i , j ) + m i n [ D ( i − 1 , j ) , D ( i , j − 1 ) , D ( i − 1 , j − 1 ) ] , 其中: i = 1 , 2 , ⋯ , x _ l e n + 1 ; j = 1 , 2 , ⋯ , y _ l e n + 1 D(i,j)=Dist(i,j)+min[D(i-1,j),D(i,j-1),D(i-1,j-1)], \\其中:i=1,2,\cdots,x\_len+1;j=1,2,\cdots,y\_len+1 D(i,j)=Dist(i,j)+min[D(i1,j),D(i,j1),D(i1,j1)],其中:i=1,2,,x_len+1;j=1,2,,y_len+1
代码实现如下2

#参考:https://github.com/slaypni/fastdtw
import numbers
import numpy as np
from collections import defaultdict
from scipy.spatial.distance import euclideandef dtw(x, y, window=None, dist):"""@param x 序列1,可以是向量,矩阵,不局限于一个数列,但是dist要匹配@param y 序列2,可以是向量,矩阵,不局限于一个数列,但是dist要匹配@param window 序列设置要走的范围,当使用Sakoe-Chiba Bands就需要自定义缩小的范围,这里默认None会矩阵全走一遍@param dist 自定义距离计算方法,可以是欧氏距离,汉明距离等等"""len_x, len_y = len(x), len(y)if window is None:window = [(i, j) for i in range(len_x) for j in range(len_y)]# 相当于矩阵的索引 i=1,2,...len_x+1 j=1,2,...len_y+1  window = ((i + 1, j + 1) for i, j in window)# 初始化矩阵中的其他元素inf和D[0, 0]=0;D使用元组记录矩阵的值和path的i,jD = defaultdict(lambda: (float('inf'),))D[0, 0] = (0, 0, 0)# 按照公式进行规划计算for i, j in window:dt = dist(x[i-1], y[j-1])D[i, j] = min((D[i-1, j][0]+dt, i-1, j), (D[i, j-1][0]+dt, i, j-1),(D[i-1, j-1][0]+dt, i-1, j-1), key=lambda a: a[0])# 求解路径path = []i, j = len_x, len_ywhile not (i == j == 0):path.append((i-1, j-1))i, j = D[i, j][1], D[i, j][2]path.reverse()return (D[len_x, len_y][0], path)if __name__ == '__main__':x = np.array([1, 2, 3, 4, 5], dtype='float')y = np.array([2, 3, 4], dtype='float')distance, path = dtw(x, y, dist=euclidean)

FastDTW之前,后来主要有两种近似计算DWT的算法,损失一定准确率的前提下减少时间和空间复杂度:

1、约束 – 限制在成本矩阵中评估的单元数

典型有两种:constraints: Sakoe-Chiba Band (left) and Itakura Parallelogram (right);很明显,缺点是当全局最优解不在band内时,就有误差。图中的阴影区域是成本矩阵的单元格,它们被填充由每个约束的 DTW 算法。每个阴影区域或窗口的宽度由参数指定。当使用约束时,DTW 会通过约束窗口找到最优的扭曲路径。但是,如果全局最优扭曲路径不完全在窗口内,则将无法找到它。使用约束以一个常数因子加速 DTW,但如果窗口大小是时间序列长度的函数,则 DTW 仍然是 O ( N 2 ) O(N^2) O(N2)约束在时间序列的时间对齐只有很小差异的领域中效果很好,并且最佳扭曲路径预计接近线性扭曲并以相对直线对角线穿过成本矩阵。但是,如果时间序列是在完全不同的时间开始和停止的事件,则约束效果不佳。在这种情况下,warp 路径可能会偏离线性 warp 很远,并且必须评估几乎整个成本矩阵以找到最佳 warp 路径。

在这里插入图片描述

下图描述了约束 DTW 不能很好地工作的情况的简化示例,必须评估整个成本矩阵以获得良好的结果。这可能发生在时间序列是受监控设备的应用程序中,这些设备以可预测的顺序发出命令(例如开/关),但命令之间的时间量(稳态条件)未指定。此类数据的示例包括航天飞机阀门特征。

在这里插入图片描述

2、抽象——对数据的简化表示执行 DTW

这种方法作者在FastDTW中也用上,如图所示,就是在低分辨率的矩阵中求解,也会有误差,因为路径不够细化。抽象通过对数据的简化表示进行操作来加速 DTW 算法。这些算法包括 IDDTW 、PDTW 和 COW 。时间序列的大小被缩小以使成本矩阵更易于计算。为较低分辨率的时间序列找到了一个扭曲路径并被映射回到全分辨率。

由此产生的加速取决于使用了多少抽象。显然,计算出的翘曲路径随着抽象级别的增加,它变得越来越不准确。投影低分辨率扭曲全分辨率的路径通常会创建一个远非最佳的扭曲路径。这是因为即使如果最优扭曲路径通过低分辨率单元,则将扭曲路径投影到更高的分辨率忽略了扭曲路径中可能非常重要的局部变化。因此不适用于局部变化剧烈的序列。

在这里插入图片描述

FastDTW:使用多级粗化的方法1

FastDTW使用下面三种方法进行改进:

1) 粗化——将时间序列缩小为更小的时间序列,以更少的数据点尽可能准确地表示相同的曲线。

2. 投影——在较低分辨率下找到最小距离扭曲路径,并将其用作更高分辨率最小距离扭曲路径的初始猜测。

3. 细化——通过局部调整扭曲路径来优化从较低分辨率投影的扭曲路径。

总结:

1、FastDTW中的分级使用更高分辨率计算,弥补了之前的Abstract的方法,原来只使用一次降低分辨率;

2、FastDTW中的细化使用半径参数控制,弥补原来的Band的方法那种不灵活性,因为Band的方法需要依靠先验知识判断最优路径大概在那些位置;而半径参数只是作为分级粗化投影的一个补充。确实很巧妙!!!

在这里插入图片描述

如图所示具体如下:粗化通过平均相邻的点对来减少时间序列的长度(或分辨率)。生成的时间序列比原始时间序列小两倍。粗化运行多次以产生时间序列的不同分辨率。投影采用以较低分辨率计算的扭曲路径,并以较高的分辨率确定它通过的单元格。由于分辨率增加了两倍,因此低分辨率扭曲路径中的单个点将映射到更高分辨率的至少四个点(如果 |X| = |Y |,则可能 > 4)。然后在细化过程中将此投影路径用作启发式方法,以找到更高分辨率的扭曲路径。细化在投影路径的邻域中找到最佳的扭曲路径,其中邻域的大小由半径参数控制。在我们的多级方法中,成本矩阵仅填充在从先前分辨率投影的路径的附近。由于扭曲路径的长度随着时间序列的长度线性增长,我们的多级方法是 O(N) 算法。 FastDTW 算法首先使用粗化来创建将被评估的所有分辨率。图中显示了一个时间序列上的例子在运行 FastDTW 算法时创建的四个分辨率(使用多少个分辨率的粗化矩阵按照实际序列长度确定)。

在图 中,从 1/8 分辨率的扭曲路径的投影显示为 1/4 分辨率的重度阴影单元。为了细化投影路径,使用非常具体的约束运行受约束的 DTW 算法,即仅评估投影扭曲路径中的单元格。这将通过从较低分辨率投影的扭曲路径区域找到最佳扭曲路径。然而,全局最优扭曲路径可能不完全包含在投影路径中。为了增加找到全局最优解的可能性,有一个半径参数来控制投影路径每一侧上的额外单元数,这些单元格也将在优化扭曲路径时进行评估。在图 中,半径参数设置为 1。由于半径而在扭曲路径细化过程中包含的单元格被轻微着色。一旦以 1/4 分辨率细化扭曲路径,该扭曲路径将投影到 1/2 分辨率,扩大半径 1,然后再次细化。最后,将扭曲路径投影到图 中的全分辨率 (1/1) 矩阵。投影被半径扩展并最后一次细化。这个细化的扭曲路径是算法的输出。 FastDTW 在所有分辨率下评估了 4 + 16 + 44 + 100 = 164 个单元,而 DTW 评估了 256 (162) 个单元。对于这个小问题,效率的提高并不是很显着,尤其是考虑到创建所有四个分辨率的开销,在长序列有很大差距。然而,FastDTW 评估的单元数与时间序列的长度成线性关系,而经典的动态时间扭曲算法总是评估 N 2 N^2 N2个单元(如果两个时间序列的长度均为 N)。

代码实现:

在这里插入图片描述

FastDTW的递归实现2

#参考:https://github.com/slaypni/fastdtw
from __future__ import absolute_import, division
import numbers
import numpy as np
from collections import defaultdict
from scipy.spatial.distance import euclideandef dtw(x, y, window=None, dist):"""@param x 序列1,可以是向量,矩阵,不局限于一个数列,但是dist要匹配@param y 序列2,可以是向量,矩阵,不局限于一个数列,但是dist要匹配@param window 序列设置要走的范围,当使用Sakoe-Chiba Bands就需要自定义缩小的范围,这里默认None会矩阵全走一遍@param dist 自定义距离计算方法,可以是欧氏距离,汉明距离等等"""len_x, len_y = len(x), len(y)if window is None:window = [(i, j) for i in range(len_x) for j in range(len_y)]# 相当于矩阵的索引 i=1,2,...len_x+1 j=1,2,...len_y+1  window = ((i + 1, j + 1) for i, j in window)# 初始化矩阵中的其他元素inf和D[0, 0]=0;D使用元组记录矩阵的值和path的i,jD = defaultdict(lambda: (float('inf'),))D[0, 0] = (0, 0, 0)# 按照公式进行规划计算for i, j in window:dt = dist(x[i-1], y[j-1])D[i, j] = min((D[i-1, j][0]+dt, i-1, j), (D[i, j-1][0]+dt, i, j-1),(D[i-1, j-1][0]+dt, i-1, j-1), key=lambda a: a[0])# 求解路径path = []i, j = len_x, len_ywhile not (i == j == 0):path.append((i-1, j-1))i, j = D[i, j][1], D[i, j][2]path.reverse()return (D[len_x, len_y][0], path)def reduce_by_half(x):"""分辨率减半,使用平均的方法"""return [(x[i] + x[1+i]) / 2 for i in range(0, len(x) - len(x) % 2, 2)]def expand_window(path, len_x, len_y, radius):"""计算radius下的时间窗"""path_ = set(path)for i, j in path:for a, b in ((i + a, j + b)for a in range(-radius, radius+1)for b in range(-radius, radius+1)):path_.add((a, b))window_ = set()for i, j in path_:for a, b in ((i * 2, j * 2), (i * 2, j * 2 + 1),(i * 2 + 1, j * 2), (i * 2 + 1, j * 2 + 1)):window_.add((a, b))window = []start_j = 0for i in range(0, len_x):new_start_j = Nonefor j in range(start_j, len_y):if (i, j) in window_:window.append((i, j))if new_start_j is None:new_start_j = jelif new_start_j is not None:breakstart_j = new_start_jreturn windowdef fastdtw(x, y, radius, dist):min_time_size = radius + 2# 长度小于min_time_size,直接使用DTW计算if len(x) < min_time_size or len(y) < min_time_size:return dtw(x, y, dist=dist)# 每次粗化一半,得到新的序列x_shrinked = reduce_by_half(x)y_shrinked = reduce_by_half(y)# 递归计算,直到满足len(x) < min_time_size or len(y) < min_time_size则回溯distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)# 根据radius计算新的计算范围window = expand_window(path, len(x), len(y), radius)return dtw(x, y, window, dist=dist)

结果

错误率计算:

在这里插入图片描述

在准确度上:

相比Band和Abstraction的方法,错误率更低,而且随着radius的增加,错误率降低,后面已经很接近DTW算法;

在这里插入图片描述

在时间上:

虽然在数列长度200以内体现不出区别,但是随着时间序列长度的增加,越来越接近线性时间复杂度。

在这里插入图片描述

参考:


  1. Salvador S, Chan P. Toward accurate dynamic time warping in linear time and space[J]. Intelligent Data Analysis, 2007, 11(5): 561-580. ↩︎ ↩︎ ↩︎

  2. GitHub - slaypni/fastdtw: A Python implementation of FastDTW ↩︎ ↩︎


http://chatgpt.dhexx.cn/article/CaLW9TED.shtml

相关文章

机器学习算法(二十三):DTW(Dynamic Time Warping,动态时间调整)

目录 1 DTW&#xff08;动态时间调整&#xff09; 2 算法的实现 3 例子 4 python实现 ​​​​​​​5 DTW的加速算法FastDTW 5.1 标准DTW算法 5.2 DTW常用加速手段 5.3 FastDTW​​​​​​​ 1 DTW&#xff08;动态时间调整&#xff09; 动态时间调整算法是大多用于检…

初识DTW(动态时间规整)算法及Python实现例

目录 1. 概要 2. 时序列相似度度量 3. DTW基本算法 4. Python实现 5. Next Action 1. 概要 DTW&#xff08; Dynamic Time Warping&#xff0c;动态时间规整&#xff09;是基于动态规划&#xff08;Dynamic Programming&#xff09;策略对两个时序列通过非线性地进行时域对…

DTW基本原理

设时间归正函数为&#xff1a;&#xff0c;式中&#xff0c;N为路径长度&#xff0c;c(n)(i(n),j(n))表示第n个匹配点对是由参考模板的第i个特征矢量与待测模板的第j个特征矢量构成的匹配点对。两者之间的距离称为局部匹配距离。DTW算法就是通过局部优化的方法实现加权距离总和…

DTW算法——Matlab实现

概述 DTW &#xff08;Dynamic time warping&#xff09;算法是可以度量两个独立时间序列的相似度的一种方法。曾被广泛应用在单词音频的匹配上。该方法主要用来解决在两段序列的时长不同的情况下&#xff0c;进行相似度的判断。 上图中&#xff0c;左侧时长相等&#xff0c;…

DTW简介

dtw算法主要针对序列匹配提出的&#xff0c;尤其是当序列出现一定的飘移&#xff0c;欧氏距离度量就会失效。dtw常用在语音匹配当中&#xff0c;在图像处理里面也有一定的应用。 现在有两个序列X,Y. X[2,3,4,7,9,2,1,2,1],Y[1,1,1,1,2,3,3,4,7,8,9,1,1,1,1] 绘制在坐标轴上如…

DTW算法

dtw算法主要针对序列匹配提出的&#xff0c;尤其是当序列出现一定的飘移&#xff0c;欧氏距离度量就会失效。dtw常用在语音匹配当中&#xff0c;在图像处理里面也有一定的应用。 现在有两个序列X,Y. X[2,3,4,7,9,2,1,2,1],Y[1,1,1,1,2,3,3,4,7,8,9,1,1,1,1] 绘制在坐标轴上如…

HMM学习笔记_1(从一个实例中学习DTW算法)

DTW为(Dynamic Time Warping,动态时间归准)的简称。应用很广&#xff0c;主要是在模板匹配中&#xff0c;比如说用在孤立词语音识别&#xff0c;计算机视觉中的行为识别&#xff0c;信息检索等中。可能大家学过这些类似的课程都看到过这个算法&#xff0c;公式也有几个&#xf…

DTW(Dynamic Time Warping)动态时间规整——简单易懂

DTW可以用来干什么呢&#xff1f; DWT可以计算两个时间序列的相似度&#xff0c;尤其适用于不同长度、不同节奏的时间序列&#xff08;比如不同的人读同一个词的音频序列&#xff09;。距离越近&#xff0c;相似度越高。 DTW在语音中的运用&#xff1a; 在实际应用中&#xff…

DTW(动态时间归整)算法的前世今生

今天和大家分享一下我刚刚学习到的DTW算法。 主要从以下几个方面进行介绍&#xff1a; 1. DTW算法的提出和应用场景。 2. DTW算法的基本原理和计算过程。 3. DTW算法的具体代码实现。 一、DTW算法的提出和应用场景 Dynamic Time Warping&#xff08;简称&#xff1a;DTW&…

时间序列匹配之dtw的python实现(二)

简介 在上一篇文章里我们介绍了dtw库的使用&#xff0c;但其限制太多&#xff0c;不够灵活&#xff0c;且作图不够方便&#xff0c;因此我们来介绍一个更加复杂的库----dtw-python。它是R语言中dtw实现的python版本&#xff0c;基本的API是对应的&#xff0c;它的优势在于能够…

DTW算法详解

DTW算法详解 1.DTW 1.1 时序相似度 在时间序列数据中&#xff0c;一个常见的任务是比较两个序列的相似度&#xff0c;作为分类或聚类任务的基础。那么&#xff0c;时间序列的相似度应该如何计算呢&#xff1f; “ 经典的时间序列相似性度量方法总体被分为两 类: 锁步度量(lo…

动态时间规整算法(DTW)原理及代码实现

Dynamic Time Warping&#xff08;DTW&#xff09;动态时间规整算法 Dynamic Time Warping&#xff08;DTW&#xff09;是一种衡量两个时间序列之间的相似度的方法&#xff0c;主要应用在语音识别领域来识别两段语音是否表示同一个单词。 1. DTW方法原理 在时间序列中&#…

LOIC网站压力测试工具

官网下载&#xff1a;https://sourceforge.net/projects/loic/ 百度云&#xff1a;https://pan.baidu.com/s/1VVUjLqtq1mMAD-TJIAnhnQ 1.软件解压后运行&#xff0c;界面如图 2.然后可以在url处输入想要测试的网站网址&#xff0c;也可以输入ip地址&#xff0c;输入完之后要…

十大抢手的网站压力测试工具

两天&#xff0c;jnj在本站发布了《如何在低速率网络中测试 Web 应用》&#xff0c;那是测试网络不好的情况。而下面是十个免费的可以用来进行Web的负载/压力测试的工具&#xff0c;这样&#xff0c;你就可以知道你的服务器以及你的WEB应用能够顶得住多少的并发量&#xff0c;以…

10大主流压力测试工具

市面上流行的压力/负载/性能测试工具多是来自国外&#xff0c;近年来国内的性能测试工具也如雨后春笋崛起。同时由于开发的目的和侧重点不同&#xff0c;其功能也有很大差异&#xff0c;下面就为您简单介绍10款目前最常见的测试产品。 1、kylinTOP测试与监控平台&#xff08;商…

jmeter压力测试

一、Jmeter数据库压力测试 1.1.先配置jdbc&#xff08;数据库连接&#xff09;驱动 1、启动jmeter&#xff0c;打开界面工具&#xff0c;添加一个线程组 2、添加一个JDBC Connection Configuration&#xff0c;连接池配置文件。右键线程组【添加】--【配置元件】- -【JDBC Co…

网站压力测试的几种方法

百度TcpCopy&#xff0c;得到的结果是&#xff1a;TCPCopy是一种请求复制&#xff08;所有基于tcp的packets&#xff09;工具&#xff0c;可以把在线流量导入到测试系统中去。曾经应用于网易的广告投放系统&#xff0c;urs系统&#xff0c;nginx hmux协议等系统&#xff0c;避免…

压力测试工具

目录 1 性能测试... 2 2 压力测试&#xff08;Stress Test&#xff09;... 2 2.1 网站测试... 2 2.2 系统测试要求... 3 3 测试工具... 3 3.1 Webbench. 4 3.1.1 Ubuntu 下载安装... 5 3.1.2 w…

开发工具-压力测试工具 ab

开发工具-压力测试工具 ab 写在前面ab工具简介下载 ab使用 ab测试结果报告信息解读 关于 post 请求的压力测试关于需要登录的测试关于报错 写在前面 在学习ab工具之前&#xff0c;我们需了解几个关于压力测试的概念 吞吐率&#xff08;Requests per second&#xff09; 概念&a…

【转】十大抢手的网站压力测试工具

两天&#xff0c;jnj在本站发布了《 如何在低速率网络中测试 Web 应用 》&#xff0c;那是测试网络不好的情况。而下面是十个免费的可以用来进行Web的负载/压力测试的工具&#xff0c;这样&#xff0c;你就可以知道你的服务器以及你的WEB应用能够顶得住多少的并发量&#xff…