前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TODS:功能强大的多元时间序列异常检测工具

TODS:功能强大的多元时间序列异常检测工具

作者头像
VachelHu
发布2023-02-28 15:52:35
1.4K0
发布2023-02-28 15:52:35
举报
文章被收录于专栏:时序人

TODS是一个全栈的自动化机器学习系统,主要针对多变量时间序列数据的异常检测。该系统可以处理三种常见的时间序列异常检测场景:点的异常检测(异常是时间点)、模式的异常检测(异常是子序列)、系统的异常检测(异常是时间序列的集合)。TODS提供了一系列相应的算法。

TODS具有如下特点:

  • 全栈式机器学习系统:支持从数据预处理、特征提取、到检测算法和人为规则每一个步骤并提供相应的接口。
  • 广泛的算法支持:包括 PyOD 提供的点的异常检测算法、最先进的模式的异常检测算法(例如 DeepLog, Telemanon ),以及用于系统的异常检测的集合算法。
  • 自动化的机器学习:旨在提供无需专业知识的过程,通过自动搜索所有现有模块中的最佳组合,基于给定数据构造最优管道。

工具源码访问如下地址获取:

https://github.com/datamllab/tods

概述

TODS 提供了详尽的用于构建基于机器学习的异常检测系统的模块,它们包括:数据处理(data processing),时间序列处理( time series processing),特征分析(feature analysis),检测算法(detection algorithms)和强化模块( reinforcement module)。这些模块所提供的功能包括常见的数据预处理、时间序列数据的平滑或变换,从时域或频域中抽取特征、多种多样的检测算法以及让人类专家来校准系统。

通过这些模块提供的功能包括:通用数据预处理、时间序列数据平滑/转换、从时域/频域中提取特征、各种检测算法,以及涉及人类专业知识来校准系统。可以时间序列数据执行三种常见的异常值检测场景:逐点检测(时间点作为异常值)、模式检测(子序列作为异常值)和系统检测(时间序列集作为异常值)。

当时间序列中存在潜在的系统故障或小故障时,通常会出现逐点异常值。这种异常值存在于全局(与整个时间序列中的数据点相比)或局部(与相邻点相比)的单个数据点上。全局异常值通常很明显,检测全局异常值的常见做法是获取数据集的统计值(例如,最小值/最大值/平均值/标准偏差)并设置检测异常点的阈值。

局部异常值通常出现在特定上下文中,具有相同值的数据点如果不在特定上下文中显示,则不会被识别为异常值。检测局部异常值的常用策略是识别上下文(通过季节性趋势分解、自相关),然后应用统计/机器学习方法(例如 AutoRegression、IsolationForest、OneClassSVM)来检测异常值。

当数据中存在异常行为时,通常会出现模式异常值。模式异常值是指与其他子序列相比其行为异常的时间序列数据的子序列(连续点)。检测模式异常值的常见做法,包括不和谐分析(例如,矩阵配置文件、HotSAX)和子序列聚类。

Discords 分析利用滑动窗口将时间序列分割成多个子序列,并计算子序列之间的距离(例如,欧几里德距离)以找到时间序列数据中的不一致。子序列聚类也将子序列分割应用于时间序列数据,并采用子序列作为每个时间点的特征,其中滑动窗口的大小为特征的数量。然后,采用无监督机器学习方法,例如聚类(例如,KMeans、PCA)或逐点异常值检测算法来检测模式异常值。

当许多系统之一处于异常状态时,系统异常值会不断发生,其中系统被定义为多元时间序列数据。检测系统异常值的目标是从许多类似的系统中找出处于异常状态的系统。例如,从具有多条生产线的工厂检测异常生产线。检测这种异常值的常用方法是执行逐点和模式异常值检测以获得每个时间点/子序列的异常值分数,然后采用集成技术为每个系统生成整体异常值分数以进行比较和检测。

Scikit-learn API

在构建机器学习管道的开始,需要进行大量实验来调整或分析算法。在 TODS 中,Scikit-learn 类似 API 可用于大多数模块,允许用户灵活地将单个函数调用到实验脚本中。这是一个调用矩阵配置文件的示例,用于使用 UCR 数据集识别模式异常值。

代码语言:javascript
复制
# !pip install -e git+https://github.com/datamllab/tods.git#egg=tods
import numpy as np 
from tods.sk_interface.detection_algorithm.MatrixProfile_skinterface import MatrixProfileSKI 
from sklearn.metrics import precision_recall_curve 
from sklearn.metrics import accuracy_score 
from sklearn.metrics import confusion_matrix 
from sklearn.metrics import classification_report 

# 数据准备
data = np.loadtxt("./500_UCR_Anomaly_robotDOG1_10000_19280_19360.txt") 

X_train = np.expand_dims(data[:10000], axis=1) 
X_test = np.expand_dims(data[10000:], axis=1) 

transformer = MatrixProfileSKI() 
transformer.fit(X_train) 
prediction_labels_train = transformer.predict(X_train) 
prediction_labels = transformer.predict(X_test) 
prediction_score = transformer.predict_score(X_test) 

y_true = prediction_labels_train 
y_pred = prediction_labels 

print('Accuracy Score: ', accuracy_score(y_true, y_pred)) 

confusion_matrix(y_true, y_pred) 
print(classification_report(y_true, y_pred))

结果如下:

代码语言:javascript
复制
Accuracy Score: 0.89 
precision recall f1-score support 
0 0.90 0.98 0.94 9005 
1 0.21 0.04 0.06 995 

accuracy 0.89 10000 
macro avg 0.55 0.51 0.50 10000 
weighted avg 0.83 0.89 0.85 10000

自动模型发现

TODS 还利用 TODS API 提供自动模型发现。自动模型发现的目标旨在根据验证集中的标签信息和给定的计算时间限制搜索最佳管道。

代码语言:javascript
复制
import pandas as pd 
from axolotl.backend.simple import SimpleRunner 
from tods import generate_dataset, generate_problem 
from tods.searcher import BruteForceSearch 

table_path = 'yahoo_sub_5.csv' 
target_index = 6 # what column is the target 
time_limit = 30 # How many seconds you wanna search 

metric = 'F1_MACRO' # F1 on label 1 

# Read data and generate dataset and problem 
df = pd.read_csv(table_path) 
dataset = generate_dataset(df, target_index=target_index) 
problem_description = generate_problem(dataset, metric) 

# Start backend 
backend = SimpleRunner(random_seed=0) 

# Start search algorithm 
search = BruteForceSearch(problem_description=problem_description, 
backend=backend) 

# Find the best pipeline 
best_runtime, best_pipeline_result = search.search_fit(input_data=[dataset], time_limit=time_limit) 
best_pipeline = best_runtime.pipeline best_output = best_pipeline_result.output 
# Evaluate the best pipeline 
best_scores = search.evaluate(best_pipeline).scores
代码语言:javascript
复制
print('Search History:') 
for pipeline_result in search.history: 
    print('-' * 52) 
    print('Pipeline id:', pipeline_result.pipeline.id) 
    print(pipeline_result.scores)
代码语言:javascript
复制
print('Best pipeline:') 
print('-' * 52) 
print('Pipeline id:', best_pipeline.id) 
print('Pipeline json:', best_pipeline.to_json()) 
print('Output:') 
print(best_output) 
print('Scores:') 
print(best_scores)

管道搜索完成后,用户可以通过管道id访问所有搜索到的管道,并保存任何管道描述文件以供后续使用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 时序人 微信公众号,前往查看

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

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

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