一种新型聚类算法(Clustering by fast search and find of density peaksd)

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

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

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

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

 

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

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

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

clear all
close all
disp(‘The only input needed is a distance matrix file‘)
disp(‘The format of this file should be: ‘)
disp(‘Column 1: id of element i‘)
disp(‘Column 2: id of element j‘)
disp(‘Column 3: dist(i,j)‘)  

%% 从文件中读取数据
mdist=input(‘name of the distance matrix file (with single quotes)?\n‘);
disp(‘Reading input distance matrix‘)
xx=load(mdist);
ND=max(xx(:,2));
NL=max(xx(:,1));
if (NL>ND)
  ND=NL;  %% 确保 DN 取为第一二列最大值中的较大者,并将其作为数据点总数
end  

N=size(xx,1); %% xx 第一个维度的长度,相当于文件的行数(即距离的总个数)  

%% 初始化为零
for i=1:ND
  for j=1:ND
    dist(i,j)=0;
  end
end  

%% 利用 xx 为 dist 数组赋值,注意输入只存了 0.5*DN(DN-1) 个值,这里将其补成了满矩阵
%% 这里不考虑对角线元素
for i=1:N
  ii=xx(i,1);
  jj=xx(i,2);
  dist(ii,jj)=xx(i,3);
  dist(jj,ii)=xx(i,3);
end  

%% 确定 dc  

percent=2.0;
fprintf(‘average percentage of neighbours (hard coded): %5.6f\n‘, percent);  

position=round(N*percent/100); %% round 是一个四舍五入函数
sda=sort(xx(:,3)); %% 对所有距离值作升序排列
dc=sda(position);  

%% 计算局部密度 rho (利用 Gaussian 核)  

fprintf(‘Computing Rho with gaussian kernel of radius: %12.6f\n‘, dc);  

%% 将每个数据点的 rho 值初始化为零
for i=1:ND
  rho(i)=0.;
end  

% Gaussian kernel
for i=1:ND-1
  for j=i+1:ND
     rho(i)=rho(i)+exp(-(dist(i,j)/dc)*(dist(i,j)/dc));
     rho(j)=rho(j)+exp(-(dist(i,j)/dc)*(dist(i,j)/dc));
  end
end  

% "Cut off" kernel
%for i=1:ND-1
%  for j=i+1:ND
%    if (dist(i,j)<dc)
%       rho(i)=rho(i)+1.;
%       rho(j)=rho(j)+1.;
%    end
%  end
%end  

%% 先求矩阵列最大值,再求最大值,最后得到所有距离值中的最大值
maxd=max(max(dist));   

%% 将 rho 按降序排列,ordrho 保持序
[rho_sorted,ordrho]=sort(rho,‘descend‘);  

%% 处理 rho 值最大的数据点
delta(ordrho(1))=-1.;
nneigh(ordrho(1))=0;  

%% 生成 delta 和 nneigh 数组
for ii=2:ND
   delta(ordrho(ii))=maxd;
   for jj=1:ii-1
     if(dist(ordrho(ii),ordrho(jj))<delta(ordrho(ii)))
        delta(ordrho(ii))=dist(ordrho(ii),ordrho(jj));
        nneigh(ordrho(ii))=ordrho(jj);
        %% 记录 rho 值更大的数据点中与 ordrho(ii) 距离最近的点的编号 ordrho(jj)
     end
   end
end  

%% 生成 rho 值最大数据点的 delta 值
delta(ordrho(1))=max(delta(:));  

%% 决策图  

disp(‘Generated file:DECISION GRAPH‘)
disp(‘column 1:Density‘)
disp(‘column 2:Delta‘)  

fid = fopen(‘DECISION_GRAPH‘, ‘w‘);
for i=1:ND
   fprintf(fid, ‘%6.2f %6.2f\n‘, rho(i),delta(i));
end  

%% 选择一个围住类中心的矩形
disp(‘Select a rectangle enclosing cluster centers‘)  

%% 每台计算机,句柄的根对象只有一个,就是屏幕,它的句柄总是 0
%% >> scrsz = get(0,‘ScreenSize‘)
%% scrsz =
%%            1           1        1280         800
%% 1280 和 800 就是你设置的计算机的分辨率,scrsz(4) 就是 800,scrsz(3) 就是 1280
scrsz = get(0,‘ScreenSize‘);  

%% 人为指定一个位置,感觉就没有那么 auto 了 :-)
figure(‘Position‘,[6 72 scrsz(3)/4. scrsz(4)/1.3]);  

%% ind 和 gamma 在后面并没有用到
for i=1:ND
  ind(i)=i;
  gamma(i)=rho(i)*delta(i);
end  

%% 利用 rho 和 delta 画出一个所谓的“决策图”  

subplot(2,1,1)
tt=plot(rho(:),delta(:),‘o‘,‘MarkerSize‘,5,‘MarkerFaceColor‘,‘k‘,‘MarkerEdgeColor‘,‘k‘);
title (‘Decision Graph‘,‘FontSize‘,15.0)
xlabel (‘\rho‘)
ylabel (‘\delta‘)  

subplot(2,1,1)
rect = getrect(1);
%% getrect 从图中用鼠标截取一个矩形区域, rect 中存放的是
%% 矩形左下角的坐标 (x,y) 以及所截矩形的宽度和高度
rhomin=rect(1);
deltamin=rect(2); %% 作者承认这是个 error,已由 4 改为 2 了!  

%% 初始化 cluster 个数
NCLUST=0;  

%% cl 为归属标志数组,cl(i)=j 表示第 i 号数据点归属于第 j 个 cluster
%% 先统一将 cl 初始化为 -1
for i=1:ND
  cl(i)=-1;
end  

%% 在矩形区域内统计数据点(即聚类中心)的个数
for i=1:ND
  if ( (rho(i)>rhomin) && (delta(i)>deltamin))
     NCLUST=NCLUST+1;
     cl(i)=NCLUST; %% 第 i 号数据点属于第 NCLUST 个 cluster
     icl(NCLUST)=i;%% 逆映射,第 NCLUST 个 cluster 的中心为第 i 号数据点
  end
end  

fprintf(‘NUMBER OF CLUSTERS: %i \n‘, NCLUST);  

disp(‘Performing assignation‘)  

%% 将其他数据点归类 (assignation)
for i=1:ND
  if (cl(ordrho(i))==-1)
    cl(ordrho(i))=cl(nneigh(ordrho(i)));
  end
end
%% 由于是按照 rho 值从大到小的顺序遍历,循环结束后, cl 应该都变成正的值了.   

%% 处理光晕点,halo这段代码应该移到 if (NCLUST>1) 内去比较好吧
for i=1:ND
  halo(i)=cl(i);
end  

if (NCLUST>1)  

  % 初始化数组 bord_rho 为 0,每个 cluster 定义一个 bord_rho 值
  for i=1:NCLUST
    bord_rho(i)=0.;
  end  

  % 获取每一个 cluster 中平均密度的一个界 bord_rho
  for i=1:ND-1
    for j=i+1:ND
      %% 距离足够小但不属于同一个 cluster 的 i 和 j
      if ((cl(i)~=cl(j))&& (dist(i,j)<=dc))
        rho_aver=(rho(i)+rho(j))/2.; %% 取 i,j 两点的平均局部密度
        if (rho_aver>bord_rho(cl(i)))
          bord_rho(cl(i))=rho_aver;
        end
        if (rho_aver>bord_rho(cl(j)))
          bord_rho(cl(j))=rho_aver;
        end
      end
    end
  end  

  %% halo 值为 0 表示为 outlier
  for i=1:ND
    if (rho(i)<bord_rho(cl(i)))
      halo(i)=0;
    end
  end  

end  

%% 逐一处理每个 cluster
for i=1:NCLUST
  nc=0; %% 用于累计当前 cluster 中数据点的个数
  nh=0; %% 用于累计当前 cluster 中核心数据点的个数
  for j=1:ND
    if (cl(j)==i)
      nc=nc+1;
    end
    if (halo(j)==i)
      nh=nh+1;
    end
  end  

  fprintf(‘CLUSTER: %i CENTER: %i ELEMENTS: %i CORE: %i HALO: %i \n‘, i,icl(i),nc,nh,nc-nh);  

end  

cmap=colormap;
for i=1:NCLUST
   ic=int8((i*64.)/(NCLUST*1.));
   subplot(2,1,1)
   hold on
   plot(rho(icl(i)),delta(icl(i)),‘o‘,‘MarkerSize‘,8,‘MarkerFaceColor‘,cmap(ic,:),‘MarkerEdgeColor‘,cmap(ic,:));
end
subplot(2,1,2)
disp(‘Performing 2D nonclassical multidimensional scaling‘)
Y1 = mdscale(dist, 2, ‘criterion‘,‘metricstress‘);
plot(Y1(:,1),Y1(:,2),‘o‘,‘MarkerSize‘,2,‘MarkerFaceColor‘,‘k‘,‘MarkerEdgeColor‘,‘k‘);
title (‘2D Nonclassical multidimensional scaling‘,‘FontSize‘,15.0)
xlabel (‘X‘)
ylabel (‘Y‘)
for i=1:ND
 A(i,1)=0.;
 A(i,2)=0.;
end
for i=1:NCLUST
  nn=0;
  ic=int8((i*64.)/(NCLUST*1.));
  for j=1:ND
    if (halo(j)==i)
      nn=nn+1;
      A(nn,1)=Y1(j,1);
      A(nn,2)=Y1(j,2);
    end
  end
  hold on
  plot(A(1:nn,1),A(1:nn,2),‘o‘,‘MarkerSize‘,2,‘MarkerFaceColor‘,cmap(ic,:),‘MarkerEdgeColor‘,cmap(ic,:));
end  

%for i=1:ND
%   if (halo(i)>0)
%      ic=int8((halo(i)*64.)/(NCLUST*1.));
%      hold on
%      plot(Y1(i,1),Y1(i,2),‘o‘,‘MarkerSize‘,2,‘MarkerFaceColor‘,cmap(ic,:),‘MarkerEdgeColor‘,cmap(ic,:));
%   end
%end
faa = fopen(‘CLUSTER_ASSIGNATION‘, ‘w‘);
disp(‘Generated file:CLUSTER_ASSIGNATION‘)
disp(‘column 1:element id‘)
disp(‘column 2:cluster assignation without halo control‘)
disp(‘column 3:cluster assignation with halo control‘)
for i=1:ND
   fprintf(faa, ‘%i %i %i\n‘,i,cl(i),halo(i));
end  

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

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

时间: 2024-10-23 14:21:37

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

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

这是一个比较新的聚类方法(文章中没看见作者对其取名,在这里我姑且称该方法为local density clustering,LDC),在聚类这个古老的主题上似乎最近一些年的突破不大,这篇文章算是很好的了,方法让人很有启发(醍醐灌顶),并且是发表在Science上,受到的关注自然非常大. 本文的核心亮点:1是用比较新颖的方法来确定聚类中心,2是采用距离的local density来进行聚类的划分.在这两点中,常见的Kmeans算法采用的方法是:用每一类的均值作为中点,用距离的最近的点来确定聚类划分

Clustering by fast search and find of density peaks代码详解

 发表在2014年Science上的聚类方法Clustering by fast search and find of density peaks,不在这赘述介绍了,其matlab代码详细注释下面给出,如果想看该方法的详细解释说明,推荐在阅读原文的基础上,参考这位博主的博文 http://blog.csdn.net/itplus/article/details/38926837 本文版权所有  转载请注明出处 http://blog.csdn.net/mxlmhgzw 无法看清的,请见我博客

Science论文&quot;Clustering by fast search and find of density peaks&quot;学习笔记

"Clustering by fast search and find of density peaks"是今年6月份在<Science>期刊上发表的的一篇论文,论文中提出了一种非常巧妙的聚类算法.经过几天的努力,终于用python实现了文中的算法,下面与大家分享一下自己对算法的理解及实现过程中遇到的问题和解决办法. 首先,该算法是基于这样的假设:类簇中心被具有较低局部密度的邻居点包围,且与具有更高密度的任何点有相对较大的距离.对于每一个数据点,要计算两个量:点的局部密度和

Clustering by fast search and find of density peaks

"Clustering by fast search and find of density peaks"是20114年6月份在<Science>期刊上发表的的一篇论文,论文中提出了一种非常巧妙的聚类算法. 首先,该算法是基于这样的假设: (1)聚类中心密度要高 (2)高密度中心点之间的距离应该相对远一些. 异常点都会被排除,同时也和形状无关. 首先,这种方法不像原先的Kmeans那样随机初始种子点然后迭代,它是根据样本的密度峰值来确定聚类中心的,当然聚类中心确定之后,后面

Hadoop实现Clustering by fast search and find of density peaks

Hadoop实现Clustering by fast search and find of density peaks 本篇博客参考:Clustering by fast search and find of density peaks论文以及http://www.cnblogs.com/peghoty/p/3945653.html. Hadoop版本:2.6.0,Myeclipse:10.0 代码可在https://github.com/fansy1990/fast_cluster下载. 1.

Hadoop实现Clustering by fast search and find of density peaks (2)

本篇博客参考:Clustering by fast search and find of density peaks论文以及http://www.cnblogs.com/peghoty/p/3945653.html. 使用版本: Hadoop版本:2.6.0,Myeclipse:10.0 本地集群情况: node101  (主节点,namenode,datanode,ResourceManager,NodeManager,SecondaryNamenode,3.7G,2核) node102  (

笔记Clustering by fast search and find of density peaks

We propose an approach based on the idea that cluster centers are characterizedby a higher density than their neighbors and by a relatively large distance from points withhigher densities. This idea forms the basis of a clustering procedure in which

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

今年 6 月份,Alex Rodriguez 和 Alessandro Laio 在 Science 上发表了一篇名为<Clustering by fast search and find of density peaks>的文章,为聚类算法的设计提供了一种新的思路.虽然文章出来后遭到了众多读者的质疑,但整体而言,新聚类算法的基本思想很新颖,且简单明快,值得学习.这个新聚类算法的核心思想在于对聚类中心的刻画上,本文将对该算法的原理进行详细介绍,并对其中的若干细节展开讨论. 最后,附上作者在补充

Clustering by fast search and find of desity peaks(基于快速搜索与寻找密度峰值的聚类)

基于快速搜索与寻找密度峰值的聚类(Alex Rodriguez and Alessandro Laio) 摘要:聚类分析目的是基于元素之间的相似度对其进行分类,应用范围从天文学到生物信息学.文献计量学到模式识别.我们提出一种方法,思想基于簇中心具有比其邻居更大密度的特点以及与更大密度点之间有一个相对较大的距离(1.簇中心点有相对高的密度 2.簇中心点之间距离一般较大,即不同类别之间一般距离较远),这种思想形成了簇数目直观出现的聚类机制的基础,自动发现和排除异常点,同时在识别簇时,不用关心其形状和