时间序列相似性属于曲线相似性/曲线匹配(curve matching)领域的内容,在这一领域,有许多有用的方法,但是国内的博客上鲜有这方面的内容,因此我选取了几种常用的方法进行一下综述性的阐述。
衡量相似性之前,我们首先定义“相似”。
正常情况下,我们认为x,y,z是形状相似的,在这三条曲线中,我们认为y,z是最相似的两条曲线(因为y,z的距离最近)。
ok,那我们先来看看寻常意义上的相似:距离最近且形状相似。本文主要详细介绍时间序列相似度计算的DTW算法和PLR算法。
1. 欧式距离
要衡量距离与形状,显然欧式距离是一个天然完美的指标,上图中我们正是基于欧式距离认为y与z是最相似的,欧式距离在诸多算法都有广泛的应用。对于长度相同的序列,计算每两点之间的距离然后求和,距离越小相似度越高(whole matching)。对于不同长度的序列,一般有两种方法处理:
1)子序列匹配(subsequence matching): 找出长序列中与短序列最相似的部分。举个栗子,设序列
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)分段线性表示。
一个时间序列,无非有三种状态:上升、下降和不变,我们将这种状态对应表示为
我画了一个草图,可能emm……不是很美观。
那么我们就可以将这个序列表示为[1,1,0,-1...]这样的序列,将相邻的