【數據挖掘】 kmeans聚類算法的原理與實現 (使用matlab)

實驗目的

(1)理解聚類算法的基本原理。
(2)掌握kmeans聚類算法的原理與實現。

實驗內容

1、數據見 data.mat,編程實現 K means 算法代碼 K_MeansMt,並寫出詳細註釋。

測試代碼如下:

load 'data.mat';
[u re]=K_MeansMt(data,3);  %最後產生簇標號 re 
[m n]=size(re);
%最後顯示聚類後的數據
figure;
hold on;
for i=1:m 
    if re(i)==1   
         plot(data(i,1),data(i,2),'ro'); 
    elseif re(i)==2
         plot(data(i,1),data(i,2),'go'); 
    else 
         plot(data(i,1),data(i,2),'bo'); 
    end
end
grid on;

測試數據

數據見 data.mat

鏈接: https://pan.baidu.com/s/1vRSaZVzEI69ING6IQWJ-zA

提取碼: 338y

實驗原理

基本K均值算法

K均值的算法步驟

  • 首先選擇K個初始質心,其中K是用戶指定的參數,即所期望的簇的個數。每個點指派到最近的質心,而指派到一個質心的點集爲一個簇。
  • 然後,根據指派到簇的點,更新每個簇的質心。
  • 重複指派和更新步驟,直到簇不發生變化,或等價的,直到質心不發生變化。
算法流程如下:
  • 選擇 k個點作爲初始質心
  • repeat:
  • 將每個點指派到最近的質心,形成 k 個簇
  • 重新計算每個簇的質心
  • until 質心不發生變化

對於鄰近性函數和質心類型的某些組合,k均值總是收斂到一個解,即k均值到達一種狀態,其中所有點都不會從一個簇轉移到另一個,因此質心不再改變。然而,由於大部分收斂都發生在早期階段,因此通常用較弱的條件替換算法(上述第5行)。例如,用“直到僅有1%的點改變簇”。

實驗代碼

%%k表示數據一共分多少類
%%data是輸入的不帶分類標號的數據
%%u是每一類的中心
%%clusterID是返回的帶分類標號的數據

function [u clusterID] = K_MeansMt(data,k)
    [m n] = size(data); %m是數據個數,n是數據維數
    maxn = zeros(1,n); %每一維最大的數
    minn = zeros(1,n); %每一維最小的數
    u = zeros(k,n); %隨機初始化,最終迭代到每一類的中心位置
    for i=1:n
        maxn(i) = max(data(:,i)); %每一維最大的數
        minn(i) = min(data(:,i)); %每一維最小的數
        for j=1:k
            u(j,i) = minn(i)+(maxn(i)-minn(i))*rand(); %隨機初始化,保證處於[minn,maxnn]之間
        end
    end
    
    while 1
        pre_u = u; %上一次求得的質心位置
        coordinate_difference{m,k} = [];
        for i=1:m
            % data(i,:)-u(j,:) 爲計算質心做準備
            for j=1:k
                coordinate_difference{i,j} = data(i,:) - u(j,:);
            end
        end
        Dist = ones(m,k)*-1;
        for i=1:m  %計算質心
            c=zeros(1,k);
            for j=1:k
                c(j) = norm(coordinate_difference{i,j});
            end
            [cmin index] = min(c);  %%哪個類的距離最小(index爲類號)
            Dist(i,index) = norm(coordinate_difference{i,index});
        end
        
        for i=1:k
            ind = find(Dist(:,i)>=0);
            u(i,:) = mean(data(ind,:));
        end
        
        if(norm(pre_u - u)<0.1)  %不斷迭代直到位置不再變化
            break;
        end
    end
    
    clusterID = [];
    for i=1:m
        dist = [];
        for j=1:k
            dist = [dist norm(data(i,:)-u(j,:))];  %每個點到穩定後的類中心的距離
        end
        [x index] = min(dist);  %%選擇距離最小的類別號
        clusterID = [clusterID;index];
    end
end     

實驗結果

學如逆水行舟,不進則退
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章