指标与业务息息相关,其价值在于发现问题和发现亮点,以便及时地解决问题和推广亮点。随着电商业务的进一步发展,业务迭代快、逻辑复杂,指标的数量越来越多,而且指标之间的差异非常大,变化非常快,如何能够快速识别系统各项异常指标,发现问题的根因,对业务来说至关重要。如果通过手动的方式去设置报警阈值容易出现疏漏,且非常耗时,成本较高。我们希望构建一套自动化方法,能够达成以下目标:
接下来将分别介绍指标异常检测、指标异常诊断。
数据科学工作的第一步是对问题进行定义。我们对异常的定义是数据指标的异常,指标的过高过低、大起大落都不正常,都需要进行预警和诊断。指标的异常分为以下三种:
指的是不遵循指标固有的分布,在统计学上的离群点,它反映的是业务当下的状态。
环比过大的突增点或者突降点,反映的是业务当下突然的变化。
前两种异常是偏单点的,是短暂剧烈的,而有些异常则相对隐蔽,是在中长期呈现出确定性上升或者下降的趋势,往往预示着某些潜在的风险,所以我们也要进行趋势的异常检测,进行业务预警和提前干预。
这三种异常是相互独立的,不同的场景可能对应不同类型的异常。
比如上图中A点同时发生了绝对值异常和波动率异常,B点因为与上一天的环比变化不大,所以只报了绝对值异常。C点和D点都只报了波动异常,但是其原因是不一样的,C点指标突降的原因是由B点造成,属于指标的正常回落,这种需要通过后处理逻辑解决。
为了实现指标检测的通用性、自动化以及时效性,我们设计了一套基于统计检验的无监督检测框架。
首先绝对值检测主要是基于GESD 检验算法,它的原理是通过计算统计量来寻找异常点。过程如下:
假设数据集中有最多r个异常值。第一步先找到离均值最大的样本i,然后计算统计量Ri,即xi 减去均值后的绝对值,除以标准差。接下来计算对应的样本点i的临界值λi,其中的参数,n 是总共的样本量,i是已剔除的第几个样本,t是具有 n-i-1自由度的t 分布的p 百分点,而p与设定的置信度α(一般α取值为0.05)及当前样本量有关。
第二步是通过剔除离均值最大的样本i,然后重复上面步骤,一共r次。
第三步寻找统计量 Ri 大于λi的样本,即为异常点。
这种方法的优点,一是无需指定异常值的个数,只需要设定异常的上限,在上限范围内,算法会自动捕捉异常点;二是克服了3Sigma检出率过低(小于1%),只能检出非常极端异常的问题。
在GESD算法中可以通过控制检出率的上限去做适应,但是这个方法的前提是要求输入的指标是正态分布。我们目前观测的电商业务指标绝大多数是属于正态分布的,当然也有个别业务指标(
第二种是波动异常检测,主要是基于波动率分布,计算分布的拐点。这里不能直接对波动率分布套用上面的办法,主要是因为指标波动率绝大多数不是正态分布所以不适用。找拐点的原理是基于二阶导数和距离来寻找曲线上的最大弯曲点。增长的波动率大于 0,下降的波动率小于 0,针对在 y 轴两侧大于 0 和小于 0 的部分,分别要找两个波动率的拐点,波动率超出拐点的范围,就认为是波动异常。但个别情况下拐点会不存在,或者拐点来得太早,导致检出率太高,所以也需要其他的方法来兜底,如quantile。一种检验方法不是万能的,需要组合来使用。
第三种是趋势异常检测,基于Man-Kendall检验。先计算统计量S, 其中sgn 是符号函数,根据指标序列前后值的相对大小关系,两两配对可以得到 -1、1、0 这样3个映射值。对统计量S做标准化,就得到了Z,可以通过查表的方式换算到p值。统计学上当 p 值小于 0.05,就认为有显著性的趋势。
它的优点一是非参数检验,即可以适用于所有的分布,因此不需要兜底方法。优点二是不要求指标序列连续,因为在进行趋势异常检测的时候,需要事先剔除绝对值异常的样本,所以大多数指标序列并不连续,但这个方法是可以支持指标不连续的。
三种异常结束之后,需要进行后处理的工作,其目的主要是减少不必要的报警,降低对业务的打扰。
第一种是数据异常,这的数据异常不是指数据源出错了,因为数据源是在数仓层面,由数仓团队来保证。这里的数据异常指的是上周期的异常导致了本周期的波动异常,比如某个指标昨天上涨了100%,今天又下降了50%,这种情况就需要基于规则来进行剔除,剔除的条件就是(1)上个周期存在波动或绝对值异常(2)本周期的波动属于回归正常的,即有波动异常但无和波动异常同向的绝对值异常。比如昨天上涨了100%,今天下降 50% ,经后处理模块会过滤掉,但是如果下降了99%,此时触发了绝对值异常还是需要预警的。通过这种方式我们一共剔除了40% 以上的波动异常。
第二种后处理是基于S级大促的信息协同,这种大促中每个小时都可能会出现指标的异常,大家都知道原因,因此没有必要去进行播报。
根据结论的可行域和确定性,可以将推断分为三个层次,即确定性推断、可能性推断和猜测性推断。
不同推断层次对应着不同的诊断方法。
猜测性推断,结论主要依赖人的经验,结论相对不明确,可操作空间有限,不在本文的方法讨论范围之内。
可能性推断,(1)可以基于机器学习去拟合指标数据,做回归预测,计算特征的重要性,这种方法的缺点是不能解释单次异常的原因。(2)如果想解释单次的异常要加上一个 shap value 算法,它可以计算每一次预测值,每一个输入特征对于目标的贡献值。这种方法具有一定的可解释性,但是不够精准,而且只能得出相关性,并非因果性。(3)可以通过贝叶斯网络来构建指标间关系的图和网络,但缺点是计算相对复杂,并且黑盒。
确定性推断,主要是基于拆解贡献度算法。拆解贡献度算法不管是加法、乘法还是除法,都是按照拆解方式来衡量各部分指标或者结构的变化对整体的影响。优点是确定性比较强,白盒化,适应性比较强,能够精准定位到异常所在的位置。但是它也存在其天然的缺点,就是针对同一个指标,有非常多的维度可以去拆解,会带来组合维度爆炸的问题。
数据科学的很多问题都需要结合业务的实际场景来选择相应的方法。因此在介绍我们的方法之前,先来介绍一下业务现状。
我们知道,平台电商的增长方式是由流量留存和付费转化来驱动的。随着人口红利见顶,流量获取日趋困难,网易严选进行了战略升级,由平台电商转型成为品牌电商,将京东、淘宝等平台电商转变成品牌合作伙伴。
而品牌电商的增长驱动方式是通过全渠道协同爆品突围,塑造明星品类来立住品牌。比如大家了解网易严选不一定是通过我们的APP,可能是通过淘宝、京东上买了一些商品从而了解到我们这个品牌。网易严选的增长视角从围绕用户的拉新、留存、付费,转化为了围绕爆品商品的打造和渠道的突破增长。
品牌电商的指标分级可以分为战略层、战术层、执行层。战略层对应的是一级指标,即北极星指标。比如大盘的GMV,它衡量的是目标的达成情况,服务于公司的战略决策。战术层对应的是二级指标,是通过将一级指标分拆到各级部门和业务线得到的,服务的是过程管理。执行层对应的是三级指标,是将二级指标进一步拆分到各级类目商品以及负责人,服务具体实施。
基于目前品牌电商的这种指标分级方式,以及需要定位到部门、人、商品这样的需求,所以需要我们的算法具有确定性、可解释性和白盒化。因此我们采用了基于拆解的方式,计算每一层每部分的指标对于整体的影响占比,也就是前面提到的拆解贡献度方法。
贡献度的计算方式包括三种,一类是加法,一类是乘法,还有一类是除法。
拆解方法如上图中所示。Y是要进行拆解的目标指标,比如大盘的GMV,Xi是其下某个拆分维度下第 i 个维值,比如某个省市的GMV,Xi1 代表当前周期的指标,Xi0 表示上一个周期的原始值。
加法的拆解公式很好理解,每个维值的变化值ΔXi除以整体的原始值Y0,就是它的贡献度。
乘法拆解采用了LMDI(Logarithmic Mean Index Method)乘积因子拆解的方式。两边同时取对数ln,即可得到加法形式,再按照上述方法,就可以得到各因子的贡献度。维值的前后比率比较大,贡献度就比较大。
除法采用双因素拆解方法,即每一个部分、每一个维值对整体的贡献度是由两个因素构成。第一个因素是波动贡献,用AXi 表示;第二个因素是结构变化贡献BXi,即每部分的结构变化贡献。举个例子,每个部门的毛利率都提升了但整个公司的毛利率却下降了。原因大概率就是某个低毛利的部门销售占比变大了,拖垮了整体,也就是我们熟知的辛普森悖论的情况。除法拆解算法中,引入BXi这部分结构变化的贡献,就能够解决这个问题。
贡献度的一个很重要的特性就是可加性,满足 MECE 不重不漏的原则。不管哪种拆解方式,把某个拆解维度下的全部维值贡献 CXi进行加和,都可以得到整体的变化率ΔY%。
假设我们对某个一级指标的异常原因进行拆解,比如销售额或者毛利额等等,拆分的维度可以是销售渠道或省市地区,也可以按照商品的品类、新老客等。假设有 n 种拆分维度,那么就需要生成 n 个维度对应的中间表,然后针对每个维度下面的每一个维度值Xi,去计算指标变化,才能得到其贡献度。
为了精准地找到指标异常的原因,面临的问题是只拆单个维度,只能得到该维度的结论,定位不到精准的问题所在。如果拆解的维度太细,比如把所有的维度都进行组合,那每一项的贡献度又太小,还是无法得到主要的原因。所以这里需要层层的下钻和穷举,在各种维度组合中搜索我们想要的结论。
假设目前有 n 种拆分维度,那么就需要首先建立2n个中间表,建立中间表的过程中要确保口径一致,并满足数仓规范,工作量是非常大的。建好这些中间表之后,再分别调用拆解算法的API计算相应的贡献度,这就产生了非常大的计算和存储消耗,即维度爆炸的问题。
为了解决维度爆炸的问题,对实现方案进行了以下优化:
优化1:把维度拆解的流程转变为基于贡献度聚合。前文中提到,因为贡献度具有可加性,首先调用一次算法计算最细粒度的末级指标的贡献度,然后需要哪个维度的贡献度,就用它去做 group by 条件对贡献度求和。这样能够省略中间表的 IO 过程,只需要一次算法调用,在集群上执行求和操作也会比调用指标拆解算法快得多。
上述是针对一级指标进行的异常诊断,我们实际业务中还需要对二级指标进行诊断,这种方法只需要再对贡献度做一次归一化即可,不需要重复计算,可以针对一级、二级指标同时进行异常诊断。
计算效率的问题得以解决,但仍存在一个问题,即结果的空间复杂度非常大,达。假设k是平均每个维度下的维值个数,单维度拆解空间+ 双维度拆解空间+ 三维度拆解空间+ n维度拆解空间=。
优化2:根据实际业务需要限制维度组合实现剪枝,将结果的空间复杂度从降至
图片
以内。具体包括两个操作,第一个是对维度进行分组,对于具有天然层次关系的维度,比如一级渠道和二级渠道,如果拆到二级渠道,其实一级渠道信息已经有了,就不用对一级渠道和二级渠道进行冗余的组合了,只需要对于跨组的维度进行组合就可以了。第二个是限制维度组合的维数,因为在归因诊断分析的时候,实际业务不会关注到特别复杂的维度上去,一般由两三个维度组合起来就够用了。
优化3:基于维度基尼系数排序,确定最佳维度,实现异常精准定位。有了剪枝后的若干拆分度以及对应的维值贡献度,如何才能优中选优,定位到主要原因呢?直观的想法就是某个维度的粒度越细,且头部top维值贡献度越大,就越可能是指标异常的最主要原因。基尼系数是比较适合这个场景的度量方式,用1减每一部分的贡献度的平方和越小,说明拆分维度越合理。
上图右侧举了1个例子,针对某次销量异常,第一种按商品维度去拆,因为每个商品的贡献度太小,所以基尼系数非常大。第二种按照二级渠道的粒度去拆,粒度比较粗,算出来的基尼系数可能是一个比较大的值。第三种按照一级行业叉乘二级渠道去算,基尼系数很有可能更小,因为二级渠道再下钻一层,有的部分出现了正的贡献度,有的部分出现了负的贡献度。正的贡献度就是对于指标的波动有正向积极作用的部分,负向贡献度就是有负向作用的。在这个例子中可以看到拆分维度行业1叉乘渠道1贡献度60%,被归为主因,也是比较符合我们认知的。所以通过基尼系数我们能够找到较为合理的拆分维度和导致指标异常的主因。
A1: 因为我们用的是确定性诊断,结论是非常明确的。如果从单纯指标这个层面来看,是通过计算写代码实现来保证准确率的。如果从业务理解的角度,比如这次异常是因为某个业务进行了某个正常的操作,或者因为其他原因导致误报或漏报,这种情况是通过收集 badcase的方式来进行准确率的评估。
A2: 这是一个非常好的实践上的问题。首先,加法和乘法混合使用这个思路是可行的,可以采用贪心地方式去搜索,算出来每一步的TOP维度值对应贡献度及下一步拆解后的贡献度,结合贡献度下降的多少来确定下一步是通过加法的拆解,还是通过乘法来拆解。
另外一种思路是先按照某一个方向,比如针对电商GMV,可以先通过加法来进行拆解,不断地拆解,拆解到最底层,比如某个商品,再对这个商品进行乘法拆解,这个商品为什么 GMV 下跌了,是流量下跌了还是转化率下跌了等等。具体的做法需要结合实际中不同的业务需求,以及时效性、开发成本等方面的考虑。
在网易严选目前的场景中,考虑到通用性以及业务现状,作为品牌电商,在外渠售卖的时候,流量、转化率等因素对于我们来讲是黑盒的,所以在我们的业务场景中,主要是以加法拆解为主。
以上是网易如何做到数据指标异常发现和诊断分析?的详细内容。更多信息请关注PHP中文网其他相关文章!