DTW算法——matlab实现(二)

article/2025/9/12 8:52:48

DTW算法——Matlab实现

本文只是简单的介绍DTW算法的目的和实现。具体的DTW可以参考一下文献:

离散序列的一致性度量方法:动态时间规整(DTW)  http://blog.csdn.net/liyuefeilong/article/details/45748399

动态时间归整/规整/弯曲(Dynamic time warping,DTW)   http://www.cnblogs.com/flypiggy/p/3603192.html

DTW相关维基百科戳这里,有兴趣同学可以在评论区一起讨论文章错误之处,谢谢

DTW是干什么的?

    动态时间规整算法,故名思议,就是把两个代表同一个类型的事物的不同长度序列进行时间上的“对齐”。比如DTW最常用的地方,语音识别中,同一个字母,由不同人发音,长短肯定不一样,把声音记录下来以后,它的信号肯定是很相似的,只是在时间上不太对整齐而已。所以我们需要用一个函数拉长或者缩短其中一个信号,使得它们之间的误差达到最小。

     再来看看运动捕捉,比如当前有一个很快的拳击动作,另外有一个未加标签的动作,我想判断它是不是拳击动作,那么就要计算这个未加标签的动作和已知的拳击动作的相似度。但是呢,他们两个的动作长度不一样,比如一个是100帧,一个是200帧,那么这样直接对每一帧进行对比,计算到后面,误差肯定很大,那么我们把已知拳击动作的每一帧找到无标签的动作的对应帧中,使得它们的距离最短。这样便可以计算出两个运动的相似度,然后设定一个阈值,满足阈值范围就把未知动作加上“拳击”标签。

DTW怎么计算?

下面我们来总结一下DTW动态时间规整算法的简单的步骤:

1. 首先肯定是已知两个或者多个序列,但是都是两个两个的比较,所以我们假设有两个序列A={a1,a2,a3,...,am}  B={b1,b2,b3,....,bn},维度m>n

2. 然后用欧式距离计算出每序列的每两点之间的距离,D(ai,bj) 其中1≤i≤m,1≤j≤n

   画出下表:

                                                          

3.  接下来就是根据上图将最短路径找出来。从D(a1,a2)沿着某条路径到达D(am,bn)。找路径满足:假如当前节点是D(ai,bj),那么下一个节点必须是在D(i+1,j),D(i,j+1),D(i+1,j+1)之间选择,并且路径必须是最短的。计算的时候是按照动态规划的思想计算,也就是说在计算到达第(i,j)个节点的最短路径时候,考虑的是左上角也即第(i-1,j)、(i-1,j-1)、(i,j-1)这三个点到(i,j)的最短距离。

4. 接下来从最终的最短距离往回找到那条最佳的输出路径, 从D(a1,b1)到D(am,bn)。他们的总和就是就是所需要的DTW距离

【注】如果不回溯路径,直接在第3步的时候将左上角三个节点到下一个节点最短的点作为最优路径节点,就是贪婪算法了。DTW是先计算起点到终点的最小值,然后从这个最小值回溯回去看看这个最小值都经过了哪些节点。

举个栗子:

已知:两个列向量a=[8 9 1]',b=[ 2 5 4 6]',其中'代表转置,也就是把行向量转换为列向量了

求:两个向量利用动态时间规整以后的最短距离

第一步:计算对应点的欧式距离矩阵d【注意开根号】

 6     3     4     27     4     5     31     4     3     5

第二步:计算累加距离D【从6出发到达5的累加距离】

 6     9    13    15
13    10    14    16
14    14    13    18

计算方法如下:

D(1,1)=d(1,1)=6

D(1,2)=D(1,1)+d(1,2)=9

...

D(2,2)=min(D(1,2),D(1,1),D(2,1))+d(2,2)=6+4=10

...

D(m,n)=min(D(m-1,n),D(m-1,n-1),D(m,n-1))+d(m,n)

网上有很多代码,但是大部分代码有误,比如网上流传比较多的错误版本:http://www.cnblogs.com/luxiaoxun/archive/2013/05/09/3069036.html

正确的代码可以自己写,挺简单,但是我找了一个可视化的代码,大家可以参考一下:

dtw.m

 

function [Dist,D,k,w,rw,tw]=dtw(r,t,pflag)
%
% [Dist,D,k,w,rw,tw]=dtw(r,t,pflag)
%
% Dynamic Time Warping Algorithm
% Dist is unnormalized distance between t and r
% D is the accumulated distance matrix
% k is the normalizing factor
% w is the optimal path
% t is the vector you are testing against
% r is the vector you are testing
% rw is the warped r vector
% tw is the warped t vector
% pflag  plot flag: 1 (yes), 0(no)
%
% Version comments:
% rw, tw and pflag added by Pau Mic[row,M]=size(r); if (row > M) M=row; r=r'; end;
[row,N]=size(t); if (row > N) N=row; t=t'; end;
d=sqrt((repmat(r',1,N)-repmat(t,M,1)).^2); %this makes clear the above instruction Thanks Pau Mic
d
D=zeros(size(d));
D(1,1)=d(1,1);for m=2:MD(m,1)=d(m,1)+D(m-1,1);
end
for n=2:ND(1,n)=d(1,n)+D(1,n-1);
end
for m=2:Mfor n=2:ND(m,n)=d(m,n)+min(D(m-1,n),min(D(m-1,n-1),D(m,n-1))); % this double MIn construction improves in 10-fold the Speed-up. Thanks Sven Mensingend
endDist=D(M,N);
n=N;
m=M;
k=1;
w=[M N];
while ((n+m)~=2)if (n-1)==0m=m-1;elseif (m-1)==0n=n-1;else [values,number]=min([D(m-1,n),D(m,n-1),D(m-1,n-1)]);switch numbercase 1m=m-1;case 2n=n-1;case 3m=m-1;n=n-1;endendk=k+1;w=[m n; w]; % this replace the above sentence. Thanks Pau Mic
end% warped waves
rw=r(w(:,1));
tw=t(w(:,2));%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if pflag% --- Accumulated distance matrix and optimal pathfigure('Name','DTW - Accumulated distance matrix and optimal path', 'NumberTitle','off');main1=subplot('position',[0.19 0.19 0.67 0.79]);image(D);cmap = contrast(D);colormap(cmap); % 'copper' 'bone', 'gray' imagesc(D);hold on;x=w(:,1); y=w(:,2);ind=find(x==1); x(ind)=1+0.2;ind=find(x==M); x(ind)=M-0.2;ind=find(y==1); y(ind)=1+0.2;ind=find(y==N); y(ind)=N-0.2;plot(y,x,'-w', 'LineWidth',1);hold off;axis([1 N 1 M]);set(main1, 'FontSize',7, 'XTickLabel','', 'YTickLabel','');colorb1=subplot('position',[0.88 0.19 0.05 0.79]);nticks=8;ticks=floor(1:(size(cmap,1)-1)/(nticks-1):size(cmap,1));mx=max(max(D));mn=min(min(D));ticklabels=floor(mn:(mx-mn)/(nticks-1):mx);colorbar(colorb1);set(colorb1, 'FontSize',7, 'YTick',ticks, 'YTickLabel',ticklabels);set(get(colorb1,'YLabel'), 'String','Distance', 'Rotation',-90, 'FontSize',7, 'VerticalAlignment','bottom');left1=subplot('position',[0.07 0.19 0.10 0.79]);plot(r,M:-1:1,'-b');set(left1, 'YTick',mod(M,10):10:M, 'YTickLabel',10*rem(M,10):-10:0)axis([min(r) 1.1*max(r) 1 M]);set(left1, 'FontSize',7);set(get(left1,'YLabel'), 'String','Samples', 'FontSize',7, 'Rotation',-90, 'VerticalAlignment','cap');set(get(left1,'XLabel'), 'String','Amp', 'FontSize',6, 'VerticalAlignment','cap');bottom1=subplot('position',[0.19 0.07 0.67 0.10]);plot(t,'-r');axis([1 N min(t) 1.1*max(t)]);set(bottom1, 'FontSize',7, 'YAxisLocation','right');set(get(bottom1,'XLabel'), 'String','Samples', 'FontSize',7, 'VerticalAlignment','middle');set(get(bottom1,'YLabel'), 'String','Amp', 'Rotation',-90, 'FontSize',6, 'VerticalAlignment','bottom');% --- Warped signalsfigure('Name','DTW - warped signals', 'NumberTitle','off');subplot(1,2,1);set(gca, 'FontSize',7);hold on;plot(r,'-bx');plot(t,':r.');hold off;axis([1 max(M,N) min(min(r),min(t)) 1.1*max(max(r),max(t))]);grid;legend('signal 1','signal 2');title('Original signals');xlabel('Samples');ylabel('Amplitude');subplot(1,2,2);set(gca, 'FontSize',7);hold on;plot(rw,'-bx');plot(tw,':r.');hold off;axis([1 k min(min([rw; tw])) 1.1*max(max([rw; tw]))]);grid;legend('signal 1','signal 2');title('Warped signals');xlabel('Samples');ylabel('Amplitude');
end


测试代码

test.m

clear
clc
a=[8 9 1 9 6 1 3 5]';
b=[2 5 4 6 7 8 3 7 7 2]';
[Dist,D,k,w,rw,tw] = DTW(a,b,1);
fprintf('最短距离为%d\n',Dist)
fprintf('最优路径为')
w


测试结果:

d =6     3     4     2     1     0     5     1     1     67     4     5     3     2     1     6     2     2     71     4     3     5     6     7     2     6     6     17     4     5     3     2     1     6     2     2     74     1     2     0     1     2     3     1     1     41     4     3     5     6     7     2     6     6     11     2     1     3     4     5     0     4     4     13     0     1     1     2     3     2     2     2     3最短距离为27
最优路径为
w =1     11     21     31     41     51     62     63     74     85     96    107    108    10


规整以后可视化如下

 

 

【更新日志:2019-9-11】

为了验证结果正确性,在python中也找到了一个工具库`dtw`

安装方法

pip install dtw

接收参数与返回参数

def dtw(x, y, dist, warp=1, w=inf, s=1.0):"""Computes Dynamic Time Warping (DTW) of two sequences.:param array x: N1*M array:param array y: N2*M array:param func dist: distance used as cost measure:param int warp: how many shifts are computed.:param int w: window size limiting the maximal distance between indices of matched entries |i,j|.:param float s: weight applied on off-diagonal moves of the path. As s gets larger, the warping path is increasingly biased towards the diagonalReturns the minimum distance, the cost matrix, the accumulated cost matrix, and the wrap path."""

输入参数:前面x和y是输入的两个序列点,dist是计算距离的方法,因为有很多距离计算的方法,只不过通常使用欧式距离,直接使用numpy里面的linalg.norm即可。

返回值:这个d有点蒙,但是如果想得到上面的27那个结果,可以看accumulated cost matrix这个返回值,wrap path就是两条路径的对应点。

调用方法(官方案例):

import numpy as np# We define two sequences x, y as numpy array
# where y is actually a sub-sequence from x
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)from dtw import dtweuclidean_norm = lambda x, y: np.abs(x - y)
d, cost_matrix, acc_cost_matrix, path = dtw(x, y, dist=euclidean_norm)
print(d)

总结

DTW算法的计算复杂度是比较高的,如果数据量较大,使用DTW的matlab函数将会十分耗时,因为matlab的循环十分耗时。因此可以考虑用matlab调用DTW的C或C++函数,计算时间大大减少。例如我之前用过的一个数据,用DTW的matlab函数需要计算几十个小时,而调用DTW的C函数,只需要几十秒就能完成。我这里有之前已经配置好的C函数,效率很快。但是如果数据量较小,使用DTW的matlab函数也比较快。


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

相关文章

【时间序列】DTW算法详解

作者 | 追光者 研究 | 机器学习与时间序列 出品 | AI蜗牛车 1.DTW 1.1 时序相似度 在时间序列数据中,一个常见的任务是比较两个序列的相似度,作为分类或聚类任务的基础。那么,时间序列的相似度应该如何计算呢? “ 经典的时间序列相…

学习dtw-python库内容 动态弯曲距离(DTW)具体实现

文章目录 一、install 数据包二、函数功能三、函数的参数以及含义四、具体实现 一、install 数据包 简单的pip install一下就好了,注意最后提示Successfully installed dtw-python-1.3.0 pip install dtw-python二、函数功能 执行 DTW 算法,并计算两个…

DTW距离

DTW(dynamic-time-wraping) 当两个时间序列等长时,我们可以使用欧氏距离来度量两者的相似性。但是当两个时间序列不等长时,欧氏距离就难以度量两者的相似性了。因此,国外学者提出了动态时间弯曲距离(Dynamic time war…

【时间序列】动态时间规整(DTW)算法简介(python)

简介 动态时间规整:(Dynamic Time Warping,DTW) 定义:用于比较不同长度的两个数组或时间序列之间的相似性或计算两者间的距离。 例1:a [1,2,3],b[3,2,2] 例2:a[1,2,3],b[2,2,2,3,4] 例1好计算,但对于例2&am…

【积】fast-DTW及其代码详解

fast-DTW 在解说中适合一个单特征的时间序列,在附录中修改了距离函数从而适合多个特征的时间序列。且距离函数用的是L1距离。如果是其他距离函数,修改即可。 1. DTW常用的加速手段 1.1 限制 亦即减少D的搜索空间,下图中阴影部分为实际的探…

DTW算法(语音识别)

DTW主要是应用在孤立词识别的算法,用来识别一些特定的指令比较好用,这个算法是基于DP(动态规划)的算法基础上发展而来的。这里介绍语音识别就先介绍下语音识别的框架,首先我们要有一个比对的模版声音,然后需…

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

简介 Dynamic Time Warping(动态时间序列扭曲匹配,简称DTW)是时间序列分析的经典算法,用来比较两条时间序列之间的距离,发现最短路径。笔者在github上搜索dtw时发现了两个比较经典的库:dtw和dtw-python。d…

Python dtw(dynamic time warping)模块

dtw是一个用于计算动态时间扭曲距离的python模块。它可以作为时间序列之间的相似性度量。 dtw模块官方文档:https://www.cnpython.com/pypi/dtw DTW(dynamic time warping)的基本思想: 参考链接:https://zhuanlan.zhihu.com/p/117634492

时间序列相似性度量-DTW

1. 背景 最近项目中遇到求解时间序列相似性问题,这里序列也可以看成向量。在传统算法中,可以用余弦相似度和pearson相关系数来描述两个序列的相似度。但是时间序列比较特殊,可能存在两个问题: 两段时间序列长度不同。如何求相似…

算法笔记-DTW动态时间规整

算法笔记-DTW动态时间规整 简介简单的例子定义讨论 约束条件步模式标准化点与点的距离函数 具体应用场景 分类点到点匹配 算法笔记-DTW动态时间规整 动态时间规整/规划(Dynamic Time Warping, DTW)是一个比较老的算法,大概在1970年左右被提出来,最早用…

DTW学习笔记1.0

目录 DTW算法的目的: DTW算法实现: 以下图两段序列为例: DTW代码实现: Dynamic programming function 示例: 单变量示例: 比较序列相似性示例: 缺点: DTW算法的目的&#xf…

动态时间规整—DTW算法

简述 Dynamic Time Warping(DTW)诞生有一定的历史了(日本学者Itakura提出),它出现的目的也比较单纯,是一种衡量两个长度不同的时间序列的相似度的方法。应用也比较广,主要是在模板匹配中&#…

语音信号处理之(一)动态时间规整(DTW)

语音信号处理之(一)动态时间规整(DTW) zouxy09qq.com http://blog.csdn.net/zouxy09 这学期有《语音信号处理》这门课,快考试了,所以也要了解了解相关的知识点。呵呵,平时没怎么听课&#xff…

【机器学习】【DTW】

转自:https://blog.csdn.net/zouxy09/article/details/9140207 一、概述 在大部分的学科中,时间序列是数据的一种常见表示形式。对于时间序列处理来说,一个普遍的任务就是比较两个序列的相似性。 在时间序列中,我们通常需要比较…

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

目录 动态时间规整算法: 从DTW到FastDTW总结:简介[^1]DTW[^1]FastDTW:使用多级粗化的方法[^1]结果 动态时间规整算法: 从DTW到FastDTW 总结: FastDTW作者对DTW的改进点很巧妙!先通过举例说明在一些情况下目前现有的方法对DTW改进…

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

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

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

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

DTW基本原理

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

DTW算法——Matlab实现

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

DTW简介

dtw算法主要针对序列匹配提出的,尤其是当序列出现一定的飘移,欧氏距离度量就会失效。dtw常用在语音匹配当中,在图像处理里面也有一定的应用。 现在有两个序列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] 绘制在坐标轴上如…