CBLOF算法-异常检测

CBLOF也是一种基于其他机器学习算法的异常检测算法。说到基于,就是CBLOF名字里面的B~Based。而他基于的是其他的聚类算法,所以他就是Cluster-Based。LOF三个字母是Local Outlier Factor,本地异常因子。合起来CBLOF 就是 Cluster-based Local Outlier Factor,基于聚类的本地异常因子。
CBLOF算法-异常检测_第1张图片

他的一个基本认知是:数据可能会在多个不同的地方聚集,形成簇。当一个点越接近大簇的时候,他是正常点的概率就越高,反之越低。那么,我们只要在CBLOF里面,套一个聚类算法,就能得到这些簇了。一般,我们会用k-means算法,距离就直接用欧氏距离。于是,我们就有了上图当中的四个簇。这里,我们明显看出来,C2、C3\C4是两个大簇,剩下的C1是个小簇。那么,距离C2、C3或者C4的中心(即K-Means里面的中心,又叫Centroids)越近,就越正常,反之越异常。

数据

用销售和利润的数据。你可以在这里找到:https://community.tableau.com/docs/DOC-1236

CBLOF算法-异常检测_第2张图片

来自:https://blog.csdn.net/juwikuang/article/details/108699190

聚类

算法的第一步是聚类。

在聚类之前,我们先对数据进行归一化。这是非常必要的一步。特别是在各种变量的变化范围不一样的情况下。

然后,我们直接用k-means聚类。

km = KMeans(n_clusters=8)
km.fit(X)

聚类以后得到下图:

在这里插入图片描述

大簇小簇

如何判断哪个簇是最大的?

  • 大小是用簇成员的多少(size)来衡量的。

其他的簇,哪个算大簇,哪个算小簇?

  • 有两个原则:绝对多数原则和突降原则

1、绝对多数

定义∣ C ∣表示簇C的大小(size)。我们把这些簇按照大小排列,则有:

从最大簇开始,一个一个的把他们的size加起来,他们的size要达到总size的绝对多数。而这个绝对多数,是一个可以设置的参数α,他的取值范围是0.5到1,一般取0.9。

2、突降

突降是用倍数β来衡量。默认值是5,也就是突降了5倍。

pyod是这样实现的:能找到同时满足两个条件的分割最好。次优是找到满足绝对多数原则的分割。最差是只找到了满足突降原则的分割。
 

large_clusters = []
small_clusters = []
count = 0
clusters  # 已经根据样本数量排好序的簇:由大到小
n_clusters = len(clusters)
sizes  # 存的每个簇的样本数量
MAX_N_POINT_IN_LARGE_CLUSTER  # 大簇的最大样本数量
BETA = 5  # 样本数量下降最大倍数
satisfy_alpha = False
satisfy_beta = False
for i in range(n_clusters):
    if satisfy_alpha and satisfy_beta:
        small_clusters.append(clusters[i])
        continue

    count += sizes[i]
    if count > MAX_N_POINT_IN_LARGE_CLUSTER:
        satisfy_alpha = True

    ratio = sizes[i] / sizes[i + 1]
    if i < n_clusters - 1 and ratio > BETA:
        satisfy_beta = True

    large_clusters.append(clusters[i])

 在这里插入图片描述

Factor 因子

计算CBLOF因子,也就是一个点到最近的大簇的距离。

  • 如果这个点是大簇里面的点,直接计算他到簇中心的距离即可。
  • 如果这个点不是大簇点,分别计算其到所有大簇的距离,选最小的作为因子。
def decision_function(X, labels):
    distances = []
    for p, label in zip(X, labels):
        if label in large_clusters:
            center = km.cluster_centers_[label]
            d = get_distance(p, center)
        else:
            d = min([get_distance(p, center) for center in large_cluster_centers])
        distances.append(d)
    return np.array(distances)

distances = decision_function(X, km.labels)

涉及到了contamination的概念。他是异常检测算法的主要参数。其实他就是表示了异常的比例。一般这个值是1%。

有了contamination,就可以用python里面的百分位函数,找出距离最大的1%的点,把他们作为异常。

threshold = np.percentile(distances, 99)
anomaly_labels = (distances > threshold) * 1

在这里插入图片描述 

————————————————
参考:https://blog.csdn.net/juwikuang/article/details/108699190

你可能感兴趣的:(机器学习,python,算法,机器学习,python,算法)