DBSCAN算法实现【超详细注释】

本文介绍了DBSCAN聚类算法的详细步骤,包括选择初始点、邻域展开、创建簇和标记噪声点。通过示例代码展示了算法的实现过程,讨论了距离选择对结果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DBSCAN

算法步骤

  • 设置每个对象为未访问

  • 随机选择一个未访问的点ppp,标记ppp表示访问

  • 如果p的半径为nnn的邻域中至少存在MinPts个对象

    • 我们就创建一个新的簇,并将ppp加入ccc
    • Nppp邻域中对象的集合
    • 对在NNN中的每个点p′p'p
      • 如果p′p'p是未访问的
        • 标记p′p'p为访问节点
        • 如果这个p′p'p也是核心节点,那么将它范围内的点加入到NNN
      • 如果p′p'p还不是任何簇中的成员,我们就把p′p'p加入ccc
    • 输出簇ccc
  • 否则,标记ppp为噪声

  • 重复以上直到每个点被访问

在这里插入图片描述

实现

def DBSCAN(poi,radius=1,MinPts=5):
    def edis(x,y):
        return math.sqrt(sum((x[i]-y[i])**2 for i in range(len(x))))
    unvisit=set([i for i in range(len(poi))]) # 创建访问表
    Clusters=[-1]*len(poi) # 一个hash表,判断哪个点对应哪个簇
    c=0

    while len(unvisit):
        # 随机选一个中心点
        p=random.choice(list(unvisit))
        unvisit.remove(p)
        # 邻域展开!
        neighbor=set()
        for id,pn in enumerate(poi):
            if edis(poi[p],pn)<=radius:
                neighbor.add(id)
        if len(neighbor)>=MinPts:
            # 创建一个新的簇
            Clusters[p]=c
            # 遍历邻域点
            while neighbor:
                id=neighbor.pop()
                if id in unvisit:
                    unvisit.remove(id)
                    # 找他的邻域
                    n=set()
                    for Id,pi in enumerate(poi):
                        if edis(poi[id],pi)<radius:
                            n.add(Id)
                    if len(n)>=MinPts:
                        # 合并
                        neighbor|=n
                    # 如果这个点不属于任何簇,将其加入c
                if Clusters[id]==-1:
                    Clusters[id]=c
        # 否则,我们认为p是一个噪声(-1)
            c+=1
    return Clusters

print(DBSCAN(points))

结果展示

嗯,离群点被标记为了-1

如何选择距离也会对结果产生很大的影响。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值