层次聚类算法及其实现

版权声明: https://blog.csdn.net/HUSTLX/article/details/50849608

  层次聚类算法分为合并算法和分裂算法。合并算法会在每一步减少聚类中心的数量,聚类产生的结果来自前一步的两个聚类的合并;分裂算法与合并算法原理相反,在每一步增加聚类的数量,每一步聚类产生的结果都将是前一步聚类中心分裂得到的。合并算法现将每个样品自成一类,然后根据类间距离的不同,合并距离小于阈值的类。我用了基于最短距离算法的层次聚类算法,最短距离算法认为,只要两个类的最小距离小于阈值,就将两个类合并成一个类。

1层次聚类算法实现步骤

①获得所有样品特征

②设置阈值

③将所有样品各分一类,聚类中心等于样品总个数。

④对所有样品循环:

         找到距离最近的两类pipj,设置距离minDis

         minDis<=T,则合并pipj否则退出循环。

2层次聚类算法的编程实现

clear all;close all;clc;

第一类数据

mu1=[0 0 ];  %均值

S1=[0.1 0 ;0 0.1];  %协方差

data1=mvnrnd(mu1,S1,100);   %产生高斯分布数据

%第二类数据

mu2=[1.25 1.25 ];

S2=[0.1 0 ;0 0.1];

data2=mvnrnd(mu2,S2,100);

第三个类数据

mu3=[-1.25 1.25 ];

S3=[0.1 0 ;0 0.1];

data3=mvnrnd(mu3,S3,100);

显示数据

plot(data1(:,1),data1(:,2),'b+');

hold on;

plot(data2(:,1),data2(:,2),'r+');

plot(data3(:,1),data3(:,2),'g+');

grid on;

%  三类数据合成一个不带标号的数据类

data=[data1;data2;data3]; 

[m,n]=size(data);

patternNum=m;

T=0.1;

pattern=zeros(m,n+1);

for i=1:patternNum

    pattern(i,n+1)=i;

    pattern(i,1:n)=data(i,:);

end

while 1

    minDis=inf;

    pi=0;

    pj=0;

%     寻找距离最近的两个类计算最小距离

    for i=1:patternNum-1

        for j=i+1:patternNum

            if(pattern(i,n+1)~=pattern(j,n+1))

                tempDis=norm(pattern(i,1:n)-pattern(j,1:n));

                if(tempDis<minDis)

                    minDis=tempDis;

                    pi=pattern(i,n+1);

                    pj=pattern(j,n+1);

                end

            end

        end

    end

%     距离小于阈值则合并两个类

    if(minDis<=T)

        if(pi>pj)

            temp=pi;

            pi=pj;

            pj=temp;

        end

        for i=1:patternNum

            if(pattern(i,n+1)==pi)

                pattern(i,n+1)=pi;

            elseif(pattern(i,n+1)>pi)

                pattern(i,n+1)=pattern(i,n+1)-1;

            end

        end

    else

        break;

    end

end

disp('ok')

[m, n]=size(pattern);

%最后显示聚类后的数据

figure;

hold on;

for i=1:m

    if pattern(i,n)==1  

         plot(pattern(i,1),pattern(i,2),'r*');

    elseif pattern(i,n)==2

         plot(pattern(i,1),pattern(i,2),'g*');

    elseif pattern(i,n)==3

         plot(pattern(i,1),pattern(i,2),'b*');

    elseif pattern(i,n)==4

         plot(pattern(i,1),pattern(i,2),'y*');

    else

         plot(pattern(i,1),pattern(i,2),'m*');

    end

end

grid on;

3层次聚类算法测试结果:

下图是产生的高斯数对及当阈值设置为T=0.1的时候的结果:

lip_image007lip_image008

T=0.5时的结果:

lip_image009

可见当阈值设的比较大时所有的都将成为一类。所以阈值的设置很重要。

基于最小距离的层次聚算法对类间距要求很高,例如将高斯数对的协方差加大,产生距离比较近的数对时,层次聚类算法就会出现很大问题如下图:

lip_image010lip_image011

但是在相同的生成参数下,kmeans却有很好的效果:

lip_image012




猜你喜欢

转载自blog.csdn.net/HUSTLX/article/details/50849608
今日推荐