当前位置 博文首页 > 文章内容

    MATLAB k-means聚类

    作者: 栏目:未分类 时间:2020-09-10 14:00:55

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    聚类算法,不是分类算法。

    分类算法是给一个数据,然后判断这个数据属于已分好的类中的具体哪一类。

    聚类算法是给一大堆原始数据,然后通过算法将其中具有相似特征的数据聚为一类。

    这里的k-means聚类,是事先给出原始数据所含的类数,然后将含有相似特征的数据聚为一个类中。

    所有资料中还是Andrew Ng介绍的明白。

    首先给出原始数据{x1,x2,...,xn},这些数据没有被标记的。

    初始化k个随机数据u1,u2,...,uk。这些xn和uk都是向量。

    根据下面两个公式迭代就能求出最终所有的u,这些u就是最终所有类的中心位置。

    公式一:

    意思就是求出所有数据和初始化的随机数据的距离,然后找出距离每个初始数据最近的数据。

    公式二:

    意思就是求出所有和这个初始数据最近原始数据的距离的均值。

    然后不断迭代两个公式,直到所有的u都不怎么变化了,就算完成了。

    先看看一些结果:

    用三个二维高斯分布数据画出的图:

    通过对没有标记的原始数据进行kmeans聚类得到的分类,十字是最终迭代位置:

    下面是Matlab代码,这里我把测试数据改为了三维了,函数是可以处理各种维度的。

    main.m

     1 clear all;
     2 close all;
     3 clc;
     4 
     5 %第一类数据
     6 mu1=[0 0 0];  %均值
     7 S1=[0.3 0 0;0 0.35 0;0 0 0.3];  %协方差
     8 data1=mvnrnd(mu1,S1,100);   %产生高斯分布数据
     9 
    10 %%第二类数据
    11 mu2=[1.25 1.25 1.25];
    12 S2=[0.3 0 0;0 0.35 0;0 0 0.3];
    13 data2=mvnrnd(mu2,S2,100);
    14 
    15 %第三个类数据
    16 mu3=[-1.25 1.25 -1.25];
    17 S3=[0.3 0 0;0 0.35 0;0 0 0.3];
    18 data3=mvnrnd(mu3,S3,100);
    19 
    20 %显示数据
    21 plot3(data1(:,1),data1(:,2),data1(:,3),'+');
    22 hold on;
    23 plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
    24 plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
    25 grid on;
    26 
    27 %三类数据合成一个不带标号的数据类
    28 data=[data1;data2;data3];   %这里的data是不带标号的
    29 
    30 %k-means聚类
    31 [u re]=KMeans(data,3);  %最后产生带标号的数据,标号在所有数据的最后,意思就是数据再加一维度
    32 [m n]=size(re);
    33 
    34 %最后显示聚类后的数据
    35 figure;
    36 hold on;
    37 for i=1:m 
    38     if re(i,4)==1   
    39          plot3(re(i,1),re(i,2),re(i,3),'ro'); 
    40     elseif re(i,4)==2
    41          plot3(re(i,1),re(i,2),re(i,3),'go'); 
    42     else 
    43          plot3(re(i,1),re(i,2),re(i,3),'bo'); 
    44     end
    45 end
    46 grid on;

    KMeans.m

     1 %N是数据一共分多少类
     2 %data是输入的不带分类标号的数据
     3 %u是每一类的中心
     4 %re是返回的带分类标号的数据
     5 function [u re]=KMeans(data,N)   
     6     [m n]=size(data);   %m是数据个数,n是数据维数
     7     ma=zeros(n);        %每一维最大的数
     8     mi=zeros(n);        %每一维最小的数
     9     u=zeros(N,n);       %随机初始化,最终迭代到每一类的中心位置
    10     for i=1:n
    11        ma(i)=max(data(:,i));    %每一维最大的数
    12        mi(i)=min(data(:,i));    %每一维最小的数
    13        for j=1:N
    14             u(j,i)=ma(i)+(mi(i)-ma(i))*rand();  %随机初始化,不过还是在每一维[min max]中初始化好些
    15        end      
    16     end
    17    
    18     while 1
    19         pre_u=u;            %上一次求得的中心位置
    20         for i=1:N
    21             tmp{i}=[];      % 公式一中的x(i)-uj,为公式一实现做准备
    22             for j=1:m
    23                 tmp{i}=[tmp{i};data(j,:)-u(i,:)];
    24             end
    25         end
    26         
    27         quan=zeros(m,N);
    28         for i=1:m        %公式一的实现
    29             c=[];
    30             for j=1:N
    31                 c=[c norm(tmp{j}(i,:))];
    32             end
    33             [junk index]=min(c);
    34             quan(i,index)=norm(tmp{index}(i,:));           
    35         end
    36         
    37         for i=1:N            %公式二的实现
    38            for j=1:n
    39                 u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
    40            end           
    41         end
    42         
    43         if norm(pre_u-u)<0.1  %不断迭代直到位置不再变化
    44             break;
    45         end
    46     end
    47     
    48     re=[];
    49     for i=1:m
    50         tmp=[];
    51         for j=1:N
    52             tmp=[tmp norm(data(i,:)-u(j,:))];
    53         end
    54         [junk index]=min(tmp);
    55         re=[re;data(i,:) index];
    56     end
    57     
    58 end