前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >KDD Cup 2021:时间序列异常检测问题开源Baseline

KDD Cup 2021:时间序列异常检测问题开源Baseline

作者头像
炼丹笔记
发布2021-05-14 17:33:03
1.4K0
发布2021-05-14 17:33:03
举报
文章被收录于专栏:炼丹笔记

作者:DOTA

线上效果

赛题简介

本次赛题的数据为时序数据,针对每条时序记录,需要选手完成具体的异常点定位。

数据与评测

文件的命名即分割了训练集和测试集,如下所示

<id>_<name>_<split-number>.txt

e.g. 004_UCR_Anomaly_2500.txt.

例子中,训练集和测试集的分割点为2500

评测:如上图异常区域为2759至2820,最后答案定位的位置,在前后100的区间内都算正确。比如这里答案只要在2659 和 2920 区间内都算正确。

常用异常检测方法

时序异常检测算法非常多,这里介绍一些,有兴趣的同学可以尝试一波。

  • ARIMA
  • 基于聚类检测
  • 基于序列建模型的RNN、LSTM
  • Local Outlier Factor
  • One-Class SVM
  • Deep-SVDD
  • First Hour Average
  • Stddev from Moving Average
  • Mean Subtraction Cumulation

基于AutoEncoder模型的异常检测

本文开源主要使用的是基于AutoEncoder模型的时间序列异常检测算法。

原始的时间序列往往面临维度高,存在噪声等情况,通过特征提取,对原始数据进行清洗和丰富等,会比直接将原始数据扔给神经网络要好。

AutoEncoder是一种典型的无监督方法,可以将其扩展为Variational AutoEncoder,或者引入情景信息,从而扩展为Conditional Variational AutoEncoder。

序列数据EDA

代码语言:javascript
复制
filename = 'data_phase2/004_UCR_Anomaly_2500.txt'
data = pd.read_csv(filename,names=['value'])
point = 2500
n_steps = 100
train = data.iloc[:point]
test = data.iloc[point:]

训练集中的数据(无异常点的数据):

测试集中的数据(有异常点的数据):

构造序列

代码语言:javascript
复制
def create_sequences(values, steps=n_steps):
    output = []
    for i in range(len(values) - steps):
        output.append(values[i : (i + steps)])
    return np.stack(output)

模型

代码语言:javascript
复制
model = keras.Sequential(
    [
        layers.Input(shape=(x_train.shape[1], x_train.shape[2])),
        layers.Conv1D(filters=16, kernel_size=4, padding="same", strides=2, activation="relu"),
        layers.Dropout(rate=0.2),
        layers.Conv1D(filters=8, kernel_size=4, padding="same", strides=2, activation="relu"),
        layers.Conv1DTranspose(filters=8, kernel_size=4, padding="same", strides=2, activation="relu"),
        layers.Dropout(rate=0.2),
        layers.Conv1DTranspose(filters=16, kernel_size=4, padding="same", strides=2, activation="relu"),
        layers.Conv1DTranspose(filters=1, kernel_size=7, padding="same"),
    ]
)
model.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-4), loss="mse")
model.summary()

自编码模型一般的神经网络,其内部结构呈现一定对称性

激活函数,一般会优先选择Relu,当Relu无法满足需求的时候,再去考虑其他激活函数,比如Relu的一些衍生版本Elu,它是Relu的其中一个优化版本,可以避免出现神经元无法更新的情况。

模型训练

训练模型很简单,只需要调用model.fit函数。虽然简单但是需要注意的是,对于AutoEncoder来说,输入和输出都是X_train特征, 除此之外在建模时划分出20%的数据集作为验证集,来验证模型的泛化性。

代码语言:javascript
复制
dota_model = model.fit(
    x_train,
    x_train,
    epochs=2009,
    batch_size=512,
    validation_split=0.2,
    callbacks=[keras.callbacks.EarlyStopping(monitor="val_loss", patience=5, mode="min")],
)

查看训练的Loss历史曲线,发现训练集和验证集都很好的进行拟合,而且训练集并没有出现“反弹”,也就是没有过拟合的现象。

异常检测

当自编码器训练好后,它应该能够学习到原始训练数据集的内在编码,然后根据学习到的编码,在一定程度内还原原始训练数据集中的数据。

因为AutoEncoder学习到了“正常数据周期模式”的编码格式,所以当一个数据集提供给该自编码器时,它会按照训练集中的“正常数据周期模式”的编码格式去编码和解码。如果解码后的数据集和输入数据集的误差在一定范围内,则表明输入的数据集是“正常的”,否则是“异常的"。

第一个Sequence的拟合情况如下:

测试集结果

异常节点为[1683,1684,,1685],因为point分割的原因,最后提交的结果,在此基础上+point之后即可。

总结

本赛题的方法很多,此处开源的版本为基于卷积的AutoEncoder版本,同时基于统计的异常相关方法,线上提交也能取的不错的成绩。由于拖稿的原因,本文章发布时开源代码还未整理好,后续整理好后会在评论区或者炼丹笔记 群中开源代码。

参考资料

  • https://compete.hexagon-ml.com/practice/competition/39
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 炼丹笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档