时间序列相似性属于曲线相似性/曲线匹配(curve matching)领域的内容,在这一领域,有许多有用的方法,但是国内的博客上鲜有这方面的内容,因此我选取了几种常用的方法进行一下综述性的阐述。
衡量相似性之前,我们首先定义“相似”。
正常情况下,我们认为x,y,z是形状相似的,在这三条曲线中,我们认为y,z是最相似的两条曲线(因为y,z的距离最近)。
ok,那我们先来看看寻常意义上的相似:距离最近且形状相似。本文主要详细介绍时间序列相似度计算的DTW算法和PLR算法。
1. 欧式距离
要衡量距离与形状,显然欧式距离是一个天然完美的指标,上图中我们正是基于欧式距离认为y与z是最相似的,欧式距离在诸多算法都有广泛的应用。对于长度相同的序列,计算每两点之间的距离然后求和,距离越小相似度越高(whole matching)。对于不同长度的序列,一般有两种方法处理:
1)子序列匹配(subsequence matching): 找出长序列中与短序列最相似的部分。举个栗子,设序列
,序列
,其中
。滚动地计算A与B的距离:
,然后找出所有d中的最小值,该距离所对应的A序列的索引即为A中与B最相似的部分。
2)滑动窗口:微软在2001年在Dimensionality Reduction for Fast Similarity Search文中提出为了减少算法复杂度,可以复制B序直到与A序列等长。
由于微软之后使用了独特的降维方法,且计算复杂度不是本文考虑的主要内容,因此,在涉及长短序列相似度计算的时候,本文均使用第一种方法。
似乎时间序列的相似性度量的计算可以就此为止了,然而远非如此。
天津大学的XIAO-LI DONG, CHENG-KUI GU, ZHENG-OU WANG在2006年Research on shape-based time series similarity measure[C]//2006 International Conference on Machine Learning and Cybernetics. IEEE, 2006: 1253-1258一文中指出了欧式距离用于衡量时间序列相似性的三个缺陷:不能辨别形状相似性
不能反映趋势动态变化幅度的相似性
基于点距离的计算不能反映不同分析频率的不同
举个栗子:
A与B的变化趋势几乎完全相反,A与C的变化趋势几乎完全相同。如果使用欧式距离去度量,那么结论就是A与B是最相似的。而实际上,在变化是A与C是相似的。
为了进一步加强对欧式距离的理解,我们不妨再举一个简单的例子:
正常来说,我们认为与y1最相似的是y3,实际上,y3就是y1向下平移得到的。然而欧式距离告诉我们,距离y1最近的是y2。
下面是使用Python进行模拟的源代码:
import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,np.pi*2,0.1)
y1=np.sin(x)
y2=np.cos(x)-2
y3=y1-2
plt.plot(y1)
plt.plot(y2)
plt.plot(y3)
plt.legend(['y1','y2','y3'])
def dis(x,y):
return(sum(x-y)**2)
dis(y1,y2)
Out[15]: 15831.914509398732
dis(y1,y3)
Out[16]: 15876.0
欧式距离对形状的度量如此糟糕,有没有更好的模型能度量形状呢?
2. 模式距离Pattern distance
首先引入一个算法,PLR(piecewise linear representation)分段线性表示。
一个时间序列,无非有三种状态:上升、下降和不变,我们将这种状态对应表示为
。假设有某个长度为S的序列,我们将其等分为K段。对于每一段计算一个斜率,斜率为正表示上升,为负表示下降,为0表示不变。
我画了一个草图,可能emm……不是很美观。
那么我们就可以将这个序列表示为[1,1,0,-1...]这样的序列,将相邻的相同模式进行合并,我们得到[1,0,-1...]的序列。这就是PLR算法。
关于PLR算法的点的分割,为了便于说理,我这里直接用的是等分的方式,然而观察上图可知,第三个模式表示为了0,实际上第三个模式是一个尖峰,是先上升后下降的,所以等分切割的方法并不科学。
KEOGH E. 在Fast similarity search in the presence of longitudinal scaling in time series data bases中提出的自底向上的搜索方法很好的解决了这个问题,感兴趣的读者可以自行了解。
因为我们将相邻的相同模式进行了合并,所以我们得到的模式序列一定是1,-1,0间隔排列的,每一个模式可能跨越了