最近在学习论文的时候发现了在science上发表的关于新型的基于密度的聚类算法

Kmean算法有很多不足的地方,比如k值的确定,初始结点选择,而且还不能检测费球面类别的数据分布,对于第二个问题,提出了Kmean++,而其他不足还没有解决,dbscan虽然可以对任意形状分布的进行聚类,但是必须指定一个密度阈值,从而去除低于此密度阈值的噪音点,这篇文章解决了这些不足。

本文提出的聚类算法的核心思想在于,对聚类中心的刻画上,而且认为聚类中心同时具有以下两种特点:

  • 本身的密度大,即它被密度均不超过它的邻居包围
  • 与其他密度更大的数据点之间的“距离”相对更大

 

通俗的理解为:给一个节点求与其距离小于一个值的节点的个数,用这个个数表示节点的密度,此时求出来的就是节点的局部密度,

经过上边的过程,每个点都可以找到两个距离与之对应,然后建立一个二维坐标轴,在坐标轴上把图形画出来,如下图

最后,附上作者在补充材料里提供的 Matlab 示例程序 (加了适当的代码注释)

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

参考:http://blog.csdn.net/aimatfuture/article/details/39405261

http://blog.csdn.net/zxdxyz/article/details/40655231

一种新型聚类算法(Clustering by fast search and find of density peaksd)的更多相关文章

  1. Science14年的聚类论文——Clustering by fast search and find of density peaks

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 这是一个比较新的聚类方法(文章中没看见作者对其取名,在这里我姑且称该方法为local density clu ...

  2. Science论文"Clustering by fast search and find of density peaks"学习笔记

    "Clustering by fast search and find of density peaks"是今年6月份在<Science>期刊上发表的的一篇论文,论文中 ...

  3. 处理输入为非对角阵的Clustering by fast search and find of density peak代码

    Clustering by fast search and find of density peak. Alex Rodriguez, Alessandro Laio 是发表在Science上的一篇很 ...

  4. Clustering by fast search and find of density peaks

    参考:http://www.52ml.net/16296.html 这个算法的优点就在于,它首先一步就能找到聚类中心,然后划分类别.而其他算法需要反复迭代才能找到中心聚类. 就是不知道代码该怎么写.. ...

  5. 发表在 Science 上的一种新聚类算法

    今年 6 月份,Alex Rodriguez 和 Alessandro Laio 在 Science 上发表了一篇名为<Clustering by fast search and find of ...

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

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

  7. 各类聚类(clustering)算法初探

    1. 聚类简介 0x1:聚类是什么? 聚类是一种运用广泛的探索性数据分析技术,人们对数据产生的第一直觉往往是通过对数据进行有意义的分组.很自然,首先要弄清楚聚类是什么? 直观上讲,聚类是将对象进行分组 ...

  8. Science上发表的超赞聚类算法

    本博客已经迁往http://www.kemaswill.com/, 博客园这边也会继续更新, 欢迎关注~ 作者(Alex Rodriguez, Alessandro Laio)提出了一种很简洁优美的聚 ...

  9. Science上发表的超赞聚类算法(转)

    作者(Alex Rodriguez, Alessandro Laio)提出了一种很简洁优美的聚类算法, 可以识别各种形状的类簇, 并且其超参数很容易确定. 算法思想 该算法的假设是类簇的中心由一些局部 ...

随机推荐

  1. vi 打开文件,行末尾有^M

    原因: Windows下的文本文件的每一行结尾,都有一个回车符('\n')和一个换行符('\r') Linux下的文本文件的每一行结尾,只有一个回车符('\n') Mac下的文本文件的每一行结尾,只有 ...

  2. (弃) Keystone CLI_选项与子命令概况

    本文档介绍icehouse发行版keystone命令 keystone Command-Line Interface (CLI)提供用于和keystone服务器交互的方便工具,但是该命令行工具逐渐受到 ...

  3. FunGuild 数据库简介

    FUNGulid = Fungi + Functional + Guild , 是一个真菌的功能注释的数据库,目前数据库中涵盖了超过12000个真菌的功能注释信息: 网址如下: http://www. ...

  4. C# WinForm下,隐藏主窗体的方法

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. 自建Nuger Server拾遗

    企业内部的包需要通过nuget来管理发布,或者一些不允许上外网的企业,通过自己的nuget服务器来使用nuget,都会考虑到自建一个nuget服务器.本文整理了一些有用的链接和使用心得,以备不时之需. ...

  6. MVC阻止用户注入JavaScript代码或者Html标记

    使用HttpUtility.HtmlEncode("")将字符串进行过滤处理

  7. Ubuntu16.04下安装CUDA8.0和tensorflow

    GPU版的Tensorflow无疑是深度学习的一大神器,当然caffe之类的框架也可以用GPU来加速训练. 注意:以下安装默认为python2.7 1. 安装依赖包 $ sudo apt-get in ...

  8. yum常用操作

    一.yum安装使用: 1.Yum:rpm的前端程序,用来解决软件包相关依赖性,可以在多个库之间定位软件包,up2date的替代工具 2.yum repository:yum repo,存储了众多rpm ...

  9. hibernate 之 sql查询

    如果用hibernate执行原生sql进行数据查询可以调用 SQLQuery query = getSession().createSQLQuery(sql); 然后再执行 query.list() ...

  10. Linux-PAM认证机制

    http://www.cnblogs.com/marility/articles/9235522.html https://www.jianshu.com/p/342c05b51b7c https:/ ...