DTW(Dynamic Time Warping)算法学习应用实践与效率对比分析

news2025/1/18 3:31:34

DTW(Dynamic Time Warping)算法是一种用于度量两个时间序列之间的相似性的方法。它的构建原理如下:

  1. 基本思想:DTW算法通过计算两个时间序列之间的最小距离,来度量它们的相似性。与欧氏距离等传统距离度量方法不同,DTW算法考虑了时间序列中元素之间的时序关系。

  2. 算法步骤:

    • 创建一个距离矩阵,用于存储计算过程中的距离。
    • 初始化第一行和第一列的值为无穷大。
    • 从矩阵的(1,1)位置开始,计算每个位置的距离。具体计算方法是将当前位置的距离设为当前位置的元素之间的距离加上三个相邻位置中最小的距离。
    • 最后返回距离矩阵的最后一个元素,即两个时间序列的DTW距离。

DTW算法的优点:

  1. 考虑了时间序列中元素之间的时序关系,适用于比较不同长度和变化速度的时间序列。
  2. 具有较好的鲁棒性,对于时间序列中的噪声、缺失数据等问题有一定的容忍度。

DTW算法的缺点:

  1. 计算复杂度较高,时间和空间复杂度都为O(n*m),其中n和m分别是两个时间序列的长度。
  2. 对于高维数据的处理能力有限,当时间序列的维度较高时,DTW算法的效果可能下降。

实例原理图如下所示:

DTW 算法重要的特征就是通过“扭曲”X 轴来解释 Y 轴变量,以达到使时间序列对齐的目的。但是简单的通过 Y 轴的变量值来扭曲 X 轴会导致“不直观”( unintuitive )的对齐,其中一个时间序列上的单个点会映射到另一个时间序列的一部分上。我们称这种我们不期望看到的行为为“奇点”( singularities )。

DTW算法的核心思想就是通过扭曲来实现序列的近似对齐处理,基于动态规划的思想找到最优匹配路径。

相关的原理这里就不再赘述了,感兴趣的话可以自行查阅即可,这里接下来主要是想要基于python开发实现DTW算法,如下所示:

def dtw_distance(s1, s2):
    """
    两序列DTW距离计算
    """
    n = len(s1)
    m = len(s2)
    # 创建一个n*m的矩阵,用于存储计算过程中的距离
    dtw_matrix = np.zeros((n + 1, m + 1))
    # 初始化第一行和第一列的值为无穷大
    dtw_matrix[0, 1:] = np.inf
    dtw_matrix[1:, 0] = np.inf
    # 计算每个位置的距离
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            cost = abs(s1[i - 1] - s2[j - 1])  # 计算s1[i]和s2[j]之间的距离
            dtw_matrix[i, j] = cost + min(
                dtw_matrix[i - 1, j], dtw_matrix[i, j - 1], dtw_matrix[i - 1, j - 1]
            )
    # 返回最终的DTW距离
    dtw = dtw_matrix[n, m]
    print("[-]" * 30)
    print("dtw_matrix: ")
    print(dtw_matrix)
    print("[-]" * 30)
    print("dtw_distance: ", dtw)
    return dtw

结果输出如下所示:

[-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]
dtw_matrix: 
[[ 0. inf inf inf inf inf]
 [inf  1.  4.  9. 16. 25.]
 [inf  1.  3.  7. 13. 21.]
 [inf  2.  2.  5. 10. 17.]
 [inf  4.  2.  4.  8. 14.]
 [inf  7.  3.  3.  6. 11.]]
[-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]
dtw_distance:  11.0

上面打印输出的是dtw动态规划过程中产生的转移矩阵,下面打印的是dtw算法计算得到的序列之间的距离。

上面的代码是不依赖于任何第三方库实现的dtw算法,在现在已经有现成的第三方库可以直接进行使用,代码实现也很简单,如下所示:

s1 = [1, 2, 3, 4, 5]
s2 = [2, 4, 6, 8, 10]
x = np.array(s1)
y = np.array(s2)
dtw_distance, dtw_matrix = fastdtw(x, y, dist=euclidean)
print("[-]" * 30)
print("dtw_matrix: ")
print(dtw_matrix)
print("[-]" * 30)
print("dtw_distance: ", dtw_distance)

结果输出如下所示:

[-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]
dtw_matrix: 
[(0, 0), (1, 0), (2, 1), (3, 1), (4, 2), (4, 3), (4, 4)]
[-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-][-]
dtw_distance:  11.0

接下来我想要对比下不同算法实现的效率情况,核心实现如下所示:

nums_list = [10,100,1000,10000]
time_list1=[]
for one_num in nums_list:
    start = time.time()
    for i in range(one_num):
        one = [random.randint(1, 1000) for _ in range(random.randint(1, 100))]
        two = [random.randint(1, 1000) for _ in range(random.randint(1, 100))]
        dtw_distance(one, two)
    end = time.time()
    delta = end - start
    time_list1.append(delta)
print(time_list1)

另一个算法也是类似,这里就不再赘述了,分别进行了四组计算,对比可视化如下:

plt.clf()
plt.plot(time_list1,label="selfDTW")
plt.plot(time_list2,label="fastDTW")
plt.legend()
plt.title("Different DTW Method TimeConsume Compare")
plt.savefig("DTW_compare.png")

结果如下所示:

很奇怪的就是我原以为第三方模块的效率应该会更高,但是在这里对比实验结果下反而是相反的情况,不知道是我哪里设置出了问题还是什么原因,如果有发现的还望不吝指教,感兴趣的话都是可以自行尝试实践下的。

基于动态时间规整(DTW)算法的变种算法有多种,以下是其中一些常见的变种算法:

  1. FastDTW(快速动态时间规整):FastDTW是对DTW算法的一种加速版本。它通过将时间序列进行下采样,然后在较小的序列上应用DTW算法来减少计算量。FastDTW在保持较小时间和空间复杂度的同时,仍能提供较好的近似DTW距离。

  2. Multivariate DTW(多变量动态时间规整):DTW算法最初应用于单变量时间序列,但在实际问题中,往往存在多个变量之间的关联。Multivariate DTW扩展了DTW算法,使其能够处理多维时间序列。它考虑了每个维度上的距离度量和对齐路径的形状。

  3. Weighted DTW(加权动态时间规整):在标准的DTW算法中,每个时间步的匹配都被视为等权重。然而,在某些应用中,不同时间步的重要性可能不同。Weighted DTW引入了一个权重系数,用于调整每个时间步的贡献,从而更好地适应不同的应用场景。

  4. Constrained DTW(约束动态时间规整):在某些情况下,我们可能希望对DTW算法的搜索空间进行限制,以便更好地满足特定的约束条件。Constrained DTW通过引入限制条件,如全局约束或局部约束,来约束匹配路径的搜索范围,从而减少计算复杂度并提高算法的效率。

这些是基于DTW算法的一些常见变种算法,每种算法都有其适用的场景和优势。具体选择哪种算法取决于你的应用需求、时间序列的特征以及对计算效率和准确性的要求。感兴趣的话都可以对照了解学习一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MariaDB安装配置、使用、授权、增删改查以及数据库备份与恢复

目录 1 MariaDB安装 1.1 MariaDB源配置 1.2 清空缓存 1.3 安装MariaDB 2 MariaDB的基本配置 2.1 启动MariaDB 2.2 MariaDB进程查看 2.3 MariaDB数据库初始化 2.3.1 数据库初始化 2.3.2 初始化测试登录 3 MariaDB的使用 3.1 查看数据库 3.2 修改密码 3.3 创建数据库test 3…

conda环境下Tesseract:Failed loading language ‘eng‘问题解决

1 问题描述 使用Tesseract进行ocr文字识别,运行识别代码,报错如下: C:\Users\lishu\anaconda3\envs\pt2\python.exe D:/code/ptcontainer/opencv/car_reg.py Traceback (most recent call last): File "D:\code\ptcontainer\opencv\…

C#WPF文本转语音实例

本文介绍C#WPF文本转语音实例 实现方法:使用类库(SpeechSynthesizer )实现的。 一、首先是安装程序包。 二、创建项目 需要添加引用using System.Speech.Synthesis; UI界面 <Windowx:Class="TextToSpeechDemo.MainWindow"xmlns="http://schemas.micr…

著名的《NP问题》是个啥概念?

一、说明 关于复杂问题&#xff0c;始终是计算机科学挡在路前的一块巨石。所谓一个问题有解&#xff0c;但需要秒完成&#xff0c;这相当于说&#xff0c;此类问题无解。还有一类问题是说不清楚到底有没有一个具体解法&#xff0c;该解法能在多项式时间复杂函数上完成&#xff…

mybatis-plus3.5.3.1 支持不同数据源sql适配

mybatis-plus3.5.3.1 支持不同数据源sql适配 背景 最近公司要求支持国产数据库达梦&#xff0c;人大金仓&#xff0c;高斯等数据库&#xff0c;这些数据库与mysql的语法有一些差异&#xff0c;需要做一些兼容操作。 解决问题 1.不同数据库分页不同 2.支持通过参数控制执行…

JQuery ajax 提交数据提示:Uncaught TypeError:Illegal invocation

JQuery ajax 提交数据提示&#xff1a;Uncaught TypeError:Illegal invocation 1 问题描述 用jQuery Ajax向DRF接口提交数据的时候&#xff0c;console提示&#xff1a;Uncaught TypeError:Illegal invocation(未捕获的异常&#xff1a;非法调用)。 这个问题可能有两种原因导…

MatrixOne 实战系列回顾 | 建模与多租户

本次分享主要介绍MatrixOne建模与多租户相关内容。 1 建模 #1 与MySQL的区别 使用create table语句建表和MySQL建表语句基本相同&#xff0c;也有几点要注意。 MatrixOne暂不支持空间数据类型&#xff0c;其他数据类型在保持与 MySQL 命名一致的情况下&#xff0c;在精度与…

android studio导入eclipse项目

网上下载一个老工程&#xff0c;.project文件里有eclipse。 android studio导入eclipse项目 eclipse项目结构 Android studio文件结构 下面是导入步骤&#xff1a; 第一步&#xff0c;打开一个项目。 选择File->New->Import Project 第二步&#xff0c;选择Eclipse项目根…

保护数据库防止数据泄露

为了避免金钱损失、声誉损害、机密性损失、不遵守政府法规等&#xff0c;保护组织的数据至关重要&#xff0c;保护数据库可以保护您的企业免受无数安全威胁&#xff0c;包括权限滥用、数据泄露、数据库注入和其他网络攻击。 选择工具保护数据库 Log360 是一站式 SIEM 解决方案…

element-plus使用el-date-picker组件时,如何禁止用户选择当前时间之后的日时分秒

element-plus使用el-date-picker组件时&#xff0c;如何禁止用户选择当前时间之后的日时分秒 例&#xff1a; 当前时间为2023-11-15 14.24&#xff0c;不能选择这之后的时分秒。&#xff08;禁止用户选择2023-11-15 14.28&#xff09; <el-date-pickerv-model"form.s…

MM MSTA-STATM数据丢失问题

2001工厂的采购视图已经维护了&#xff0c;但是在MSTA里面找不到对应的记录 解决方案&#xff1a; 1、se38 执行程序 RMMMVERW 参考 data were lost in table msta | SAP Community 2、取数逻辑换位置&#xff0c;从marc 取数 附加&#xff1a;RMMMVERW 执行界面 执行后…

nvm安装详细教程(卸载旧的nodejs,安装nvm、node、npm、cnpm、yarn及环境变量配置)

文章目录 一、完全卸载旧的nodejs1、打开系统的控制面板&#xff0c;点击卸载程序&#xff0c;卸载nodejs&#xff08;1&#xff09;打开系统的控制面板&#xff0c;点击程序下的卸载程序&#xff08;2&#xff09;找到node.js&#xff0c;鼠标右击出现下拉框&#xff0c;点卸载…

【Python语言】字典的使用方法总结

目录 1、基本知识 1.1 定义 1.2 定义字典变量 1.3 定义空字典 2、字典的常用方法介绍 2.1 基于key获取value 2.2 嵌套字典 2.3 新增元素 2.4 更新元素 2.5 删除元素 2.6 清空字典 2.7 获取全部的key 2.8 遍历字典 2.9 统计字典内的元素数量 3、 字典常用操作总结…

如何快速搭建Spring Boot接口调试环境并实现公网访问

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

Figma语言设置教程:简易切换至中文,提高操作便捷性!

Figma是世界领先的在线协作UI设计工具。它摆脱了Sketch等传统设计软件对设备的依赖&#xff0c;使设计师可以随时随地使用任何设备打开网页浏览器&#xff0c;轻松实现跨平台、跨时空的设计合作。那么&#xff0c;Figma如何改变中文&#xff0c;以提高国内设计师的使用体验呢&a…

ZOC8 for Mac:最佳终端仿真器,助力您的工作效率飞升!

在现代的工作环境中&#xff0c;终端仿真器扮演着不可或缺的角色。无论是开发人员、系统管理员还是网络工程师&#xff0c;都需要一个功能强大、易于使用的终端仿真器来处理各种任务。而ZOC8 for Mac正是为这些专业人士而打造的最佳选择。 作为一款全功能的终端仿真软件&#…

聊天即绘画,我来给好说 AI 当「甲方」

很多人说 “AI 能解放生产力”&#xff0c;放几个月前&#xff0c;小编并不这么想。用过 SD 画图的朋友都知道&#xff0c;拟提示词、调参数那都是脑力活&#xff0c;反复试错的过程就像在操纵机器、给 AI 打下手。 但最近&#xff0c;好说上线了 “聊天即绘画” 的 AI 绘画 2…

解决:Android TextView 设置斜体后右侧文字被遮挡

一、问题说明 遇到一个比较奇怪的情况&#xff0c;给 TextView 文字设置倾斜后&#xff0c;右侧的文字会被遮挡&#xff0c;感觉这应该是 Android 的一个 bug &#xff01; 上代码&#xff1a; <TextViewandroid:id"id/tv_title"android:layout_width"wra…

【Git企业开发】第八节.企业级开发模型和企业级项目管理实战

文章目录 前言一、企业级开发模型 1.1 系统开发环境 1.2 Git分支设计规范二、企业级项目管理实战 2.1 DevOps研发平台 2.2 开发场景-基于git flow模型的实践 2.3 环境bug修复总结 前言 一、企业级开发模型 我们知道&#xff0c;一个软件从零开始到最终…

新手小白看过来——带你快速入门跨境电商

近几年来&#xff0c;国内外贸交易是越来越火爆&#xff0c;其中跨境电商成为了2023年的热门风口行业&#xff0c;尽管现在做跨境电商的从业者有很多&#xff0c;但仍然有许多0基础小白想通过跨境电商获取人生的第一桶金&#xff0c;那么新手应该如何在跨境电商领域取得成功呢&…