DTAI 研究小组使用的时间序列距离库(例如动态时间规整)。该库提供纯 Python 实现和 C 快速实现。C 实现仅依赖 Cython。它与 Numpy 和 Pandas 兼容,并且可以避免不必要的数据复制操作。
文档:http://dtaidistance.readthedocs.io
例子:
from dtaidistance import dtw
import numpy as np
s1 = np.array([0.0, 0, 1, 2, 1, 0, 1, 0, 0])
s2 = np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2)
引用这篇作品:
Wannes Meert、Kilian Hendrickx、Toon Van Craenendonck、Pieter Robberechts、Hendrik Blockeel 和 Jesse Davis。
DTAIDistance(版本 v2)。泽诺多.
http://doi.org/10.5281/zenodo.5901139
v2 中的新功能:
ssize_t
而不是int
允许在 64 位机器上使用更大的数据结构,并且与 Numpy 更兼容。max_dist
参数与 Silva 和 Batista 在 PrunedDTW [7] 上的工作类似。该工具箱现在实现了与 PrunedDTW 相同的版本,因为它修剪了更多的部分距离。此外,按照 Silva 和 Batista 的建议,添加了use_pruning
参数来自动将max_dist
设置为欧几里德距离,以加快计算速度(可以使用新方法ub_euclidean
)。dtaidistance.dtw_ndim
包中的多维序列。 $ pip install dtaidistance
或者
$ conda install -c conda-forge dtaidistance
pip 安装需要 Numpy 作为依赖项来编译与 Numpy 兼容的 C 代码(使用 Cython)。但是,这种依赖关系是可选的并且可以删除。
源代码可在 github.com/wannesm/dtaidistance 获取。
如果您在编译过程中遇到任何问题(例如基于C的实现或OpenMP不可用),请参阅文档以获取更多选项。
from dtaidistance import dtw
from dtaidistance import dtw_visualisation as dtwvis
import numpy as np
s1 = np.array([0., 0, 1, 2, 1, 0, 1, 0, 0, 2, 1, 0, 0])
s2 = np.array([0., 1, 2, 3, 1, 0, 0, 0, 2, 1, 0, 0, 0])
path = dtw.warping_path(s1, s2)
dtwvis.plot_warping(s1, s2, path, filename="warp.png")
仅基于两个数字序列的距离测量:
from dtaidistance import dtw
s1 = [0, 0, 1, 2, 1, 0, 1, 0, 0]
s2 = [0, 1, 2, 0, 0, 0, 0, 0, 0]
distance = dtw.distance(s1, s2)
print(distance)
最快的版本(30-300次)直接使用c,但需要一个数组作为输入(双精度类型),并且(可选)还通过将max_dist
设置为欧几里德上限来修剪计算:
from dtaidistance import dtw
import array
s1 = array.array('d',[0, 0, 1, 2, 1, 0, 1, 0, 0])
s2 = array.array('d',[0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2, use_pruning=True)
或者您可以使用 numpy 数组(数据类型为 double 或 float):
from dtaidistance import dtw
import numpy as np
s1 = np.array([0, 0, 1, 2, 1, 0, 1, 0, 0], dtype=np.double)
s2 = np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0])
d = dtw.distance_fast(s1, s2, use_pruning=True)
检查__doc__
以获取有关可用参数的信息:
print(dtw.distance.__doc__)
预计有许多选项可以提前停止动态规划算法正在探索的某些路径或调整距离测量计算:
window
:只允许从两条对角线偏移到这个量。max_dist
:如果返回的距离测量值大于此值,则停止。max_step
:不允许步长大于此值。max_length_diff
:如果两个系列的长度差异较大,则返回无穷大。penalty
:如果应用压缩或扩展(在距离之上),则添加惩罚。psi
:Psi 松弛以忽略序列的开始和/或结束(对于循环序列)[2]。use_pruning
:根据欧几里德上限修剪计算。 如果除了距离之外,您还希望完整矩阵看到所有可能的扭曲路径:
from dtaidistance import dtw
s1 = [0, 0, 1, 2, 1, 0, 1, 0, 0]
s2 = [0, 1, 2, 0, 0, 0, 0, 0, 0]
distance, paths = dtw.warping_paths(s1, s2)
print(distance)
print(paths)
具有所有扭曲路径的矩阵可以可视化如下:
from dtaidistance import dtw
from dtaidistance import dtw_visualisation as dtwvis
import random
import numpy as np
x = np.arange(0, 20, .5)
s1 = np.sin(x)
s2 = np.sin(x - 1)
random.seed(1)
for idx in range(len(s2)):
if random.random() < 0.05:
s2[idx] += (random.random() - 0.5) / 2
d, paths = dtw.warping_paths(s1, s2, window=25, psi=2)
best_path = dtw.best_path(paths)
dtwvis.plot_warpingpaths(s1, s2, paths, best_path)
请注意psi
参数,该参数放宽了开头和结尾处的匹配。在此示例中,即使正弦波略有偏移,也会产生完美匹配。
要计算序列列表中所有序列之间的 DTW 距离度量,请使用方法dtw.distance_matrix
。您可以设置变量以使用更多或更少的 c 代码( use_c
和use_nogil
)以及并行或串行执行( parallel
)。
distance_matrix
方法需要一个列表/数组的列表:
from dtaidistance import dtw
import numpy as np
series = [
np.array([0, 0, 1, 2, 1, 0, 1, 0, 0], dtype=np.double),
np.array([0.0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0]),
np.array([0.0, 0, 1, 2, 1, 0, 0, 0])]
ds = dtw.distance_matrix_fast(series)
或矩阵(如果所有系列都具有相同的长度):
from dtaidistance import dtw
import numpy as np
series = np.matrix([
[0.0, 0, 1, 2, 1, 0, 1, 0, 0],
[0.0, 1, 2, 0, 0, 0, 0, 0, 0],
[0.0, 0, 1, 2, 1, 0, 0, 0, 0]])
ds = dtw.distance_matrix_fast(series)
您可以指示计算仅填充距离测量矩阵的一部分。例如,将计算分布在多个节点上,或者仅将源系列与目标系列进行比较。
from dtaidistance import dtw
import numpy as np
series = np.matrix([
[0., 0, 1, 2, 1, 0, 1, 0, 0],
[0., 1, 2, 0, 0, 0, 0, 0, 0],
[1., 2, 0, 0, 0, 0, 0, 1, 1],
[0., 0, 1, 2, 1, 0, 1, 0, 0],
[0., 1, 2, 0, 0, 0, 0, 0, 0],
[1., 2, 0, 0, 0, 0, 0, 1, 1]])
ds = dtw.distance_matrix_fast(series, block=((1, 4), (3, 5)))
这种情况下的输出将是:
# 0 1 2 3 4 5
[[ inf inf inf inf inf inf] # 0
[ inf inf inf 1.4142 0.0000 inf] # 1
[ inf inf inf 2.2360 1.7320 inf] # 2
[ inf inf inf inf 1.4142 inf] # 3
[ inf inf inf inf inf inf] # 4
[ inf inf inf inf inf inf]] # 5
距离矩阵可用于时间序列聚类。您可以使用现有方法,例如scipy.cluster.hierarchy.linkage
或两个包含的聚类方法之一(后者是 SciPy 链接方法的包装器)。
from dtaidistance import clustering
# Custom Hierarchical clustering
model1 = clustering.Hierarchical(dtw.distance_matrix_fast, {})
cluster_idx = model1.fit(series)
# Augment Hierarchical object to keep track of the full tree
model2 = clustering.HierarchicalTree(model1)
cluster_idx = model2.fit(series)
# SciPy linkage clustering
model3 = clustering.LinkageTree(dtw.distance_matrix_fast, {})
cluster_idx = model3.fit(series)
对于跟踪完整聚类树( HierarchicalTree
或LinkageTree
)的模型,可以将树可视化:
model.plot("myplot.png")
选修的:
发展:
DTAI distance code.
Copyright 2016-2022 KU Leuven, DTAI Research Group
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.