我对k-means的实现给出了不同的结果

时间:2017-11-16 18:13:40

标签: initialization cluster-analysis k-means centroid

我尝试实施Lloyd的算法,直到我多次运行它才显得很好。有时它会给出我想要的结果,有时它会给出奇怪的中心。 我试图改变条件,以便它在收敛时停止,但它没有帮助。很抱歉没有将评论翻译成英文,我希望它足够清楚。

我在代码中唯一的随机性是在我的集群清空的情况下,所以我用随机点替换它。当这种情况发生时,我不知道该怎么做。

我无法看到问题。你能告诉我结果数字可能出现什么问题吗?

Plotting resulting centers and points

This is the other case when something goes wrong

这是我的代码: (A是一个矩阵,其行是我的点)

% initialization of centroids; further-first method
n=size(A,1);
dim=size(A,2);
centri=zeros(k,dim); %matrix of centroids
for i=1:n
    centri(1,:)=centri(1,:)+A(i,:);
end
centri(1,:)=centri(1,:)/n;
for j=2:k %u svakom koraku postavljamo za centar onu tocku koja je najdalje od centra 1,..j-1
    maks=zeros(1,n);
    %maks(i) je najveca udaljenost te tocke do centra =max d(x(i),c), c centri
    for i=1:n
        dist=zeros(1,j-1);
        for l=1:j-1
            dist(l)=norm(A(i,:)-centri(l,:));
        end
        if(size(dist,2)==1) maks(i)=dist;
        else
            maks(i)=max(dist);
        end
        %maks(i)=0;
        %for l=1:j-1
          %  if(maks(i)<dist(l)) maks(i)=dist(l);
           % end
        %end
    end
    [maksi, ind]=max(maks);
    centri(j,:)=A(ind(1),:);
end

indeksi=zeros(1,n);
for i=1:n 
    indeksi(i)=randi(k,1);
end  
% u centrima je postavljena pocetna inicijalizacija
br_iter=0;
tic

while br_iter<=1000
    br_iter=br_iter+1;

    for i=1:n
        dist=zeros(1,k); % udaljenosti od tocke x do centra j
        for j=1:k
            dist(j)=norm(A(i,:)-centri(j,:));
        end
        [mini, ind]=min(dist); % ind je vektor za koji se poprima minimalna vrijednost
        indeksi(i)=ind(1); % uzmemo prvi po redu
    end
    % sad radimo nove centroide koji su aritmetička sredina svih vektora koji mu pripadaju
    for j=1:k
        centri(j,:)=zeros(1,dim);
        brojac=0;
        for i=1:n
            if indeksi(i)==j 
                centri(j,:)=centri(j,:)+A(i,:);
                brojac=brojac+1;
            end
        end
        if brojac 
            centri(j,:)=centri(j,:)/brojac;
        else
            ind=randi(n, 1);
            centri(j,:)=A(ind,:);
        end
    end
end 
toc
for i=1:n
    plot(A(i,1), A(i,2), '.b');
   if(i==1) hold on;
   end
end

for i=1:k
    plot(centri(i,1), centri(i,2), '+r');
end
hold off

1 个答案:

答案 0 :(得分:0)

从中心开始,所有零都不是推荐的方法。 在第一次迭代之后,除了其中一个中心之外的所有中心都将为空。所以随机性确实会对你的结果产生影响。

您显示的结果是k-means的典型。它并不保证能够满足最佳效果,但它可能会陷入“局部最佳”状态。

所以我认为您的代码中没有错误。只是开始条件不是非常明智地选择&amp;你错误地认为k-means总能给出好的结果。