本文将简要介绍三种常见的异常值及相应的检测策略。然后将基于两个受支持的API提供示例代码:用于开发时间序列离群值检测管道的TODSAPI和用于试验第三方包的scikit-learnAPI。时间序列异常值检测旨在识别数据中的意外或罕见实例。异常值检测作为数据分析最重要的任务之一,在时间序列数据上有着广泛的应用,如欺诈检测、故障检测、网络安全攻击检测等。例如,雅虎[1]和微软[2]已经建立了自己的时间序列异常值检测服务来监控他们的业务数据并触发异常值警报。在时间序列数据上,离群值可以分为三种情况:逐点离群值、模式(集体)离群值和系统离群值。概述TODS[3]是一个全栈机器学习系统,用于对多变量时间序列数据进行异常值检测。TODS提供了构建基于机器学习的异常值检测系统的详细模块,包括:数据处理、时间序列处理、特征分析、检测算法和增强模块。通过这些模块提供的功能包括:通用数据预处理、时间序列数据平滑/转换、时域/频域特征提取、各种检测算法,以及涉及人类专业知识来校准系统。可以对时间序列数据执行三种常见的异常值检测场景:逐点检测(时间点作为异常值)、模式检测(子序列作为异常值)和系统检测(时间序列集作为异常值)。当时间序列中存在潜在的系统故障或故障时,通常会出现逐点异常值。此类异常值存在于全局(与整个时间序列中的数据点相比)或局部(与相邻点相比)的单个数据点上。全局异常值通常很明显,检测全局异常值的常见做法是获取数据集的统计数据(例如,最小值/最大值/均值/标准差)并设置阈值以检测异常值。局部异常值通常出现在特定的上下文中,具有相同值的数据点如果没有出现在特定的上下文中则不会被识别为异常值。检测局部异常值的常见策略是识别上下文(通过季节性趋势分解、自相关),然后应用统计/机器学习方法(例如AutoRegression、IsolationForest、OneClassSVM)来检测异常值。当数据中存在异常行为时,通常会出现模式异常值。模式异常值是时间序列数据的子序列(连续点),与其他子序列相比表现异常。检测模式异常值的常见做法包括不协调分析(例如,矩阵配置文件[6]、HotSAX[7])和子序列聚类[4]。Discord分析利用滑动窗口将时间序列拆分为多个子序列,并计算子序列之间的距离(例如欧氏距离)以发现时间序列数据中的不一致性。子序列聚类也将子序列分割应用于时间序列数据,并在每个时间点使用子序列作为特征,其中滑动窗口的大小是特征的数量。然后,采用无监督机器学习方法,例如聚类(例如KMeans、PCA)或逐点异常值检测算法来检测模式异常值。当许多系统中的一个处于异常状态时,系统异常值不断出现,其中系统被定义为多元时间序列数据。检测系统异常值的目标是在众多相似系统中找出一个处于异常状态的系统。例如,从拥有多条生产线的工厂检测异常生产线。检测此类异常值的常用方法是执行逐点和模式异常值检测以获得每个时间点/子序列的异常值分数,然后使用集成技术为每个系统生成总体异常值分数以进行比较和检测。使用Scikit-learnAPI进行试验在构建机器学习管道之初,需要进行大量试验来调整或分析算法。在TODS中,一个类似于Scikit-learn的API可用于大多数模块,允许用户灵活地将单个函数调用到实验脚本中。下面是调用矩阵配置文件以使用UCR数据集[5]识别模式异常值的示例。#!pipinstall-egit+https://github.com/datamllab/tods.git#egg=todsimportnumpyasnpfromtods.sk_interface.detection_algorithm.MatrixProfile_skinterfaceimportMatrixProfileSKIfromsklearn.metricsimportprecision_recall_curvefromsklearn.metricsimportaccuracy_scorefromsklearn.metricsimportconfusion_matrixfromsklearn.metricsimportclassification_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_trainy_pred=prediction_labelsprint('AccuracyScore:',accuracy_score(y_true,y_pred))confusion_matrix(y_true,y_pred)print(classification_report(y_true,y_pred))结果如下:AccuracY分数:0.89精确召回F1得分支持00.900.980.980.94900510.210.210.040.06995精度0.8910000宏观AVG0.550.510.510.510.5010000加权AVG0.890.890.890.890.8510000todsapiapiapiapiapiapiap为了在不开发工作的情况下以可重现的方式管理实验,因为TODS中将结合更多的超参数和组件,我们的管道构建和执行API允许用户使用单个脚本生成各种可重现的管道。生成的管道存储为描述文件,如.json或.yml文件,可以很容易地使用不同的数据集复制/执行这些文件并与同事共享。下面的示例利用TODSAPI构建.json格式的自动编码器管道,并使用TODS后端引擎运行管道以检测YahooWebIntrusion数据集中的异常点[1]。Step1:生成流水线描述文件流水线生成脚本如下。虽然它看起来比Scikit-learn界面更长,但用户可以轻松地添加带有候选的超参数。fromd3mimportindexfromd3m.metadata.baseimportArgumentTypefromd3m.metadata.pipelineimportPipeline,PrimitiveStep#创建管道pipeline_description=Pipeline()pipeline_description.add_input(name='inputs')#Step0:dataset_to_dataframestep_0=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.data_processing.dataset_to_dataframe'))step_0.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='inputs.0')step_0.add_output('produce')pipeline_description.add_step(step_0)#Step1:column_parserstep_1=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.data_processing.column_parser'))step_1.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='steps.0.produce')step_1.add_output('produce')pipeline_description.add_step(step_1)#步骤2:extract_columns_by_semantic_types(attributes)step_2=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.data_processing.extract_columns_by_semantic_types'))step_2.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='steps.1.produce')step_2.add_output('produce')step_2.add_hyperparameter(name='semantic_types',argument_type=ArgumentType.VALUE,data=['[https://metadata.datadrivendiscovery.org/types/Attribute](https://link.zhihu.com/?target=https%3A//metadata.datadrivendiscovery.org/types/Attribute)'])pipeline_description.add_step(step_2)#步骤3:extract_columns_by_semantic_types(targets)step_3=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.data_processing.extract_columns_by_semantic_types'))step_3.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='steps.0.produce')step_3.add_output('produce')step_3.add_hyperparameter(name='semantic_types',argument_type=ArgumentType.VALUE,data=['[https://metadata.datadrivendiscovery.org/types/TrueTarget](https://link.zhihu.com/?target=https%3A//metadata.datadrivendiscovery.org/types/TrueTarget)'])pipeline_description.add_step(step_3)attributes='steps.2.produce'targets='steps.3.produce'#第4步:处理step_4=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.timeseries_processing.transformation.axiswise_scaler'))step_4.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference=attributes)step_4.add_output('produce')pipeline_description.add_step(step_4)#Step5:algorithmstep_5=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.detection_algorithm.pyod_ae'))step_5.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='steps.4.produce')step_5.add_output('produce')pipeline_description.add_step(step_5)#步骤6:预测step_6=PrimitiveStep(primitive=index.get_primitive('d3m.primitives.tods.data_processing.construct_predictions'))step_6.add_argument(name='inputs',argument_type=ArgumentType.CONTAINER,data_reference='steps.5.produce')step_6.add_argument(name='reference',argument_type=ArgumentType.CONTAINER,data_reference='steps.1.produce')step_6.add_output('produce')pipeline_description.add_step(step_6)#最终输出pipeline_description.add_output(name='outputpredictions',data_reference='steps.6.produce')#输出到jsondata=pipeline_description.to_json()withopen('autoencoder_pipeline.json','w')asf:f.write(data)print(data)Step2:运行流水线创建流水线描述文件后,我们可以运行流水线描述文件并对无监督流水线进行评估,如下所示:importsysimportargparseimportosimportpandasaspdfromtodsimportgenerate_dataset,load_pipeline,evaluate_pipelinethis_path=os.path.dirname(os.path.abspath(__file__))table_path=os.path.join(this_path,'yahoo_sub_5.csv')#文件数据集的路径target_index=6#哪一列是标签pipeline_path="./autoencoder_pipeline.json"metric="ALL"#读取数据并生成数据集df=pd.read_csv(table_path)dataset=generate_dataset(df,target_index)#加载默认管道pipeline=load_pipeline(pipeline_path)#运行管道pipeline_result=evaluate_pipeline(dataset,pipeline,metric)print(pipeline_result.scores)metricvaluenormalizedrandomSeedfold0F1_MACRO0.5090590.50905900虽然这个API需要一个脚本来生成管道描述文件,但它提供了一个灵活的接口来生成多个管道带有标签信息的自动模型发现除了手动创建管道之外,TODS还利用TODSAPI提供自动模型发现。自动模型发现的目标是根据验证集中的标签信息和给定的计算时间限制来搜索最优流水线。importpandasaspdfromaxolotl.backend.simpleimportSimpleRunnerfromtodsimportgenerate_dataset,generate_problemfromtods.searcherimportBruteForceSearchtable_path='yahoo_sub_5.csv'target_index=6#目标是哪一列time_limit=30#你想搜索多少秒metric='F1_MACRO'#F1onlabel1#读取数据并生成数据集和问题df=pd.read_csv(table_path)dataset=generate_dataset(df,target_index=target_index)problem_description=generate_problem(dataset,metric)#启动后端backend=SimpleRunner(random_seed=0)#开始搜索算法search=BruteForceSearch(problem_description=problem_description,backend=backend)#找到最好的管道best_runtime,best_pipeline_result=search.search_fit(input_data=[dataset],time_limit=time_limit)best_pipeline=best_runtime.pipelinebest_output=best_pipeline_result.output#评估最佳pipelinebest_scores=search.evaluate(best_pipeline).scoresprint('SearchHistory:')forpipeline_resultinsearch.history:print('-'*52)print('Pipelineid:',pipeline_result.pipeline.id)print(pipeline_result.scores)print('最佳管道:')print('-'*52)print('Pipelineid:',best_pipeline.id)print('Pipelinejson:',best_pipeline.to_json())print('Output:')print(best_output)print('分数:')print(best_scores)pipeline搜索完成后,用户可以通过pipelineid访问所有搜索到的pipeline,并保存任何pipeline描述文件以备后用总结项目组正在积极为这个项目开发更多的特性,包括带有可视化工具、半监督学习算法和高级管道搜索器的图形用户界面。目标是使时间序列数据的离群值检测更容易访问和更容易。我希望您喜欢阅读这篇文章,在接下来的文章中,我将详细介绍检测时间序列数据中不同类型异常值的常用策略,并介绍TODS中具有合成标准的数据合成器。
