DBSCAN算法介绍

DBSCAN基本介绍

DBSCAN 是一种著名的密度聚类算法,它基于一组“邻域”(neighborhood)参数(ε,MinPts)来刻画样本分布的紧密程度.给定数据集D={x_{1},x_{2},...,x_{m}},

定义下面这几个概念

 

 DBSCAN定义的基本概念(MinPts = 3):虚线显示出ε-邻域, x_{1}是核心对象, x_{2}x_{1}密度直达, x_{3}x_{1}密度可达,x_{3}x_{4}密度相连.由上图我们可以直观地理解概念


基于这些概念,DBSCAN将“”定义为: 由密度可达关系导出的最大的密度相连样本集合.形式化地说,给定邻域参数(ε, MinPts),簇CD是满足以下性质的非空样本子集:
                        连接性(connectivity ): x_{i}C, x_{j}C  \Rightarrow  x_{i}x_{j}密度相连
                        最大性(maximality):    x_{i}C, x_{j}x_{i}密度可达 \Rightarrow  x_{j} ∈C

那么,如何从数据集D中找出满足以上性质的聚类簇呢?实际上,若x为核心对象,由x密度可达的所有样本组成的集合记为X = {x^{'}D \mid x^{'}x密度可达},则不难证明X即为满足连接性与最大性的簇.

于是,DBSCAN算法先任选数据集中的一个核心对象为“种子”(seed),再由此出发确定相应的聚类簇,算法描述如图下图所示.在第1~7行中,算法先根据给定的邻域参数(ε, MinPts)找出所有核心对象;然后在第10~24行中,以任一核心对象为出发点,找出由其密度可达的样本生成聚类簇,直到所有核心对象均被访问过为止.

伪代码展示:

来源《机器学习》

 

 此处有一个可视化网站:

Visualizing DBSCAN Clustering (naftaliharris.com)

通过这个网站,我们可以直观地看到DBSCAN的聚类过程

算法的不稳定

某个样本可能到两个核心对象的距离都小于Eps,但是这两个核心对象由于不是密度直达,又不属于同一个聚类簇,那么如果界定这个样本的类别呢?如图这个蓝点该分给哪个簇呢?

 一般来说,此时DBSCAN采用先来后到,先进行聚类的类别簇会标记这个样本为它的类别。也就是说BDSCAN的算法不是完全稳定的算法。

代码展示,python

 次代码没有根据上述伪代码编写

import numpy as np
import matplotlib.pyplot as plt

def distance(x, y):
    return np.linalg.norm(x - y)

def find_neighbors(center, eps, data):
    """
    找出中心点的邻近点
    :param center: 中心点
    :param eps: 半径
    :param data: 数据集
    :return: 返回邻近点在data的索引
    """
    neighbors = []
    N, D = data.shape
    for i in range(N):
        if distance(center, data[i,:]) < eps:
            neighbors.append(i)
    return neighbors

def DBscan(data, eps, min_samples):
    N, D = data.shape
    labels = np.full(N, -1) # 默认为-1噪声点
    cluster = 0
    for i in range(N):
        if labels[i] != -1:     # 判断是否已经分类,是则遍历下一个
            continue
        # 该索引点的邻域点
        neighbors = find_neighbors(data[i,:], eps, data)
        # 邻域点为1则表示为噪声点,直接下一个
        if len(neighbors) == 1:
            continue
        # 判断是否为核心点,是则执行拓展聚类
        elif len(neighbors) >= min_samples:
            labels[i] = cluster
            expand_cluster(data, labels, neighbors, eps, min_samples, cluster)
            cluster += 1
    return labels

def expand_cluster(data, labels, neighbors, eps, min_samples, cluster):
    for neib_index in neighbors:
        if labels[neib_index] == -1:
            labels[neib_index] = cluster
            nerb_nerbs = find_neighbors(data[neib_index,:], eps, data)
            if len(nerb_nerbs) >= min_samples:
                neighbors.extend(nerb_nerbs)

 训练数据:

data = np.loadtxt(r"data\Aggregation.txt")    # 导入数据
# 设置参数
eps = 1.5
min_samples = 5
labels = DBscan(data, eps, min_samples)

参数对聚类结果的影响:

改变eps

改变min_samples

 

  我们可以看到,当eps、min_samples的值过大、过小都会对聚类结果造成影响

一种常用的方法是通过可视化数据分布和密度来选择邻域半径。可以绘制数据点的散点图,并根据数据点之间的距离来选择合适的邻域半径。可以尝试不同的邻域半径值,观察聚类结果的质量,选择能够较好地将数据点划分为不同聚类的邻域半径。

其它数据的效果展示

算法改进 

尽管DBSCAN算法在密度聚类中具有很多优点,但它也存在一些限制和挑战。下面是一些可能的改进方法,可以进一步提升DBSCAN算法的性能和适用性:

  1. 自适应邻域半径:传统的DBSCAN算法使用固定的邻域半径来定义邻域范围,这可能对于密度变化较大的数据集不够灵活。改进的方法之一是引入自适应邻域半径,根据数据点的密度变化来调整邻域半径的大小。可以考虑使用局部密度估计方法,例如基于k近邻的方法,来动态地确定每个数据点的邻域半径。
  2. 高维数据处理:DBSCAN算法在处理高维数据时可能会遇到维度灾难的问题。高维数据中的距离计算变得困难,密度的定义也变得模糊。为了改进DBSCAN在高维数据上的性能,可以考虑使用特征选择或降维技术,将数据映射到更低维度的空间中,以减少维度灾难的影响。
  3. 基于密度的参数选择:DBSCAN算法的性能非常依赖于邻域半径和最小邻居数目的选择。为了改进算法的鲁棒性,可以考虑基于数据集的密度分布进行参数选择。例如,可以使用统计方法或可视化方法来估计数据点之间的密度分布,从而自动选择合适的邻域半径和最小邻居数目。
  4. 噪音点处理:DBSCAN算法对于噪音点的处理是通过将其标记为噪音点来实现的。然而,在实际应用中,噪音点可能会对聚类结果产生一定的干扰。为了改进噪音点的处理,可以考虑引入噪音点的权重,或者使用半监督的方法来对噪音点进行更精确的处理。
  5. 大数据集处理:对于大规模数据集,DBSCAN算法可能会面临存储和计算效率的挑战。为了改进算法的可扩展性,可以考虑使用基于索引的加速技术,如R树或KD树,来提高算法的效率。另外,可以采用分布式计算或增量计算的方法来处理大规模数据集。

这些改进方法只是对DBSCAN算法进行优化的一部分,具体的改进方法取决于应用场景和需求。通过结合领域知识和实际问题的特点,可以选择适合的改进方法来提升DBSCAN算法的性能和适用性。

部分参考 周志华《机器学习》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值