我目前在做一些和异常检测相关的工作,并参加到了pyod里面的CBLOF算法的开发。所以,我对于CBLOF的论文以及pyod里面的实现都非常熟悉。
对于手写算法系列的文章。有兴趣的可以研究一下代码。时间紧的也可以跳过代码不看。但是,即使你并不想看代码,也建议你来看我的文章。毕竟,我是实现了这些代码的,说明我自己首先理解了这些算法,我才好意思写文章。而且在实现的过程中,就像本文一样,可以把一些中间步骤都作图打印出来。
异常检测
异常检测一般来说是一种无监督学习的方法。他在没有标签的情况下,利用各种算法来区分正常值和异常值。
当然,如果有标签,就可以用分类算法解决异常检测了。虽然这也是异常检测,但是这样的算法还是分类算法。只有无监督的异常检测,一般才认为是异常检测算法。
异常检测的算法,从传统的统计方法,到机器学习,再到深度学习,应有尽有。
很多异常检测的算法,都是基于已有的机器学习算法的。比如KNN的异常检测算法,就是看一个点到由近到远第K个点的距离,然后找出距离最大的少数点作为异常。
CBLOF 基于聚类的本地异常因子
我们今天要学的CBLOF也是一种基于其他机器学习算法的异常检测算法。说到基于,就是CBLOF名字里面的B~Based。而他基于的是其他的聚类算法,所以他就是Cluster-Based。LOF三个字母是Local Outlier Factor,本地异常因子。合起来CBLOF 就是 Cluster-based Local Outlier Factor,基于聚类的本地异常因子。
他的一个基本认知是:数据可能会在多个不同的地方聚集,形成簇。当一个点越接近大簇的时候,他是正常点的概率就越高,反之越低。那么,我们只要在CBLOF里面,套一个聚类算法,就能得到这些簇了。一般,我们会用k-means算法,距离就直接用欧氏距离。于是,我们就有了上图当中的四个簇。这里,我们明显看出来,C2和C4是两个大簇,剩下的C1和C3是两个小簇。那么,距离C2或者C4的中心(即K-Means里面的中心,又叫Centroids)越近,就越正常,反之越异常。
数据
这里,我们以一个实际的例子,来具体介绍本算法。
我们这里用销售和利润的数据。你可以在这里找到:
https://community.tableau.com/docs/DOC-1236
我们可以看到,绝大多数点都集中在左中的一小块区域。极少数的点分布在其他区域。
聚类
我们说到,这个算法的第一步是聚类,那么我们就来对他进行聚类。
在聚类之前,我们先对数据进行归一化。这是非常必要的一步。特别是在各种变量的变化范围不一样的情况下。
(篇幅所限,大多数代码就不贴了,文末给出代码地址。)
然后,我们直接用k-means聚类。
km = KMeans(n_clusters=8)
km.fit(X)
聚类以后,我们得到下图。图中按照颜色区分了每个簇
大簇小簇
我现在问你一个问题,哪个簇是最大的?
希望你猜对了,那个看起来最小的蓝色的簇是最大的。最小的簇是紫色的簇,虽然他面积很大,但是他只有一个点。所以,我们这里的大小,是用簇成员的多少(size)来衡量的。
那么其他的簇,哪个算大簇,哪个算小簇呢?
我们先来定义个 ∣ C ∣ |C| ∣C∣,表示簇 C C C的大小(size)。我们把这些簇按照大小排列,则有:
∣ C 1 ∣ ≥ ∣ C 2 ∣ ≥