最近做异常检测,基于基线进行异常判断,可是用到了好多算法,如,3sigma、箱线图、MAD等,但是显示数据来了,哥哥算法暴露出了缺陷。
下限可以做某习惯的基线,以下为异常,以上为正常
上限可以做某频率的基线,以下为正常,异常为异常
1、3sima
lower = mean + 3*sigma high = mean - 3*sigma
讯享网
讯享网def get_3sigma(samples_list): men = np.mean(samples_list) sigma = np.std(samples_list) low_limit = men - 3 * sigma high_limit = men + 3 * sigma return [low_limit, high_limit] 3sigma data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4], range:[0.6914, 7.3086] data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4, 100], range:[-58.075, 77.51] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 5, 4, 5, 5, 4, 100], range:[-58.08, 77.61] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 6, 4, 6, 6, 4, 100], range:[-58.009, 77.897] data:[4, 4, 4, 46, 4, 4, 4, 34, 4, 0, 4, 6, 4, 6, 6, 24, 100], range:[-58.068, 88.126] data:[4, 4, 5, 100], range:[-96.03, 152.33] data:[1, 0, 8, 100], range:[-99.072, 153.772] data:[1, 3, 3, 6, 8, 10, 10, 1000], range:[-856.81, 1116.8] data:[1, 100], range:[-98.0, 199.0] data:[1, 1, 100], range:[-106.00, 174.00] data:[0, 0, 0, 3, 0, 0], range:[0, 3.96847] data:[0, 0, 0, 3, 3, 0], range:[0, 5.9286]
接近正态分布的时候表现优秀。
当分布不是正态分布的时候,或者数据量很少的时候,方差非常大,导致上下界严重不合理。
下限出现了负值,上限也异常的大。
2、箱线图
IQR = Q3-Q1 lower = Q1 - 1.5*IQR high = Q3 + 1.5*IQR
讯享网def tukey_box(samples_list): q2 = np.quantile(samples_list, 0.5) q1 = np.quantile(samples_list, 0.25) q3 = np.quantile(samples_list, 0.75) q4 = np.quantile(samples_list, 1.0) iqr = q3 - q1 left = q1 - 1.5 * iqr right = q3 + 1.5 * iqr return left, right tukey_box data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4], range:(2.5, 6.5) data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4, 100], range:(2.5, 6.5) data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 5, 4, 5, 5, 4, 100], range:(4.0, 4.0) data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 6, 4, 6, 6, 4, 100], range:(4.0, 4.0) data:[4, 4, 4, 46, 4, 4, 4, 34, 4, 0, 4, 6, 4, 6, 6, 24, 100], range:(1.0, 9.0) data:[4, 4, 5, 100], range:(-33.125, 65.875) data:[1, 0, 8, 100], range:(-44.625, 76.375) data:[1, 3, 3, 6, 8, 10, 10, 1000], range:(-7.5, 20.5) data:[1, 100], range:(-48.5, 149.5) data:[1, 1, 100], range:(-73.25, 124.75) data:[0, 0, 0, 3, 0, 0], range:(0, 0.0) data:[0, 0, 0, 3, 3, 0], range:(0, 5.625)
数据分布均匀,数据种类众多的时候,表现优秀。
同样存在IQR过大的情况,并且当众数过多的时候,上下限值严重不合理
参考:异常值检测方法-箱线图(boxplot)
3、MAD
def get_mad_range(samples_list): med = np.median(samples_list, axis=0) abs_dev = np.absolute(samples_list - med) med_abs_dev = np.median(abs_dev) mad = 1.4826 * med_abs_dev low_limit = med - 3 * mad high_limit = med + 3 * mad return [low_limit, high_limit] mad_range data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4], range:[4.0, 4.0] data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4, 100], range:[4.0, 4.0] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 5, 4, 5, 5, 4, 100], range:[4.0, 4.0] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 6, 4, 6, 6, 4, 100], range:[4.0, 4.0] data:[4, 4, 4, 46, 4, 4, 4, 34, 4, 0, 4, 6, 4, 6, 6, 24, 100], range:[4.0, 4.0] data:[4, 4, 5, 100], range:[2.2761, 6.7239] data:[1, 0, 8, 100], range:[-13.2912, 22.2912] data:[1, 3, 3, 6, 8, 10, 10, 1000], range:[-8.5673, 22.5673] data:[1, 100], range:[-169.6661, 270.003] data:[1, 1, 100], range:[1.0, 1.0] data:[0, 0, 0, 3, 0, 0], range:[0, 3.96847] data:[0, 0, 0, 3, 3, 0], range:[0, 5.9286]
选择算法的时候,本以为MAD方法是个完美的算法,可是还是出了问题。
MAD算法的下限值比较不错,但是也有不如意的,会出现负值,这里我们可以进行下限约束>=0:
讯享网low_limit = med - 3 * mad if med - 3 * mad > 0 else 0
上限值遇到众数比较多的时候,MAD=0,因此上限值=median中位数,例如第1-4条数据:
上下限都为4,当出现5的时候就是异常了,按照异常检测场景,这里是不合理的。
参考:异常检测方法-MAD
4、优化
试过的组合:
- 3*sigma+tukey_box
- MAD+tukey_box
- MAD+mean
- MAD+median
- MAD+1*sigma
- MAD+2*sigma
- MAD+3*sigma
结果MAD+2*sigma表现**,原理上分析,当MAD=0时,MAD算法的上限不合理,这时众数偏多,并且接近正态分布,因此当MAD=0的时候,上限值用2*sigma替代。
MAD+2*sigma代码:
def get_mad_range(samples_list): med = np.median(samples_list, axis=0) abs_dev = np.absolute(samples_list - med) med_abs_dev = np.median(abs_dev) mad = 1.4826 * med_abs_dev low_limit = med - 3 * mad if med - 3 * mad > 0 else 0 high_limit = med + 3 * mad if mad != 0 else np.mean(samples_list) + 2 * np.std(samples_list) return [low_limit, high_limit] mad_range data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4], range:[4.0, 7.3086] data:[4, 4, 4, 4, 4, 5, 4, 4, 5, 0, 4, 5, 4, 5, 5, 4, 100], range:[4.0, 77.51] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 5, 4, 5, 5, 4, 100], range:[4.0, 77.61] data:[4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 6, 4, 6, 6, 4, 100], range:[4.0, 77.897] data:[4, 4, 4, 46, 4, 4, 4, 34, 4, 0, 4, 6, 4, 6, 6, 24, 100], range:[4.0, 88.126] data:[4, 4, 5, 100], range:[2.2761, 6.7239] data:[1, 0, 8, 100], range:[0, 22.2912] data:[1, 3, 3, 6, 8, 10, 10, 1000], range:[0, 22.5673] data:[1, 100], range:[0, 270.003] data:[1, 1, 100], range:[1.0, 174.00] data:[0, 0, 0, 3, 0, 0], range:[0, 2.979] data:[0, 0, 0, 3, 3, 0], range:[0, 3.61903]
优秀!完美!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/45755.html