ucr数据集_DTW算法在兆级数据下的优化

本文是基于对 《Searching and Mining Trillions of Time Series Subsequences under Dynamic Time Warping》的理解和总结。论文地址。

1.前言

大多数针对时序的数据挖掘算法使用序列的相似度作为核心,因此这部分算法的时间复杂度会极大的影响整体算法的效率。然而大部分论文仅针对百万级的数据进行挖掘,并不能满足业界对于可以高效处理亿级数据的需求。本文着重介绍了几个针对DTW算法的优化,使得复杂度明显下降。

2.概念和假设

在进行详细的论述之前,本文先介绍了部分基本概念以及算法所基于的假设。

2.1 序列查询

假设有一个序列

和一个查询序列
, n>>m。这个任务需要从T 中寻找一个与Q最匹配的子序列C. 为了确定这是最优的序列就需要对于T的每一个子序列做逐个比对。因此当n很大的时候需要花费大量的时间,本文针对这个任务的算法进行了优化。

2.2 DTW

Dynamic Time Wrap(DTW) 是一个用来计算两段时间序列相似度的算法。与传统的仅仅计算相同位置上元素的欧式距离的方法不同,DTW允许 one-to-many 映射。也就是说对于一个输入序列Q, 其中的每一个元素可以被映射到另一个序列C的同一位置, 反之也成立。但是要保证序列的单调性。 假设

是一个从查询序列位置到目标序列位置的映射,

if
.

因此DTW功能就是寻找到一个可以最小化欧式距离的映射。DTW一般是通过动态规划来实现,具体实现可以参照这里。时间复杂度为

。 但是O(n^2)在n很大时已经是一个不太高效的复杂度, 因此通常会采用 Sakoe-Chiba band 来限制DP的搜索范围。其核心思想是一个点不太可能被映射到一个偏离很远的位置,因为要保证序列的单调性。如图中绿线所示,假设带宽为R则实际复杂度为
.因此之后会采取很多 复杂度低于
的方法来做剪枝。

cf28a67e97b56f197a2f265db4e2fd5a.png

2.3 假设

2.3.1 所有的时间子序列都必须被normalize

文章在这里着重强调了这部分的重要性。从文章中可以看出如果时间序列没有经过normalization的处理,其抗噪性是很差的。而且文章也提出,对于每一段子序列,在比较前都要经过normalization 的处理,这样才能产生最好的结果。仅仅对整个数据集做normalization是不够的。

2.3.2 DTW是最好的metric

从上图可以看出DTW确实比naive 欧式距离要合理。

2.3.3 如果查询长度不确定那么就无法做index

做index确实可以提高查询速度,但是在实际情况下,如果不知道查询序列的长度, 那么就需要建立很多不同长度的index来应对不同长度的query。而这个index所需要的存储空间正比于数据集的大小,所以对于兆级数据来说并不现实(我感觉这个假设不太make sense)。主要还是为了说明现在的方法是最优解。

3 已知的优化方法

3.1 在计算距离时去掉平方根

因位这个算法的目的是找出距离最短的子序列,并且所用的metric是欧式距离,所以去除平方根并不会影响不同子序列之间的排名关系。

3.2 lower bounding

对于很大的序列,一个常见的优化方法就是通过建立lower bound来剪枝。文章介绍了两种lower bound:

以及

计算两个序列起始值,结束值,最大值以及最小值的距离中的最大值,因此复杂度为O(n).但是由于多数采用了 normalization,因此大部分情况下最大值以及最小值的距离不太可能成为
。 因此复杂度可以优化至O(1).

对于查询序列Q建立了一个upper bound U和lower bound L来封装查询序列. 具体的U 和 L 的计算方式根据问题的不同。通过如下公式来计算图中阴影部分面积。但是这里感觉变量名非常有混淆性,真不懂为什么要用
不用
. 具体信息考这里.

b717504ce6b50e08c3b6ebe5142187b6.png

3.3 Early abandoning of ED and

在计算序列的欧式距离或者

时,如果其距离已经超过了之前的最短距离,那么就可以放弃这个子序列。

3.4 Early abandoning of DTW

在计算DTW的时候,由于DTW是从左向右计算的,所以可以通过计算已有的DTW距离加上从当前位置向后的

来再进行一次剪枝。具体公式如下图:

当这个距离大于最佳距离时剪枝。这里的前提条件是已经计算过

因此可以保证
一定小于最佳距离。不然这个剪枝就无法成立了。

d4519cabe82020c7de5cf9b53c8d6af4.png

4 UCR

4.1 Early abandoning Z-normalization

这一部分是基于之前每个子序列都要normalization的假设。实际上normalization是可以和计算ED合并在一起的,这样在对

或者ED做剪枝的同时可以对normalization做同样的剪枝。算法如下图:

8202f170a77ab1daa75cd637f23c62e6.png

具体实现方法如下:

为了对子序列做normalization,需要计算两个参数:

f6aa28f3ad0d52bc9e328bab0ba46b08.png

为了减少这两个参数所需的计算量,文章使用了circular buffer。 在计算这两个参数时使用累积的

,也就是图中的ex和ex2. 在每一次前进至下一个子序列时累加上对应的值,并且在进入到下一个子序列前将当前子序列起点的值移除。这保证了参数的计算是O(1)的。于此同时在计算欧式距离的同时对每一个点做normalize这样就达到了对normalization剪枝的目的。

4.2 Reordering Early Abandoning

在对ED做剪枝的时候,单纯的从左向右并不一定能够最快的达到剪枝的目的。

af9a481f4d47762cae75f1380a168ede.png

如图所示,经过重新排序后右边只需要做5次计算就可以完成剪枝但是左边却需要9次。这里同样是基于之前的假设,由于文章采用的是 Z-normalization, 那么查询序列Q的每一个值都会用来和很多目标序列的值

进行比较,因此相对于Q的每一个点来说
是一个均值为0的高斯分布。所以离原点最远的点最有可能产生大的距离,因此优先计算这些点。这个方法不适用于DTW.

4.3 Reverse the Query/Data Role in

之前提到在建立

在计算时一般是针对查询序列(
)而非目标序列 (
),因为查询序列只需要计算而每次更新目标序列都需要重新计算。结合4.4 在剪枝时可以先使用
进行剪枝再使用
进行剪枝来提高查询效率。

4076ca4de9272b584f98653d445aa4dc.png

4.4 Cascading Lower Bounds

在针对DTW优化时,由于有多个LB可以选择,可以先选择剪枝能力差但是计算迅速的LB如下图所示。依次渐进至剪枝能力更强但是计算复杂度更高的方法来提高剪枝效率。

a0485a24cb9a5df7c9628dfb879a2eb9.png

5.0 实验结果

论文对比了其他几种查询算法。

naive:单纯计算Z-normaliztion 之后的欧式距离

state-of-the-art: 计算Z-normaliztion, 并使用 section3 中介绍的early abandoning。

从论文中可以看到ucr在多个数据集上都极大的提高了运算速度。并且在处理极长的子序列(72500)与目标序列(3billion)时能将时间从35天缩短至15小时。具体实验细节参考这里。

9794433172b5761298dbc2cef37b37de.png

6.0 结论

总的来说这篇文章是针对序列查询算法的几个部位进行优化,最为出彩的部分就是关于最佳排序的假设。但是有些不足的就是没有提供每个优化对于剪枝效率的影响。不过总体来说这篇论文还是有着很广泛的应用场景,尤其是生物这种经常要做DNA序列查找的领域,这个方法可以极大的提高实验效率,难道21世纪真的是生物的世纪 ?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UCR数据集是一个常用的时间序列数据集,其中包含了许多用于分类的数据。在Python中,使用UCR数据集可以使用tslearn库来实现。tslearn库是一个时间序列处理库,提供了多种时间序列数据处理和分析工具。在tslearn中,可以使用datasets模块来加载UCR数据集并进行操作。以下是具体的步骤: 1. 安装tslearn库 可以在终端中输入以下命令来安装: pip install tslearn 2. 加载UCR数据集 可以使用datasets模块来加载UCR数据集: from tslearn.datasets import UCR_UEA_datasets x_train, y_train, x_test, y_test = UCR_UEA_datasets().load_dataset(dataset_name) 其中,dataset_name是数据集的名称,比如”ECGFiveDays”。x_train和y_train是训练集数据和标签,x_test和y_test是测试集数据和标签。 3. 数据预处理 在训练模型之前,需要对数据进行预处理。常用的方法包括标准化、归一化、特征提取等。可以使用tslearn提供的工具函数来实现: from tslearn.preprocessing import TimeSeriesScalerMeanVariance scaler = TimeSeriesScalerMeanVariance(mu=0.0, std=1.0) x_train = scaler.fit_transform(x_train) x_test = scaler.transform(x_test) 在这里,使用了TimeSeriesScalerMeanVariance函数对数据进行了标准化处理,使得数据的均值为0,标准差为1。 4. 构建模型并训练 在经过预处理之后,可以使用任意的分类模型对数据进行分类。常用的模型包括KNN、SVM、随机森林等。以下是使用KNN模型对数据进行分类的示例代码: from tslearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=5, metric='dtw') knn.fit(x_train, y_train) score = knn.score(x_test, y_test) 5. 模型预测和评估 在训练完模型之后,可以使用训练好的模型对新的时间序列数据进行分类预测,以及对模型进行评估。以下是KNN模型的预测和评估代码: y_pred = knn.predict(x_test) accuracy = np.mean(y_pred == y_test) print(f"Accuracy: {accuracy:.2%}") 这里使用了np.mean函数来计算预测准确率。可以根据需要选择不同的评估指标。 总体来说,使用tslearn库中的datasets模块,可以方便地加载UCR数据集并进行分类模型的训练和评估。需要注意的是,在加载数据集之后需要对数据进行预处理,并根据具体情况选择合适的分类模型进行训练和评估。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值