【问题标题】:Dynamic Time Warping recursive implementation动态时间规整递归实现
【发布时间】:2026-01-07 05:20:06
【问题描述】:

女士们,先生们,晚上好,
我想在 Python 中实现一个动态时间规整 (DTW) 算法。

出于测试目的,我设置了一个小的随机距离矩阵(例如,由曼哈顿度量生成),然后用它调用我的 DTW 算法。

import numpy as np
from dynamic_time_warping import compute_dtw

x=np.zeros((3,4))
x[0,2]=1.0
x[0,3]=2.0
x[1,2]=1.0
x[1,3]=2.0
x[2,0]=1.0
x[2,1]=1.0
x[2,3]=1.0

compute_dtw(x)

我的DTW算法如下:

def compute_dtw(W):
    if W.shape[0]==1 or W.shape[1]==1:
        C=float("inf")
    if W.shape[0]==1 and W.shape[1]==1:
        C=0.0
    else:
        C=W[len(W),len(W)]+min(compute_dtw(W[0:-1, 0:-1]),
            compute_dtw(W[0:-1]), compute_dtw(W[:, 0:-1]))
    return C

我希望算法获取 x 的 m*n 值并将其添加到下一个最小值,我试图通过使用更小的矩阵再次调用该函数来实现该最小值。 (compute_dtw(W[0:-1, 0:-1]), compute_dtw(W[0:-1]), compute_dtw(W[:, 0:-1]))

通过脚本后,这给了我以下错误:

C=W[len(W),len(W)]+min(compute_dtw(W[0:-1, 0:-1]), compute_dtw(W[0:-1]), compute_dtw(W[:, 0:-1])) IndexError: index 3 is 尺寸为 3 的轴 0 超出范围

显然,我正在调用不存在的数组元素,但我无法弄清楚它在哪里中断。

感谢您的建议和帮助!

//更新代码:

def compute_dtw(W):
    if W.shape[0]==1 and W.shape[1]==1:
        C=0.0
    elif W.shape[0]==1 or W.shape[1]==1:
        C=float("inf")
    else:
        C=W[W.shape[0]-1,W.shape[1]-1]+min(compute_dtw(W[0:-1, 0:-1]), compute_dtw(W[0:-1]), compute_dtw(W[:, 0:-1]))
    return C

【问题讨论】:

  • 有什么东西被保存到矩阵W中了吗?看起来不是这样......此外,DTW 算法中的递归,就像在许多其他算法中一样,是使用动态编程实现的,以避免进行冗余计算,这会将您的时间复杂度从 O(MN) 提高到 O(2^N)甚至更糟。这是 DTW 的动态编程实现:github.com/talcs/simpledtw/blob/master/simpledtw.py

标签: python optimization recursion


【解决方案1】:

Python 索引从零开始。在您第一次通过时,您调用了元素 [3,3](它不存在),因此出现了越界错误。

我对动态时间扭曲不是很熟悉,但我认为应该使用特定轴的.shape,而不是len(),后者只是数组第一维的长度。即使这样,您也必须调整递归以遍历每个连续数组的边界。

最后,return 语句应该与if 块处于同一级别。目前,compute_dtw 在前两种情况下不会返回任何内容,只有当形状在两个轴上都大于长度 1 时。

【讨论】:

  • 哎呀,谢谢你的提示。我更新了第一个帖子。它现在似乎起作用了。刚刚开始在完整数据集(100 个时间序列 69 个数据点)上运行似乎需要相当长的时间......如果您可以查看更新的代码,将不胜感激。
  • @Dahlai,我希望这些建议听起来不刺耳(不是我的意图)。 DTW 完成后,您是否期望传入的“矩阵”与传入的维度相同?我认为现在它将返回一个标量。祝你好运。
  • 一点也不!我想得到一个标量,它表示通过距离矩阵的最短路径。在我的数据上运行脚本,但它似乎永远运行。不幸的是,还有一些故障排除工作要做。
  • ,原来我需要使用动态规划,否则我会得到太多的函数调用。无论如何感谢您的帮助!