1. 程式人生 > >Matlab實現K均值聚類

Matlab實現K均值聚類

作為第一個部落格,我寫了一個簡單的K均值聚類演算法。過程大致如下:
(1)從n個樣本中任意選擇(一般是隨機分配),k個作為初始聚類中心;
(2)對於剩下的其它樣本點,根據它們與這些聚類中心的距離,分別將它們分配給與其最相似的中心所在的類別 C j
(3)計算每個新類的聚類中心;
(4)不斷重複步驟(2)(3),直到所有樣本點的分類不再改變或類中心不再改變。

一、方法說明

  • 在(2)計算距離的時候,我用的是歐式距離

    dij=k=1n(XikXjk)2
    其中,i和j表示第i個點和第j個點,n表示聚類物件是n維的,比如聚類物件為2維的,我們計算第一個點和第二個點的歐式距離:
    d
    12
    =(x11x21)2+(x12x22)2


  • 在(3)更新聚類中心時,對於每一個類,重新計算該類的中心:

    uj=mi=11{c(i)=j}x(i)mi=11{c(i)=j}

  • 二、Matlab實現
    資料是用rand隨機生成的100個點,K均值聚類的程式如下:
    function [C,new_u,iter]=Kmeans(data,k) %該程式對data聚類,k
    %從data中隨機選擇k個樣本作為初始均值向量{u1,u2}
    [row,col]=size(data);%row為樣本個數,col為維數
    %隨機抽取樣本點作為初始中心的向量
    rand('seed',9);num=randsample(length(data),k,'false'); u=zeros*data(num,:);new_u=data(num,:); %初始化元胞,和迭代次數 C=cell(1,k);iter=1; while(new_u~=u) u=new_u;C=cell(1,k); for i=1:k %計算每一個樣本點與中心的歐式距離 dist(:,i)=sqrt(sum((data-repmat(u(i,:),row,1)).^2,2)); end for j=1:row index=find
    (dist(j,:)==min(dist(j,:))); C{1,index}=[C{1,index};data(j,:)]; end for i=1:k new_u(i,:)=sum(C{1,i})/length(C{1,i}); end iter=iter+1; %迭代次數 end KmeansPlot(C,new_u,k);%畫圖 end


    聚類結果如下:

    這裡寫圖片描述


    三、虛擬碼
    在這裡,給讀者再貼上一個周志華寫的機器學習裡k均值聚類的虛擬碼,便於理解。
    這裡寫圖片描述


    四、總結

    1. k均值不需要計算任意兩點的距離,因此比其它聚類方法有更快的收斂速度
    2. k均值被批評可能陷入區域性最優,全域性最優需要藉助模擬退火演算法或遺傳演算法
    3. 容易受到初始點選擇的影響,不適合非凸問題,受異常資料影響受不同類別密度方差大小的影響,解決方法是二分k均值

    [1]王星編著.大資料分析 方法與應用[M].北京:清華大學出版社.2013.
    [2]周志華著.機器學習[M].北京:清華大學出版社.2016.