告别K-Means!用Python手撸Science上的DPC算法,搞定任意形状数据聚类

news2026/5/24 4:50:42
密度峰值聚类DPC用Python突破传统K-Means的局限当面对螺旋形、环形或交叉分布的数据集时许多数据科学从业者都有过这样的经历反复调整K-Means参数却始终无法获得理想的聚类效果。这正是2014年发表在《Science》上的密度峰值聚类算法(DPC)要解决的核心问题。与传统方法不同DPC通过创新的密度峰值概念能够自动识别任意形状数据中的自然聚类中心无需预先指定簇数量。1. 为什么需要超越K-MeansK-Means算法自1967年提出以来因其简单高效成为最广泛使用的聚类工具。但它存在两个根本性局限球形分布假设K-Means基于样本与簇中心的欧式距离进行划分隐含假设数据呈球形分布。这在处理螺旋形、月牙形等复杂结构时效果显著下降。K值依赖需要人工指定聚类数量K而实际应用中K往往未知。错误的K值会导致完全偏离真实结构的聚类结果。# 典型K-Means在复杂数据上的失败案例 from sklearn.cluster import KMeans import matplotlib.pyplot as plt # 生成螺旋数据集 theta np.linspace(0, 4*np.pi, 200) r np.linspace(0.5, 1, 200) x r * np.cos(theta) y r * np.sin(theta) spiral np.column_stack([x, y]) # K-Means聚类 kmeans KMeans(n_clusters3).fit(spiral) plt.scatter(spiral[:,0], spiral[:,1], ckmeans.labels_) plt.title(K-Means在螺旋数据上的表现) plt.show()相比之下DPC算法具有三大突破性优势形状无关性基于局部密度而非距离可识别任意形状的簇自动中心发现通过密度峰值自动确定聚类中心无需预设K值离群点鲁棒性对噪声数据不敏感能自然区分核心点与边缘点2. DPC算法核心原理拆解DPC建立在两个直观而强大的假设基础上假设一聚类中心点的局部密度应显著高于周围邻居假设二聚类中心应与更高密度的点保持较远距离这两个假设转化为两个核心计算指标2.1 局部密度(ρ)计算局部密度衡量数据点周围的样本密集程度DPC提供两种计算方式计算方式公式适用场景截断核ρᵢ ∑ⱼχ(dᵢⱼ - d_c)离散型数据高斯核ρᵢ ∑ⱼexp(-(dᵢⱼ/d_c)²)连续型数据其中d_c是关键参数——截断距离通常选择使每个点平均有1%-2%的邻居落在d_c范围内。def compute_density(dists, dc, methodgaussian): 计算局部密度 if method cutoff: rho np.sum(dists dc, axis1) - 1 # 排除自身 else: # gaussian rho np.sum(np.exp(-(dists/dc)**2), axis1) - 1 return rho2.2 相对距离(δ)计算对于每个点iδᵢ定义为若是最高密度点δᵢ max(dᵢⱼ)其他点δᵢ min(dᵢⱼ) where ρⱼ ρᵢdef compute_delta(dists, rho): 计算相对距离 N len(rho) delta np.zeros(N) nearest_higher np.zeros(N, dtypeint) # 按密度降序排序索引 rho_order np.argsort(-rho) for i, idx in enumerate(rho_order): if i 0: # 最高密度点 delta[idx] np.max(dists[idx]) nearest_higher[idx] -1 else: # 找出密度更高的点 higher_mask rho rho[idx] if np.any(higher_mask): delta[idx] np.min(dists[idx, higher_mask]) nearest_higher[idx] np.argmin(dists[idx, higher_mask]) else: delta[idx] np.max(dists[idx]) nearest_higher[idx] -1 return delta, nearest_higher2.3 决策图与中心选择将ρ和δ绘制为决策图(Decision Graph)聚类中心表现为右上角的离群点——同时具有高ρ和高δ。实际应用中可以设定ρ和δ的双阈值或选择ρ×δ乘积最大的前K个点作为中心。3. 完整DPC实现与可视化下面我们实现完整的DPC流程并在螺旋数据集上进行测试class DensityPeakClustering: def __init__(self, dc_percent2.0): self.dc_percent dc_percent def fit(self, X): # 计算距离矩阵 self.dists np.sqrt(((X[:, None] - X) ** 2).sum(axis2)) # 确定截断距离dc N X.shape[0] position int(N * (N - 1) * self.dc_percent / 100) self.dc np.sort(self.dists.ravel())[position N] # 计算局部密度 self.rho compute_density(self.dists, self.dc) # 计算相对距离 self.delta, self.nearest_higher compute_delta(self.dists, self.rho) return self def find_centers(self, autoTrue, KNone): if auto: # 自动阈值法 rho_thresh (np.min(self.rho) np.max(self.rho)) / 2 delta_thresh (np.min(self.delta) np.max(self.delta)) / 2 self.centers np.where((self.rho rho_thresh) (self.delta delta_thresh))[0] else: # 指定K值法 product self.rho * self.delta self.centers np.argsort(-product)[:K] return self.centers def assign_clusters(self): K len(self.centers) self.labels -np.ones(len(self.rho), dtypeint) # 标记中心点 for i, center in enumerate(self.centers): self.labels[center] i # 按密度降序分配标签 for idx in np.argsort(-self.rho): if self.labels[idx] -1: self.labels[idx] self.labels[self.nearest_higher[idx]] return self.labels可视化展示# 生成测试数据 from sklearn.datasets import make_moons X, _ make_moons(n_samples300, noise0.05) # DPC聚类 dpc DensityPeakClustering(dc_percent2).fit(X) centers dpc.find_centers(autoTrue) labels dpc.assign_clusters() # 绘制结果 plt.figure(figsize(12,5)) plt.subplot(121) plt.scatter(dpc.rho, dpc.delta, ck, s10) plt.scatter(dpc.rho[centers], dpc.delta[centers], cr, s50) plt.xlabel(Density (ρ)) plt.ylabel(Delta (δ)) plt.title(Decision Graph) plt.subplot(122) plt.scatter(X[:,0], X[:,1], clabels, cmapviridis, s20) plt.scatter(X[centers,0], X[centers,1], cred, markerx, s100) plt.title(Clustering Result) plt.show()4. 实战优化与参数调优虽然DPC理论优雅但实际应用中需要注意几个关键点4.1 截断距离dc的选择dc直接影响密度计算结果建议采用以下策略百分比法保持1%-2%的邻居比例默认方法k近邻法取每个点到第k近邻的距离中位数网格搜索在候选dc值中选择使聚类结果最稳定的值def find_optimal_dc(dists, percent_range(1,3)): 寻找最佳dc值 N dists.shape[0] results [] for percent in np.linspace(*percent_range, 10): position int(N * (N - 1) * percent / 100) dc np.sort(dists.ravel())[position N] rho compute_density(dists, dc) delta, _ compute_delta(dists, rho) product rho * delta # 使用轮廓系数评估稳定性 centers np.argsort(-product)[:3] labels assign_clusters(rho, centers, nearest_higher) if len(np.unique(labels)) 1: score silhouette_score(dists, labels, metricprecomputed) results.append((percent, dc, score)) return max(results, keylambda x: x[2])4.2 处理大规模数据原始DPC的O(N²)复杂度限制了其在大型数据集的应用可通过以下方法优化子采样先在小样本上确定dc和中心再扩展到全数据集KD树/球树加速最近邻搜索分布式计算将距离矩阵计算分布到多台机器from sklearn.neighbors import KDTree def fast_compute_density(X, dc, k30): 使用KDTree加速密度计算 tree KDTree(X) counts tree.query_radius(X, rdc, count_onlyTrue) return counts - 1 # 排除自身4.3 多维度数据预处理高维数据中距离度量可能失效建议使用PCA等降维技术保留主要特征采用马氏距离考虑特征相关性对连续和离散特征分别处理from sklearn.decomposition import PCA # 高维数据预处理 pca PCA(n_components0.95) X_reduced pca.fit_transform(X_highdim) dpc DensityPeakClustering().fit(X_reduced)5. DPC进阶应用场景DPC的特殊优势使其在多个领域大放异彩5.1 异常检测高δ低ρ的点往往是异常值这种方法比传统阈值法更可靠def find_anomalies(rho, delta, alpha0.1): 基于DPC的异常检测 rho_norm (rho - np.min(rho)) / (np.max(rho) - np.min(rho)) delta_norm (delta - np.min(delta)) / (np.max(delta) - np.min(delta)) anomaly_scores delta_norm - rho_norm threshold np.percentile(anomaly_scores, 100*(1-alpha)) return anomaly_scores threshold5.2 层次聚类扩展通过调整dc值可以自然获得层次聚类结构从小dc开始识别细粒度簇逐渐增大dc观察簇的合并过程构建聚类树状图5.3 图像分割应用将像素的坐标和颜色作为特征DPC可实现自动图像分割def image_segmentation(image, dc_percent0.5): 基于DPC的图像分割 h, w image.shape[:2] coords np.indices((h, w)).transpose(1,2,0).reshape(-1,2) colors image.reshape(-1, 3) features np.hstack([coords/10, colors]) # 坐标权重降低 dpc DensityPeakClustering(dc_percent).fit(features) centers dpc.find_centers(autoTrue) labels dpc.assign_clusters() return labels.reshape(h, w)在实际项目中DPC算法特别适合处理那些传统方法难以应对的复杂结构数据。我曾在一个客户行为分析项目中使用DPC成功识别出5种独特的用户群体这些群体在传统的RFM模型中被混为一谈。算法的自动中心发现功能帮助我们发现了两个从未考虑过的重要客户细分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2639819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…