簡體   English   中英

正確實現k-means算法

[英]Implementing k-means algorithm correctly

我剛剛開始學習編碼,並開始編寫標准的k-means算法。 我在由三個不同的高斯生成的數據集上嘗試了實現,它似乎運行良好。 但是,我在虹膜數據集上進行了嘗試,然后不時(大約三分之一的時間)我的函數僅返回兩個集合,換句話說,它僅返回兩個簇。

我偷看了本地MATLAB kmeans函數的代碼,但由於缺乏編碼知識,最終迷失了自己。 我將非常感謝您的幫助!

function [R,C,P,it] = mykmeans(X,K)
% X -- data matrix
% K -- number of clusters
% C -- partition sets
% P -- matrix of prototypes
% R -- binary indicator matrix: R(i,j) specifies whether the ith data is
% classified into jth cluster
% it -- number of iterations until convergence

% N points with M dimensions
[N,M] = size(X) ;

%% Initialisation

% At this step we randomly partition the data matrix into K equally sized
% matrices and compute the centre of each of these matrices.
% I -- randomised index vector
% v -- number of data points assigned to each cluster
% U -- randomly partitioned matrices

v = N/K ;
C = cell(K,1) ;
U = cell(K,1) ;
I = randperm(N) ;
oldR = zeros(N,K) ;

% C{1} = X(I(1:v),:) ;
% U{1} = mean(X(I(1:v),:)) ;
for k=1:K
    C{k} = X(I(1+v*(k-1):k*v),:) ;
    U{k} = mean(C{k}) ;
end

P = cell2mat(U) ;

converged = 0 ;
it = 0 ;
while converged ~= 1

    %% Assignment step

    % Each element of D{n} contains squared euclidean distance of nth data 
    % point from the kth prototype
    D = cell(N,1) ;
    R = zeros(N,K) ;
    for n=1:N
        D{n} = sum((repmat(X(n,:),K,1) - P).^2,2) ;
        [~,k] = min(D{n}) ;
        R(n,k) = 1 ; 
    end

    %% Update step

    C = cell(K,1) ; % reset C
    for k=1:K
        for n=1:N
            P(k,:) = R(n,k)*X(n,:) + P(k,:) ; % compute numerator of mean vector
            if R(n,k) == 1
                C{k} = [C{k};X(n,:)] ;
            end
        end
    end

    P = P ./ (sum(R)') ; % divide by denominator of mean vectors to get prototypes

%% Check for convergence

    if sum(sum(R == oldR))==N*K || it == 100 % convergence criteria
        converged = 1 ;
    else
        oldR = R ;
        it = it+1 ;
    end
end %while

實際上,該問題似乎不是編碼問題,而是理解k均值的問題。

實際上,在k均值期間,簇可能會變空。 您需要為此在代碼中說明,否則結果中的簇數可能小於k。

可能的解決方案可能是:

  • 為空群集分配一個隨機數據點作為新群集中心
  • 選擇距離最大群集最遠的點作為空群集的新群集中心

因此,一般方法如下:

  1. 初始化k個群集中心(例如:隨機)
  2. 將所有數據點分配給最近的集群中心
  3. 根據分配重新計算聚類中心
  4. 檢查空集群
  5. 重復步驟2-4,直到收斂為止(==集群中心在上一次迭代中未發生變化)

這里可以找到有關空集群問題的很好的說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM