商品异动检测-kats算法实现

背景

为服务好xx战役,需要对各个xg类目的表现情况做好监控,为此工程侧期望能够沉淀出一套异动情况、异动原因的快速/准确的反馈、归纳以及对未来是否还能维稳的预测能力。本次主要是以爆品商品订单的持续异常下滑为切入点,做订单异动检测算法工程化的设计。

异动检测能力工程化目标

  • 趋势变化检测:加速放缓、跌速增加

  • 趋势拐点检测:在某个时间点趋势发生变化

  • 时序异常检测:检测时序数据中的异常点

  • 趋势差异检测:比如某些品类商品的变化趋势和其他的明显不同

业界相关产品/算法调研

在相对完善的指标体系建设背景下,我们需要通过指标以及指标波动的解读来描述、追踪、推动业务。当一个指标波动时,首先需要从业务视角判断其波动是否异常,即异动检测;其次判断异常背后的原因是什么,即异动归因。

弹内相关产品调研

脱敏

 

业界公认算法

常用的时序算法包括经典的时序统计模型ç, 异常检测模型Isolation Forest,深度学习模型AutoEncoder,以及工业界模型greykite/luminol(LinkedIn), Propet/Kats(Meta), Twitter-AD(Twitter), SR-CNN(Microsoft)

优劣势对比

算法按照数据要求、适用范围、精度、计算速度、准确度、计算速度、可解释性、算法灵活性几个维度做比较:

算法数据要求适用范围精度计算速度准确度可解释性算法灵活性
Arima小规模数据
Isolation Forest大规模数据
AutoEncoder各种类型的数据
Greykite/Luminol(LinkedIn)大规模数据
Propet/Kats(Meta)大规模数据
Twitter-AD(Twitter)大规模数据
SR-CNN(Microsoft)大规模数据
  • 数据要求方面,Arima、AutoEncoder和SR-CNN的数据要求较高,而Isolation Forest和Twitter-AD的数据要求较低。

  • 适用范围方面,Greykite/Luminol、Propet/Kats和Isolation Forest适用于大规模数据,Arima适用于小规模数据,AutoEncoder适用于各种类型的数据,而Twitter-AD适用于中等规模的数据。

  • 精度方面,AutoEncoder和SR-CNN的精度较高,Isolation Forest和Greykite/Luminol的精度处于中等水平,Arima和Propet/Kats的精度较低。

  • 计算速度方面,Isolation Forest和SR-CNN的计算速度较快,而Greykite/Luminol、Propet/Kats和Arima的计算速度较慢。

  • 准确度方面,Isolation Forest和AutoEncoder的准确度较高,而其他算法的准确度则处于中等水平。

  • 可解释性方面,Propet/Kats和AutoEncoder的可解释性较高,而Greykite/Luminol、Twitter-AD和SR-CNN的可解释性较低。

  • 算法灵活性方面,Greykite/Luminol、Propet/Kats和Twitter-AD的灵活性较高,而其他算法的灵活性则处于中等水平。

数据集验证

img

结论

Kats+STL分解:对于季节性变化较为明显的订单指标,可以使用Kats中的STL分解算法进行异常检测。该算法将时间序列分解为三个部分:季节性、趋势性和残差部分,从而更好地进行异常检测

应用算法简单介绍

Prophet是Meta推出的时间序列预测的开源库,其背后的原理是基于回归中的可加模型, 另外用分段线性或逻辑增长曲线模拟时序的趋势,用傅里叶级数模拟年周期,用虚拟变量模拟周周期,以及考虑了假期/事件对时序的影响。它适用于具有周期性和假期时间影响的时间序列, Prophet 对缺失数据和趋势变化具有鲁棒性,并且通常可以很好地处理异常值。 因为其提供统计显著及置信区间, 如果实际值在置信区间之外,可判断为是异常值。 所以其工具也可作为异常检测手段使用。

随后,Meta数据科学团队开发了一个叫Kats的Python工具包,将一系列的时序模型打包成可以复用的框架,以便使用者在上面进行一站式的时间序列分析:包含变点/异常值/趋势识别、时序预测、特征提取/嵌入、多变量分析等等。

总体方案设计

img

img

方案

脱敏

算法报告

数据集

取直营最近一天的爆品商品近30天的每日订单数据做算法输入

  • 输入:xxxx.item_ord_detection_kats_algo_input(约3500个爆品)

  • 输出:xxxx.item_ord_detection_kats_algo_res_opt

本报告基于kats支持的几种异常检测器来开展:

img

各检测算法&脚本

官方算法文档:https://github.com/facebookresearch/Kats/blob/v0.2.0/tutorials/kats_202_detection.ipynb

img

CUSUMDetector 异常点检测

CUSUM是一种检测时间序列中均值上升或下降变化的方法。实现有两个主要步骤:

  • Locate变化点:这是一个迭代过程,在时间序列的中间初始化一个变化点和CUSUM时间序列。下一个变化点是先前的CUSUM时间序列最大化(或最小化)的位置。这个迭代过程会一直持续,直到找到一个稳定的变化点或超过迭代次数的限制。

  • Test变化点的统计学意义。进行对数似然比检验,以测试在步骤1中计算出的变化点是否存在时间序列均值的变化。零假设是均值不变。默认情况下,只有在步骤2中拒绝零假设时,我们才会报告检测到的变化点。

CUSUMDetector具体可调试参数(标黄重点调试):

参数key含义默认值/类型
threshold阀值0.01/float
max_iter寻找变化点的最大迭代次数10/int
delta_std_ratio平均值之差必须大于数据的标准差乘以这个参数才能被视为变化1.0/float
min_abs_changemu0和mu1之间的最小绝对差值(mu0: 变化点之前的平均值;mu1: 变化点之后的平均值;)0/int
start_point变化点的起始索引None/Optionalint
change_directions一个包含“increase”和/或“decrease”的列表,用于指定要检测的变化类型None/Optional[List[str]]
interest_window一个包含兴趣窗口的起始和结束位置的列表,在该窗口中寻找变化点None/Optional[Tuple[int, int]]
magnitude_quantile大小比较的分位数None/Optionalfloat
magnitude_ratio可比较的比率1.3/float
magnitude_comparable_day可以具有可比较大小的最大天数的百分比,以便被视为回归0.5/float
return_all_changepoints返回发现的所有变化点,即使是不显著的。False/bool
单突变点检测脚本
多突变点检测脚本

BOCPDetector 贝叶斯异常区间检测

贝叶斯在线变点检测(BOCPD)是一种用于检测时间序列中持续存在突变的方法。实现基于论文《Bayesian Online Changepoint Detection》(Adams&McKay,2007)。

有几个特性将BOCPD与Kats支持的其他变点检测方法区分开来:

  • 在线模型:这种检测不需要预先知道整个序列。它只需要向前查看几步(由检测器方法中的滞后参数指定)进行预测,并在新数据到达时修正预测。

  • 贝叶斯模型:用户可以指定关于变点概率的先验信念(使用检测器方法中的changepoint_prior参数),并指定生成时间序列的潜在概率模型的参数(使用检测器方法中的model_parameters参数)。目前,我们支持三种不同类型的潜在概率模型(使用检测器方法中的model参数指定)。

BOCPD检测方法的基本思想是使用贝叶斯推理来判断下一个点是否为变点。这要求用户指定(或使用默认值)变点概率和生成时间序列中传入数据点的潜在预测模型(UPM)。目前算法支持三种不同类型的潜在模型:

  • 正态分布(未知均值,已知方差)

  • 趋势变化分布

  • Poisson过程模型

BOCPDetector具体可调试参数(标黄重点调试):

参数key含义默认值/类型
model生成每个段内数据的潜在概率模型NORMAL_KNOWN_MODEL:已知方差的正态模型。使用此模型查找通常分布数据中的水平移位。TREND_CHANGE_MODEL:该模型假设每个段都是由普通线性回归生成的。使用此模型了解时间序列中的斜率或趋势的变化。POISSON_PROCESS_MODEL:这假设Poisson生成模型。将其用于计数数据,其中大多数值接近于零
model_parameters模型参数对应于特定模型的特定参数模型对应的参数体:NormalKnownParameters,TrendChangeParameters,PoissonModelParameters
lag指向检测变点的滞后。在看到“滞后”数量的数据点后报告变点。更高的滞后会更确定这确实是一个变点。较低的滞后将更快地检测到变点。这是一个权衡。10/int
changepoint_prior这是一种贝叶斯算法。此参数指定了给定点是变点的先验概率True/bool
threshold在每个时刻报告观察变点的概率,通过将超过此阈值的点标记为变点来获得实际的变点0.5/float
debug允许用户查看为什么变点未能正确检测的调试信息False/bool
检测脚本

RobustStatDetector多突变点检测

RobustStatDetector是一种变点检测算法,类似于CUSUMDetector,用于发现均值变化。其工作方式如下:

  1. 使用移动平均法对时间序列进行平滑处理;

  2. 计算平滑时间序列中一定数量的数据点(由detector方法中的comparison_window参数指定)之间的差异;

  3. 计算差异的z-scores和p-values。返回p-value小于预定阈值的点(由detector方法中的p_value_cutoff参数指定);

  4. 与CUSUMDetector不同,RobustStatDetector可以在单次运行中检测多个变点。

RobustStatDetector具体可调试参数(标黄重点调试):

参数key含义默认值/类型
p_value_cutoff标记变点的p-value阈值1e-2/float
smoothing_window_size平滑窗口的长度5/int
comparison_windowdiff函数的步长,即算法查看多少数据点来进行比较。-2/int
检测脚本

OutlierDetector离群点检测

Kats提供了OutlierDetector模块来检测时间序列中的异常值。由于异常值可能会在下游处理中引起很多问题,因此能够检测它们非常重要。OutlierDetector还提供了处理或删除找到的异常值的功能。

异常值检测算法如下:

  1. 对输入时间序列进行季节分解,使用指定的加法或乘法分解(默认为加法)。

  2. 通过仅删除趋势或删除趋势和季节性(如果季节性很强)来生成残差时间序列。

  3. .检测残差中超出3倍四分位距的点。可以使用OutlierDetector中的iqr_mult参数调整此乘数。

OutlierDetector具体可调试参数(标黄重点调试):

参数key含义默认值/类型
decomp加法或乘法'additive'/str
iqr_mult四分位距上的乘数用于分类异常值3.0/float
检测脚本

MultivariateAnomalyDetector跨时序检测

MultivariateAnomalyDetector异常检测方法非常适用于跨多个时间序列检测异常。异常是基于与预测稳定状态行为的偏差检测出来的。通过使用向量自回归(VAR)模型对时间序列之间的线性相互依赖关系进行建模,可以预测指标系统的稳定状态行为。这种方法尤其适用于检测多变量异常 - 即在多个时间序列中持续存在的小异常

检测脚本

检测结果比对

算法参数

详情见脚本:kats2_1.py(直营爆品近30天口径)

策略
  • Base策略:基于置信度confidence倒序取大于0.7的检测结果

  • 策略1:各检测算法结果的交集/并集

  • 策略2:部分检测算法结果的并集+部分检测算法结果的交集

数据&分析
商品id检测结果解析
628032051803imgCUSUMDetector单突变点检测出的日期:0611; CUSUMDetector多突变点检测出日期:0611,0621;OutlierDetector离群点检测出0609、0611
610295940401imgCUSUMDetector单突变点检测出的日期:0703; CUSUMDetector多突变点检测出日期:0619,0621;RobustStatDetector离群点检测出0628
620189523811imgCUSUMDetector多突变点检测出日期:0630;RobustStatDetector离群点检测出0630、0702、0703

生产检测链路

img

  • 核心脚本