社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

【机器学习】异常检测算法之(HBOS)-Histogram-based Outlier Score

机器学习初学者 • 3 年前 • 395 次点击  

HBOS全名为:Histogram-based Outlier Score。它是一种单变量方法的组合,不能对特征之间的依赖关系进行建模,但是计算速度较快,对大数据集友好,其基本假设是数据集的每个维度相互独立,然后对每个维度进行区间(bin)划分,区间的密度越高,异常评分越低。理解了这句话,基本就理解了这个算法。下面我专门画了两个图来解释这句话。

一、HBOS算法流程

1、静态宽度直方图

标准的直方图构建方法,在值范围内使用k个等宽箱,样本落入每个箱的频率(相对数量)作为密度(箱子高度)的估计,时间复杂度:O(n)
注意:等宽分箱,每个箱中的数据宽度相同,不是指数据个数相同。例如序列[5,10,11,13,15,35,50,55,72,92,204,215],数据集中最大值是215,最小值是5,分成3个箱,故每个箱的宽度应该为(215-5)/3=70,所以箱的宽度是70,这就要求箱中数据之差不能超过70,并且要把不超过70的数据全放在一起,最后的分箱结果如下:
箱一:5,10,11,13,15,35,50,55,72;箱二:92;箱三:204,215

这个是分5箱的图

2、动态宽度直方图

首先对所有值进行排序,然后固定数量的N/k 个连续值装进一个箱里,其 中N是总实例数,k是箱个数,直方图中的箱面积表示实例数,因为箱的宽度是由箱中第一个值和最后一个值决定的,所有箱的面积都一样,因此每一个箱的高度都是可计算的。这意味着跨度大的箱的高度低,即密度小,只有一种情况例外,超过k个数相等,此时允许在同一个箱里超过N/k值,时间复杂度:O(n×log(n))
还是用序列[5,10,11,13,15,35,50,55,72,92,204,215]举例,也是假如分3箱,那么每箱都是4个,宽度为边缘之差,第一个差为15-5=10,第二差为72-35=37,第三个箱宽为215-92=123,为了保持面积相等,所以导致后面的很矮,前面的比较高,如下图所示(非严格按照规则):

二、算法推导过程

对每个维度都计算了一个独立的直方图,其中每个箱子的高度表示密度的估计,然后为了使得最大高度为1(确保了每个特征与异常值得分的权重相等),对直方图进行归一化处理。最后,每一个实例的HBOS值由以下公式计算:
推导过程:
假设样本p第 i 个特征的概率密度为p i ( p ) ,则p的概率密度可以计算为,d为总的特征的个数:
两边取对数:
概率密度越大,异常评分越小,为了方便评分,两边乘以“-1”:
最后可得:

PyOD是一个可扩展的Python工具包,用于检测多变量数据中的异常值。它可以在一个详细记录API下访问大约20个离群值检测算法。

三、应用案例详解

1、基本用法

from pyod.models.hbos HBOSHBOS(       n_bins=10,        alpha=0.1,        tol=0.5,        contamination=0.1       )

2、模型参数

n_bins:分箱的数量
alpha:用于防止边缘溢出的正则项
tol:用于设置当数据点落在箱子外时的宽容度
contamination:用于设置异常点的比例
3、应用案例
#导入包from pyod.utils.data import generate_data,evaluate_print
# 样本的生成X_train, y_train, X_test, y_test = generate_data(n_train=200, n_test=100, contamination=0.1)
X_train.shape(200, 2)
X_test.shape(100, 2)
from pyod.models import hbosfrom pyod.utils.example import visualize
# 模型训练clf = hbos.HBOS()clf.fit(X_train)y_train_pred = clf.labels_y_train_socres = clf.decision_scores_
#返回未知数据上的分类标签 (0: 正常值, 1: 异常值)y_test_pred = clf.predict(X_test) # 返回未知数据上的异常值 (分值越大越异常)y_test_scores = clf.decision_function(X_test)
print(y_test_pred)array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
print(y_test_scores)array([1.94607743, 1.94607743, 1.94607743, 3.18758465, 2.99449223, 1.94607743, 3.18758465, 2.99449223, 1.94607743, 3.18758465, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 3.18758465, 3.18758465, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 1.94607743, 2.99449223, 2.99449223, 3.18758465, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 3.18758465, 3.18758465, 1.94607743, 1.94607743, 1.94607743, 2.99449223, 3.18758465, 2.99449223, 1.94607743, 1.94607743, 3.18758465, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 2.99449223, 1.94607743, 2.99449223, 1.94607743, 3.18758465, 3.18758465, 1.94607743, 2.99449223, 2.99449223, 1.94607743, 1.94607743, 1.94607743, 1.94607743, 2.99449223, 1.94607743, 3.18758465, 1.94607743, 6.36222028, 6.47923046, 6.5608128 , 6.52101746, 6.36222028, 6.52015473, 6.44010653, 5.30002108, 6.47923046, 6.51944504])
# 模型评估clf_name = 'HBOS'evaluate_print(clf_name, y_test, y_test_scores)HBOS ROC:1.0, precision @ rank n:1.0
# 模型可视化visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,y_test_pred, show_figure=True, save_figure=False )


四、总   结

HBOS这个算法原理简单,复杂度低,在大数据场景比较好用,但是异常识别的效果一般,且针对特征间比较独立的场景,简单点讲该算法就是把数据划分为多个区间,然后根据每个区间的频次根据概率密度函数转化为对应的出现概率,在将这个概率转化为异常分数,以此来区分异常数据
因此HBOS在全局异常检测问题上表现良好,但在局部异常的检测上效果一般。



    
往期精彩回顾




Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/131004
 
395 次点击