实现机器学习的循序渐进指南XI——DBSCAN

目录

介绍

DBSCAN模型

开始

聚类算法

参数估计

结论与分析


可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表。

介绍

基于密度的噪声应用空间聚类(DBSCAN)是一种基于密度的聚类算法。与其他聚类算法不同,DBSCAN将最大密度可到达样本集视为聚类。KMeans缺乏对非球形数据进行聚类的能力,而DBSCAN可以对任何形状的数据进行聚类。

DBSCAN模型

开始

  • Ε邻域:来自对象的半径为ε的对象。
  • 核心要点:如果一个样本在ε-邻居内具有超过指定数量的点(m),则该样本是核心点。
  • 直接密度可达对于样本集合D,如果样本点qpΕ邻域内,并且p为核心对象,那么对象q从对象p直接密度可达
  • 密度可达:如果存在对象链p1...pn,对象q可以从p密度到达,其中p1 = ppn = q使得pi + 1可以直接密度可达pi,对于所有1 <= i <= n(直接密度可达和密度可达之间的差值是当直接密度可达时pq的邻居内,而当密度可达时p不在q的邻居内)
  • 密度连通性:对象p是与对象q连接的密度如果有一个对象o使得pq都是从对象o可达的密度
  • 噪声:至少一个核心对象无法达到密度可达的对象

让我们举一个例子来解释上面的术语,如下所示,其中m = 4。因为在所有红色样本的ε-邻居中有超过m个样本,所以它们都是核心点密度可达BC不是核心要点。青色圆圈中的样品直接密度可达。棕色圆圈中的样本是密度连通性的N对任何其他样本都不可达,因此它是一个噪声点

聚类算法

首先,我们通过计算所有样本ε-邻居中的样本数来找到所有核心点。剩余样本暂时标记为噪声点。我们提供几种类型的距离,即:

  • 欧几里德距离:

  • 余弦距离:

  • 曼哈顿距离:

def calculateDistance(self, x1, x2):
    if self.distance_type == "Euclidean":
        d = np.sqrt(np.sum(np.power(x1 - x2, 2), axis=1))
        #d = np.sqrt(np.sum(np.power(x1 - x2, 2)))
    elif self.distance_type == "Cosine":
        d = np.dot(x1, x2)/(np.linalg.norm(x1)*np.linalg.norm(x2))
    elif self.distance_type == "Manhattan":
        d = np.sum(x1 - x2)
    else:
        print("Error Type!")
        sys.exit()
    return d

对于给定样本,如果此样本与另一个样本之间的距离小于ε,则它们位于同一邻居中。

def getCenters(self, train_data):
    neighbor = {}
    for i in range(len(train_data)):
        distance = self.calculateDistance(train_data[i], train_data)
        index = np.where(distance <= self.eps)[0]
        if len(index) > self.m:
            neighbor[i] = index
    return neighbor

然后,我们随机选择一个未访问的核心点P来合并与其密度连通的样本。接下来,我们访问Pε-邻居内的样本Q。如果Q是核心点,QP的同一簇中并在Q上进行相同的处理(如深度优先搜索)否则,请访问下一个示例。具体来说,Pε-邻居的搜索过程如下所示:

  • 选择核心点A并找到其ε-邻居中的所有样本。Aε-邻居内的样本属于A的簇。然后连续访问Aε-邻域内的样本。

  • 访问Aε-邻居中的样本B B是核心样本,访问Bε-邻居内的样本。

  • 访问Bε-邻居中的样本CC属于AC不是核心点。访问Bε-邻居内的其他样本。

  • 访问Bε-邻居中的另一个样本D D是核心点。访问Dε-邻居内的样本。

  • 访问样本E E不是核心点。现在,没有任何点密度可达到A。停止A的聚类。

k = 0
unvisited = list(range(sample_num))               # samples which are not visited
while len(centers) > 0:
    visited = []
    visited.extend(unvisited)
    cores = list(centers.keys())
    # choose a random cluster center
    randNum = np.random.randint(0, len(cores))
    core = cores[randNum]
    core_neighbor = []                              # samples in core's neighbor
    core_neighbor.append(core)
    unvisited.remove(core)
    # merege the samples density-connectivity
    while len(core_neighbor) > 0:
        Q = core_neighbor[0]
        del core_neighbor[0]
        if Q in initial_centers.keys():
            diff = [sample for sample in initial_centers[Q] if sample in unvisited]
            core_neighbor.extend(diff)
            unvisited = [sample for sample in unvisited if sample not in diff]
    k += 1
    label[k] = [val for val in visited if val not in unvisited]
    for index in label[k]:
        if index in centers.keys():
            del centers[index]

参数估计

DBSCAN算法需要2个参数ε,它们指定了彼此之间的接近点应该如何被视为集群的一部分;而参数m,它指定一个点应该包含在一个簇中的邻居数量。以wiki为例,我们计算在同一分区内从每个点到最近邻居的距离,如下所示,我们可以很容易地确定ε= 22

对于参数m,我们计算核心点的ε邻域内有多少样本,如下所示。我们选择m = 129,因为它是第一个谷底。

结论与分析

DBSCAN能够聚类非球形数据,但不能反映高维数据。当密度分布不​​均匀时,聚类性能不太好。KMeansDBSCAN之间的聚类性能如下所示。很容易发现DBSCAN具有比KMeans更好的聚类性能。

可以在MachineLearning找到本文中的相关代码和数据集。

有兴趣的小伙伴可以查看上一篇

 

原文地址:https://www.codeproject.com/Articles/5129186/Step-by-Step-Guide-to-Implement-Machine-Learning-8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值