惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
量子位
aimingoo的专栏
aimingoo的专栏
V
Visual Studio Blog
Y
Y Combinator Blog
Vercel News
Vercel News
云风的 BLOG
云风的 BLOG
宝玉的分享
宝玉的分享
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Security Blog
Microsoft Security Blog
B
Blog
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
博客园 - 聂微东
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派
DBSCAN - 算法原理和实现 - 少数派
2024-11-17 · via 少数派

概念

DBSCAN(Density-Based Spatial Clustering of Applications with Noise),有噪声的基于密度聚类算法。

  • 将簇定义为具有足够高密度的区域;
  • 可以在有噪声的空间数据中发现任意形状的聚类。

关于DBSCAN的一些定义:

  • E邻域:对于给定对象,半径为Ε内的区域。
  • 核心对象:E邻域内样本点数大于等于MinPts的给定对象。
  • 直接密度可达:对于样本集合D,如果样本点qpΕ邻域内,并且p为核心对象,那么对象q从对象p直接密度可达。
  • 密度可达:对于样本集合D,给定一串样本点p_1,p_2,…,p_np=p_1q=p_n,假如对象p_ip_{i-1}直接密度可达,那么对象q从对象p密度可达。
  • 密度相连:存在样本集合D中的一点o,如果对象o到对象p和对象q都是密度可达的,那么pq密度相联。

DBSCAN目的是找到密度相连对象的最大集合。

算法

伪代码

REPEAT:
    选取未处理的一个点P进行处理
    IF P是核心点
        THEN 找出P的所有密度相连的点,形成簇
    ELSE P是非核心点
        标记P为噪声
        CONTINUE
UNTIL所有点都被处理

Python代码实现

import numpy as np


def dist2D(p1, p2):
    d = np.sqrt(sum([np.power(p1[i] - p2[i], 2) for i in range(len(p1))]))
    return d


def dbscan(D, Eps, MinPts, dist):
    c = 0  # 初始化簇的个数为0
    n = len(D)  # 点的个数
    visited = np.zeros(n, dtype=int)  # 访问列表
    C = np.zeros(n, dtype=int)  # 簇号列表
    while 0 in visited:  # 当还有点未被访问到
        p = np.random.choice(np.where(visited == 0)[0].tolist())  # 随机选取未被访问到的点
        visited[p] = 1  # 标记该点被访问
        N = np.empty(0, dtype=int)  # 邻域点集
        for i in range(n):
            if dist(D[p], D[i]) <= Eps:
                N = np.append(N, i)  # 计算E邻域的点
        if len(N) < MinPts:
            C[p] = -1  # 如果E邻域的点数小于MinPts,则为非核心点(噪声)
        else:  # 否则,为核心店
            c += 1  # 新建簇号
            '''找到所有该点的密度相连的点,标记簇号'''
            C[p] = c
            while 0 in visited[N]:
                _p = np.random.choice(np.intersect1d(N, np.where(visited == 0)[0]))
                visited[_p] = 1
                _N = np.empty(0, dtype=int)
                for i in range(n):
                    if dist(D[_p], D[i]) <= Eps:
                        _N = np.append(_N, i)
                if len(_N) >= MinPts:
                    N = np.append(N, _N)
                if C[_p] == 0:
                    C[_p] = c
    return C

测试

'''
导入dbscan算法
'''
import matplotlib.pyplot as plt

data = np.loadtxt("788points.txt", dtype="float32", delimiter=",")
data_c = dbscan(data, 2, 14, dist2D)

plt.scatter([a[0] for a in data], [a[1] for a in data], c=data_c)
dbscan分类结果图
dbscan分类结果图

参考

基于密度的聚类算法DBSCAN原理与实现 - 知乎 (zhihu.com)

DBSCAN_百度百科 (baidu.com)