1。adtk智能运维简介AIOps数据基本都是时间序列的形式,异常检测告警是AIOps的重要组成部分。笔者最近在处理时序数据时使用了adtkpython库,这里分享给大家。什么是adtk?adtk(AnomalyDetectionToolkit)是一个用于无监督异常检测的python工具包,它提供了常用的算法和处理函数:简单有效的异常检测算法(detector)异常特征处理(transformers)处理流程控制(Pipe)2。安装pipinstalladtk3。adtk数据需要时序数据主要包括时间和对应的指标(如cpu、内存、数量等)。python中的数据分析一般是pandasDataFrame,adtk要求输入数据的index必须是一个DatetimeIndex。pandas提供了时间序列的时间生成和处理方法。pd.date_rangestamps=pd.date_range("2012-10-0818:15:05",periods=4,freq="D")#DatetimeIndex(['2012-10-0818:15:05','2012-10-0918:15:05',#'2012-10-1018:15:05','2012-10-1118:15:05'],#dtype='datetime64[ns]',freq='D')pd.Timestamptmp=pd.Timestamp("2018-01-05")+pd.Timedelta("1day")print(tmp,tmp.timestamp(),tmp.strftime('%Y-%m-%d'))#2018-01-0600:00:001515196800.02018-01-06pd.Timestamp(tmp.timestamp(),unit='s',tz='亚洲/上海')#Timestamp('2018-01-0608:00:00+0800',tz='Asia/Shanghai')pd.to_datetimeadtk提供validate_series来验证时序数据的有效性,比如importpandasaspfromadtk.dataimportvalidate_seriesfromadtk.visualizationimportplotdf=pd.read_csv('./data/nyc_taxi.csv',index_col="timestamp",parse_dates=True)df=validate_series(df)plot(df)4.异常特征处理(transformers)adtk中的Transformers提供了很多时间序列特征处理方法:一般我们获取时间序列特征,通常是根据滑动到时间窗口,收集sta时间窗上的统计特征;分解季节性趋势以区分哪些是季节性部分,哪些是趋势的一部分。时间序列降维映射:针对细粒度的时间序列数据,数据量大,针对检测算法在效率方面,降维方法可以在降维的同时,保留时间序列的主要趋势等特征,提供时间效率。这对于使用CNN进行时间序列分类特别有效。adtk主要提供基于pca的降维和重构方法,主要应用于多维时间序列。4.1滑动窗口atdk提供了singlewide-mouthRollingAggregate和2-windowDoubleRollingAggregate的滑动方式。统计特征支持均值、中值、汇总、最大值、最小值、分位数、方差、标准差、偏度、峰度、直方图等,['mean','median','sum','min','max','quantile','iqr','idr','count','nnz','nunique','std','var','skew','kurt','hist']其中'iqr':是分位数75%和25%差异'idr':是分位数90%和10%插值csv',index_col="timestamp",parse_dates=True)s=validate_series(s)s_transformed=RollingAggregate(agg='quantile',agg_params={"q":[0.25,0.75]},window=5).transform(s)DoubleRollingAggregate提供两个窗口统计特征的差异,比如前5分钟和后5分钟,意思等agg参数和RollingAggregate中一样,新增的参数diff主要是衡量差距的函数:importpandasaspfromadtk.dataimportvalidate_seriesfromadtk.transformerimportDoubleRollingAggregates=pd.read_csv('./data/ec2_cpu_utilization_53ea38.csv',index_col="timestamp",parse_dates=True)s=validate_series(s)s_transformed=DoubleRollingAggregate(agg="median",window=5,diff="diff").transform(s)'diff':减去前者'rel_diff':相对差值聚合指标的值(右减左除左)。仅当聚合指标是标量时才适用。'abs_rel_diff':(back-front)/front,relativedifference'l1':l1regular'l2':l2regular4.2季节性拆解时间序列可以分解为趋势部分、季节性部分和残差部分。atdk中的ClassicSeasonalDecomposition提供了这三部分的拆解,去掉趋势部分和季节部分,返回残差部分。freq:设置季节性周期趋势:可以设置是否保持趋势来自adtk.transformerimportClassicSeasonalDecompositions=pd.read_csv('./data/nyc_taxi.csv',index_col="timestamp",parse_dates=True)s=validate_series(s)s_transformed=ClassicSeasonalDecomposition().fit_transform(s)s_transformed=ClassicSeasonalDecomposition(trend=True).fit_transform(s)4.3降维与重构adtk提供的pca对数据进行降维到主成分PcaProjection和重构方法PcaReconstruction。df=pd.read_csv('./data/generator.csv',index_col="Time",parse_dates=True)df=validate_series(df)fromadtk.transformerimportPcaProjections=PcaProjection(k=1).fit_transform(df)plot(pd.concat([df,s],axis=1),ts_linewidth=1,ts_markersize=3,curve_group=[("速度(kRPM)","功率(kW)"),"pc0"]);fromadtk.transformerimportPcaReconstructiondf_transformed=PcaReconstruction(k=1).fit_transform(df).rename(columns={"Speed(kRPM)":"Speedreconstruction(kRPM)","Power(kW)":"Powerreconstruction(kW)"})plot(pd.concat([df,df_transformed],axis=1),ts_linewidth=1,ts_markersize=3,curve_group=[("Speed(kRPM)","Power(kW)"),("Speedreconstruction(kRPM)","Powerreconstruction(kW)")]);../_images/notebooks_demo_99_0.png5.异常检测算法(detector)adtk主要提供无监督或基于规则的时间序列检测算法,可用于常规异常检测。检测离群值离群值是与正常数据有显着差异的数据点。adtk主要提供检测算法包括adtk.detector.ThresholdADadtk.detector.QuantileADadtk.detector.InterQuartileRangeADadtk.detector.GeneralizedESDTestAD。ThresholdADadtk.detector.ThresholdAD(low=None,high=None)参数:low:下限,小于这个值,认为异常high:上限,大于这个值,认为异常总结:固定阈值算法fromadtk.detectorimportThresholdADthreshold_ad=ThresholdAD(high=30,low=15)anomalies=threshold_ad.detect(s)QuantileADadtk.detector.QuantileAD(low=None,high=None)参数:low:分位数下限,范围(0,1),当low=0.25,表示Q1high:分位数上限,范围(0,1),当low=0.25时,表示Q3原理:通过历史数据计算给定的low和high对应的分位数值Q_low,Q_high,小于Q_low或更大比Q_high,都算异常总结:分位数阈值算法fromadtk.detectorimportQuantileADquantile_ad=QuantileAD(high=0.99,low=0.01)anomalies=quantile_ad.fit_detect(s)InterQuartileRangeADadtk.detector.InterQuartileRangeAD(c=3.0)参数:c:系数分位数范围,用于确定上下限,可以是float或者(float,float)原理:当c为float时,根据历史数据计算Q3+c*IQR作为上限值,大于上限值,被认为是不正常的。当c=(float1,float2)时,(Q1-c1*IQR,Q3+c2*IQR)由历史数据计算为正常范围,不在正常范围内则认为异常。总结:箱线图算法fromadtk.detectorimportInterQuartileRangeADiqr_ad=InterQuartileRangeAD(c=1.5)anomalies=iqr_ad.fit_detect(s)GeneralizedESDTestADadtk.detector.GeneralizedESDTestAD(alpha=0.05)参数:alpha:显着性水平(Significancelevel),alpha越小,表示识别出的异常肯定是真的。异常原理:将样本点的值与样本的均值除以样本的标准差,取最大值,通过t分布计算阈值,通过比较阈值来确定异常值计算步骤。计算步骤简述:设置显着性水平alpha,通常为0.05来指定离群值比例h,如果h=5%,表示50个样本中有2个离群点,计算数据集的均值mu和标准将所有样本的偏差sigma与均值进行比较,取绝对值,再除以标准差,求最大值,得到esd_1。在剩下的样本点重复步骤3,得到hesd计算每个esd值的临界值:lambda_i(使用t分布计算)统计每个esd是否大于lambda_i,大于则认为你异常fromadtk.detectorimportGeneralizedESDTestADesd_ad=GeneralizedESDTestAD(alpha=0.3)anomalies=esd_ad.fit_detect(s)Spike和LevelShift异常的表现形式不是outliers,而是通过与相邻点的比较,即突增或突降adtk提供了adtk.detector.PersistAD和adtk.detector.LevelShiftAD检测方法PersistADadtk.detector.PersistAD(window=1,c=3.0,side='both',min_periods=None,agg='median')参数:window:参考窗口长度,可为int,strc:分位数倍数,用于确定上下限范围side:检测范围,为‘positive’时检测突增,为‘negative’时检测突然下降,当为'both'时,检测突然增加min_periods:参考窗口中的最小数,小于这个数会报异常,默认为None,表示每个时间点必须有一个值agg:参考窗口统计量的计算方法,因为当前值是和参考窗口中产生的统计量进行比较的,所以参考窗口中的数据要作为统计量进行计算。默认为'median',表示参考窗口的中值。将参考窗口中的一位数据与参考窗口中的统计量相差,得到新的时间序列s1;计算s1的(Q1-c*IQR,Q3+c*IQR)为正常范围;如果当前值与其参考窗口的统计差异,不在2中的正常范围内,则视为异常。参数调整:window:模型越大,模型越不敏感,不易被尖峰干扰rangefordatawithsmallbulkationsmin_periods:Yes对缺失值的容忍度越大,越少允许缺失值过多agg:统计的聚合方式与统计的特性有关,比如'median'不易受极值影响总结:先计算一个新的Time序列,然后使用boxplot进行异常检测fromadtk.detectorimportPersistADpersist_ad=PersistAD(c=3.0,side='positive')anomalies=persist_ad.fit_detect(s)LevelShiftADadtk。detector.LevelShiftAD(window,c=6.0,side='both',min_periods=None)参数:window:支持(10,5),表示使用两个相邻的滑动窗口,左边窗口的中值代表参考值,中值在右边窗口代表Currentvaluec:数值越大,波动大的数据正常范围越大,波动小的数据正常范围越小,默认为6.0side:detectionrange,当为'positive',检测骤增,'为负'时,检测骤降,'两者'时,同时检测骤增和骤降。:该模型用于检测突变。与PersistAD相比,其抗抖动能力更强,不易出现adtk.detectorimportLevelShiftADlevel_shift_ad=LevelShiftAD(c=6.0,side='both',window=5)anomalies=level_shift_ad的误报。fit_detect(s)Seasonaladtk.detector.SeasonalADadtk.detector.SeasonalAD(freq=None,side='both',c=3.0,trend=False)SeasonalAD主要根据ClassicSeasonalDecomposition进行处理判断。参数:freq:seasonalcyclec:值越大,波动大的数据正常范围越大,波动小的数据正常范围越小,默认6.0side:detectionrange,'positive'时检测突增,为‘negative’时检测突降,为‘both’时检测突增突降趋势:是否考虑趋势fromadtk.detectorimportSeasonalADseasonal_ad=SeasonalAD(c=3.0,side="both")anomalies=seasonal_ad.fit_detect(s)plot(s,anomaly=anomalies,ts_markersize=1,anomaly_color='red',anomaly_tag="marker",anomaly_markersize=2);管道组合算法fromadtk.pipeimportPipelinesteps=[("deseasonal",ClassicSeasonalDecomposition()),("quantile_ad",QuantileAD(high=0.995,low=0.005))]pipeline=Pipeline(steps)anomalies=pipeline.fit_detect(s)plot(s,anomaly=anomalies,ts_markersize=1,anomaly_markersize=2,anomaly_tag="marker",anomaly_color='red');6.总结本文介绍了ADTK,一种用于时间序列异常检测的无监督算法工具包。ADTK提供了简单的异常检测算法和时序特征处理函数,希望对你有所帮助。总结如下:adtk要求输入数据为datetimeIndex,validate_series来验证数据的有效性,这样时序adtk单窗口双窗口滑动,处理统计特征adtk分解时间序列的季节部分,并得到时间序列的残差部分,可以根据这个判断异常值得到,adtk支持异常值、变异和季节异常检测。通过fit_detect获取异常点序列,或者通过Pipeline连接多个异常检测算法
