Matrix Profile, 时间分析“利”器~

本文介绍了MatrixProfile在时序分析中的应用,特别是其在异常检测方面的优势。通过模拟数据,展示了MatrixProfile如何准确识别异常点,无论是在单一异常还是多重异常的情况下。此外,还探讨了使用外部时序作为匹配对象的可能性,以及在离线和在线分析中的表现。MatrixProfile以其快速、无参数和广泛应用性成为时序分析的有效工具。
摘要由CSDN通过智能技术生成

前言

时序分析是一个很流行的话题,因为很多领域都可以存在时序数据。应用最广泛也是最经典的应该属于金融领域,常见的就是各种股票或者价格预测。

今天介绍一个在时序分析中有一定地位的经典模型:Matrix Profile。

Matrix Profile 是什么呢? 其实不是一种算法名称,更确切的讲是一种数据结构。

这里引用官方动图:

a0b77f602ffa9d9d2ffb15df4423c2d9.gif

一个滑动窗口m,不断与时序进行匹配,计算他们的(欧式)距离,并且记录距离的最小值。

换句话说,Matrix Profile可以测出每个时序窗口是不是整个时序亲生的。如果是亲生的,那么距离很小。如果不是亲生的,那么距离很远。

亲生的称为Motifs,就是重复的片段。

非亲生的称为discord或者anomaly,也就是异常。

这就是Matrix Profile 的全部,原理很简单,实施很难,只要是计算量太大(穷举)。所以大部分研究人员都花时间去研究如何快速计算MP。

“算法”特点

这里看看官方的介绍,有三个特点:

1. 快。上亿个时间序列,每个时序100年的长度,分辨率为1s,一天就计算了完了。

2. 无参数,没有什么超参数,开箱即用。

3. 无应用壁垒,只要是时序都行

cd2338abc359309e3b6ad19393fa768b.png

看样子是个利器,我们来实测一下效果。

牛刀小试

首先我们虚拟一段数据,采用波形图外加随机噪声,异常部分我们模拟数据丢失

89209b2b1e5c766b3abf08e434b109b6.png

我们采用官方的代码来进行分析,matrixprofile 提供了analyze,可以快速分析不同m对应的分析结果。

from matplotlib import pyplot as plt
import numpy as np
import matrixprofile as mp
profile, figures = mp.analyze(ts)

可以看到分析的结果很全面:里面包含了不同窗口的计算的结果,对应的最佳窗口长度,分析出的Motif和异常点。

4e71862b7cd23649841f37b77d89b08b.png

9bc9e5e1532cdf263ce82a8b1f4bbfc4.png

d48872c45f2c7569d26f8ef66720ab67.png

我们最关心的是异常点,可以看出Matrix profile还是很准确的点出了异常所在问题

可以看到m值为8 和276分析的结果完全不同,m值很关键,几乎决定了模型是否可用。但是贴心的是,这个包提供的函数能分析出最佳的m值,这就是所谓的“无参数”模型

看样子很不错。

加大难度

我们可以尝试一下MP是否可以测出多个异常点,这次模拟的异常点包括多种:有的幅值过高,有的过低,有的直接是“躺平”

404033fbe12a0a00eb38b9b6b3896f09.png

这次代码略有不同,这里采用固定的window 长度,因为我们没必要再分析一次数据。然后,我们调用discover里面的函数去发掘异常点。

需要说明的是,这种代码和上面的代码的效果是一致的,不过是更加灵活而已。

window_size = 297
profile = mp.compute(ts,window_size )
profile = mp.discover.discords(profile, k=5)
figures = mp.visualize(profile)
profile['discords']
plt.figure(figsize=(20, 7))
plt.plot(np.arange(ts.shape[0]), ts)
plt.scatter(sorted(profile['discords']), ts[sorted(profile['discords'])],c='r', marker='*',s=100)

3c49321be228be8e4aaddf0cc94bfed4.png

同样的,我们可以在MP 曲线上看到异常点的位置都明显格格不入。也就是说,还是有可能设置阈值他们筛选出来的

新玩法

既然MP是计算整个时序与其他片段的距离,那么我们是否可以采用“外部”时序作为匹配的对象呢?很常见的案例:我们知道这种心跳曲线是正常,凡是和他匹配距离小的,就是正常的。距离大的,就是异常。

这个思路是可行的!

profile = mp.compute(ts,query=ts2,windows = window_size,sample_pct=1)
profile = mp.discover.discords(profile, k=10)
figures = mp.visualize(profile)
profile['discords']
plt.figure(figsize=(20, 7))
plt.plot(np.arange(ts.shape[0]), ts)
plt.scatter(sorted(profile['discords']), ts[sorted(profile['discords'])],c='r', marker='*',s=100)

我们模拟新的数据,并且知道这段数据最开始部分是正常的,所以我们把这部分数据作为固定的时间片段,然后让其他数据滚动匹配。

6452d4e979a4173b6001c4f5fad8711c.png

87b4cc0c6f4de42aca1de94d2d10a8c9.png

效果还依然不错。

Bonus

看样子MP在离线数据分析上效果还可以,尤其是针对周期型数据。对于在线呢?这里我们可以实时计算MP,并且设定阈值来查看检测的结果。可以看到,MP能检测到异常的起始点,但是需要合理的阈值

bc3dc91dde0cc1e6dd52b8a7d143c2bf.gif

总结

本文介绍了经典的matrix profile的使用,它可以用于时序的异常检测,但是会有一些局限性。最适合的场景是离线分析,而不是在线分析。对于时序分析来说,开箱即用,简单粗暴,最重要的是:快!算是一把利器。

14071db07bcb29f678045f9654ffa40d.gif

 
 
●适婚农村青年找对象有多难?
●品牌知名度分析
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值