2012-06-08 5 views
6

Estoy intentando trazar el codo de k significa con el siguiente código:K significa encontrar codo cuando la trama codo es una curva suave

load CSDmat %mydata 
for k = 2:20 
    opts = statset('MaxIter', 500, 'Display', 'off'); 
    [IDX1,C1,sumd1,D1] = kmeans(CSDmat,k,'Replicates',5,'options',opts,'distance','correlation');% kmeans matlab 
    [yy,ii] = min(D1');  %% assign points to nearest center 

    distort = 0; 
    distort_across = 0; 
    clear clusts; 
    for nn=1:k 
     I = find(ii==nn);  %% indices of points in cluster nn 
     J = find(ii~=nn);  %% indices of points not in cluster nn 
     clusts{nn} = I;   %% save into clusts cell array 
     if (length(I)>0) 
      mu(nn,:) = mean(CSDmat(I,:));    %% update mean 
      %% Compute within class distortion 
      muB = repmat(mu(nn,:),length(I),1); 
      distort = distort+sum(sum((CSDmat(I,:)-muB).^2)); 
      %% Compute across class distortion 
      muB = repmat(mu(nn,:),length(J),1); 
      distort_across = distort_across + sum(sum((CSDmat(J,:)-muB).^2)); 
     end 
    end 
    %% Set distortion as the ratio between the within 
    %% class scatter and the across class scatter 
    distort = distort/(distort_across+eps); 

     bestD(k)=distort; 
     bestC=clusts; 
end 
figure; plot(bestD); 

Los valores de bestD (a menos de varianza cluster/entre varianza cluster) son

[ 
0.401970132754914 
0.193697163350293 
0.119427184084282 
0.0872681777446508 
0.0687948264457301 
0.0566215549396577 
0.0481117619129058 
0.0420491551659459 
0.0361696583755145 
0.0320384092689509 
0.0288948343304147 
0.0262373245283877 
0.0239462330460614 
0.0218350896369853 
0.0201506779033703 
0.0186757121130685 
0.0176258625858971 
0.0163239661159014 
0.0154933431470081 
] 

El código está adaptado de Lihi Zelnik-Manor, marzo de 2005, Caltech.

La relación de parcela dentro de la varianza del conglomerado a la varianza entre conglomerados es una curva suave con una rodilla que es lisa como una curva, traza los datos bestD indicados anteriormente. ¿Cómo encontramos la rodilla para tales gráficos?

+5

¿Podría compartir también la trama? –

+1

posible duplicado de [encontrar el mejor punto de equilibrio en una curva] (http://stackoverflow.com/questions/2018178/finding-the-best-trade-off-point-on-a-curve) – Amro

+1

Ver [ how-do-i-determine-k-when-using-k-means-clustering] (http://stackoverflow.com/questions/1793532/how-do-i-determine-k-when-using-k-means -clustering) en SO. – denis

Respuesta

0

creo que es mejor usar sólo su "dentro de la distorsión de clase" como parámetro de optimización:

%% Compute within class distortion 
muB = repmat(mu(nn,:),length(I),1); 
distort = distort+sum(sum((CSDmat(I,:)-muB).^2)); 

Utilice esta sin dividiendo este valor por "distort_across". Si se calcula el "derivado" de este:

unexplained_error = within_class_distortion; 
derivative = diff(unexplained_error); 
plot(derivative) 

El derivado (k) le indica la cantidad del error inexplicable se ha reducido mediante la adición de un nuevo clúster. Sugiero que deje de agregar clusters cuando la disminución de este error sea menos de diez veces la primera disminución que obtuvo.

for (i=1:length(derivative)) 
    if (derivative(i) < derivative(1)/10) 
     break 
    end 
end 
k_opt = i+1; 

De hecho, el método para obtener el número óptimo de clusters es dependiente de la aplicación, pero creo que se puede obtener un buen valor de k usando esta sugerencia.

Cuestiones relacionadas