k-means算法及matlab實現


K-means算法很簡單,它屬於無監督學習算法中的聚類算法中的一種方法吧,利用歐式距離進行聚合啦。

解決的問題如圖所示哈:有一堆沒有標簽的訓練樣本,並且它們可以潛在地分為K類,我們怎么把它們划分呢?     那我們就用K-means算法進行划分吧。

image

 

算法很簡單,這么做就可以啦:

第一步:隨機初始化每種類別的中心點,u1,u2,u3,……,uk;

第二步:重復以下過程:

image

然后 ,就沒有然后了,就這樣子。

太簡單, 不解釋。

 

 

2017年10月14日補:

今晚造了一個輪子,k-means算法在matlab中的實現,使用的是歐氏距離; 共有兩個文件,分別為euclidean_distance.m 與k_means.m;   代碼如下(或:http://pan.baidu.com/s/1o8p6sfo 密碼:4hhb):

 

euclidean_distance.m文件:

function [ output ] = euclidean_distance(data, center)
% 用於計算訓練樣本與聚類中心的的歐氏距離的平方;
% 其中  data為一個 矩陣 M×N, 表示樣本集,其中M表示共有M個樣本, N表示每一個樣本的維度;
%      centre 為一個矩陣 K×N,表示K個聚類中心,N表示樣本的維度;
%      output 為一個矩陣,大小為M×K; 第x行y列表示第X個樣本與第Y個聚類中心的距離;(每一行表示一個樣本與K個聚類中心的距離);


% 作者:殷和義;
% 時間:2017年10月14日;




data_num = size(data, 1);
center_num = size(center, 1);
output = zeros(data_num, center_num);
for i = 1:center_num
    difference = data - repmat(center(i,:), data_num, 1);    %求樣本集與第i個聚類中心的差;
    sum_of_squares = sum(difference .* difference, 2);        %求平方, 並對每一行求和;
    output(:, i) = sum_of_squares;             
end

end

 

k_means.m 文件

function [ output ] = k_means(data, k_value)
% 功能:實現K-means算法的聚類功能;
% 輸入:    data, 為一個 矩陣 M×N, 表示樣本集,其中M表示共有M個樣本, N表示每一個樣本的維度;
%           k_value, 表示聚類的類別數目;
% 輸出:    output, 是一個列向量 M×,表示每一個樣本屬於的類別編號;

% 作者: 殷和義;
% 時間: 2017年10月14日


%從樣本中,隨機選取K個樣本作為初始的聚類中心;
data_num = size(data, 1);
temp = randperm(data_num, k_value)';     
center = data(temp, :);

%用於計數迭代次數:
iteration = 0;
while 1
    %獲得樣本集與聚類中心的距離;
    distance = euclidean_distance(data, center);
    %將距離矩陣的每一行從小到大排序, 獲得相應的index值,其實我們只需要index的第一列的值;
    [~, index] = sort(distance, 2, 'ascend');

    %接下來形成新的聚類中心;
    center_new = zeros(k_value, size(data, 2));
    for i = 1:k_value
        data_for_one_class = data(index(:, 1) == i, :);          
        center_new(i,:) = mean(data_for_one_class, 1);    %因為初始的聚類中心為樣本集中的元素,所以不會出現某類別的樣本個數為0的情況;
    end
   
    %輸出迭代次數,給眼睛一個反饋;
    iteration = iteration + 1;
    fprintf('進行迭代次數為:%d\n', iteration);
    
    % 如果這兩次的聚類中心不變,則停止迭代,跳出循環;
    if center_new == center
        break;
    end
    
    center = center_new;
end

output = index(:, 1);
    
end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM