DNNV vs RNN
在实际处理时序数据的时候思考了这么一个问题(知乎上也有人问):为什么要用RNN,不能把时间序列的数据都作为特征值输入全连接神经网络(DNN)吗?
我看到知乎上有个回答不错:
如果固定了就是前四天输入,预测第五天,普通的全连接完全可以解决这个问题,无非是拟合一个四元的高阶函数罢了。但是大多数的时序问题,输入是变长的,而且非常长。有时输出也要求是变长一个序列。网络的形状都是固定的,故而普通的全连接无法解决输入输出的变长问题。
上面的回答我是认可的,在定长window作为输入下,确实可以用DNN或者其他机器学习模型,只不过收敛速度会慢些。
下面我们回到RNN如何处理时序数据。举例来说,我们做故障预测(注意这里是预测),已经知道了故障发生点,如何使用时序数据进行故障预测。
RNN方法一(有问题的方法)
首先我们不可能固定确定的window作为输入,因为不知道应该取1分钟,还是3分钟,还是5分钟。。。因此我们可能需要先截取一个相对较长的时间,比如5分钟的数据作为输入,也就是说故障发生点的前五分钟数据拿出来进行label,并且分成不同长度:
- 故障发生点向前推30秒
- 故障发生点向前推1分钟
- 故障发生点向前推2分钟
- 故障发生点向前推3分钟
- 故障发生点向前推4分钟
- 故障发生点向前推5分钟
相当于不同长度的时间序列打标为故障,同时取正常数据也是相同数据量的长度数据打标为正常。塞到RNN训练。
判定的时候,每一个instance的时间序列需要截成上述6种序列输入到model进行判定。即从当前时刻,向前推30秒判断;向前推1分钟判断。。。但是如果30秒判定会有故障,那么1分钟也应该判定会有故障,余此类推,这么来看,就没有必要把时间序列截成6段。这就是该方法最大的问题。
RNN方法二
上述方法问题的根源在于标注不对,即不确定到底应该是多长的时间序列应该标注为故障。比如有的故障对应了前面30秒,有的故障对应了前面50秒,有的对应了前面80秒等等。最理想的方案是我们人工标注数据集,比如我们获得了2千个故障,那么人工标注每个故障发生前多久的时间序列为故障序列。这样的序列可能每个长度都不一样,假设有两千种长度,然后统一塞到RNN模型做训练。
判定的时候,需要根据长度种类,从当前时刻拿出对应的长度来判定,那么需要拿出多少种长度呢?需要拿出2000种长度吗?答案是不需要的。这就是RNN的强大之处,只要给定一个instance的历史序列(可以类比一篇文章),那么在任何一个位置,给定一个片段,RNN是能够记住(反应)之前序列信息的。比如abcde->1
,那么给定de
,RNN输出为1
,不需要给定全部序列,因为de已经带了abc的信息。但是如果有另一条序列,xyzde->0
,那么给定de
,RNN有50%概率给1
或0
,因为de可以表示为abcde,也可以是xyzde。因此,输入还是越多越好。
那么上面的故障预测问题到底怎么设计比较合适呢?这就和我们的目标相关。目标是给定当前时刻,向前推一段时间的序列(也可以是几段序列),即当前时刻,给定n个window,判定接下来m个时间后/内(或者给定时间段)会发生故障。
按照上面的目标,我们可以先定义预测window,即接下来多久会发生故障,比如1分钟以内。那么标注数据需要是在故障发生点1分钟前的序列。如果训练数据是多条变长的序列,那么在做inference的时候会变得很困难,因为不知道要取多久的序列好。因此最好我们做成定长的序列,包括训练和推断。例如,我们的目标是预测1分钟之内会发生故障,通过人工观察到2千条序列,在故障之前的异常序列有10分钟到3分钟不等。那么我们要尝试不同的序列窗口,例如尝试3分钟,4分钟,5分钟,一直到15分钟,看哪个效果好用哪个。
具体过程如下:比如尝试5分钟的序列,对于故障1:
- 定位故障起始时间为12:00:00
- 因为预测1分钟之内发生故障,因此11:59:00为序列结束时间向前推5分钟(11:54:00)的序列标注为1,该序列称之为序列0
- 如果以秒为单位,那么取剩下的59秒形成59个序列,标注为1:
序列1:[11:55:01, 11:59:01]->1
序列2:[11:55:02, 11:59:02]->1
序列3:[11:55:03, 11:59:03]->1
序列4:[11:55:04, 11:59:04]->1
序列5:[11:55:05, 11:59:05]->1
序列6:[11:55:06, 11:59:06]->1
序列7:[11:55:07, 11:59:07]->1
序列8:[11:55:08, 11:59:08]->1
序列9:[11:55:09, 11:59:09]->1
......
序列59:[11:55:59, 11:59:59]->1
对于故障2,故障3也做类似的标注,相当于一个故障有60比data,2000个故障有12万笔data,进行训练得到model。
inference时的时间窗口也是取5分钟,即当前时刻要预测接下来(1分钟之内)是否会发生异常,需要从当前时刻向前取5分钟的序列,输入到model得到结果。
上面的过程是尝试序列窗口为5分钟的,我们要尝试多种序列窗口,并且一定要覆盖夸异常区间的。比如人工标注了2000个故障,发现1000个故障前的异常数据序列有3分钟,另外一千个故障前面的异常序列有5分钟,那么序列窗口一定要尝试6分钟,7分钟等,即跨5分钟的序列。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。