【问题标题】:Detect cluster outliers检测集群异常值
【发布时间】:2022-01-19 14:52:52
【问题描述】:

我有一个数据集,其中每个数据样本都包含 10-20 个二维坐标点。数据大多是干净的,但偶尔会有错误注释的点。为了说明,干净的注释数据如下所示:

要么聚集在一个小区域,要么分布在一个更大的区域。我试图过滤掉的异常值如下所示:

离群值远离“正确”的集群。

我尝试了 z-score 过滤,但这种方法错误地将许多注释标记为异常值

std_score = np.abs((points - points.mean(axis=0)) / (np.std(points, axis=0) + 0.01))
validity = np.all(std_score <= np.quantile(std_score, 0.95, axis=0), axis=1)

有没有专门解决这个问题的方法?

【问题讨论】:

    标签: python numpy statistics outliers


    【解决方案1】:

    这似乎是一个典型的聚类问题,如果数据看起来像您建议的那样,来自 scikit-learn 的 KMeans 应该可以解决问题。让我们看看我们如何做到这一点。

    首先我正在生成一个数据样本,它可能看起来有点像您的数据。

    import numpy as np
    import matplotlib.pylab as plt
    
    np.random.seed(1) # For reproducibility
    
    cluster_1 = np.random.normal(loc = [1,1], scale = [0.2,0.2], size = (20,2))
    cluster_2 = np.random.normal(loc = [2,1], scale = [0.4,0.4], size = (5,2))
    
    plt.scatter(cluster_1[:,0], cluster_1[:,1])
    plt.scatter(cluster_2[:,0], cluster_2[:,1])
    plt.show()
    
    points = np.vstack([cluster_1, cluster_2])
    
    

    这就是数据的样子。

    我们将进一步进行 KMeans 聚类。

    from sklearn.cluster import KMeans
    
    kmeans = KMeans(n_clusters = 2).fit(points)
    

    我们选择 n_clusters 作为 2,认为数据集中有 2 个集群。找到这些集群后,让我们看看它们。

    plt.scatter(points[kmeans.labels_==0][:,0], points[kmeans.labels_==0][:,1], label='cluster_1')
    plt.scatter(points[kmeans.labels_==1][:,0], points[kmeans.labels_==1][:,1], label ='cluster_2')
    plt.scatter(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], label = 'cluster_center')
    plt.legend()
    plt.show()
    

    这将如下图所示。

    这应该可以解决您的问题。但是有一些事情应该牢记在心。

    • 不会一直完美。
    • 如果您没有任何异常值,可能会出现问题。可以通过轮廓分数来解决。
    • 很难知道要丢弃哪个聚类(可以通过定位聚类中心(绿色点)来完成,也可以通过找到点数较少的聚类来完成。

    尾注:您可能会遗漏一些要点,但会使整个过程自动化。取决于您希望在节省的数据与节省的手动时间方面做出多少权衡。

    【讨论】:

    • k-means 听起来不太适合我,主要是在点分布在整个平面上并且大部分数据都是干净的情况下。此外,我认为我无法为我拥有的每个数据样本计算迭代算法作为 k 均值,因为我有数十万个样本。
    • @DominikFicek 您的数据集是否仅包含 25 个点。其次,我认为它的计算成本并不高。并且运行时间很快。你能画出一个数据集有多极端吗?您展示的示例,KMeans 应该适用于此。
    • 我的数据集有很多样本,每个样本包含 10-20 个点。我想要实现的是从每个样本中删除异常值,因此我必须为每个样本计算 k-means。即使那样,我也不是真的相信 k-means 是这里的方式,我想有一个统计测试或类似的东西可以实现这一点。
    猜你喜欢
    • 2021-10-22
    • 2013-12-21
    • 2019-07-24
    • 1970-01-01
    • 2019-08-27
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多