5.8 时间序列相似度

 

对于时间序列来说,比较两个时间序列的相似性是一个很普遍的任务。通俗来说,两个时间序列的数据越接近,它们的图像“长得越像”,两个时间序列就越相似,而形容它们“长得像”的程度就是相似度,用sm表示。

假设用数学方法可以计算两个时间序列AB的的相似度,用Sim(…)来表示这个方法,则:

sm=Sim(A,B)

理论上Sim(…)的函数形式有无穷多种,我们还是介绍一种简单有效的方法——动态时间规划(Dynamic Time Warping,简称DTW)。

如果两个时间序列是完全对齐(对应位置的点数值接近)的,只要计算两个时间序列数据对应位置的距离(如绝对差)之和即可,如下图中的两个时间序列:

..

(a)(b)中的两个时间序列AB完全对齐,两者非常相似,只要计算两者的距离之和即可,把它作为时间序列AB的相似度sm

sm=sum(|Ai-Bi|),i[1,n]

其中AiA的第i个元素,BiB的第i个元素,nAB的元素个数。

实际中的时间序列并不总是完全对齐的,但直观看上去两个时间序列还是“长的很像”,比如下图中的两个时间序列:

..

(a)(b)中的两个时间序列整体上形状非常相似,但是它们在x轴上并不完全对齐,比如A上的a1,a2,a3,a4B上的b1,b2,b3,b4应该一一对应,但是从图中很明显的看出,它们不能完全对齐。直接计算对应位置数据的距离之和不一定能得到两者相似的结果,遇到这种情况应该怎么做呢?

在比较两个时间序列的相似度之前,需要将其中一个(或者两个)时间序列在x轴上扭曲,以使两个时间序列对齐。

那如何才能使两个时间序列对齐呢?也就是说怎样扭曲才是正确的?直观上理解,当然是扭曲一个序列后可以与另一个序列重合,这时两个时间序列中所有对应点的距离之和是最小的。

假设我们有两个时间序列AB,他们的长度是n:(DTW算法允许两个时间序列不等长,但无论是否等长,算法过程都是一样的,实际应用中等长的时间序列更常见,所以就以长度相等的时间序列来介绍了)

A= [a1,a2,…, an]

B= [b1,b2,…, bn]

我们依然采用两个时间序列中对应点的距离来计算相似度,因为可以扭曲x轴,所以并不是在两个序列中依次取对应点来计算距离,而是每个点有可能对应另一个序列中的多个点,从下图中可以看到有这种情况发生:

..

当然,扭曲x轴有一定要求:

1. 每个点都必须用到,不可跳过;

2. 时间序列中数据顺序不变;

3. 虽然可以“一对多”,但不可以交叉。

如果时间序列的长度是有限的,理论上扭曲x轴的方式就是有限的,只要穷举所有的扭曲方式,逐一计算扭曲后的两个时间序列的距离,距离最小时的扭曲方式就是我们需要的,但这样计算量太大,所以采用动态规划的方法来高效的完成计算。

为了对齐这两个序列,我们需要构造一个n*n的距离矩阵D,矩阵元素dij表示aibj两个点的距离(也就是时间序列A的每一个点和B的每一个点之间的距离,距离越小则相似度越高,这里先不考虑顺序),一般采用绝对差dij= |ai-bj|表示两点的距离。每一个矩阵元素表示点aibj对齐。DTW算法可以归结为寻找一条通过距离矩阵中若干个点的路径,路径通过的点即为两个序列进行计算的对齐的点,如下图:

..

假设上图的网格就是距离矩阵D,每个格都是一个矩阵元素dij,图中的实线W是最短距离之和的路径,怎么才能找到这条W呢?

我们把这条路径定义为规整路径,用W来表示,W的第k个元素定义为wk=(i,j),定义了序列aibj的对应关系,即:

W=[w1,w2,…,wk],k[n,2*n-1]

这条路径不是随意选择的,需要满足以下几个约束:

1. 边界条件

两个时间序列AB的首尾位置必须对应,即a1对应b1an对应bn,因此所选的路径必定是从左上角出发,在右下角结束,即w1=(1,1),wn=(n,n)

2. 连续性

如果wm-1=(a’,b’),那么对于路径的下一个点wm=(a,b)需要满足 (a-a’)1 (b-b’)1,也就是不可能跨过某个点去对齐,只能和自己相邻的点对齐。这样可以保证AB中的每个坐标都在W中出现。

3. 单调性

如果wm-1=(a’,b’),那么对于路径的下一个点wm=(a,b)需要满足(a-a’)0(b-b’)0,这样就限制了W上面的点必须是随着时间单调进行的。

结合连续性和单调性约束,每一个格点的路径就只有三个方向了。比如路径已经通过了格点(i, j),那么下一个通过的格点只可能是下列三种情况之一:(i+1, j)(i, j+1)或者(i+1, j+1),如下图:

..

满足上面这些约束条件的路径有近3n个,我们感兴趣的是使规整路径W经过的距离和最小,把它作为时间序列AB的相似度sm

sm=min(sum(D(wi)))/n

其中D(wi)是距离矩阵Dwi的位置信息取距离,除以n是计算平均距离。

为了得到距离和最小的路径W,我们定义一个累加距离矩阵C,从(1, 1)点开始匹配两个时间序列AB,每到一个点都累加之前所有点计算的距离,到达终点(n, n)后,这个累积距离就是我们上面说的总距离,也就是序列AB的相似度sm

累积距离cij可以按下面的方式表示,累积距离cij为当前距离dij(距离矩阵Di行第j列的元素)与可以到达该点的最小的邻近元素的累积距离之和:

cij=α*dij+min(c(i-1)(j-1),c(i-1)j,ci(j-1))

其中α是惩罚系数,用来对不同的路径进行惩罚,如不希望两个时间序列发生一对多时,可以使他们该路径的α大于1

最佳路径W是使得延路径的积累距离达到最小值的这条路径,而最小值就是时间序列AB的相似度。

sm=ckk/n

SPL例程:


A

B

C

D

E

1

[2,1,5,2,4]

/A




2

[1,5,5,3,5]

/B




3

1

/惩罚系数α



4

=A1.((v=~,A2.(abs(~-v))))

/距离矩阵D


5

=A4.(~.(null))

/初始化累计距离矩阵C

6

=CD=[]

/记录路径



7

for A4.len()

for A4(1).len()

/循环D中的每一个元素

8



=A7-1

/i-1


9



=B7-1

/j-1


10



=[C8,C9]

/(i-1,j-1)


11



=[C8,B7]

/(i-1,j)


12



=[A7,C9]

/(i,j-1)


13



=[C10,C11,C12]

/可能的三种情况

14



if C8==0&&C9==0

=D26=0

/1个元素时

15




=D25=C10

16



else if C8==0

=D26=A5(A7)(C9)

/1行元素时

17




=D25=C12

18



else if C9==0

=D26=A5(C8)(B7)

/1列元素时

19




=D25=C11

20



else

=A5(C8)(C9)

/其他元素时

21




=A5(C8)(B7)

22




=A5(A7)(C9)

23




=[D20,D21,D22]

/可能路径

24




=D23.pmin()

25




=C13(D24)

26




=D23(D24)

27



=if(D25==C10,1,A3)

/惩罚系数α

28



=CD.insert(0,[D25])

/记录路径

29



=A4(A7)(B7)

/距离dij


30



=D26+C29*C27

/累计距离cij

31



=A5(A7)(B7)=C30

/更新累计距离矩阵C

32

=A6.group((#-1)\(A4.~.len()))

/路径矩阵


33

=path=[[A4.len(),A4.~.len()]]

/初始化路径序列

34

=A6.m(-1)




35

for

=path.insert(0,[A34])

/逆向记录路径

36


=A34(1)




37


=A34(2)




38


if B36==1&&B37==1

break



39


=A32(B36)(B37)



40


=A34=B39



41

=path.rvs()

/路径




42

=A5.m(-1).m(-1)/A1.len()

/距离(相似度)

计算结果示例

距离矩阵D

..

累计距离矩阵C

..

图中蓝色的线是最佳路径W

W=[(1,1),(2,1),(3,2),(3,3),(4,4),(5,5)]

最终的曲线相似度sm

sm=3/5=0.6

两个时间序列的对应关系:..

两个时间序列的对齐后的时间序列:

..

(a)中是时间序列AB,图(b)是它们对齐后的时间序列A2B2,从图中可以明显看出对齐后,两个时间序列还是比较相似的。

例程中计算时间序列AB相似度时用的是它们的原值,实际情况中两个时间序列的量纲可能不一致,所以可能需要对他们进行标准化(第4章的4.2节介绍过这些方法),而后才能用DTW计算它们的相似度。

DTW算法还支持多维空间的曲线计算相似度,只是距离要重新定义了(比如用欧式距离),其他计算过程是类似的。