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

article/2025/9/12 14:44:04

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

Dynamic Time Warping(DTW)是一种衡量两个时间序列之间的相似度的方法,主要应用在语音识别领域来识别两段语音是否表示同一个单词。

1. DTW方法原理

在时间序列中,需要比较相似性的两段时间序列的长度可能并不相等,在语音识别领域表现为不同人的语速不同。而且同一个单词内的不同音素的发音速度也不同,比如有的人会把“A”这个音拖得很长,或者把“i”发的很短。另外,不同时间序列可能仅仅存在时间轴上的位移,亦即在还原位移的情况下,两个时间序列是一致的。在这些复杂情况下,使用传统的欧几里得距离无法有效地求的两个时间序列之间的距离(或者相似性)。

DTW通过把时间序列进行延伸和缩短,来计算两个时间序列性之间的相似性:

如上图所示,上下两条实线代表两个时间序列,时间序列之间的虚线代表两个时间序列之间的相似的点。DTW使用所有这些相似点之间的距离的和,称之为归整路径距离(Warp Path Distance)来衡量两个时间序列之间的相似性。

2. DTW计算方法:

令要计算相似度的两个时间序列为X和Y,长度分别为|X|和|Y|。

归整路径(Warp Path)

归整路径的形式为W=w1,w2,...,wK,其中Max(|X|,|Y|)<=K<=|X|+|Y|。

wk的形式为(i,j),其中i表示的是X中的i坐标,j表示的是Y中的j坐标。

归整路径W必须从w1=(1,1)开始,到wK=(|X|,|Y|)结尾,以保证X和Y中的每个坐标都在W中出现。

另外,W中w(i,j)的i和j必须是单调增加的,以保证图1中的虚线不会相交,所谓单调增加是指:

 最后要得到的归整路径是距离最短的一个归整路径:

 最后求得的归整路径距离为D(|X|,|Y|),使用动态规划来进行求解:

上图为代价矩阵(Cost Matrix) D,D(i,j)表示长度为i和j的两个时间序列之间的归整路径距离。

3. DTW实现:

matlab代码:

function dist = dtw(t,r)
n = size(t,1);
m = size(r,1);
% 帧匹配距离矩阵
d = zeros(n,m);
for i = 1:nfor j = 1:md(i,j) = sum((t(i,:)-r(j,:)).^2);end
end
% 累积距离矩阵
D = ones(n,m) * realmax;
D(1,1) = d(1,1);
% 动态规划
for i = 2:nfor j = 1:mD1 = D(i-1,j);if j>1D2 = D(i-1,j-1);elseD2 = realmax;endif j>2D3 = D(i-1,j-2);elseD3 = realmax;endD(i,j) = d(i,j) + min([D1,D2,D3]);end
end
dist = D(n,m);

C++实现:

dtwrecoge.h

/***dtwrecoge.h*********************************************************************/
#ifndef dtwrecoge_h
#define dtwrecoge_h#include<stdio.h>
#include<math.h>#define DTWMAXNUM 2000
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(a) ((a)>0?(a):(-(a)))
#define DTWVERYBIG 100000000.0/*****************************************************************************/
/* DTWDistance,求两个数组之间的匹配距离
/* A,B分别为第一第二个数组,I,J为其数组长度,r为匹配窗口的大小
/* r的大小一般取为数组长度的1/10到1/30
/* 返回两个数组之间的匹配距离,如果返回-1.0,表明数组长度太大了
/*****************************************************************************/
double DTWDistanceFun(double *A,int I,double *B,int J,int r);/*****************************************************************************/
/* DTWTemplate,进行建立模板的工作
/* 其中A为已经建立好的模板,我们在以后加入训练样本的时候,
/* 以已建立好的模板作为第一个参数,I为模板的长度,在这个模板中不再改变
/* B为新加入的训练样本,J为B的长度,turn为训练的次数,在第一次
/* 用两个数组建立模板时,r为1,这是出于权值的考虑
/* temp保存匹配最新训练后的模板,建议temp[DTWMAXNUM],函数返回最新训练后模板的长度
/* 如果函数返回-1,表明训练样本之间距离过大,需要重新选择训练样本,
/* tt为样本之间距离的阈值,自行定义
/*****************************************************************************/
int DTWTemplate(double *A,int I,double *B,int J,double *temp,int turn,double tt,double *rltdistance);#endif

 dtwrecoge.cpp

/*dtwrecoge.cpp**************************************************************/#include "dtwrecoge.h"
double distance[DTWMAXNUM][DTWMAXNUM]; /*保存距离*/
double dtwpath[DTWMAXNUM][DTWMAXNUM]; /*保存路径*//*****************************************************************************/
/* DTWDistance,求两个数组之间的匹配距离
/* A,B分别为第一第二个数组,I,J为其数组长度,r为匹配窗口的大小/* r的大小一般取为数组长度的1/10到1/30
/* 返回两个数组之间的匹配距离,如果返回-1.0,表明数组长度太大了
/*****************************************************************************/
double DTWDistanceFun(double *A,int I,double *B,int J,int r)
{int i,j;double dist;int istart,imax;int r2=r+ABS(I-J);/*匹配距离*/double g1,g2,g3;int pathsig=1;/*路径的标志*//*检查参数的有效性*/if(I>DTWMAXNUM||J>DTWMAXNUM){//printf("Too big number\n");return -1.0;}/*进行一些必要的初始化*/for(i=0;i<I;i++){for(j=0;j<J;j++){dtwpath[i][j]=0;distance[i][j]=DTWVERYBIG;}}/*动态规划求最小距离*//*这里我采用的路径是 -------. |.   |.     |.       |*/distance[0][0]=(double)2*ABS(A[0]-B[0]);for(i=1;i<=r2;i++){distance[i][0]=distance[i-1][0]+ABS(A[i]-B[0]);}for(j=1;j<=r2;j++){distance[0][j]=distance[0][j-1]+ABS(A[0]-B[j]);}for(j=1;j<J;j++){istart=j-r2;if(j<=r2)istart=1;imax=j+r2;if(imax>=I)imax=I-1;for(i=istart;i<=imax;i++){g1=distance[i-1][j]+ABS(A[i]-B[j]);g2=distance[i-1][j-1]+2*ABS(A[i]-B[j]);g3=distance[i][j-1]+ABS(A[i]-B[j]);g2=MIN(g1,g2);g3=MIN(g2,g3);distance[i][j]=g3;}}dist=distance[I-1][J-1]/((double)(I+J));return dist;
}/*end DTWDistance*//*****************************************************************************/
/* DTWTemplate,进行建立模板的工作
/* 其中A为已经建立好的模板,我们在以后加入训练样本的时候,
/* 以已建立好的模板作为第一个参数,I为模板的长度,在这个模板中不再改变
/* B为新加入的训练样本,J为B的长度,turn为训练的次数,在第一次
/* 用两个数组建立模板时,r为1,这是出于权值的考虑
/* temp保存匹配最新训练后的模板,建议temp[DTWMAXNUM],函数返回最新训练后模板的长度
/* 如果函数返回-1,表明训练样本之间距离过大,需要重新选择训练样本,
/* tt为样本之间距离的阀值,自行定义
/* rltdistance保存距离,第一次两个数组建立模板时可以随意赋予一个值,
/* 后面用前一次返回的值赋予该参数
/*****************************************************************************/
int DTWTemplate(double *A,int I,double *B,int J,double *temp,int turn,double tt,double *rltdistance)
{double dist;int i,j;int pathsig=1;dist=DTWDistanceFun(A,I,B,J,(int)(I/30));if(dist>tt){printf("\nSample doesn't match!\n");return -1;}if(turn==1)*rltdistance=dist;else{*rltdistance=((*rltdistance)*(turn-1)+dist)/turn;}/*寻找路径,这里我采用了逆向搜索法*/i=I-1;j=J-1;while(j>=1||i>=1){double m;if(i>0&&j>0){m=MIN(MIN(distance[i-1][j],distance[i-1][j-1]),distance[i][j-1]);if(m==distance[i-1][j]){dtwpath[i-1][j]=pathsig;i--;}else if(m==distance[i-1][j-1]){dtwpath[i-1][j-1]=pathsig;i--;j--;}else{dtwpath[i][j-1]=pathsig;j--;}}else if(i==0){dtwpath[0][j-1]=pathsig;j--;}else{/*j==0*/dtwpath[i-1][0]=pathsig;i--;}}dtwpath[0][0]=pathsig;dtwpath[I-1][J-1]=pathsig;/*建立模板*/for(i=0;i<I;i++){double ftemp=0.0;int ntemp=0;for(j=0;j<J;j++){if(dtwpath[i][j]==pathsig){ftemp+=B[j];ntemp++;}}ftemp/=((double)ntemp);temp[i]=(A[i]*turn+ftemp)/((double)(turn+1));/*注意这里的权值*/}return I;/*返回模板的长度*/
}//end DTWTemplate

C++代码下载:DTW算法.rar


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

相关文章

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…

windows环境压力测试工具Apache ab安装及使用(apache benchmark)

1.首先下载并解压安装包,下载地址Apache Haus Downloads 2.解压到C盘,并进入bin目录,复制路径,并配置环境变量,保存后就OK了 3.可以开始使用了,测试一下吧 ab -n 2000 -c 10 -k http://localhost:6868/dataScreenLibrary/findPublicShareByPk?id4 常用参数详解&#xff1a; …

Jmeter--压力测试工具

前言&#xff1a;Jmeter是一款抗压测试工具&#xff0c;具体是干嘛用的相信在来到这的小伙伴都对它有了一些基本的了解&#xff0c;这里就不做过多的赘述了&#xff0c;本文主要是记录一下Jmeter的下载使用过程是怎么样的~ 一、下载 官网地址&#xff1a;Apache JMeter - Dow…

JMeter压力测试工具

1 简介 JMeter是开源软件Apache基金会下的一个性能测试工具&#xff0c;用来测试部署在服务器端的应用程序的性能。 2 下载安装和启动 JMeter可以在JMeter的官方网站下载(https://jmeter.apache.org/) 官网找到Download 下载zip压缩包后, 解压到本地就行 进入/bin目录, 运…

简单好用的网站压力测试工具

简单好用的网站压力测试工具 下载&#xff1a;https://files.cnblogs.com/files/wordblog/%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7.rar

网站压测工具Apache-ab,webbench,Apache-Jemeter

网站压测工具Apache-ab&#xff0c;webbench&#xff0c;Apache-Jemeter 1、搭建测试网站2、Apache自带工具ab3、webbench4、Windows下安装Apache-Jmeter 1、搭建测试网站 编译LAMP网站部署&#xff1a;LAMP web1配置&#xff1a; yum方式搭建网站 初始化 cd /etc/yum.repos.…

10大主流压力测试工具推荐

在移动应用和Web服务正式发布之前&#xff0c;除了进行必要的功能测试和安全测试&#xff0c;为了保证互联网产品的服务交付质量&#xff0c;往往还需要做压力/负载/性能测试。然而很多传统企业在试水互联网的过程中&#xff0c;往往由于资源或产品迭代速度等原因忽视了这一块工…

Linux中Makefile详细教程

目录 Makefile Makefile的介绍 Makefile简单的编写 .PHONY 问题&#xff1a; 如果只执行make&#xff0c;它执行的是Makefile里哪一段语句呢&#xff1f; 怎么知道我的可执行程序是最新的呢&#xff1f; Makefile编译多个文件 进度条小程序 Makefile Makefile的介绍 …

Makefile入门教程

转载&#xff1a; https://www.linuxidc.com/Linux/2014-08/105304.htm Makefile入门教程 回顾 首先&#xff0c;我把需要的文件全部写出来&#xff08;在《GCC学习笔记》处&#xff09;。 main.c文件 #include <stdio.h> #include "math.h" int main() { int…

Makefile教程(入门介绍)

文章目录 前言一、Makefile介绍二、make和Makefile的关系三、学习makefile的意义四、编写一个简单的Makefile总结 前言 本篇文章将带大家学习Makefile&#xff0c;Makefile在文件的编译中起到重要作用&#xff0c;在Linux中我们也是经常使用到Makefile&#xff0c;下面我将会带…

VCS使用Makefile教程

在从事IC验证工作的过程中&#xff0c;其实最开始的一步不是写什么test plan或者说verification of structure&#xff0c;而是应该知道makefile怎么写&#xff0c;先写出一个通用&#xff0c;基础的编译仿真脚本&#xff0c;可能会让你编译仿真轻松一点。 这份Makefile使用教程…

Makefile教程(Makefile的结构)

文章目录 前言一、Makefile的结构二、深入案例三、Makefile中的一些技巧总结 前言 一、Makefile的结构 Makefile 通常由一系列规则组成&#xff0c;每条规则定义了如何从源文件生成目标文件。每个规则又由目标、依赖和命令三部分组成。 下面是 Makefile 规则的基本结构&…

linux初试gcc makefile菜鸟教程

linux初试gcc makefile菜鸟教程 1.实验环境 1.ubuntu16(安装教程) 2.gcc (gcc安装&#xff1a;apt install gcc) 3.make (make安装 apt install make) 用C举个小例子 2.源码 main.c /*************************************************************************> File N…