密度峰值聚类算法MATLAB程序

凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/

密度峰值聚类算法简介见:[转] 密度峰值聚类算法(DPC)

数据见:MATLAB中“fitgmdist”的用法及其GMM聚类算法,保存为gauss_data.txt文件,数据最后一列是类标签。

1. MATLAB程序

  1. clear all
  2. close all
  3. %% 从文件中读取数据
  4. data_load=dlmread('gauss_data.txt');
  5. [num,dim]=size(data_load); %数据最后一列是类标签
  6. data=data_load(:,1:dim-1); %去掉标签的数据
  7. mdist=pdist(data); %两两行之间距离
  8. A=tril(ones(num))-eye(num);
  9. [x,y]=find(A~=0);
  10. % Column 1: id of element i, Column 2: id of element j', Column 3: dist(i,j)'
  11. xx=[x y mdist'];
  12. ND=max(xx(:,2));
  13. NL=max(xx(:,1));
  14. if (NL>ND)
  15. ND=NL; %% 确保 DN 取为第一二列最大值中的较大者,并将其作为数据点总数
  16. end
  17. N=size(xx,1); %% xx 第一个维度的长度,相当于文件的行数(即距离的总个数)
  18.  
  19. %% 初始化为零
  20. for i=1:ND
  21. for j=1:ND
  22. dist(i,j)=0;
  23. end
  24. end
  25.  
  26. %% 利用 xx 为 dist 数组赋值,注意输入只存了 0.5*DN(DN-1) 个值,这里将其补成了满矩阵
  27. %% 这里不考虑对角线元素
  28. for i=1:N
  29. ii=xx(i,1);
  30. jj=xx(i,2);
  31. dist(ii,jj)=xx(i,3);
  32. dist(jj,ii)=xx(i,3);
  33. end
  34.  
  35. %% 确定 dc
  36. percent=2.0;
  37. fprintf('average percentage of neighbours (hard coded): %5.6f\n', percent);
  38.  
  39. position=round(N*percent/100); %% round 是一个四舍五入函数
  40. sda=sort(xx(:,3)); %% 对所有距离值作升序排列
  41. dc=sda(position);
  42.  
  43. %% 计算局部密度 rho (利用 Gaussian 核)
  44. fprintf('Computing Rho with gaussian kernel of radius: %12.6f\n', dc);
  45.  
  46. %% 将每个数据点的 rho 值初始化为零
  47. for i=1:ND
  48. rho(i)=0.;
  49. end
  50.  
  51. % Gaussian kernel
  52. for i=1:ND-1
  53. for j=i+1:ND
  54. rho(i)=rho(i)+exp(-(dist(i,j)/dc)*(dist(i,j)/dc));
  55. rho(j)=rho(j)+exp(-(dist(i,j)/dc)*(dist(i,j)/dc));
  56. end
  57. end
  58. %
  59. % "Cut off" kernel
  60. %
  61. %for i=1:ND-1
  62. % for j=i+1:ND
  63. % if (dist(i,j)<dc)
  64. % rho(i)=rho(i)+1.;
  65. % rho(j)=rho(j)+1.;
  66. % end
  67. % end
  68. %end
  69. %% 先求矩阵列最大值,再求最大值,最后得到所有距离值中的最大值
  70. maxd=max(max(dist));
  71. %% 将 rho 按降序排列,ordrho 保持序
  72. [rho_sorted,ordrho]=sort(rho,'descend');
  73. %% 处理 rho 值最大的数据点
  74. delta(ordrho(1))=-1.;
  75. nneigh(ordrho(1))=0;
  76. %% 生成 delta 和 nneigh 数组
  77. for ii=2:ND
  78. delta(ordrho(ii))=maxd;
  79. for jj=1:ii-1
  80. if(dist(ordrho(ii),ordrho(jj))<delta(ordrho(ii)))
  81. delta(ordrho(ii))=dist(ordrho(ii),ordrho(jj));
  82. nneigh(ordrho(ii))=ordrho(jj);
  83. % 记录 rho 值更大的数据点中与 ordrho(ii) 距离最近的点的编号 ordrho(jj)
  84. end
  85. end
  86. end
  87.  
  88. %% 生成 rho 值最大数据点的 delta 值
  89. delta(ordrho(1))=max(delta(:));
  90.  
  91. %% 决策图
  92. disp('Generated file:DECISION GRAPH')
  93. disp('column 1:Density')
  94. disp('column 2:Delta')
  95.  
  96. fid = fopen('DECISION_GRAPH', 'w');
  97. for i=1:ND
  98. fprintf(fid, '%6.2f %6.2f\n', rho(i),delta(i));
  99. end
  100.  
  101. %% 选择一个围住类中心的矩形
  102. disp('Select a rectangle enclosing cluster centers')
  103.  
  104. %% 每台计算机,句柄的根对象只有一个,就是屏幕,它的句柄总是 0
  105. %% >> scrsz = get(0,'ScreenSize')
  106. %% scrsz =
  107. %% 1 1 1280 800
  108. %% 1280 和 800 就是你设置的计算机的分辨率,scrsz(4) 就是 800,scrsz(3) 就是 1280
  109. scrsz = get(0,'ScreenSize');
  110.  
  111. %% 人为指定一个位置
  112. figure('Position',[6 72 scrsz(3)/4. scrsz(4)/1.3]);
  113.  
  114. %% ind 和 gamma 在后面并没有用到
  115. for i=1:ND
  116. ind(i)=i;
  117. gamma(i)=rho(i)*delta(i);
  118. end
  119.  
  120. %% 利用 rho 和 delta 画出一个所谓的“决策图”
  121. subplot(2,1,1)
  122. tt=plot(rho(:),delta(:),'o','MarkerSize',5,'MarkerFaceColor','k','MarkerEdgeColor','k');
  123. title ('Decision Graph','FontSize',15.0)
  124. xlabel ('\rho')
  125. ylabel ('\delta')
  126.  
  127. fig=subplot(2,1,1);
  128. rect = getrect(fig);
  129.  
  130. %% getrect 从图中用鼠标截取一个矩形区域, rect 中存放的是
  131. %% 矩形左下角的坐标 (x,y) 以及所截矩形的宽度和高度
  132. rhomin=rect(1);
  133. deltamin=rect(2); %% 作者承认这是个 error,已由 4 改为 2 了!
  134.  
  135. %% 初始化 cluster 个数
  136. NCLUST=0;
  137.  
  138. %% cl 为归属标志数组,cl(i)=j 表示第 i 号数据点归属于第 j 个 cluster
  139. %% 先统一将 cl 初始化为 -1
  140. for i=1:ND
  141. cl(i)=-1;
  142. end
  143.  
  144. %% 在矩形区域内统计数据点(即聚类中心)的个数
  145. for i=1:ND
  146. if ( (rho(i)>rhomin) && (delta(i)>deltamin))
  147. NCLUST=NCLUST+1;
  148. cl(i)=NCLUST; %% 第 i 号数据点属于第 NCLUST 个 cluster
  149. icl(NCLUST)=i; %% 逆映射,第 NCLUST 个 cluster 的中心为第 i 号数据点
  150. end
  151. end
  152. fprintf('NUMBER OF CLUSTERS: %i \n', NCLUST);
  153. disp('Performing assignation')
  154.  
  155. %assignation
  156. %% 将其他数据点归类 (assignation)
  157. for i=1:ND
  158. if (cl(ordrho(i))==-1)
  159. cl(ordrho(i))=cl(nneigh(ordrho(i)));
  160. end
  161. end
  162. %halo
  163. %% 由于是按照 rho 值从大到小的顺序遍历,循环结束后, cl 应该都变成正的值了.
  164.  
  165. %% 处理光晕点,halo这段代码应该移到 if (NCLUST>1) 内去比较好吧
  166. for i=1:ND
  167. halo(i)=cl(i);
  168. end
  169. if (NCLUST>1)
  170. % 初始化数组 bord_rho 为 0,每个 cluster 定义一个 bord_rho 值
  171. for i=1:NCLUST
  172. bord_rho(i)=0.;
  173. end
  174. % 获取每一个 cluster 中平均密度的一个界 bord_rho
  175. for i=1:ND-1
  176. for j=i+1:ND
  177. %% 距离足够小但不属于同一个 cluster 的 i 和 j
  178. if ((cl(i)~=cl(j))&& (dist(i,j)<=dc))
  179. rho_aver=(rho(i)+rho(j))/2.; %% 取 i,j 两点的平均局部密度
  180. if (rho_aver>bord_rho(cl(i)))
  181. bord_rho(cl(i))=rho_aver;
  182. end
  183. if (rho_aver>bord_rho(cl(j)))
  184. bord_rho(cl(j))=rho_aver;
  185. end
  186. end
  187. end
  188. end
  189.  
  190. %% halo 值为 0 表示为 outlier
  191. for i=1:ND
  192. if (rho(i)<bord_rho(cl(i)))
  193. halo(i)=0;
  194. end
  195. end
  196. end
  197.  
  198. %% 逐一处理每个 cluster
  199. for i=1:NCLUST
  200. nc=0; %% 用于累计当前 cluster 中数据点的个数
  201. nh=0; %% 用于累计当前 cluster 中核心数据点的个数
  202. for j=1:ND
  203. if (cl(j)==i)
  204. nc=nc+1;
  205. end
  206. if (halo(j)==i)
  207. nh=nh+1;
  208. end
  209. end
  210. fprintf('CLUSTER: %i CENTER: %i ELEMENTS: %i CORE: %i HALO: %i \n', i,icl(i),nc,nh,nc-nh);
  211. end
  212.  
  213. cmap=colormap;
  214. for i=1:NCLUST
  215. ic=int8((i*64.)/(NCLUST*1.));
  216. subplot(2,1,1)
  217. hold on
  218. plot(rho(icl(i)),delta(icl(i)),'o','MarkerSize',8,'MarkerFaceColor',cmap(ic,:),'MarkerEdgeColor',cmap(ic,:));
  219. end
  220. subplot(2,1,2)
  221. disp('Performing 2D nonclassical multidimensional scaling')
  222. Y1 = mdscale(dist, 2, 'criterion','metricstress');
  223. plot(Y1(:,1),Y1(:,2),'o','MarkerSize',2,'MarkerFaceColor','k','MarkerEdgeColor','k');
  224. title ('2D Nonclassical multidimensional scaling','FontSize',15.0)
  225. xlabel ('X')
  226. ylabel ('Y')
  227. for i=1:ND
  228. A(i,1)=0.;
  229. A(i,2)=0.;
  230. end
  231. for i=1:NCLUST
  232. nn=0;
  233. ic=int8((i*64.)/(NCLUST*1.));
  234. for j=1:ND
  235. if (halo(j)==i)
  236. nn=nn+1;
  237. A(nn,1)=Y1(j,1);
  238. A(nn,2)=Y1(j,2);
  239. end
  240. end
  241. hold on
  242. plot(A(1:nn,1),A(1:nn,2),'o','MarkerSize',2,'MarkerFaceColor',cmap(ic,:),'MarkerEdgeColor',cmap(ic,:));
  243. end
  244.  
  245. %for i=1:ND
  246. % if (halo(i)>0)
  247. % ic=int8((halo(i)*64.)/(NCLUST*1.));
  248. % hold on
  249. % plot(Y1(i,1),Y1(i,2),'o','MarkerSize',2,'MarkerFaceColor',cmap(ic,:),'MarkerEdgeColor',cmap(ic,:));
  250. % end
  251. %end
  252. faa = fopen('CLUSTER_ASSIGNATION', 'w');
  253. disp('Generated file:CLUSTER_ASSIGNATION')
  254. disp('column 1:element id')
  255. disp('column 2:cluster assignation without halo control')
  256. disp('column 3:cluster assignation with halo control')
  257. for i=1:ND
  258. fprintf(faa, '%i %i %i\n',i,cl(i),halo(i));
  259. end

2. 结果

注:出错的话,将Y1 = mdscale(dist, 2, 'criterion','metricstress');换一个准则函数,比如改为Y1 = mdscale(dist, 2, 'criterion','sstress');

密度峰值聚类算法MATLAB程序的更多相关文章

  1. 密度峰值聚类算法(DPC)

    密度峰值聚类算法(DPC) 凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 简介 基于密度峰值的聚类算法全称为基于快速搜索和发现密度峰值的聚类算法(cl ...

  2. 密度峰值聚类算法原理+python实现

    ​ 密度峰值聚类(Density peaks clustering, DPC)来自Science上Clustering by fast search and find of density peaks ...

  3. 简单易学的机器学习算法——基于密度的聚类算法DBSCAN

    一.基于密度的聚类算法的概述     最近在Science上的一篇基于密度的聚类算法<Clustering by fast search and find of density peaks> ...

  4. 简单易学的机器学习算法—基于密度的聚类算法DBSCAN

    简单易学的机器学习算法-基于密度的聚类算法DBSCAN 一.基于密度的聚类算法的概述 我想了解下基于密度的聚类算法,熟悉下基于密度的聚类算法与基于距离的聚类算法,如K-Means算法之间的区别.    ...

  5. 【机器学习】DBSCAN Algorithms基于密度的聚类算法

    一.算法思想: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法.与划分和层 ...

  6. 标准差分进化算法matlab程序实现(转载)

    标准差分进化算法matlab程序实现 自适应差分演化算法方面的Matlab和C++代码及论文 差分进化算法 DE-Differential Evolution matlab练习程序(差异演化DE) [ ...

  7. 蚁群算法 matlab程序(已执行)

    下面是解放军信息project大学一个老师编的matlab程序,请尊重原作者劳动,引用时请注明出处. 我经过改动添加了凝视,已经执行过,无误, function [R_best,L_best,L_av ...

  8. 谱聚类算法—Matlab代码

    % ========================================================================= % 算 法 名 称: Spectral Clus ...

  9. K-medodis聚类算法MATLAB

    国内博客,上介绍实现的K-medodis方法为: 与K-means算法类似.只是距离选择与聚类中心选择不同. 距离为曼哈顿距离 聚类中心选择为:依次把一个聚类中的每一个点当作当前类的聚类中心,求出代价 ...

随机推荐

  1. cookie,webstorage的理解

    在前两天的开发时,遇到一个问题,需要将一个网页在预加载时,优先出一个弹出框,但是再次加载时不希望它出现,在经过一段时间的搜索和尝试之后,发现了大多使用的两种方式:生成cookie和webStorage ...

  2. Docker容器数据卷介绍和命令

    是什么 一句话:有点类似我们Redis里面的rdb和aof文件 先来看看Docker的理念: *  将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的 *   ...

  3. s3c2440裸机-UART编程(一、UART硬件介绍及传输原理)

    1.uart硬件介绍 UART的全称是Universal Asynchronous Receiver and Transmitter(异步收发器). uart主要用于: 1.打印调试 2.数据传输 串 ...

  4. 以太网驱动的流程浅析(二)-Ifconfig的详细代码流程【原创】

    以太网驱动流程浅析(二)-ifconfig的详细代码流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<L ...

  5. MySQL 的 4 种隔离级别,你了解么?

    1.什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做.事务的结束 ...

  6. python中可变与不可变类型的全局变量

    python中的不可变类型的全局变量如int  a=1,str  b='hello', 若需要修改必须加global申明, 而全局变量是可变类型的,如list, dict ,则直接修改list.app ...

  7. IT兄弟连 Java语法教程 数据类型 进制转换

    ●  正十进制转换为二进制 拆分法,将十进制整数拆分为若干个二进制权重的和,若有该权重则下面写1,否则写0.如: 34 = 32 + 2 128 64 32 16 8 4 2 1 0  0  1  0 ...

  8. flex——justify-content属性引起的一个样式问题

     前言  在flex布局出现以前,我一般习惯使用浮动布局(float)来实现下列布局   现在尽量少用浮动布局,虽然好用,但有时会带来一些意想不到的问题,甚至导致布局错位,   一开始浮动布局只是为了 ...

  9. docker 中 安装配置 mysqlcluster(arm)

    1:创建两个docker container 这里我使用给指定 container ip的形式创建: 查看容器网络 docker network ls 创建一个新的bridge网络 docker ne ...

  10. 【转】ASP.NET Core 如何设置发布环境

    在ASP.NET Core中自带了一些内置对象,可以读取到当前程序处于什么样的环境当中,比如在ASP.NET Core的Startup类的Configure方法中,我们就会看到这么一段代码: publ ...