文章:Searching and mining trillions of time series subsequences under dynamic time warping
来源:KDD2012
解决的问题:
使用DTW做时间序列检索速度太慢。
贡献:
作者使用了4个Trick(也即UCR suite)来提升检索速度,使得可以用DTW在可接受的时间内对万亿级别(10^12)的时间序列数据进行检索。
作者首先声明他们的工作是基于4个假设进行的:
1、必须对用于匹配的时间序列子序列进行标准化,仅仅是对整个时间序列标准化是不够的。
因为整个时间序列(或者说整个数据集)的不同子序列有可能出现噪声、平移、幅度的缩放、叠加线性趋势等多种不同的失真,如果只对整个时间序列进行标准化,并不能完全消除这些子序列的失真,这样用Q去跟这些子序列比对的时候,计算出来的距离就会偏大,所以要分别对每个子序列标准化。
此外,作者使用Trick2的一个基本假设就是子序列服从均值为0的高斯分布,所以对子序列进行标准化是必要的。
2、DTW是最好的距离度量。
当使用多达40个数据集综合进行评估时,部分距离度量在部分数据集表现得比DTW更好,但综合来看还是DTW更好。
3、无法对任意长度的时间序列匹配建立索引。
无法直接对DTW距离建立索引是因为DTW距离不满足三角不等式且计算复杂度太高,但仍然可以对下界距离建立索引来提高检索速度。
索引的目的是通过下界来快速过滤掉部分子序列,减少计算DTW的次数,但要建索引需要先完整地计算一遍下界,所以只有进行多次检索的时候索引才有意义。
问题在于作者先假设了必须对每个子序列都进行标准化,在这个前提下,如果两次检索的Q的长度不一样,就得分别建两次索引,这在万亿级别数据量下显然是不合理的,还不如就用顺序检索。
4、对应万亿级别的数据量,用几个小时来生成结果是合理的。
朴素DTW的Python实现:
import numpy as np
from scipy.spatial.distance import cdist
def make_dist_matrix(Q,C):
#输入序列Q和C,返回距离矩阵
M=np.zeros((len(Q)+1,len(C)+1))
M[0,1:]=float("inf")
M[1:,0]=float("inf")
M[1:,1:]=cdist([[q] for q in Q],[[c] for c in C],'euclidean')
return M
def naive_DTW(Q,C,fun=make_dist_matrix):
#输入序列Q和C,返回DTW距离
M1=fun(Q,C)
M2=M1[1:,1:] #浅copy
for i in range(len(Q)):
for j in range(len(C)):
M2[i,j]+=min(M1[i,j],M1[i+1,j],M1[i,j+1]) #刷DP表
return M2[-1,-1]
对DWT的改进:
由于朴素DTW的时间复杂度太高,计算太慢,所以人们提出了各种各样的改进方案。
多核计算:
虽然使用多核并行计算能获得基本上线性级别的加速,但这跟算法没什么关系。
全局约束:
对从左上到右下移动路径的