ML中的DBSCAN集群|基于密度的聚类

2021年4月13日09:54:51 发表评论 1,037 次浏览

聚类分析或简单地说, 聚类基本上是一种无监督的学习方法, 可以将数据点分为多个特定的批次或组, 这样, 同一组中的数据点具有相似的属性, 而不同组中的数据点在某种意义上具有不同的属性。它包括基于不同演变的许多不同方法。

例如。 K均值(点之间的距离), 亲和力传播(图形距离), 均值偏移(点之间的距离), DBSCAN(最近点之间的距离), 高斯混合(马哈拉诺比斯到中心的距离), 谱聚类(图形距离)等。

从根本上讲, 所有聚类方法都使用相同的方法, 即首先我们计算相似度, 然后使用它将数据点聚类为组或批次。在这里, 我们将专注于基于密度的含噪声应用程序空间聚类(DBSCAN)群集方法。

簇是数据空间中的密集区域, 由点密度较低的区域分隔。的

DBSCAN算法

基于"集群"和"噪声"的直观概念。关键思想是, 对于群集的每个点, 给定半径的邻域必须至少包含最少数量的点。

ML中的DBSCAN集群|基于密度的聚类1

为什么选择DBSCAN?

分区方法(K均值, PAM聚类)和层次聚类用于查找球形聚类或凸形聚类。换句话说, 它们仅适用于紧凑且间隔良好的群集。此外, 它们还受到数据中存在噪声和异常值的严重影响。

现实生活中的数据可能包含违规行为, 例如–

i)簇可以是任意形状, 如下图所示。

ii)数据可能包含噪音。

ML中的DBSCAN集群|基于密度的聚类2

下图显示了一个包含非凸簇和离群值/噪声的数据集。给定这样的数据, k-均值算法很难识别具有任意形状的这些聚类。

DBSCAN算法需要两个参数–

eps:它定义了数据点周围的邻域, 即, 如果两个点之间的距离小于或等于" eps", 则将它们视为邻居。如果eps值选择得太小, 则大部分数据将被视为离群值。如果选择非常大, 则群集将合并, 并且大多数数据点将位于同一群集中。查找eps值的一种方法是基于k距离图。

最小点数

:eps半径内的最小邻居(数据点)数。数据集越大, 必须选择更大的MinPts值。通常, 最小MinPts可以从数据集中的维数D得出, 如MinPts> = D + 1。 MinPts的最小值必须至少选择3。

在此算法中, 我们有3种类型的数据点。核心点:如果点在eps内的点数超过MinPts, 则该点就是核心点。边界点:在eps内少于MinPts的点, 但它在核心点附近。噪点或异常值:不是核心点或边界点的点。

ML中的DBSCAN集群|基于密度的聚类3

DBSCAN算法可以在以下步骤中抽象化–

  1. 找到eps内的所有相邻点, 并确定核心点或与MinPts相邻的点进行访问。
  2. 对于尚未分配给集群的每个核心点, 请创建一个新集群。
  3. 递归查找其所有密度连接点, 并将其分配给与核心点相同的群集。
    一个点一种和b如果存在一点, 就说是密度连接C在它的邻居和两个点中都有足够数量的点一种和b在eps距离。这是一个链接过程。因此, 如果b是的邻居C, C是的邻居d, d是的邻居Ë, 而后者又是一种暗示b是的邻居一种.
  4. 遍历数据集中剩余的未访问点。不属于任何群集的那些点是噪声。

下面是伪代码中的DBSCAN聚类算法:

DBSCAN(dataset, eps, MinPts){
# cluster index
C = 1
for each unvisited point p in dataset {
         mark p as visited
         # find neighbors
         Neighbors N = find the neighboring points of p

         if |N|>=MinPts:
             N = N U N'
             if p' is not a member of any cluster:
                 add p' to cluster C 
}

以上算法在Python中的实现:

在这里, 我们将使用Python库斯克莱恩计算DBSCAN。我们还将使用matplotlib.pyplot用于可视化集群的库。

可以找到使用的数据集这里.

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler
from sklearn import datasets
  
# Load data in X
db = DBSCAN(eps = 0.3 , min_samples = 10 ).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype = bool )
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
  
# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len ( set (labels)) - ( 1 if - 1 in labels else 0 )
  
print (labels)
  
# Plot result
import matplotlib.pyplot as plt
  
# Black removed and is used for noise instead.
unique_labels = set (labels)
colors = [ 'y' , 'b' , 'g' , 'r' ]
print (colors)
for k, col in zip (unique_labels, colors):
     if k = = - 1 :
         # Black used for noise.
         col = 'k'
  
     class_member_mask = (labels = = k)
  
     xy = X[class_member_mask & core_samples_mask]
     plt.plot(xy[:, 0 ], xy[:, 1 ], 'o' , markerfacecolor = col, markeredgecolor = 'k' , markersize = 6 )
  
     xy = X[class_member_mask & ~core_samples_mask]
     plt.plot(xy[:, 0 ], xy[:, 1 ], 'o' , markerfacecolor = col, markeredgecolor = 'k' , markersize = 6 )
  
plt.title( 'number of clusters: %d' % n_clusters_)
plt.show()

输出如下:

ML中的DBSCAN集群|基于密度的聚类4

黑点代表异常值。通过更改eps和MinPts,我们可以更改集群配置。

现在应该提出的问题是,为什么我们要使用DBSCAN,而K-Means是聚类分析中广泛使用的方法?

K-MEANS的缺点:

K均值仅形成球形簇。当数据不是球形时(即在所有方向上都具有相同的方差), 该算法将失败。

ML中的DBSCAN集群|基于密度的聚类5

K-Means算法对异常敏感。离群值可以在很大程度上扭曲K均值中的聚类。

ML中的DBSCAN集群|基于密度的聚类6

K-Means算法需要先指定优先级等的簇数。

DBSCAN算法基本上克服了K-Means算法的上述缺点。DBSCAN算法通过基于距离测量将彼此接近的数据点分组来识别密集区域。

参考文献:

https://en.wikipedia.org/wiki/DBSCAN

https://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html

首先, 你的面试准备可通过以下方式增强你的数据结构概念:Python DS课程。


木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: