减法聚类(Subtractive Clustering)算法实践

news/2024/4/29 20:14:38/文章来源:https://blog.csdn.net/qq_39784672/article/details/127793867

算法概述

减法聚类算法(Subtractive Clustering Method)是一种不需要提前规定聚类数、只需根据样本数据即可快速决定聚类中心的一种密度聚类算法。该算法把所有样本数据点作为聚类中心的候选点,利用密度函数计算每个候选点的密度指标,选取其中密度指标最大的点作为聚类中心,再去掉已知选择的聚类中心,计算剩余点的密度指标,选取其中密度指标最大的点作为下一个聚类中心。不断重复上述过程,直到满足收敛条件[1]^{[1]}[1]。最终即可得到的已知数目的聚类中心。

具体实现流程

  • Step1:已知n个处于m维空间的数据样本点 (x1,x2,...,xn)(x_1,x_2,...,x_n)(x1,x2,...,xn),每个数据点都是候选聚类中心,定义数据点 xix_ixi 处的密度指标为:
    Di=∑j=1nexp⁡(−∥xi−xj∥2(ra/2)2)D_i=\sum_{j=1}^n\exp(-\frac{\|x_i-x_j\|^2}{(r_a/2)^2}) Di=j=1nexp((ra/2)2xixj2)
    其中 rar_ara 是一个常数,一个数据点的邻近数据点越多,该数据点的密度指标越大。rar_ara 也可以理解为以 xix_ixi 数据点为中心,以 rar_ara 为半径的圆形区域,区域以外的数据点对该点的密度指标影响较小。

  • Step2:按照上式计算得到各个样本点的密度指标,密度指标最大的点定义为聚类中心 ckc_kck ,其密度指标为 DckD_{c_k}Dck 。此时 k=1k=1k=1 ,那么每一个数据点 xix_ixi 的密度指标可用以下公式进行更新:
    Di=Di−Dckexp⁡(−∥xi−xck∥2(rb/2)2)D_i = D_i - D_{c_k}\exp{(-\frac{\|x_i-x_{c_k}\|^2}{(r_b/2)^2})} Di=DiDckexp((rb/2)2xixck2)
    其中 rbr_brb 是一个常数。可以看出,经过更新公式重新计算密度指标后,靠近聚类中心 ckc_kck 的数据点密度指标明显减小了,这样做的好处是可以避免其成为下一个聚类中心。rbr_brb 定义了一个密度指标显著减小的影响范围[2]^{[2]}[2]

  • Step3:根据更新修正后的样本数据点密度指标,找出最大值Dmax=max⁡(Di)D_{max}=\max(D_i)Dmax=max(Di),选出下一个聚类中心ck+1c_{k+1}ck+1,重复Step2进行更新修正。

  • Step4:不断迭代计算修正后的密度指标最大值 DmaxD_{max}Dmax ,直到满足下式:
    DmaxDc1<δ\frac{D_{max}}{D_{c_1}}<\delta Dc1Dmax<δ
    则迭代结束,最终聚类个数为 K=kK=kK=k 。一般取δ≥0.5\delta\ge0.5δ0.5 效果较好。

关于Step1和Step2中的ra,rbr_a, r_bra,rb 可通过如下方法进行确定:
ra=rb=12min⁡j{max⁡i(∥xi−xj∥)}r_a=r_b=\frac{1}{2}\min_j\{\max_i(\|x_i-x_j\|)\} ra=rb=21jmin{imax(xixj)}
其中 ra、rbr_a、r_brarb 取样本集合最中间的样本到距离它最远的样本之间距离的一半[3]^{[3]}[3]

代码实现

为了避免太多循环操作,代码中尽量使用矩阵计算。

首先,创建CSM减法聚类方法类。

import numpy as np
import time
import matplotlib.pyplot as plt
from sklearn.metrics import pairwise_distances_argmin
from sklearn.datasets._samples_generator import make_blobsclass SCM:def __init__(self, r_a = None, r_b = None, delta = 0.5):"""Subtractive Clustering Method:param r_a: float,初始化密度指标邻域大小:param r_b: float,迭代修正密度指标邻域大小:param delta: float,迭代停止阈值"""self.r_a = r_aself.r_b = r_bself.delta = deltaself.cluster_centers = np.array([])def fit(self, X):"""聚类主函数:param X: NxM array,输入样本数据点,N为样本点数量,M为样本数据维数:return: KxM array,聚类中心点集合,K为中心点数量,M为中心点维数"""# 计算欧式距离矩阵EDM(NxN)EDM = self.compute_squared_EDM(X)if not self.r_a or not self.r_b:# 计算r_a和r_bself.r_a = self.r_b = 0.5 * np.min(np.max(EDM, axis = 1))# 计算每个样本点的密度指标D = np.sum(np.exp(-1 * EDM / (0.25 * self.r_a ** 2)), axis = 1)# 选取最大密度指标点作为聚类中心self.cluster_centers = np.append(self.cluster_centers, X[np.argmax(D)]).reshape(-1, X.shape[1])Dc1, Dmax = np.max(D), np.max(D)while True:# 更新修正各点密度指标D -= Dmax * np.exp(-1 * EDM[:, np.argmax(D)] / (0.25 * self.r_b ** 2))Dmax = np.max(D)# 判断是否满足迭代结束条件if Dmax / Dc1 < self.delta:break# 选取最大密度指标点作为下一个聚类中心self.cluster_centers = np.vstack((self.cluster_centers, X[np.argmax(D)]))@staticmethoddef compute_squared_EDM(X):# 获得矩阵都行和列,因为是行向量,因此一共有n个向量n, m = X.shape# 计算Gram 矩阵G = np.dot(X, X.T)# 因为是行向量,n是向量个数,沿y轴复制n倍,x轴复制一倍H = np.tile(np.diag(G), (n, 1))return np.sqrt(H + H.T - 2 * G)

ok,直接开始测试。测试部分代码参考了这篇文章[5]^{[5]}[5]

# Generate sample data
np.random.seed(0)
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples = 3000, n_features = 2, centers = centers, cluster_std = 0.5)
# plot result
fig = plt.figure(figsize = (8, 3))
fig.subplots_adjust(left = 0.02, right = 0.98, bottom = 0.05, top = 0.9)
# original data
ax = fig.add_subplot(1, 2, 1)
row, _ = np.shape(X)
for i in range(row):ax.plot(X[i, 0], X[i, 1], '#4EACC5', marker = '.')
ax.set_title('Original Data')
ax.set_xticks(())
ax.set_yticks(())
# compute clustering with SCM
scm = SCM()
t0 = time.time()
scm.fit(X)
t = time.time() - t0
csm_cluster_centers = np.sort(scm.cluster_centers, axis = 0)
csm_labels = pairwise_distances_argmin(X, csm_cluster_centers)
# SCM
ax = fig.add_subplot(1, 2, 2)
import matplotlib.colors as mcolorscolors = list(mcolors.TABLEAU_COLORS.keys())  # 颜色变化
for k, col in zip(range(len(csm_cluster_centers)), colors):my_members = csm_labels == k  # my_members是布尔型的数组(用于筛选同类的点,用不同颜色表示)cluster_center = csm_cluster_centers[k]ax.plot(X[my_members, 0], X[my_members, 1], 'w',markerfacecolor = col, marker = '.')  # 将同一类的点表示出来ax.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor = col,markeredgecolor = 'k', marker = 'o')  # 将聚类中心单独表示出来
ax.set_title('Subtractive Clustering')
ax.set_xticks(())
ax.set_yticks(())
plt.text(-3.5, 1.8,'train time: %.2fs\ndelta: %.2f\nnumber of centers: %d' % (t, scm.delta, len(scm.cluster_centers)))plt.show()

测试结果如下图所示。

csm_0.5

csm_0.4

总结

  • 欧式距离矩阵求解

    矩阵运算很好用,能避免for循环,提升运算效率。本代码中距离矩阵构建方法参见文章[4]^{[4]}[4]

参考

[1] 马慧,赵捧未,王婷婷. 语义减法聚类研究[J]. 计算机工程与科学,2016,38(9):1924-1929. DOI:10.3969/j.issn.1007-130X.2016.09.027.

[2] 袁银莉. 改进的模糊聚类算法[J]. 绍兴文理学院学报,2009,29(10):46-49. DOI:10.3969/j.issn.1008-293X.2009.10.012.

[3] 邵堃侠,郭卫民,杨宁,等. 基于K-means算法的RBF神经网络预测光伏电站短期出力[J]. 上海电机学院学报,2017,20(1):27-33. DOI:10.3969/j.issn.2095-0020.2017.01.006.

[4] https://blog.csdn.net/LoveCarpenter/article/details/85048291

[5] https://blog.csdn.net/qq_41938858/article/details/87738035

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot项目实战笔记:电脑商城项目实战(SpringBoot+MyBatis+MySQL)

花了一段实现刚学完SpringBoot&#xff0c;做个项目练练手。教程视频来源于B站。视频链接&#xff1a;【SpringBoot项目实战完整版】SpringBootMyBatisMySQL电脑商城项目实战_哔哩哔哩_bilibili一、系统概述与环境搭建 1. 系统开发及运行环境 电脑商城系统开发所需的环境及相…

高质量测试的12个步骤

简介 假设您正在实现某个功能&#xff0c;经过一番艰苦卓绝的编码后&#xff0c;终于可以提交、合并代码了。流水线开始运行&#xff0c;几分钟后失败了。部分单元测试用例失败了……这会让您很痛苦&#xff0c;因为修改的是别人遗留下来的程序&#xff0c;所以您并不清楚单元…

docker环境连接tdengine服务

1.开发app项目 <!--引入TDEngine--> <dependency><groupId>com.taosdata.jdbc</groupId><artifactId>taos-jdbcdriver</artifactId><version>3.0.0</version> </dependency> <!-- 引入jdbc --> <dependency&g…

Vue(四)——使用脚手架(1)

安装和启动&#xff1a; 目录 分析脚手架结构 render函数 修改默认配置 ref属性 props配置项 mixin混入 插件 scoped样式 分析脚手架结构 脚手架文件结构 ├── node_modules ├── public│ ├── favicon.ico: 页签图标│ └── index.html: 主页面├── …

【Linux修炼手册:基本指令(上)】

目录 1 ls 指令 2 pwd命令 3 cd 指令 4 touch指令 5 mkdir指令&#xff08;重要&#xff09; 6 rmdir指令 && rm 指令&#xff08;重要&#xff09; 7 cp指令&#xff08;重要&#xff09; 8 mv指令&#xff08;重要&#xff09; 9 cat 总结&#xff1a; 1 ls…

C语言如何做到四舍五入保留小数

C语言中的格式化打印 : 例如&#xff1a; printf("%.2f",21.195); 输出是 21.20 四舍五入保留了定义宏变量 #define 即符号常量 也能够四舍五入保留 而变量和常变量 并不四舍五入&#xff1a; float a21.195 ;const float b21.195;printf("%.2f \n %.2f&quo…

Java本地搭建宝塔部署实战springboot工艺管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套java开发的工艺管理系统源码&#xff0c;该系统是前后端分离的架构&#xff0c;前端使用Vue2&#xff0c;后端使用SpringBoot2。 技术架构 技术框架&#xff1a;SpringBoot2.0.0 Mybatis1.3.…

【linux】stat文件属性中三个时间的区别(Access time,Modify time,Change time)

在了解这三个时间之前&#xff0c;我们了解什么是stat。 stat 文件名/目录 表示查看这个文件或者目录的属性&#xff0c;当然属性中包括我们的三个时间属性。 例如&#xff1a; OK&#xff0c;了解完stat之后 ,我们开始进入主题&#xff1a;Access time,Modify time,Change t…

几款很好看的爱心表白代码(动态)

分享几款好看的爱心表白代码❤️爱心代码❤️&#xff08;C语言&#xff09;❤️流动爱心❤️&#xff08;htmlcssjs&#xff09;❤️线条爱心❤️&#xff08;htmlcssjs&#xff09;❤️biu表白爱心❤️&#xff08;htmlcssjs&#xff09;❤️matlab爱心函数❤️&#xff08;需…

LSTM--火灾温度预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第R2周&#xff1a;LSTM-火灾温度预测&#x1f356; 作者&#xff1a;K同学啊一句话介绍LSTM&#xff0c;它是RNN的进阶版&#xff0c;如果…

静态路由———初学

文章目录实验需求:关键命令&#xff1a;静态路由默认路由实验配置接下来是配置pc的IP地址静态路由的配置保存实验需求: PC1 在 LAN1 中&#xff0c;PC2 在 LAN2 中&#xff0c;使用静态路由实现 pc1 和 pc2 之间的互相通信 本实验使用Cisco Packet Tracer 模拟器搭建 所有的路…

公考求的是稳定,搞IT求的是高薪,鱼和熊掌能否兼得?

程序员和公务员&#xff0c;大概是最让大家耳熟能详的两种职业。 这也是中国现代年轻人最具有代表性的两种职业。 程序员是从事程序开发、程序维护的专业人员。一般将程序员分为程序设计人员和程序编码人员&#xff0c;但两者的界限并不非常清楚&#xff0c;特别是在中国。软…

Verilog功能模块——Uart收发

摘要本文分享了一种通用的Uart收发模块&#xff0c;可实现Uart协议所支持的任意波特率&#xff0c;任意位宽数据&#xff08;5~8&#xff09;&#xff0c;任意校验位&#xff08;无校验、奇校验、偶校验、1校验、0校验&#xff09;&#xff0c;任意停止位&#xff08;1、1.5、2…

前端反爬思考,好友从百度搜到了我的文章,链接却是别人的

今天感叹可以改完八阿哥早点下班&#xff0c;在吃饭的时候&#xff0c;就想着自己也写了一段时间了&#xff0c;看看百度这个强大的引擎能不能搜到我的博客文章。 1、发现文章被爬走了 吃饭的时候用手机搜的&#xff0c;感觉还挺开心&#xff0c;我还给朋友炫耀&#xff0c;你看…

Import Error: from torchtext.data import to_map_style_dataset解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…

电子统计台账:快速设置产品的排除与保留

目录 1 基础操作 2 设置垂直过滤模板 2.1 排除法 2.2 保留法 3 完成其他设置 4 小提示&#xff1a;项目导入导出 实践中&#xff0c;企业数据文件中可能有很多产品&#xff0c;中间混杂诸如“累计”、“合计”、“报表人”、“企业负责人”等信息。我们需要用简单的操作完…

洛谷千题详解 | P1018 [NOIP2000 提高组] 乘积最大【C++、Python、Java、pascal语言】

博主主页&#xff1a;Yu仙笙 专栏地址&#xff1a;洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析&#xff1a; C源码&#xff1a; Python源码&#xff1a; Pascal源码&#xff1a; Java源码&#xff1a; -------------------------------------------------…

苯丙氨酸甲酯双三氟甲基磺酰亚胺[PheC1][Tf2N]氨基酸酯离子液体

苯丙氨酸甲酯双三氟甲基磺酰亚胺[PheC1][Tf2N]氨基酸酯离子液体 纯度&#xff1a;95% 外观与形状:液体/固体, 储存:存放于惰性气体之中 应避免湿气 (吸湿) 包装规格(Packing):50g、100g、500g 保存方法&#xff1a;密闭&#xff0c;阴凉&#xff0c;通风干燥处 氨基酸酯…

返回Series或DataFrame中指定列中指定数量的最小值nsmallest()函数

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 返回Series或DataFrame中 指定列中指定数量的最小值 nsmallest()函数 [太阳]选择题 下列说法错误的是? import pandas as pd mySeries pd.Series([31, 21, 11]) print("【显示】mySer…

Numpy手撸softmax regression

算法介绍 Softmax 回归&#xff08;或多项逻辑回归&#xff09;是将逻辑回归推广到我们想要处理多个类的情况。 在逻辑回归中&#xff0c;我们假设标签是二元的&#xff1a;y(i)∈{0,1}y^{(i)} \in \{0,1\}y(i)∈{0,1},我们使用这样的分类器来区分两种手写数字。 Softmax 回归…